diff --git a/board/aarch64/Config.in b/board/aarch64/Config.in index 8e0974310..dc4fbce90 100644 --- a/board/aarch64/Config.in +++ b/board/aarch64/Config.in @@ -9,6 +9,7 @@ source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/freescale-imx8mp-evk/Config.in" source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/friendlyarm-nanopi-r2s/Config.in" source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/marvell-cn9130-crb/Config.in" source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/marvell-espressobin/Config.in" +source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/microchip-ev23x71a/Config.in" source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/microchip-sparx5-pcb135/Config.in" source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/raspberrypi-rpi64/Config.in" source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/styx-dcp-sc-28p/Config.in" diff --git a/board/aarch64/microchip-ev23x71a/Config.in b/board/aarch64/microchip-ev23x71a/Config.in new file mode 100644 index 000000000..dc3e8254d --- /dev/null +++ b/board/aarch64/microchip-ev23x71a/Config.in @@ -0,0 +1,7 @@ +config BR2_PACKAGE_MICROCHIP_EV23X71A + bool "Microchip EV23X71A (Laguna)" + depends on BR2_aarch64 + help + Support for the Microchip EV23X71A evaluation board, based on + the LAN969x (Laguna) family of TSN capable switches. 24 GbE + copper ports, 4 SFP+ ports, and a separate management port. diff --git a/board/aarch64/microchip-ev23x71a/EVB-LAN9696-24port.png b/board/aarch64/microchip-ev23x71a/EVB-LAN9696-24port.png new file mode 100644 index 000000000..bb71baaa6 Binary files /dev/null and b/board/aarch64/microchip-ev23x71a/EVB-LAN9696-24port.png differ diff --git a/board/aarch64/microchip-ev23x71a/LICENSE b/board/aarch64/microchip-ev23x71a/LICENSE new file mode 100644 index 000000000..8cdb30a3a --- /dev/null +++ b/board/aarch64/microchip-ev23x71a/LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2026 The KernelKit Authors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/board/aarch64/microchip-ev23x71a/README.md b/board/aarch64/microchip-ev23x71a/README.md new file mode 100644 index 000000000..195d5534c --- /dev/null +++ b/board/aarch64/microchip-ev23x71a/README.md @@ -0,0 +1,463 @@ +# Microchip EV23X71A (Laguna) + +The board + +Evaluation board for the Microchip LAN969x (Laguna) family, a TSN capable +28-port switch with a Cortex-A53 CPU core. + +| **Property** | **Value** | +|--------------|---------------------------------------------| +| SoC | LAN969x, ARM Cortex-A53 single-core @ 1 GHz | +| Memory | 1 GiB DDR4 x16 RAM | +| Storage | 4 GiB eMMC on SDMMC0, 2 MiB QSPI NOR | +| Switch | 24 x GbE copper, 4 x SFP+, 1 x RGMII NPI | +| Console | `ttyAT0`, 115200 8N1 | + +## Status + +Supported: + +- switch core and SerDes, all ports +- eMMC, I2C (including the SFP mux), SPI, USB host +- watchdog, temperature sensor, SGPIO LEDs +- our own boot chain, from BL2 to a slot booted out of the eMMC, with + the environment held in the authenticated control device tree + +Not yet done: + +- TSN queueing. PSFP and time aware shaping need `NET_SCH_TAPRIO`, + `NET_ACT_GATE`, `NET_SCH_ETS`, and `NET_SCH_CBS`, all currently off +- HSR/PRP offload, see above +- MAC addresses. With no environment in flash the board falls back to + `lan969x_otp_get_mac()`, which derives 30 addresses for this board + from OTP, but the OTP address block is blank on our sample, so + interfaces come up random. Provisioning it is a one way operation, + `boot-monitor.rb --otp-data :` in monitor mode + +## Boot Chain + +The board ships with Microchip's boot chain in the eMMC `fip` and `fip.bak` +partitions. The Firmware Image Package (FIP) contains all the components of +ARM Trusted Firmware (TF-A) required to boot the system: BL2, BL31, BL33 +(U-Boot), any certificates and the optional BL32 (OP-TEE). + +The first-stage bootloader (BL1) in mask ROM walks through the FIP sources in +turn, `fip`, then `fip.bak`, then a raw offset, moving on whenever an image +fails to load or authenticate. Leaving a working FIP in `fip.bak` is thus a +way back from a bad one. + +When a valid FIP is found and loaded into SRAM, BL1 jumps to BL2 which brings +up DDR and loads BL31 and U-Boot as BL33. + +> [!NOTE] +> The vendor U-Boot has neither `blkmap`, SquashFS support nor `sysboot`, so +> it cannot map a signed `rootfs.itb` and read `/boot/syslinux/*.conf` out of +> it, which is how Infix boots. It is possible to [Netboot](#netboot) from +> it, though we recommend going for the adapted [Bootloader](#bootloader) to +> be able to boot properly from eMMC. + +## Boot Mode Strapping + +The DIP switch marked *VCore Configuration Strapping* tells BL1 where to +look for the FIP: + +| **VCORE[3:0]** | **Mode** | **Description** | +|----------------|--------------|------------------------------------------------| +| 0000 | eMMC FC0 | Boot from eMMC, boot trace on Flexcom0, 115200 | +| 0001 | QSPI0 FC0 | Boot from NOR, boot trace on Flexcom0, 115200 | +| 0011 | eMMC | Boot from eMMC | +| 0100 | QSPI0 | Boot from NOR | +| 1000 | QSPI0 FC0 HS | Boot from NOR, boot trace on Flexcom0, 921600 | +| 1010 | TF-A FC0 | TF-A monitor on Flexcom0, 115200 | +| 1011 | TF-A FC0 HS | TF-A monitor on Flexcom0, 921600 | +| 1111 | SPI client | QSPI0 as SPI client, internal CPU disabled | + +Only the "Flexcom0" modes give the firmware a console. For the rest +`lan969x_console_init()` selects none, so BL1, BL2, and BL31 print nothing and +the first line on the wire is U-Boot's banner, which brings up its own +console. + +That is also the only way to quiet the firmware. Our `LOG_LEVEL` covers BL2 +and BL31, but BL1 lives in mask ROM and traces at the level it was built with +in 2023, so its `INFO:` lines cannot be turned off from here. Use 0000 while +working on the boot chain, when that trace is what you came for, and 0011 for +a quiet boot. + +### Debricking + +> [!TIP] +> Keep a released vendor FIP in the NOR flash while working with U-Boot or any +> other part of the FIP, so that 0001 always reaches a prompt no matter what +> the eMMC holds. From a running U-Boot: +> +> ``` +> setenv autoboot off +> dhcp +> tftpboot ${loadaddr} lan969x_a0-release.fip +> run nor_fip_upd +> ``` +> +> Even with both flashes unusable the board is recoverable. Strap 1010 leaves +> BL1 in TF-A monitor mode, which [`fwu-lan969x_a0-release.html`][4] drives +> over USB, writing the GPT and FIP to either flash from blank. + +## Bootloader + +Infix keeps its own U-Boot from Microchip's tree, which carries the LAN969x +support, together with Microchip's Trusted Firmware: + +```bash +make laguna_boot_defconfig +make +``` + +The build produces one `fip.bin`, with BL2, BL31, and U-Boot as BL33 in it. +Microchip package BL2 inside the FIP, unlike MediaTek where it lives in a +partition of its own, so there is a single artifact to place. BL1 in ROM +authenticates BL2, so the FIP always carries certificates, which is why the +build needs mbed TLS to parse X.509 in BL1 and BL2. That comes from the +`mbedtls-atf` package, pinned to the 2.28 series ATF 2.8 builds against, since +Buildroot's `mbedtls` tracks 3.x. + +This defconfig builds the `mchp_lan969x_defconfig` plus local fragments, which +add `blkmap`, SquashFS, `sysboot`, and the signed image validation the Infix +boot flow needs, and pin the control device tree to this board. The board +environment, `lan969x-env.dtsi`, sets the load addresses and names the kernel +device tree to pick out of the SquashFS. + +Two build variables are not obvious. `KEY_ALG=ecdsa`, because the LAN969x +crypto driver is built around the Silex ECDSA engine and will not compile +against an mbed TLS configured for RSA only. And `GENERATE_COT=1`, because +BL1 authenticates BL2: without it the FIP has no certificates and the ROM +refuses to boot it. + +Trusted Firmware is pinned to a commit rather than a tag, since no tag carries +the fix for `ERR-LAN969X-001`. The boot ROM's ECDSA verifier mishandles any +P-256 value whose most significant byte is zero, which happens for about one +in 256 random coordinates or signature scalars, so roughly one build in a +hundred produced a FIP the ROM rejected: + +``` +INFO: Authenticating image id=6 (sign) +INFO: Authenticated image id=6 (sign) = 12 +NOTICE: Image(6) load error: 12 +``` + +`cert_create` now screens the values it generates and retries, for details, +see [`ERRATA.md`][5] in the Microchip Trusted Firmware tree. + +## Installing + +The bootloader and the Linux image are separate builds, combined into one eMMC +image using the `mkimage.sh` script: + +```bash +make laguna_boot_defconfig O=x-boot-laguna && make O=x-boot-laguna +make aarch64_defconfig && make +utils/mkimage.sh -b x-boot-laguna -r output -t emmc microchip-ev23x71a +``` + +Install the FIP first, copy `x-boot-laguna/images/fip.bin` to your TFTP server +directory. Strap board to 0001, stop autoboot, and write the FIP to the eMMC: + +``` +setenv fip_fw fip.bin +run mmc_fip0_dlup +``` + +Strap back to 0000 and power cycle. With no `aux` partition to find, the new +U-Boot reports `NO BOOTABLE MEDIA FOUND` and netboots, which is how the rest +of the install happens: see [Installing to Onboard Storage][2] for addressing +the netbooted system and streaming the image onto the eMMC. + +The first boot after installing grows `var` to fill the eMMC and reboots once +by itself. The kernel complains that the backup GPT is not at the end of the +disk until that has happened, which is expected. + +### Updating the FIP + +Once Infix runs from the eMMC the bootloader is just another partition, +`fip` is `mmcblk0p1` and `fip.bak` is `mmcblk0p2`, and nothing mounts +either of them: + +```bash +scp x-boot-laguna/images/fip.bin admin@board:/tmp +ssh admin@board.local 'sudo dd if=/tmp/fip.bin of=/dev/mmcblk0p1 conv=fsync' +``` + +Reboot and check the BL2 build date in the banner. Only then mirror it +into `fip.bak`, so that BL1's fallback stays one known good step behind +whatever is being tried in `fip`: + +```bash +ssh admin@board.local 'sudo dd if=/tmp/fip.bin of=/dev/mmcblk0p2 conv=fsync' +``` + +The same from the U-Boot prompt, which resolves the partition by name: + +``` +setenv autoboot off +dhcp +tftpboot ${loadaddr} fip.bin +setexpr blkcnt ${filesize} + 0x1ff +setexpr blkcnt ${blkcnt} / 0x200 +part start mmc 0 fip fipstart +mmc write ${loadaddr} ${fipstart} ${blkcnt} +``` + +The `mmc_fip0_dlup` helper used during bring-up belongs to the vendor +environment, so it is only there when booting the NOR image. + +## Netboot + +Once the Infix U-Boot is in place, netbooting needs no script at all: hand out +a `rootfs.itb` as the DHCP boot file and `ixprepdhcp` fetches, validates, and +boots it, see the [netboot HowTo][1]. + +The recipe below is for boards still running the vendor U-Boot, before our FIP +has been written. Save it as `netboot.sh`, or paste the lines at the prompt +one at a time: + +``` +# Run: mkimage -T script -d netboot.sh netboot.scr +setenv fdt_addr_r 0x68000000 +setenv kernel_addr_r 0x62000000 +setenv ramdisk_addr_r 0x70000000 + +setenv srvpath ix/ev23x71a +tftp ${fdt_addr_r} ${srvpath}/lan9696-ev23x71a.dtb +tftp ${kernel_addr_r} ${srvpath}/Image +tftp ${ramdisk_addr_r} ${srvpath}/rootfs.itb + +setexpr rdkbsize ${filesize} / 0x400 +setenv bootargs "console=ttyAT0,115200 root=/dev/ram0 brd.rd_size=0x${rdkbsize} rauc.slot=net loglevel=4 usbcore.authorized_default=2" +booti ${kernel_addr_r} ${ramdisk_addr_r}#verity ${fdt_addr_r} +``` + +The addresses keep kernel, device tree, and RAM disk clear of each other in +the 896 MiB starting at 0x60000000. `setexpr` stores bare hex, hence the `0x` +in front of `${rdkbsize}`. `rauc.slot=net` marks the system as network booted +rather than running from a slot, the same variable `ixbootslot.sh` sets for a +real one. + +Two details are peculiar to the U-Boot that ships with the board: + +- Pass `rootfs.itb`, not the bare `rootfs.squashfs`. It is built without + `SUPPORT_RAW_INITRD`, so the `addr:size` form of the ramdisk argument is + never parsed, and anything that is neither a FIT nor a legacy uImage is + rejected with `Wrong Ramdisk Image Format`. + +- Name the `verity` configuration. `mchp_lan969x_defconfig` sets + `MULTI_DTB_FIT`, since U-Boot carries a device tree for each LAN969x board, + and in 2023.04 that makes `fit_conf_get_node()` pick a configuration by + matching compatible strings, never falling back to the `default` property. + Our ITB carries a ramdisk and no device tree, so there is nothing to match, + and it fails with `Could not find configuration node`. + +The ITB is signed with the Infix development key, which that U-Boot knows +nothing about, so it prints `-` for the signature and loads the ramdisk +anyway; only keys marked required in the bootloader's control device tree can +fail an image. + +To boot without typing anything, wrap the script and hand it out over DHCP as +the boot file: + +```bash +mkimage -T script -C none -n netboot -d netboot.sh netboot.scr +``` + +The vendor U-Boot will not source it by itself, its `bootcmd` runs `mmc_boot`, +so point it at the script once: + +``` +setenv autoboot off +setenv bootcmd 'dhcp; source ${loadaddr}' +saveenv +``` + +`dhcp` fetches the boot file to `${loadaddr}`, 0x64000000 in the shipped +environment and clear of the three addresses above. `saveenv` writes the +`Env` partition in the eMMC; the original value is `run mmc_boot`. With +a relay on the board's supply, a power cycle then becomes the whole +build, flash, and boot cycle. + +## Switch Core + +The board reports part `0x969b` revision 0, a LAN9696RED (lan969x-60-RED). +The driver reads `GCB_CHIP_ID` at probe but never prints it, so read it out: + +``` +devmem 0xe2010000 32 +``` + +Bits 27:12 hold the part, 31:28 the revision. Which part it is decides what +the driver offers: `sparx5_init_features()` enables PTP and PSFP for the TSN, +RED, and VAO variants only, and leaves a plain LAN9694, LAN9696, or LAN9698 +without either. + +| **ID** | **Part** | **Family** | **PTP, PSFP** | +|----------|--------------|-------------|---------------| +| `0x9694` | LAN9694 | lan969x-40 | no | +| `0x9691` | LAN9691VAO | lan969x-40 | yes | +| `0x9695` | LAN9694TSN | lan969x-40 | yes | +| `0x969a` | LAN9694RED | lan969x-40 | yes | +| `0x9696` | LAN9696 | lan969x-60 | no | +| `0x9692` | LAN9692VAO | lan969x-65 | yes | +| `0x9697` | LAN9696TSN | lan969x-60 | yes | +| `0x969b` | LAN9696RED | lan969x-60 | yes | +| `0x9698` | LAN9698 | lan969x-100 | no | +| `0x9693` | LAN9693VAO | lan969x-100 | yes | +| `0x9699` | LAN9698TSN | lan969x-100 | yes | +| `0x969c` | LAN9698RED | lan969x-100 | yes | +| `0x7546` | SparX-5-64 | Enterprise | no | +| `0x7549` | SparX-5-90 | Enterprise | no | +| `0x7552` | SparX-5-128 | Enterprise | no | +| `0x7556` | SparX-5-160 | Enterprise | no | +| `0x7558` | SparX-5-200 | Enterprise | no | +| `0x0546` | SparX-5-64i | Industrial | yes | +| `0x0549` | SparX-5-90i | Industrial | yes | +| `0x0552` | SparX-5-128i | Industrial | yes | +| `0x0556` | SparX-5-160i | Industrial | yes | +| `0x0558` | SparX-5-200i | Industrial | yes | + +The register is the same on SparX-5, only the address differs, since +`TARGET_GCB` sits elsewhere in that family's register map: + +``` +devmem 0x611010000 32 +``` + +The RED in the part number is hardware HSR/PRP RedBox support. + +## Interfaces + +The sparx5 driver leaves naming to the kernel, which hands out `eth0` and up +in probe order, this makes it off-by-one from the numbering in the official +documentation. The product specific `90-ev23x71a-rename-ifaces.rules` renames +them to the usual interface names: + +| **Device tree** | **Interface** | **Port** | +|--------------------|----------------|---------------------| +| `port@0..port@23` | `e1` .. `e24` | 1G copper, QSGMII | +| `port@24..port@27` | `e25` .. `e28` | 10G SFP+ | +| `port@29` | `e29` | 1G RGMII management | + +Attaching 29 PHYs takes the driver a good half second each, far longer than +the ten seconds `hw-wait` waits for slow devices by default. The product +therefore raises it in `/etc/default/hw-wait`, so that services which expect +the ports to exist do not start ahead of them. + +## LEDs + +The board has one software controlled status LED and a green and yellow pair +per SFP cage, driven over SGPIO: + +``` +green:status front panel status +green:lan-0 .. green:lan-3 SFP1 .. SFP4, green +yellow:lan-0 .. yellow:lan-3 SFP1 .. SFP4, yellow +``` + +The common `/etc/iitod.json` drives `green:boot` and `green:status` from +inputs this board has no LEDs for, so the product ships its own. It blinks +`green:status` at 1 Hz while booting, holds it on once `run/startup/success` +is asserted, and flashes 5 Hz for a fail-safe boot or a panic. The green SFP +LEDs get the kernel netdev trigger, bound to `e25` through `e28`, for link and +activity. + +The yellow ones are left alone for now. `iitod` writes any key in a rule's +`then` object straight to the LED's sysfs directory, so they can be given a +trigger later without touching any code. + +## Debug and Analysis + +`DEBUG_FS` is on in the aarch64 configuration, and the driver puts its VCAP +state there: + +``` +/sys/kernel/debug/sparx5/vcaps/ +├── is0_0, is0_1, is0_2 decoded rules, CLM-0 through CLM-2 +├── is2_0, is2_1, es0_0, es2_0 the remaining VCAP instances +├── raw_is0_0, raw_is2_0, ... raw entry dump of each of the above +└── eth0 .. eth28 per port key set selection +``` + +Reading `is2_0` after a `tc filter add` shows what the classifier actually +programmed, which is the quickest way to separate an unsupported match from a +broken one. The per port files show which key sets each lookup is configured +for, which is what decides whether a rule can match on a given port at all. + +Every port netdev links to its device tree node, so they can be mapped back to +switch ports whatever order they probed in: + +```bash +for d in /sys/class/net/eth*; do + echo "$(basename $d) -> $(readlink $d/of_node)" +done +``` + +Counters come from `ethtool`, which implements the structured groups as +well as the flat set: + +```bash +ethtool -S eth0 # flat, the full sparx5 counter set +ethtool -S eth0 --all-groups # mac, phy, ctrl, and rmon groups +ethtool -T eth0 # timestamping, empty unless the part has PTP +ethtool -m eth24 # SFP module EEPROM, read through the i2c mux +``` + +There is no `ethtool -p`, the driver implements no `set_phys_id`, and no +devlink support at all, so do not go looking for `devlink dev info`. + +PHY registers over the GCB MDIO controller, with `mdio` from mdio-tools +(the `mdio-netlink` module is built for this kernel): + +```bash +# mdio # list buses +# mdio e20101a8.mdio-mii phy 0x03 # the management port PHY, a LAN8841 +BMCR(0x00): 0x1040 + flags: -reset -loopback +aneg-enable -power-down -isolate -aneg-restart + -collision-test + speed: 1000-half + +BMSR(0x01): 0x796d + capabilities: -100-t4 +100-tx-f +100-tx-h +10-t-f +10-t-h -100-t2-f -100-t2-h + flags: +ext-status +aneg-complete -remote-fault +aneg-capable +link + -jabber +ext-register + +ID(0x02/0x03): 0x00221652 + +ESTATUS(0x0F): 0x2000 + capabilities: -1000-x-f -1000-x-h +1000-t-f -1000-t-h + +# mdio e20101a8.mdio-mii phy 0x04 raw 0x1 +0x7949 +``` + +The bus name is the one dmesg prints for each port, `PHY +[e20101a8.mdio-mii:0d]`, and the INDY quads answer at 0x04 through 0x1b. +Scanning the whole bus, `mdio e20101a8.mdio-mii` with no object, instead +fails with `Unable to read status (-5)`: `mscc_miim_read()` returns +`-EIO` when the controller flags a read error, which is what an address +with no PHY behind it does, and the scan gives up there. Address a +specific PHY instead. Loading `mdio-netlink` needs root, so run the +tool under `sudo`. + +Sensors and LEDs are plain class devices, `/sys/class/hwmon/*/temp1_input` +for the die temperature and `/sys/class/leds/` for the status LED and the +SGPIO driven port LEDs. + +For the eMMC, the mmc core exposes the negotiated bus parameters and the +card's own health estimate: + +```bash +cat /sys/kernel/debug/mmc0/ios # timing, bus width, clock +cat /sys/class/mmc_host/mmc0/mmc0:0001/life_time # EXT_CSD wear estimate +cat /sys/class/mmc_host/mmc0/mmc0:0001/pre_eol_info # 0x01 normal, 0x03 urgent +``` + +[0]: https://microchip-ung.github.io/bsp-doc/ +[1]: https://www.kernelkit.org/infix/latest/netboot/ +[2]: https://www.kernelkit.org/infix/latest/netboot/#installing-to-onboard-storage +[4]: https://github.com/microchip-ung/arm-trusted-firmware/releases/latest +[5]: https://github.com/microchip-ung/arm-trusted-firmware diff --git a/board/aarch64/microchip-ev23x71a/dts/Makefile b/board/aarch64/microchip-ev23x71a/dts/Makefile new file mode 100644 index 000000000..4190893a4 --- /dev/null +++ b/board/aarch64/microchip-ev23x71a/dts/Makefile @@ -0,0 +1 @@ +dtb-y += microchip/lan9696-ev23x71a.dtb diff --git a/board/aarch64/microchip-ev23x71a/dts/microchip/infix.dtsi b/board/aarch64/microchip-ev23x71a/dts/microchip/infix.dtsi new file mode 100644 index 000000000..e39f876f8 --- /dev/null +++ b/board/aarch64/microchip-ev23x71a/dts/microchip/infix.dtsi @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Common Infix OS defaults + */ + +/ { + chosen { + infix { + /* Default admin user password: 'admin' */ + factory-password-hash = "$5$mI/zpOAqZYKLC2WU$i7iPzZiIjOjrBF3NyftS9CCq8dfYwHwrmUK097Jca9A"; + usb-ports = <&usb>; + usb-port-names = "USB"; + }; + }; +}; diff --git a/board/aarch64/microchip-ev23x71a/dts/microchip/lan9696-ev23x71a.dts b/board/aarch64/microchip-ev23x71a/dts/microchip/lan9696-ev23x71a.dts new file mode 100644 index 000000000..105ad2317 --- /dev/null +++ b/board/aarch64/microchip-ev23x71a/dts/microchip/lan9696-ev23x71a.dts @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Infix OS device tree for Microchip EV23X71A (Laguna) + */ + +#include +#include "infix.dtsi" diff --git a/board/aarch64/microchip-ev23x71a/genimage.cfg.in b/board/aarch64/microchip-ev23x71a/genimage.cfg.in new file mode 100644 index 000000000..b42557d42 --- /dev/null +++ b/board/aarch64/microchip-ev23x71a/genimage.cfg.in @@ -0,0 +1,81 @@ +image cfg.ext4 { + empty = true + temporary = true + size = 128M + ext4 { + label = "cfg" + use-mke2fs = true + features = "uninit_bg" + extraargs = "-m 0 -i 4096" + } +} + +# The /var partition will be expanded automatically at first boot +# to use the full size of the eMMC. +image var.ext4 { + empty = true + temporary = true + size = 128M + ext4 { + label = "var" + use-mke2fs = true + features = "uninit_bg" + extraargs = "-m 0 -i 4096" + } +} + +image #IX_ID##VERSION#-ev23x71a-#TARGET#.img { + hdimage { + partition-table-type = "gpt" + gpt-no-backup = true + } + + # BL1, in ROM, looks up the FIP by GPT partition name, so these + # two must keep their names. Microchip's own layout gives them + # 128 MiB each, which a 1 MiB image does not need. + partition fip { + image = "fip.bin" + offset = 1M + size = 4M + } + + partition fip.bak { + image = "fip.bin" + size = 4M + } + + # Not used by Infix, its boot logic is stateless, but kept so a + # vendor U-Boot has somewhere of its own to save an environment. + partition Env { + size = 2M + } + + partition aux { + partition-uuid = D4EF35A0-0652-45A1-B3DE-D63339C82035 + image = "aux.ext4" + } + + partition primary { + partition-type-uuid = 0FC63DAF-8483-4772-8E79-3D69D8477DE4 + bootable = true + size = 250M + image = "rootfs.squashfs" + } + + partition secondary { + partition-type-uuid = 0FC63DAF-8483-4772-8E79-3D69D8477DE4 + bootable = true + size = 250M + image = "rootfs.squashfs" + } + + partition cfg { + partition-uuid = 7aa497f0-73b5-47e5-b2ab-8752d8a48105 + image = "cfg.ext4" + } + + partition var { + partition-uuid = 8046A06A-E45A-4A14-A6AD-6684704A393F + image = "var.ext4" + } +} diff --git a/board/aarch64/microchip-ev23x71a/microchip-ev23x71a.hash b/board/aarch64/microchip-ev23x71a/microchip-ev23x71a.hash new file mode 100644 index 000000000..2b1e74432 --- /dev/null +++ b/board/aarch64/microchip-ev23x71a/microchip-ev23x71a.hash @@ -0,0 +1,2 @@ +# Locally calculated +sha256 d48246c717b505cc11df95171f2fd548b389e1a463f1af4c68d0b69fe0d1009b LICENSE diff --git a/board/aarch64/microchip-ev23x71a/microchip-ev23x71a.mk b/board/aarch64/microchip-ev23x71a/microchip-ev23x71a.mk new file mode 100644 index 000000000..9d2267b5d --- /dev/null +++ b/board/aarch64/microchip-ev23x71a/microchip-ev23x71a.mk @@ -0,0 +1,36 @@ +# Microchip EV23X71A (Laguna) kernel configuration fixups +define MICROCHIP_EV23X71A_LINUX_CONFIG_FIXUPS + # LAN969x SoC + $(call KCONFIG_ENABLE_OPT,CONFIG_ARCH_LAN969X) + $(call KCONFIG_ENABLE_OPT,CONFIG_COMMON_CLK_LAN966X) + $(call KCONFIG_ENABLE_OPT,CONFIG_PINCTRL_OCELOT) + + # Serial console (FLEXCOM), ttyAT naming to match the bootloader + $(call KCONFIG_ENABLE_OPT,CONFIG_MFD_ATMEL_FLEXCOM) + $(call KCONFIG_ENABLE_OPT,CONFIG_SERIAL_ATMEL) + $(call KCONFIG_ENABLE_OPT,CONFIG_SERIAL_ATMEL_CONSOLE) + $(call KCONFIG_ENABLE_OPT,CONFIG_SERIAL_ATMEL_TTYAT) + + # Switch core, SerDes, and MDIO + $(call KCONFIG_ENABLE_OPT,CONFIG_SPARX5_SWITCH) + $(call KCONFIG_ENABLE_OPT,CONFIG_LAN969X_SWITCH) + $(call KCONFIG_ENABLE_OPT,CONFIG_PHY_SPARX5_SERDES) + $(call KCONFIG_ENABLE_OPT,CONFIG_MDIO_MSCC_MIIM) + $(call KCONFIG_SET_OPT,CONFIG_MICROSEMI_PHY,m) + + # eMMC + $(call KCONFIG_ENABLE_OPT,CONFIG_MMC_SDHCI_PLTFM) + $(call KCONFIG_ENABLE_OPT,CONFIG_MMC_SDHCI_OF_AT91) + + # I2C, SPI, and DMA + $(call KCONFIG_ENABLE_OPT,CONFIG_I2C_AT91) + $(call KCONFIG_ENABLE_OPT,CONFIG_SPI_ATMEL) + $(call KCONFIG_ENABLE_OPT,CONFIG_AT_XDMAC) + + # Watchdog and entropy + $(call KCONFIG_ENABLE_OPT,CONFIG_DW_WATCHDOG) + $(call KCONFIG_SET_OPT,CONFIG_HW_RANDOM_ATMEL,m) +endef + +$(eval $(ix-board)) +$(eval $(generic-package)) diff --git a/board/aarch64/microchip-ev23x71a/rootfs/usr/share/product/microchip,ev23x71a/etc/default/hw-wait b/board/aarch64/microchip-ev23x71a/rootfs/usr/share/product/microchip,ev23x71a/etc/default/hw-wait new file mode 100644 index 000000000..490decc90 --- /dev/null +++ b/board/aarch64/microchip-ev23x71a/rootfs/usr/share/product/microchip,ev23x71a/etc/default/hw-wait @@ -0,0 +1,3 @@ +# The LAN969x switch core attaches 29 PHYs, one at a time, taking a good +# half second each, so the default ten seconds is not enough. +HW_WAIT_TIMEOUT=60 diff --git a/board/aarch64/microchip-ev23x71a/rootfs/usr/share/product/microchip,ev23x71a/etc/iitod.json b/board/aarch64/microchip-ev23x71a/rootfs/usr/share/product/microchip,ev23x71a/etc/iitod.json new file mode 100644 index 000000000..b80a3b8bd --- /dev/null +++ b/board/aarch64/microchip-ev23x71a/rootfs/usr/share/product/microchip,ev23x71a/etc/iitod.json @@ -0,0 +1,65 @@ +{ + "input": { + "path": { + "locate": { "path": "/run/led/locate" }, + + "startup": { "path": "/run/finit/cond/usr/startup-config-ok" }, + "fail-safe": { "path": "/run/finit/cond/usr/failure-config-ok" }, + "panic": { "path": "/run/finit/cond/usr/failure-config-error" } + } + }, + + "output": { + "led": { + "green:status": { + "rules": [ + { "if": "locate", "then": "@blink-1hz" }, + { "if": "panic", "then": "@blink-5hz" }, + { "if": "fail-safe", "then": "@blink-5hz" }, + { "if": "startup", "then": "@on" }, + { "if": "true", "then": "@blink-1hz" } + ] + }, + + "green:lan-0": { + "rules": [ + { "if": "true", "then": { "trigger": "netdev", "device_name": "e25", "link": 1, "rx": 1, "tx": 1 } } + ] + }, + "green:lan-1": { + "rules": [ + { "if": "true", "then": { "trigger": "netdev", "device_name": "e26", "link": 1, "rx": 1, "tx": 1 } } + ] + }, + "green:lan-2": { + "rules": [ + { "if": "true", "then": { "trigger": "netdev", "device_name": "e27", "link": 1, "rx": 1, "tx": 1 } } + ] + }, + "green:lan-3": { + "rules": [ + { "if": "true", "then": { "trigger": "netdev", "device_name": "e28", "link": 1, "rx": 1, "tx": 1 } } + ] + } + } + }, + + "aliases": { + "on": { + "brightness": true + }, + "off": { + "brightness": false + }, + "blink-1hz": { + "trigger": "timer", + "delay_on": 500, + "delay_off": 500 + }, + "blink-5hz": { + "trigger": "timer", + "delay_on": 100, + "delay_off": 100 + } + } +} diff --git a/board/aarch64/microchip-ev23x71a/rootfs/usr/share/product/microchip,ev23x71a/etc/udev/rules.d/90-ev23x71a-rename-ifaces.rules b/board/aarch64/microchip-ev23x71a/rootfs/usr/share/product/microchip,ev23x71a/etc/udev/rules.d/90-ev23x71a-rename-ifaces.rules new file mode 100644 index 000000000..db0d6c834 --- /dev/null +++ b/board/aarch64/microchip-ev23x71a/rootfs/usr/share/product/microchip,ev23x71a/etc/udev/rules.d/90-ev23x71a-rename-ifaces.rules @@ -0,0 +1,41 @@ +# Rename LAN969x switch ports by device tree node path. +# +# The sparx5 driver leaves naming to the kernel, which hands out eth0 +# and up in probe order. Match on OF_FULLNAME instead, which the port +# netdevs carry now that their of_node is populated, and give them the +# names on the front panel. +# +# EV23X71A port layout (switch@e00c0000, ethernet-ports): +# port@0 .. port@23 1G copper over QSGMII, e1 .. e24 +# port@24 .. port@27 10G SFP+, e25 .. e28 +# port@29 1G RGMII management, e29, as in the Microchip docs + +ACTION=="add", SUBSYSTEM=="net", ENV{OF_FULLNAME}=="*/switch@e00c0000/ethernet-ports/port@0", NAME="e1" +ACTION=="add", SUBSYSTEM=="net", ENV{OF_FULLNAME}=="*/switch@e00c0000/ethernet-ports/port@1", NAME="e2" +ACTION=="add", SUBSYSTEM=="net", ENV{OF_FULLNAME}=="*/switch@e00c0000/ethernet-ports/port@2", NAME="e3" +ACTION=="add", SUBSYSTEM=="net", ENV{OF_FULLNAME}=="*/switch@e00c0000/ethernet-ports/port@3", NAME="e4" +ACTION=="add", SUBSYSTEM=="net", ENV{OF_FULLNAME}=="*/switch@e00c0000/ethernet-ports/port@4", NAME="e5" +ACTION=="add", SUBSYSTEM=="net", ENV{OF_FULLNAME}=="*/switch@e00c0000/ethernet-ports/port@5", NAME="e6" +ACTION=="add", SUBSYSTEM=="net", ENV{OF_FULLNAME}=="*/switch@e00c0000/ethernet-ports/port@6", NAME="e7" +ACTION=="add", SUBSYSTEM=="net", ENV{OF_FULLNAME}=="*/switch@e00c0000/ethernet-ports/port@7", NAME="e8" +ACTION=="add", SUBSYSTEM=="net", ENV{OF_FULLNAME}=="*/switch@e00c0000/ethernet-ports/port@8", NAME="e9" +ACTION=="add", SUBSYSTEM=="net", ENV{OF_FULLNAME}=="*/switch@e00c0000/ethernet-ports/port@9", NAME="e10" +ACTION=="add", SUBSYSTEM=="net", ENV{OF_FULLNAME}=="*/switch@e00c0000/ethernet-ports/port@10", NAME="e11" +ACTION=="add", SUBSYSTEM=="net", ENV{OF_FULLNAME}=="*/switch@e00c0000/ethernet-ports/port@11", NAME="e12" +ACTION=="add", SUBSYSTEM=="net", ENV{OF_FULLNAME}=="*/switch@e00c0000/ethernet-ports/port@12", NAME="e13" +ACTION=="add", SUBSYSTEM=="net", ENV{OF_FULLNAME}=="*/switch@e00c0000/ethernet-ports/port@13", NAME="e14" +ACTION=="add", SUBSYSTEM=="net", ENV{OF_FULLNAME}=="*/switch@e00c0000/ethernet-ports/port@14", NAME="e15" +ACTION=="add", SUBSYSTEM=="net", ENV{OF_FULLNAME}=="*/switch@e00c0000/ethernet-ports/port@15", NAME="e16" +ACTION=="add", SUBSYSTEM=="net", ENV{OF_FULLNAME}=="*/switch@e00c0000/ethernet-ports/port@16", NAME="e17" +ACTION=="add", SUBSYSTEM=="net", ENV{OF_FULLNAME}=="*/switch@e00c0000/ethernet-ports/port@17", NAME="e18" +ACTION=="add", SUBSYSTEM=="net", ENV{OF_FULLNAME}=="*/switch@e00c0000/ethernet-ports/port@18", NAME="e19" +ACTION=="add", SUBSYSTEM=="net", ENV{OF_FULLNAME}=="*/switch@e00c0000/ethernet-ports/port@19", NAME="e20" +ACTION=="add", SUBSYSTEM=="net", ENV{OF_FULLNAME}=="*/switch@e00c0000/ethernet-ports/port@20", NAME="e21" +ACTION=="add", SUBSYSTEM=="net", ENV{OF_FULLNAME}=="*/switch@e00c0000/ethernet-ports/port@21", NAME="e22" +ACTION=="add", SUBSYSTEM=="net", ENV{OF_FULLNAME}=="*/switch@e00c0000/ethernet-ports/port@22", NAME="e23" +ACTION=="add", SUBSYSTEM=="net", ENV{OF_FULLNAME}=="*/switch@e00c0000/ethernet-ports/port@23", NAME="e24" +ACTION=="add", SUBSYSTEM=="net", ENV{OF_FULLNAME}=="*/switch@e00c0000/ethernet-ports/port@24", NAME="e25" +ACTION=="add", SUBSYSTEM=="net", ENV{OF_FULLNAME}=="*/switch@e00c0000/ethernet-ports/port@25", NAME="e26" +ACTION=="add", SUBSYSTEM=="net", ENV{OF_FULLNAME}=="*/switch@e00c0000/ethernet-ports/port@26", NAME="e27" +ACTION=="add", SUBSYSTEM=="net", ENV{OF_FULLNAME}=="*/switch@e00c0000/ethernet-ports/port@27", NAME="e28" +ACTION=="add", SUBSYSTEM=="net", ENV{OF_FULLNAME}=="*/switch@e00c0000/ethernet-ports/port@29", NAME="e29" diff --git a/board/aarch64/microchip-ev23x71a/uboot/extras.config b/board/aarch64/microchip-ev23x71a/uboot/extras.config new file mode 100644 index 000000000..db23bdc15 --- /dev/null +++ b/board/aarch64/microchip-ev23x71a/uboot/extras.config @@ -0,0 +1,28 @@ +# One board, one control device tree. The vendor defconfig carries a +# device tree for each LAN969x board and selects between them with +# MULTI_DTB_FIT, which also makes fit_conf_get_node() match FIT +# configurations by compatible string instead of honoring the default +# property, see the board README. +CONFIG_DEFAULT_DEVICE_TREE="lan969x_ev23x71a" +CONFIG_OF_LIST="lan969x_ev23x71a" +# CONFIG_MULTI_DTB_FIT is not set +# CONFIG_DTB_RESELECT is not set + +# No persisted environment: everything comes from the control device +# tree, which is authenticated as part of the FIP. A writable +# environment would otherwise be enough to bypass secure boot, since +# clearing env_fdt_path alone stops the device tree import. +# +# Needs the ENV_IS_NOWHERE patch for the board's env_get_location(), +# see patches/uboot/, without which env_init() fails with -ENODEV. +CONFIG_ENV_IS_NOWHERE=y +# CONFIG_ENV_IS_IN_MMC is not set +# CONFIG_ENV_IS_IN_SPI_FLASH is not set +# CONFIG_ENV_IS_IN_FAT is not set +# CONFIG_SYS_REDUNDAND_ENVIRONMENT is not set + +CONFIG_AUTOBOOT=y + +# Board environment, see lan969x-env.dtsi. Appended after the common +# Infix ones, so it can extend them through the &env label. +CONFIG_DEVICE_TREE_INCLUDES="infix-env.dtsi infix-key.dtsi lan969x-env.dtsi" diff --git a/board/aarch64/microchip-ev23x71a/uboot/lan969x-env.dtsi b/board/aarch64/microchip-ev23x71a/uboot/lan969x-env.dtsi new file mode 100644 index 000000000..e065757d3 --- /dev/null +++ b/board/aarch64/microchip-ev23x71a/uboot/lan969x-env.dtsi @@ -0,0 +1,37 @@ +/* + * Board environment, applied on top of the common Infix one. DRAM + * starts at 0x60000000, and the addresses mirror the layout used on + * other Infix boards: the kernel is staged 64 MiB in, clear of where + * booti relocates it to at the start of DRAM. + */ +/ { + config { + /* + * Name the partition holding the environment, rather than + * inheriting the offset from lan969x.dtsi, which points + * into the middle of the Infix layout. + */ + u-boot,mmc-env-partition = "Env"; + }; +}; + +&env { + bootcmd = "run ixboot"; + boot_targets = "mmc0"; + + board = "microchip,ev23x71a"; + fdtfile = "microchip/lan9696-ev23x71a.dtb"; + + loadaddr = "0x63000000"; + fdt_addr_r = "0x63f00000"; + kernel_addr_r = "0x64000000"; + fdtoverlay_addr_r = "0x67f00000"; + scriptaddr = "0x68000000"; + ramdisk_addr_r = "0x6a000000"; + + /* This is a development board, keep developer mode enabled. */ + ixbtn-devmode = "setenv dev_mode yes; echo Enabled"; + + /* No front panel button to hold, and no button command built. */ + ixbtn-factory = "echo Unavailable"; +}; diff --git a/board/common/rootfs/usr/libexec/infix/hw-wait b/board/common/rootfs/usr/libexec/infix/hw-wait index d06338fea..9e30dcfa0 100755 --- a/board/common/rootfs/usr/libexec/infix/hw-wait +++ b/board/common/rootfs/usr/libexec/infix/hw-wait @@ -4,6 +4,11 @@ ident=$(basename "$0") +# Seconds to wait, boards with very slow switch cores raise this in +# their product specific /etc/default/hw-wait +HW_WAIT_TIMEOUT=10 +[ -r /etc/default/hw-wait ] && . /etc/default/hw-wait + report() { if [ -r "/tmp/$ident" ]; then @@ -14,7 +19,7 @@ report() rm -f "/tmp/$ident" } -for _ in $(seq 50); do +for _ in $(seq $((HW_WAIT_TIMEOUT * 5))); do again= for dl in /sys/class/devlink/*; do diff --git a/configs/aarch64_defconfig b/configs/aarch64_defconfig index 3df284660..0398137b6 100644 --- a/configs/aarch64_defconfig +++ b/configs/aarch64_defconfig @@ -141,6 +141,7 @@ BR2_PACKAGE_BANANAPI_BPI_R64=y BR2_PACKAGE_FRIENDLYARM_NANOPI_R2S=y BR2_PACKAGE_MARVELL_CN9130_CRB=y BR2_PACKAGE_MARVELL_ESPRESSOBIN=y +BR2_PACKAGE_MICROCHIP_EV23X71A=y BR2_PACKAGE_RASPBERRYPI_RPI64=y BR2_PACKAGE_STYX_DCP_SC_28P=y IX_VENDOR_HOME="https://www.kernelkit.org" diff --git a/configs/laguna_boot_defconfig b/configs/laguna_boot_defconfig new file mode 100644 index 000000000..1fcfb6640 --- /dev/null +++ b/configs/laguna_boot_defconfig @@ -0,0 +1,44 @@ +BR2_aarch64=y +BR2_cortex_a53=y +BR2_TOOLCHAIN_EXTERNAL=y +BR2_TOOLCHAIN_EXTERNAL_BOOTLIN=y +BR2_DL_DIR="$(BR2_EXTERNAL_INFIX_PATH)/dl" +BR2_CCACHE=y +BR2_CCACHE_DIR="$(BR2_EXTERNAL_INFIX_PATH)/.ccache" +BR2_ENABLE_DEBUG=y +BR2_PACKAGE_OVERRIDE_FILE="$(BR2_EXTERNAL_INFIX_PATH)/local.mk" +BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_INFIX_PATH)/patches" +BR2_SSP_NONE=y +BR2_INIT_NONE=y +BR2_SYSTEM_BIN_SH_NONE=y +# BR2_PACKAGE_BUSYBOX is not set +# BR2_PACKAGE_IFUPDOWN_SCRIPTS is not set +# BR2_TARGET_ROOTFS_TAR is not set +BR2_PACKAGE_MBEDTLS_ATF=y +BR2_TARGET_ARM_TRUSTED_FIRMWARE=y +BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_GIT=y +BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_REPO_URL="https://github.com/microchip-ung/arm-trusted-firmware.git" +BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_REPO_VERSION="0317e2ebb555d02ad694c5a7157b7db5b51a4ea4" +BR2_TARGET_ARM_TRUSTED_FIRMWARE_PLATFORM="lan969x_a0" +BR2_TARGET_ARM_TRUSTED_FIRMWARE_FIP=y +BR2_TARGET_ARM_TRUSTED_FIRMWARE_UBOOT_AS_BL33=y +BR2_TARGET_ARM_TRUSTED_FIRMWARE_ADDITIONAL_VARIABLES="KEY_ALG=ecdsa GENERATE_COT=1 LOG_LEVEL=30" +BR2_TARGET_ARM_TRUSTED_FIRMWARE_IMAGES="fip.bin" +BR2_TARGET_UBOOT=y +BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y +BR2_TARGET_UBOOT_CUSTOM_GIT=y +BR2_TARGET_UBOOT_CUSTOM_REPO_URL="https://github.com/microchip-ung/u-boot.git" +BR2_TARGET_UBOOT_CUSTOM_REPO_VERSION="bsp-v2024.04-2026.06" +BR2_TARGET_UBOOT_BOARD_DEFCONFIG="mchp_lan969x" +BR2_TARGET_UBOOT_CONFIG_FRAGMENT_FILES="${BR2_EXTERNAL_INFIX_PATH}/board/common/uboot/extras.config ${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/microchip-ev23x71a/uboot/extras.config" +BR2_TARGET_UBOOT_CUSTOM_DTS_PATH="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/microchip-ev23x71a/uboot/lan969x-env.dtsi" +BR2_TARGET_UBOOT_NEEDS_DTC=y +BR2_PACKAGE_HOST_BMAP_TOOLS=y +BR2_PACKAGE_HOST_GENIMAGE=y +BR2_PACKAGE_HOST_RAUC=y +BR2_PACKAGE_HOST_UBOOT_TOOLS=y +BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y +BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y +BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y +IX_TRUSTED_KEYS=y +IX_TRUSTED_KEYS_DEVELOPMENT=y diff --git a/doc/ChangeLog.md b/doc/ChangeLog.md index d2f736a2c..dfcc1d54b 100644 --- a/doc/ChangeLog.md +++ b/doc/ChangeLog.md @@ -19,11 +19,17 @@ All notable changes to the project are documented in this file. - Include .pkg files in release builds - The `statd` service now logs at `notice` level by default, like other services, and supports `-v ` to adjust verbosity at runtime +- Hardware sensors are now children of the component they measure, so the + CPU temperature belongs to the CPU component, and VPD components are + named after the board they sit on, `vpd-cpu`, `vpd-product` ### Added - Add NanoPi R2S Plus support (on-board 32 GB eMMC), including U-Boot device tree selection so the eMMC is enabled when present +- Add Microchip EV23X71A (Laguna) support: LAN969x switch with 24 GbE + copper ports, four SFP+ cages, and a management port, booting Infix + from eMMC with the usual A/B slots ### Fixes @@ -35,6 +41,8 @@ All notable changes to the project are documented in this file. or services keep the system busy, logged as: statd[3558]: mdns: operational datastore busy, retrying ... +- Fix missing CPU temperature in `show system` and the web interface on + SparX-5, LAN969x, and x86 boards [ma13]: https://github.com/troglobit/mdns-alias/releases/tag/v1.3 diff --git a/doc/hardware.md b/doc/hardware.md index f794e20eb..c54c22b5a 100644 --- a/doc/hardware.md +++ b/doc/hardware.md @@ -3,6 +3,34 @@ The hardware infomation and status is handled by the YANG model [IETF hardware][1], with deviations and augmentations in _infix-hardware_. +## Sensors + +Temperature, fan, voltage, current, and power readings are components of +class `sensor`, one per reading. A sensor name is a list key and nothing +more: what a sensor measures follows from the component it belongs to, +named by its `parent`. Clients must select on class, never on names, +which vary with the SoC, the driver, and the board. + +The SoC die temperature, for instance, is any `celsius` sensor whose +parent has class `cpu`: + +``` +/ietf-hardware:hardware/component[class='iana-hardware:sensor'] +``` + +with `parent` resolving to the component of class `iana-hardware:cpu`. +An SoC reporting several dies or clusters yields several such sensors, +and the hottest is the one to report. Over RESTCONF: + +```sh +curl -su admin:admin \ + https://example/restconf/data/ietf-hardware:hardware/component +``` + +Which hwmon device or thermal zone belongs to which component is decided +when the data is collected, and is the only place platform specific names +are recognized. + ## GPS/GNSS Receivers Infix supports GPS/GNSS receivers for hardware status monitoring and NTP diff --git a/doc/netboot.md b/doc/netboot.md index 202f0daa1..c225119af 100644 --- a/doc/netboot.md +++ b/doc/netboot.md @@ -114,6 +114,75 @@ The output is `netboot.scr` which we symlink to above in the dnsmasq setup step. +## Bootfile rootfs.itb + +By default, the U-Boot downloads whatever the DHCP server hands out as +the boot file, so point that straight at a `rootfs.itb`: + +``` +cd /srv/ftp +ln -sf ix/ev23x71a/rootfs.itb /srv/ftp/bootfile-enp17s0 +``` + +U-Boot validates the image signature, finds the SquashFS inside it, and +boots it as a RAM disk with `rauc.slot=net`, so the running system knows +it came off the network rather than from a slot. + +This is also how a device with empty storage comes up on its own. With +no `aux` partition there is no primary or secondary slot to try, so +`ixpreboot` reports + +``` +NO BOOTABLE MEDIA FOUND, falling back to netboot +``` + +and goes straight to DHCP. A factory fresh board therefore reaches a +running system with nobody at the console. + + +## Installing to Onboard Storage + +A netbooted device is a complete system, so it can install itself. +Build the bootloader and the Infix image separately, then combine them: + +``` +make _boot_defconfig O=x-boot && make O=x-boot +make _defconfig && make +utils/mkimage.sh -b x-boot -r output -t emmc +``` + +The netbooted system starts from the factory configuration, which does +not necessarily bring up a management interface, so give it an address +first: + +``` +admin@board:~$ sudo udhcpc -i e29 +``` + +Then stream the image from the PC. Most of it is empty filesystem, so +compressing it on the way saves a lot of wire time: + +``` +gzip -c x-boot/images/*-emmc.img \ + | ssh admin@board.local 'gunzip | sudo dd of=/dev/mmcblk0 bs=1M conv=fsync' +``` + +Nothing on the target is mounted from the medium while netbooted, so the +write is safe. When it completes the kernel re-reads the partition +table and complains: + +``` +GPT:Primary header thinks Alt. header is not at the end of the disk. +GPT:Alternate GPT header not at the end of the disk. +GPT: Use GNU Parted to correct GPT errors. +``` + +That is expected. The table describes the image, not the medium it +landed on. The first boot of the installed system moves the backup +header with `sgdisk -e`, grows the last partition to fill the medium, and +resizes the filesystem, in two stages with a reboot in between. + + ## U-Boot Commands U-Boot is a maze of environment variables, some with values, some wrap diff --git a/package/Config.in b/package/Config.in index 6998f5804..3befdb365 100644 --- a/package/Config.in +++ b/package/Config.in @@ -29,6 +29,7 @@ source "$BR2_EXTERNAL_INFIX_PATH/package/klish-plugin-sysrepo/Config.in" source "$BR2_EXTERNAL_INFIX_PATH/package/landing/Config.in" source "$BR2_EXTERNAL_INFIX_PATH/package/libsrx/Config.in" source "$BR2_EXTERNAL_INFIX_PATH/package/lowdown/Config.in" +source "$BR2_EXTERNAL_INFIX_PATH/package/mbedtls-atf/Config.in" source "$BR2_EXTERNAL_INFIX_PATH/package/mcd/Config.in" source "$BR2_EXTERNAL_INFIX_PATH/package/mdns-alias/Config.in" source "$BR2_EXTERNAL_INFIX_PATH/package/netbrowse/Config.in" diff --git a/package/mbedtls-atf/Config.in b/package/mbedtls-atf/Config.in new file mode 100644 index 000000000..5ce135239 --- /dev/null +++ b/package/mbedtls-atf/Config.in @@ -0,0 +1,18 @@ +config BR2_PACKAGE_MBEDTLS_ATF + bool "mbedtls-atf" + depends on BR2_TARGET_ARM_TRUSTED_FIRMWARE + help + mbed TLS sources for Arm Trusted Firmware. + + Platforms with Trusted Board Boot, e.g. Microchip LAN969x + (Laguna), authenticate each image in the FIP against a chain + of X.509 certificates. ATF parses those with mbed TLS, which + it compiles into BL1 and BL2 from source, pointed out by the + MBEDTLS_DIR build variable. Nothing is installed on target. + + This is separate from the mbedtls package, which tracks the + 3.x series for use as a library. ATF 2.8 builds only against + the 2.28 LTS series, and expects sources, such as + library/rsa_internal.c, that 3.x no longer has. + + https://www.trustedfirmware.org/projects/mbed-tls/ diff --git a/package/mbedtls-atf/mbedtls-atf.hash b/package/mbedtls-atf/mbedtls-atf.hash new file mode 100644 index 000000000..4eb309b71 --- /dev/null +++ b/package/mbedtls-atf/mbedtls-atf.hash @@ -0,0 +1,3 @@ +# Locally calculated +sha256 dbd42a11c26143aa8de1c07fd6ec6765395e86b06f583f051cfa60e8f0b23125 mbedtls-atf-2.28.5.tar.gz +sha256 cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30 LICENSE diff --git a/package/mbedtls-atf/mbedtls-atf.mk b/package/mbedtls-atf/mbedtls-atf.mk new file mode 100644 index 000000000..6d498adef --- /dev/null +++ b/package/mbedtls-atf/mbedtls-atf.mk @@ -0,0 +1,30 @@ +################################################################################ +# +# mbedtls-atf +# +# mbed TLS sources for Arm Trusted Firmware, which needs them to parse +# the X.509 certificates in a FIP when a platform has Trusted Board Boot, +# as Microchip LAN969x (Laguna) does. ATF compiles them into BL1 and BL2 +# itself, so there is nothing to build or install here. +# +# The mbedtls package cannot be used for this: it tracks 3.x, while ATF +# 2.8 builds only against the 2.28 LTS series. +# +################################################################################ + +MBEDTLS_ATF_VERSION = 2.28.5 +MBEDTLS_ATF_SITE = $(call github,Mbed-TLS,mbedtls,mbedtls-$(MBEDTLS_ATF_VERSION)) +MBEDTLS_ATF_LICENSE = Apache-2.0 +MBEDTLS_ATF_LICENSE_FILES = LICENSE +MBEDTLS_ATF_INSTALL_TARGET = NO + +$(eval $(generic-package)) + +ifeq ($(BR2_PACKAGE_MBEDTLS_ATF),y) +# MAKE_OPTS is expanded when the ATF build step runs, so appending to it +# from here works even though Buildroot reads this file after the package +# was defined. DEPENDENCIES is read at definition time and cannot be +# appended to, hence the explicit ordering. +ARM_TRUSTED_FIRMWARE_MAKE_OPTS += MBEDTLS_DIR=$(MBEDTLS_ATF_DIR) +$(ARM_TRUSTED_FIRMWARE_TARGET_BUILD): $(MBEDTLS_ATF_TARGET_EXTRACT) +endif diff --git a/patches/linux/6.18.46/0001-net-phy-marvell10g-Support-firmware-loading-on-88X33.patch b/patches/linux/6.18.46/0001-net-phy-marvell10g-Support-firmware-loading-on-88X33.patch index 41e6df0fe..46bef3501 100644 --- a/patches/linux/6.18.46/0001-net-phy-marvell10g-Support-firmware-loading-on-88X33.patch +++ b/patches/linux/6.18.46/0001-net-phy-marvell10g-Support-firmware-loading-on-88X33.patch @@ -1,8 +1,9 @@ From 7f49c30ee90aa0be9e9164a9948bfe8a1331fea6 Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Tue, 19 Sep 2023 18:38:10 +0200 -Subject: [PATCH 01/51] net: phy: marvell10g: Support firmware loading on +Subject: [PATCH 01/64] net: phy: marvell10g: Support firmware loading on 88X3310 +Organization: Wires When probing, if a device is waiting for firmware to be loaded into its RAM, ask userspace for the binary and load it over XMDIO. diff --git a/patches/linux/6.18.46/0002-net-phy-marvell10g-Fix-power-up-when-strapped-to-sta.patch b/patches/linux/6.18.46/0002-net-phy-marvell10g-Fix-power-up-when-strapped-to-sta.patch index bdd2bbe0a..4c15f122c 100644 --- a/patches/linux/6.18.46/0002-net-phy-marvell10g-Fix-power-up-when-strapped-to-sta.patch +++ b/patches/linux/6.18.46/0002-net-phy-marvell10g-Fix-power-up-when-strapped-to-sta.patch @@ -1,8 +1,9 @@ From b9ab146b15ea489f948f5a11980fe924ded4daae Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Tue, 21 Nov 2023 20:15:24 +0100 -Subject: [PATCH 02/51] net: phy: marvell10g: Fix power-up when strapped to +Subject: [PATCH 02/64] net: phy: marvell10g: Fix power-up when strapped to start powered down +Organization: Wires On devices which are hardware strapped to start powered down (PDSTATE == 1), make sure that we clear the power-down bit on all units diff --git a/patches/linux/6.18.46/0003-net-phy-marvell10g-Add-LED-support-for-88X3310.patch b/patches/linux/6.18.46/0003-net-phy-marvell10g-Add-LED-support-for-88X3310.patch index 164abc4ad..7593ed5e9 100644 --- a/patches/linux/6.18.46/0003-net-phy-marvell10g-Add-LED-support-for-88X3310.patch +++ b/patches/linux/6.18.46/0003-net-phy-marvell10g-Add-LED-support-for-88X3310.patch @@ -1,7 +1,8 @@ From 48bf1d41a21cbe093ec241d8ee483abc70a1b8dc Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Wed, 15 Nov 2023 20:58:42 +0100 -Subject: [PATCH 03/51] net: phy: marvell10g: Add LED support for 88X3310 +Subject: [PATCH 03/64] net: phy: marvell10g: Add LED support for 88X3310 +Organization: Wires Pickup the LEDs from the state in which the hardware reset or bootloader left them, but also support further configuration via diff --git a/patches/linux/6.18.46/0004-net-phy-marvell10g-Support-LEDs-tied-to-a-single-med.patch b/patches/linux/6.18.46/0004-net-phy-marvell10g-Support-LEDs-tied-to-a-single-med.patch index 012173b7d..9cecc4a98 100644 --- a/patches/linux/6.18.46/0004-net-phy-marvell10g-Support-LEDs-tied-to-a-single-med.patch +++ b/patches/linux/6.18.46/0004-net-phy-marvell10g-Support-LEDs-tied-to-a-single-med.patch @@ -1,8 +1,9 @@ From 7f10824be067ddb40e89ccb66ebe9b0bda3a3f96 Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Tue, 12 Dec 2023 09:51:05 +0100 -Subject: [PATCH 04/51] net: phy: marvell10g: Support LEDs tied to a single +Subject: [PATCH 04/64] net: phy: marvell10g: Support LEDs tied to a single media side +Organization: Wires In a combo-port setup, i.e. where both the copper and fiber interface are available to the user, the LEDs may be physically located either diff --git a/patches/linux/6.18.46/0005-net-phy-Do-not-resume-PHY-when-attaching.patch b/patches/linux/6.18.46/0005-net-phy-Do-not-resume-PHY-when-attaching.patch index 74b9255db..b51781a3e 100644 --- a/patches/linux/6.18.46/0005-net-phy-Do-not-resume-PHY-when-attaching.patch +++ b/patches/linux/6.18.46/0005-net-phy-Do-not-resume-PHY-when-attaching.patch @@ -1,7 +1,8 @@ From 60c64feacdd6a2259d09545d45227f2c44c36e53 Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Wed, 27 Mar 2024 10:10:19 +0100 -Subject: [PATCH 05/51] net: phy: Do not resume PHY when attaching +Subject: [PATCH 05/64] net: phy: Do not resume PHY when attaching +Organization: Wires The PHY should not start negotiating with its link-partner until explicitly instructed to do so. diff --git a/patches/linux/6.18.46/0006-net-bridge-avoid-classifying-unknown-multicast-as-mr.patch b/patches/linux/6.18.46/0006-net-bridge-avoid-classifying-unknown-multicast-as-mr.patch index cfd7d94b7..101739bf9 100644 --- a/patches/linux/6.18.46/0006-net-bridge-avoid-classifying-unknown-multicast-as-mr.patch +++ b/patches/linux/6.18.46/0006-net-bridge-avoid-classifying-unknown-multicast-as-mr.patch @@ -1,8 +1,9 @@ From 615860e3041a3837e09895425edd87aa16fa5965 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Mon, 4 Mar 2024 16:47:28 +0100 -Subject: [PATCH 06/51] net: bridge: avoid classifying unknown multicast as +Subject: [PATCH 06/64] net: bridge: avoid classifying unknown multicast as mrouters_only +Organization: Wires Unknown multicast, MAC/IPv4/IPv6, should always be flooded according to the per-port mcast_flood setting, as well as to detected and configured diff --git a/patches/linux/6.18.46/0007-net-bridge-Ignore-router-ports-when-forwarding-L2-mu.patch b/patches/linux/6.18.46/0007-net-bridge-Ignore-router-ports-when-forwarding-L2-mu.patch index 5d605bbd2..a6e9e0459 100644 --- a/patches/linux/6.18.46/0007-net-bridge-Ignore-router-ports-when-forwarding-L2-mu.patch +++ b/patches/linux/6.18.46/0007-net-bridge-Ignore-router-ports-when-forwarding-L2-mu.patch @@ -1,8 +1,9 @@ From bf77eac4d9bc46717a5ce5cf30bd66e17d11b16e Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Tue, 5 Mar 2024 06:44:41 +0100 -Subject: [PATCH 07/51] net: bridge: Ignore router ports when forwarding L2 +Subject: [PATCH 07/64] net: bridge: Ignore router ports when forwarding L2 multicast +Organization: Wires Multicast router ports are either statically configured or learned from control protocol traffic (IGMP/MLD/PIM). These protocols regulate IP diff --git a/patches/linux/6.18.46/0008-net-bridge-drop-delay-for-applying-strict-multicast-.patch b/patches/linux/6.18.46/0008-net-bridge-drop-delay-for-applying-strict-multicast-.patch index b4da0b6aa..bbd58fe38 100644 --- a/patches/linux/6.18.46/0008-net-bridge-drop-delay-for-applying-strict-multicast-.patch +++ b/patches/linux/6.18.46/0008-net-bridge-drop-delay-for-applying-strict-multicast-.patch @@ -1,8 +1,9 @@ From e0fb904d3050df4c7651d04fc823a6c1dd0ef459 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Thu, 4 Apr 2024 16:36:30 +0200 -Subject: [PATCH 08/51] net: bridge: drop delay for applying strict multicast +Subject: [PATCH 08/64] net: bridge: drop delay for applying strict multicast filtering +Organization: Wires This *local* patch drops the initial delay before applying strict multicast filtering, introduced in [1] and recently updated in [2]. diff --git a/patches/linux/6.18.46/0009-net-bridge-Differentiate-MDB-additions-from-modifica.patch b/patches/linux/6.18.46/0009-net-bridge-Differentiate-MDB-additions-from-modifica.patch index 907c5c7d5..bc80fa137 100644 --- a/patches/linux/6.18.46/0009-net-bridge-Differentiate-MDB-additions-from-modifica.patch +++ b/patches/linux/6.18.46/0009-net-bridge-Differentiate-MDB-additions-from-modifica.patch @@ -1,8 +1,9 @@ From 1bc840aa52d09ab5a3f51d75674f2ac517a9ff5a Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Thu, 16 May 2024 14:51:54 +0200 -Subject: [PATCH 09/51] net: bridge: Differentiate MDB additions from +Subject: [PATCH 09/64] net: bridge: Differentiate MDB additions from modifications +Organization: Wires Before this change, the reception of an IGMPv3 report (and analogously for MLDv2) that adds a new group, would trigger two MDB RTM_NEWMDB diff --git a/patches/linux/6.18.46/0010-nvmem-layouts-onie-tlv-Let-device-probe-even-when-TL.patch b/patches/linux/6.18.46/0010-nvmem-layouts-onie-tlv-Let-device-probe-even-when-TL.patch index a495a04e3..c94ca34ee 100644 --- a/patches/linux/6.18.46/0010-nvmem-layouts-onie-tlv-Let-device-probe-even-when-TL.patch +++ b/patches/linux/6.18.46/0010-nvmem-layouts-onie-tlv-Let-device-probe-even-when-TL.patch @@ -1,8 +1,9 @@ From 31ec2dddbe45228f3ad3e4f850b65125cd2b9f06 Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Fri, 24 Nov 2023 23:29:55 +0100 -Subject: [PATCH 10/51] nvmem: layouts: onie-tlv: Let device probe even when +Subject: [PATCH 10/64] nvmem: layouts: onie-tlv: Let device probe even when TLV is invalid +Organization: Wires Before this change, probing an NVMEM device, expected to contain a valid TLV, would fail if it had not been provisioned yet. But an diff --git a/patches/linux/6.18.46/0011-net-usb-r8152-add-r8153b-support-for-link-activity-L.patch b/patches/linux/6.18.46/0011-net-usb-r8152-add-r8153b-support-for-link-activity-L.patch index b0bff94a6..0552cd4bc 100644 --- a/patches/linux/6.18.46/0011-net-usb-r8152-add-r8153b-support-for-link-activity-L.patch +++ b/patches/linux/6.18.46/0011-net-usb-r8152-add-r8153b-support-for-link-activity-L.patch @@ -1,8 +1,9 @@ From ed17421a32311c8bdd685b65e24f83e998449305 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sun, 11 Aug 2024 11:27:35 +0200 -Subject: [PATCH 11/51] net: usb: r8152: add r8153b support for link/activity +Subject: [PATCH 11/64] net: usb: r8152: add r8153b support for link/activity LEDs +Organization: Wires This patch adds support for the link/activity LEDs on the NanoPi R2S and OrangePi R1 Plus. diff --git a/patches/linux/6.18.46/0012-arm64-dts-mediatek-mt7986a-rename-BPi-R3-ports-to-ma.patch b/patches/linux/6.18.46/0012-arm64-dts-mediatek-mt7986a-rename-BPi-R3-ports-to-ma.patch index 49b51b3cf..406800e5b 100644 --- a/patches/linux/6.18.46/0012-arm64-dts-mediatek-mt7986a-rename-BPi-R3-ports-to-ma.patch +++ b/patches/linux/6.18.46/0012-arm64-dts-mediatek-mt7986a-rename-BPi-R3-ports-to-ma.patch @@ -1,8 +1,9 @@ From 72267d352c38207ddb1d84af6141de93db5d150a Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sun, 10 Aug 2025 18:52:54 +0200 -Subject: [PATCH 12/51] arm64: dts: mediatek: mt7986a: rename BPi R3 ports to +Subject: [PATCH 12/64] arm64: dts: mediatek: mt7986a: rename BPi R3 ports to match case +Organization: Wires For ref. see: https://wiki.banana-pi.org/File:Bpi-r3_Metal_case.jpg diff --git a/patches/linux/6.18.46/0013-drm-panel-simple-Add-a-timing-for-the-Raspberry-Pi-7.patch b/patches/linux/6.18.46/0013-drm-panel-simple-Add-a-timing-for-the-Raspberry-Pi-7.patch index 373446783..68669080c 100644 --- a/patches/linux/6.18.46/0013-drm-panel-simple-Add-a-timing-for-the-Raspberry-Pi-7.patch +++ b/patches/linux/6.18.46/0013-drm-panel-simple-Add-a-timing-for-the-Raspberry-Pi-7.patch @@ -1,8 +1,9 @@ From 7106cd3a9e250c5e3974dd642d8cc19af5ef2ac7 Mon Sep 17 00:00:00 2001 From: Mattias Walström Date: Wed, 20 Aug 2025 21:38:24 +0200 -Subject: [PATCH 13/51] drm/panel-simple: Add a timing for the Raspberry Pi 7" +Subject: [PATCH 13/64] drm/panel-simple: Add a timing for the Raspberry Pi 7" panel +Organization: Wires The Raspberry Pi 7" 800x480 panel uses a Toshiba TC358762 DSI to DPI bridge chip, so there is a requirement for the timings diff --git a/patches/linux/6.18.46/0014-input-touchscreen-edt-ft5x06-Add-polled-mode.patch b/patches/linux/6.18.46/0014-input-touchscreen-edt-ft5x06-Add-polled-mode.patch index bb7844b87..cda7b5435 100644 --- a/patches/linux/6.18.46/0014-input-touchscreen-edt-ft5x06-Add-polled-mode.patch +++ b/patches/linux/6.18.46/0014-input-touchscreen-edt-ft5x06-Add-polled-mode.patch @@ -1,7 +1,8 @@ From 3bc1d86fcd0e24960152f4d758aa250057b63fcb Mon Sep 17 00:00:00 2001 From: Mattias Walström Date: Thu, 21 Aug 2025 11:20:23 +0200 -Subject: [PATCH 14/51] input:touchscreen:edt-ft5x06: Add polled mode +Subject: [PATCH 14/64] input:touchscreen:edt-ft5x06: Add polled mode +Organization: Wires Not all hardware has interrupts therefore we need to poll the touchscreen. diff --git a/patches/linux/6.18.46/0015-FIX-net-dsa-mv88e6xxx-Fix-timeout-on-waiting-for-PPU.patch b/patches/linux/6.18.46/0015-FIX-net-dsa-mv88e6xxx-Fix-timeout-on-waiting-for-PPU.patch index 39bcba81e..eb441a09e 100644 --- a/patches/linux/6.18.46/0015-FIX-net-dsa-mv88e6xxx-Fix-timeout-on-waiting-for-PPU.patch +++ b/patches/linux/6.18.46/0015-FIX-net-dsa-mv88e6xxx-Fix-timeout-on-waiting-for-PPU.patch @@ -1,8 +1,9 @@ From b0a42be0c80c3d44305f80e6e867a911aa00d35c Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Tue, 12 Mar 2024 10:27:24 +0100 -Subject: [PATCH 15/51] [FIX] net: dsa: mv88e6xxx: Fix timeout on waiting for +Subject: [PATCH 15/64] [FIX] net: dsa: mv88e6xxx: Fix timeout on waiting for PPU on 6393X +Organization: Wires In a multi-chip setup, delays of up to 750ms are observed before the device (6393X) signals completion of PPU initialization (Global 1, diff --git a/patches/linux/6.18.46/0016-net-dsa-mv88e6xxx-Improve-indirect-register-access-p.patch b/patches/linux/6.18.46/0016-net-dsa-mv88e6xxx-Improve-indirect-register-access-p.patch index 03aa9b563..fdb0fd3a5 100644 --- a/patches/linux/6.18.46/0016-net-dsa-mv88e6xxx-Improve-indirect-register-access-p.patch +++ b/patches/linux/6.18.46/0016-net-dsa-mv88e6xxx-Improve-indirect-register-access-p.patch @@ -1,8 +1,9 @@ From 5810a287ae29b817a4294ebed04358f730f65065 Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Wed, 27 Mar 2024 15:52:43 +0100 -Subject: [PATCH 16/51] net: dsa: mv88e6xxx: Improve indirect register access +Subject: [PATCH 16/64] net: dsa: mv88e6xxx: Improve indirect register access perf on 6393 +Organization: Wires When operating in multi-chip mode, the 6393 family maps a subset of commonly used global registers to the outermost address space (in diff --git a/patches/linux/6.18.46/0017-net-dsa-mv88e6xxx-Honor-ports-being-managed-via-in-b.patch b/patches/linux/6.18.46/0017-net-dsa-mv88e6xxx-Honor-ports-being-managed-via-in-b.patch index 17fcd3c28..1c72832c7 100644 --- a/patches/linux/6.18.46/0017-net-dsa-mv88e6xxx-Honor-ports-being-managed-via-in-b.patch +++ b/patches/linux/6.18.46/0017-net-dsa-mv88e6xxx-Honor-ports-being-managed-via-in-b.patch @@ -1,8 +1,9 @@ From 38a0d0b99db217d86d8b2b2b832858df24b235a0 Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Mon, 22 Apr 2024 23:18:01 +0200 -Subject: [PATCH 17/51] net: dsa: mv88e6xxx: Honor ports being managed via +Subject: [PATCH 17/64] net: dsa: mv88e6xxx: Honor ports being managed via in-band-status +Organization: Wires Keep all link parameters in their unforced states when the port is declared as being managed via in-band-status, and let the MAC diff --git a/patches/linux/6.18.46/0018-net-dsa-mv88e6xxx-Limit-rsvd2cpu-policy-to-user-port.patch b/patches/linux/6.18.46/0018-net-dsa-mv88e6xxx-Limit-rsvd2cpu-policy-to-user-port.patch index ec2be34ca..0dcb06322 100644 --- a/patches/linux/6.18.46/0018-net-dsa-mv88e6xxx-Limit-rsvd2cpu-policy-to-user-port.patch +++ b/patches/linux/6.18.46/0018-net-dsa-mv88e6xxx-Limit-rsvd2cpu-policy-to-user-port.patch @@ -1,8 +1,9 @@ From c4fffd95d964d7a911b6039cc8e7e5d736a47e4d Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Wed, 24 Apr 2024 22:41:04 +0200 -Subject: [PATCH 18/51] net: dsa: mv88e6xxx: Limit rsvd2cpu policy to user +Subject: [PATCH 18/64] net: dsa: mv88e6xxx: Limit rsvd2cpu policy to user ports on 6393X +Organization: Wires For packets with a DA in the IEEE reserved L2 group range, originating from a CPU, forward it as normal, rather than classifying it as diff --git a/patches/linux/6.18.46/0019-net-dsa-tag_dsa-Use-tag-priority-as-initial-skb-prio.patch b/patches/linux/6.18.46/0019-net-dsa-tag_dsa-Use-tag-priority-as-initial-skb-prio.patch index 60a0743e6..78bb597b8 100644 --- a/patches/linux/6.18.46/0019-net-dsa-tag_dsa-Use-tag-priority-as-initial-skb-prio.patch +++ b/patches/linux/6.18.46/0019-net-dsa-tag_dsa-Use-tag-priority-as-initial-skb-prio.patch @@ -1,8 +1,9 @@ From 5027f6ffd52d93916153bce5bbea45e510cdde00 Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Tue, 28 May 2024 10:38:42 +0200 -Subject: [PATCH 19/51] net: dsa: tag_dsa: Use tag priority as initial +Subject: [PATCH 19/64] net: dsa: tag_dsa: Use tag priority as initial skb->priority +Organization: Wires Use the 3-bit priority field from the DSA tag as the initial packet priority on ingress to the CPU. diff --git a/patches/linux/6.18.46/0020-net-dsa-Support-MDB-memberships-whose-L2-addresses-o.patch b/patches/linux/6.18.46/0020-net-dsa-Support-MDB-memberships-whose-L2-addresses-o.patch index d19eee19d..dbf4bd741 100644 --- a/patches/linux/6.18.46/0020-net-dsa-Support-MDB-memberships-whose-L2-addresses-o.patch +++ b/patches/linux/6.18.46/0020-net-dsa-Support-MDB-memberships-whose-L2-addresses-o.patch @@ -1,8 +1,9 @@ From ac1320e82a14564a734664a0a8f7a0c116aaccdd Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Tue, 16 Jan 2024 16:00:55 +0100 -Subject: [PATCH 20/51] net: dsa: Support MDB memberships whose L2 addresses +Subject: [PATCH 20/64] net: dsa: Support MDB memberships whose L2 addresses overlap +Organization: Wires Multiple IP multicast groups (32 for v4, 2^80 for v6) map to the same L2 address. This means that switchdev drivers may receive multiple MDB diff --git a/patches/linux/6.18.46/0021-net-dsa-Support-EtherType-based-priority-overrides.patch b/patches/linux/6.18.46/0021-net-dsa-Support-EtherType-based-priority-overrides.patch index 1518ba71d..c6525ff82 100644 --- a/patches/linux/6.18.46/0021-net-dsa-Support-EtherType-based-priority-overrides.patch +++ b/patches/linux/6.18.46/0021-net-dsa-Support-EtherType-based-priority-overrides.patch @@ -1,7 +1,8 @@ From 8e49aca4ae513ea525bdf82b5f05045c11448f6a Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Thu, 21 Mar 2024 19:12:15 +0100 -Subject: [PATCH 21/51] net: dsa: Support EtherType based priority overrides +Subject: [PATCH 21/64] net: dsa: Support EtherType based priority overrides +Organization: Wires --- include/net/dsa.h | 4 ++++ diff --git a/patches/linux/6.18.46/0022-net-dsa-mv88e6xxx-Support-EtherType-based-priority-o.patch b/patches/linux/6.18.46/0022-net-dsa-mv88e6xxx-Support-EtherType-based-priority-o.patch index ff5f14bc3..851ece142 100644 --- a/patches/linux/6.18.46/0022-net-dsa-mv88e6xxx-Support-EtherType-based-priority-o.patch +++ b/patches/linux/6.18.46/0022-net-dsa-mv88e6xxx-Support-EtherType-based-priority-o.patch @@ -1,8 +1,9 @@ From e474fdde8c8131bbf996112e274f9842c659aa42 Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Fri, 22 Mar 2024 16:15:43 +0100 -Subject: [PATCH 22/51] net: dsa: mv88e6xxx: Support EtherType based priority +Subject: [PATCH 22/64] net: dsa: mv88e6xxx: Support EtherType based priority overrides +Organization: Wires --- drivers/net/dsa/mv88e6xxx/chip.c | 64 +++++++++++++++++++++++++++++ diff --git a/patches/linux/6.18.46/0023-net-dsa-mv88e6xxx-Add-mqprio-qdisc-support.patch b/patches/linux/6.18.46/0023-net-dsa-mv88e6xxx-Add-mqprio-qdisc-support.patch index 538b03592..09d2a5480 100644 --- a/patches/linux/6.18.46/0023-net-dsa-mv88e6xxx-Add-mqprio-qdisc-support.patch +++ b/patches/linux/6.18.46/0023-net-dsa-mv88e6xxx-Add-mqprio-qdisc-support.patch @@ -1,7 +1,8 @@ From fd4efe5794c4abc5e1d0f06f70466d6e2eccd37d Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Tue, 28 May 2024 11:04:22 +0200 -Subject: [PATCH 23/51] net: dsa: mv88e6xxx: Add mqprio qdisc support +Subject: [PATCH 23/64] net: dsa: mv88e6xxx: Add mqprio qdisc support +Organization: Wires Add support for attaching mqprio qdisc's to mv88e6xxx ports and use the packet's traffic class as the outgoing priority when no PCP bits diff --git a/patches/linux/6.18.46/0024-net-dsa-mv88e6xxx-Use-VLAN-prio-over-IP-when-both-ar.patch b/patches/linux/6.18.46/0024-net-dsa-mv88e6xxx-Use-VLAN-prio-over-IP-when-both-ar.patch index b47582ec5..9706f7444 100644 --- a/patches/linux/6.18.46/0024-net-dsa-mv88e6xxx-Use-VLAN-prio-over-IP-when-both-ar.patch +++ b/patches/linux/6.18.46/0024-net-dsa-mv88e6xxx-Use-VLAN-prio-over-IP-when-both-ar.patch @@ -1,8 +1,9 @@ From e9dc3d87cc9812e1b81f19ea1ad15b0492e35b91 Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Wed, 29 May 2024 13:20:41 +0200 -Subject: [PATCH 24/51] net: dsa: mv88e6xxx: Use VLAN prio over IP when both +Subject: [PATCH 24/64] net: dsa: mv88e6xxx: Use VLAN prio over IP when both are available +Organization: Wires Switch the priority sourcing precdence to prefer VLAN PCP over IP DSCP, when both are available. diff --git a/patches/linux/6.18.46/0025-FIX-net-dsa-mv88e6xxx-Trap-locally-terminated-VLANs.patch b/patches/linux/6.18.46/0025-FIX-net-dsa-mv88e6xxx-Trap-locally-terminated-VLANs.patch index 5b6afab28..6038626e4 100644 --- a/patches/linux/6.18.46/0025-FIX-net-dsa-mv88e6xxx-Trap-locally-terminated-VLANs.patch +++ b/patches/linux/6.18.46/0025-FIX-net-dsa-mv88e6xxx-Trap-locally-terminated-VLANs.patch @@ -1,8 +1,9 @@ From 365989e8bc430a722c62fae7a54aa76d95403d44 Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Tue, 26 Nov 2024 19:45:59 +0100 -Subject: [PATCH 25/51] [FIX] net: dsa: mv88e6xxx: Trap locally terminated +Subject: [PATCH 25/64] [FIX] net: dsa: mv88e6xxx: Trap locally terminated VLANs +Organization: Wires Before this change, in a setup like the following, packets assigned to VLAN 10 were forwarded between the switch ports, even though the diff --git a/patches/linux/6.18.46/0026-net-dsa-mv88e6xxx-collapse-disabled-state-into-block.patch b/patches/linux/6.18.46/0026-net-dsa-mv88e6xxx-collapse-disabled-state-into-block.patch index 7f64a66e1..4981c6a5e 100644 --- a/patches/linux/6.18.46/0026-net-dsa-mv88e6xxx-collapse-disabled-state-into-block.patch +++ b/patches/linux/6.18.46/0026-net-dsa-mv88e6xxx-collapse-disabled-state-into-block.patch @@ -1,8 +1,9 @@ From cc07a927ce3d66cbb5507b97d71f2e4289e3932a Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Thu, 16 Jan 2025 12:35:12 +0100 -Subject: [PATCH 26/51] net: dsa: mv88e6xxx: collapse disabled state into +Subject: [PATCH 26/64] net: dsa: mv88e6xxx: collapse disabled state into blocking +Organization: Wires This patch changes the behavior of switchcore ports wrt. the port state. Instead of disabling the port, the driver now treats the disabled state diff --git a/patches/linux/6.18.46/0027-net-dsa-mv88e6xxx-Only-activate-LAG-offloading-when-.patch b/patches/linux/6.18.46/0027-net-dsa-mv88e6xxx-Only-activate-LAG-offloading-when-.patch index 25713888b..fdc08b297 100644 --- a/patches/linux/6.18.46/0027-net-dsa-mv88e6xxx-Only-activate-LAG-offloading-when-.patch +++ b/patches/linux/6.18.46/0027-net-dsa-mv88e6xxx-Only-activate-LAG-offloading-when-.patch @@ -1,8 +1,9 @@ From 293bd6b0ff1a613e7a2f864039517881f1dd7191 Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Wed, 12 Feb 2025 22:03:14 +0100 -Subject: [PATCH 27/51] net: dsa: mv88e6xxx: Only activate LAG offloading when +Subject: [PATCH 27/64] net: dsa: mv88e6xxx: Only activate LAG offloading when bridged +Organization: Wires The current port isolation scheme for mv88e6xxx is detailed here: https://lore.kernel.org/netdev/20220203101657.990241-1-tobias@waldekranz.com/ diff --git a/patches/linux/6.18.46/0028-net-dsa-mv88e6xxx-Add-LED-support-for-6393X.patch b/patches/linux/6.18.46/0028-net-dsa-mv88e6xxx-Add-LED-support-for-6393X.patch index b86aebd16..0ed4cfd6c 100644 --- a/patches/linux/6.18.46/0028-net-dsa-mv88e6xxx-Add-LED-support-for-6393X.patch +++ b/patches/linux/6.18.46/0028-net-dsa-mv88e6xxx-Add-LED-support-for-6393X.patch @@ -1,7 +1,8 @@ From cbdcda769e36b4c2c4870b01a02efd4223f327e1 Mon Sep 17 00:00:00 2001 From: Mattias Walström Date: Wed, 14 Jan 2026 18:22:41 +0100 -Subject: [PATCH 28/51] net: dsa: mv88e6xxx: Add LED support for 6393X +Subject: [PATCH 28/64] net: dsa: mv88e6xxx: Add LED support for 6393X +Organization: Wires Original commit: commit 462277b926140ee2d231317e92afb6cabf640268 diff --git a/patches/linux/6.18.46/0029-wifi-brcmfmac-support-deletion-and-recreation-of-pri.patch b/patches/linux/6.18.46/0029-wifi-brcmfmac-support-deletion-and-recreation-of-pri.patch index a10c95d75..bcf38abee 100644 --- a/patches/linux/6.18.46/0029-wifi-brcmfmac-support-deletion-and-recreation-of-pri.patch +++ b/patches/linux/6.18.46/0029-wifi-brcmfmac-support-deletion-and-recreation-of-pri.patch @@ -1,11 +1,12 @@ From 38ed86d1c1b291c40e6a15681acc09234014a271 Mon Sep 17 00:00:00 2001 From: Mattias Walström Date: Thu, 15 Jan 2026 22:47:37 +0100 -Subject: [PATCH 29/51] wifi: brcmfmac: support deletion and recreation of +Subject: [PATCH 29/64] wifi: brcmfmac: support deletion and recreation of primary interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit +Organization: Wires The Broadcom FullMAC firmware does not allow the primary interface (bsscfgidx 0) to be deleted - it always exists in firmware. However, diff --git a/patches/linux/6.18.46/0030-wifi-brcmfmac-check-connection-state-before-querying.patch b/patches/linux/6.18.46/0030-wifi-brcmfmac-check-connection-state-before-querying.patch index 4294e225e..aaa994bc4 100644 --- a/patches/linux/6.18.46/0030-wifi-brcmfmac-check-connection-state-before-querying.patch +++ b/patches/linux/6.18.46/0030-wifi-brcmfmac-check-connection-state-before-querying.patch @@ -1,11 +1,12 @@ From 854fa7b14fd0e6612884a3020279f613daeaf07f Mon Sep 17 00:00:00 2001 From: Mattias Walström Date: Mon, 19 Jan 2026 13:06:53 +0100 -Subject: [PATCH 30/51] wifi: brcmfmac: check connection state before querying +Subject: [PATCH 30/64] wifi: brcmfmac: check connection state before querying station info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit +Organization: Wires In station mode, brcmf_cfg80211_get_station() queries the firmware for station info even when not connected to an AP. This results in error diff --git a/patches/linux/6.18.46/0031-wifi-brcmfmac-suppress-log-spam-for-regulatory-restr.patch b/patches/linux/6.18.46/0031-wifi-brcmfmac-suppress-log-spam-for-regulatory-restr.patch index 3a18cac59..ff45e6c01 100644 --- a/patches/linux/6.18.46/0031-wifi-brcmfmac-suppress-log-spam-for-regulatory-restr.patch +++ b/patches/linux/6.18.46/0031-wifi-brcmfmac-suppress-log-spam-for-regulatory-restr.patch @@ -1,11 +1,12 @@ From 93c0d322dc996a4cb3b1fbe7de5b4d103c4ff936 Mon Sep 17 00:00:00 2001 From: Mattias Walström Date: Tue, 20 Jan 2026 20:12:10 +0100 -Subject: [PATCH 31/51] wifi: brcmfmac: suppress log spam for +Subject: [PATCH 31/64] wifi: brcmfmac: suppress log spam for regulatory-restricted channels MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit +Organization: Wires When scanning, the driver attempts to set each channel and logs an error if the firmware rejects it. For regulatory-restricted channels, diff --git a/patches/linux/6.18.46/0032-wifi-brcmfmac-reduce-log-noise-during-AP-to-station-.patch b/patches/linux/6.18.46/0032-wifi-brcmfmac-reduce-log-noise-during-AP-to-station-.patch index 06f6b2cda..cbc5c15be 100644 --- a/patches/linux/6.18.46/0032-wifi-brcmfmac-reduce-log-noise-during-AP-to-station-.patch +++ b/patches/linux/6.18.46/0032-wifi-brcmfmac-reduce-log-noise-during-AP-to-station-.patch @@ -1,11 +1,12 @@ From 974f5187c4e1e618b7a4912b0fe8f7f02d8f2102 Mon Sep 17 00:00:00 2001 From: Mattias Walström Date: Tue, 20 Jan 2026 20:18:45 +0100 -Subject: [PATCH 32/51] wifi: brcmfmac: reduce log noise during AP to station +Subject: [PATCH 32/64] wifi: brcmfmac: reduce log noise during AP to station transition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit +Organization: Wires When transitioning from AP mode to station mode (e.g., hostapd stopping and wpa_supplicant starting), several non-fatal errors can occur: diff --git a/patches/linux/6.18.46/0033-net-phy-air_en8811h-add-OF-device-table-for-auto-loa.patch b/patches/linux/6.18.46/0033-net-phy-air_en8811h-add-OF-device-table-for-auto-loa.patch index dc703ba12..60f48320e 100644 --- a/patches/linux/6.18.46/0033-net-phy-air_en8811h-add-OF-device-table-for-auto-loa.patch +++ b/patches/linux/6.18.46/0033-net-phy-air_en8811h-add-OF-device-table-for-auto-loa.patch @@ -1,8 +1,9 @@ From ea6dd4989c7bb939e925f4c9173966e1c314ffa6 Mon Sep 17 00:00:00 2001 From: Mattias Walström Date: Tue, 17 Feb 2026 21:59:59 +0100 -Subject: [PATCH 33/51] net: phy: air_en8811h: add OF device table for +Subject: [PATCH 33/64] net: phy: air_en8811h: add OF device table for auto-loading +Organization: Wires mdio_uevent() only emits an OF-style MODALIAS via of_device_uevent_modalias(), never the mdio: binary format that diff --git a/patches/linux/6.18.46/0034-drm-vc4-dsi-enable-video-and-then-retry-failed-trans.patch b/patches/linux/6.18.46/0034-drm-vc4-dsi-enable-video-and-then-retry-failed-trans.patch index 92046f485..033f2d322 100644 --- a/patches/linux/6.18.46/0034-drm-vc4-dsi-enable-video-and-then-retry-failed-trans.patch +++ b/patches/linux/6.18.46/0034-drm-vc4-dsi-enable-video-and-then-retry-failed-trans.patch @@ -1,8 +1,9 @@ From be81d065db8772a936a8aa82a58cbb64e04e9c20 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Fri, 20 Sep 2024 12:05:18 +0100 -Subject: [PATCH 34/51] drm: vc4: dsi: enable video and then retry failed +Subject: [PATCH 34/64] drm: vc4: dsi: enable video and then retry failed transfers +Organization: Wires The DSI block appears to be able to come up stuck in a condition where it leaves the lanes in HS mode or just jabbering. This stops LP diff --git a/patches/linux/6.18.46/0035-drm-vc4-dsi-Clocks-should-be-running-before-reset.patch b/patches/linux/6.18.46/0035-drm-vc4-dsi-Clocks-should-be-running-before-reset.patch index 23554b0e4..2a2364a45 100644 --- a/patches/linux/6.18.46/0035-drm-vc4-dsi-Clocks-should-be-running-before-reset.patch +++ b/patches/linux/6.18.46/0035-drm-vc4-dsi-Clocks-should-be-running-before-reset.patch @@ -1,7 +1,8 @@ From 68d70ad3bf8403c46abbb915082ecd62f22b67f0 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 8 Jun 2022 17:23:47 +0100 -Subject: [PATCH 35/51] drm: vc4: dsi: Clocks should be running before reset +Subject: [PATCH 35/64] drm: vc4: dsi: Clocks should be running before reset +Organization: Wires The initialisation sequence differs slightly from the documentation in that the clocks are meant to be running before resets and diff --git a/patches/linux/6.18.46/0036-drm-vc4-Ensure-DSI-is-enabled-for-FIFO-resets.patch b/patches/linux/6.18.46/0036-drm-vc4-Ensure-DSI-is-enabled-for-FIFO-resets.patch index 1dbcadf53..ce2c4917c 100644 --- a/patches/linux/6.18.46/0036-drm-vc4-Ensure-DSI-is-enabled-for-FIFO-resets.patch +++ b/patches/linux/6.18.46/0036-drm-vc4-Ensure-DSI-is-enabled-for-FIFO-resets.patch @@ -1,7 +1,8 @@ From 1c76f7dc3d027966639b7d5ca6f65129547c6a2d Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Fri, 5 Apr 2024 17:51:55 +0100 -Subject: [PATCH 36/51] drm/vc4: Ensure DSI is enabled for FIFO resets +Subject: [PATCH 36/64] drm/vc4: Ensure DSI is enabled for FIFO resets +Organization: Wires The block must be enabled for the FIFO resets to be actioned, so ensure this is the case. diff --git a/patches/linux/6.18.46/0037-drm-vc4-Reset-DSI-AFE-on-disable.patch b/patches/linux/6.18.46/0037-drm-vc4-Reset-DSI-AFE-on-disable.patch index 5b6b875f2..3d408454a 100644 --- a/patches/linux/6.18.46/0037-drm-vc4-Reset-DSI-AFE-on-disable.patch +++ b/patches/linux/6.18.46/0037-drm-vc4-Reset-DSI-AFE-on-disable.patch @@ -1,7 +1,8 @@ From 10c7894512493d96255f5b04c173e3c221d02ecc Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Thu, 26 May 2022 18:56:19 +0100 -Subject: [PATCH 37/51] drm: vc4: Reset DSI AFE on disable +Subject: [PATCH 37/64] drm: vc4: Reset DSI AFE on disable +Organization: Wires vc4_dsi_bridge_disable wasn't resetting things during shutdown, so add that in. diff --git a/patches/linux/6.18.46/0038-drm-vc4-dsi-Handle-the-different-command-FIFO-widths.patch b/patches/linux/6.18.46/0038-drm-vc4-dsi-Handle-the-different-command-FIFO-widths.patch index 75009fdfd..a20f3a1c0 100644 --- a/patches/linux/6.18.46/0038-drm-vc4-dsi-Handle-the-different-command-FIFO-widths.patch +++ b/patches/linux/6.18.46/0038-drm-vc4-dsi-Handle-the-different-command-FIFO-widths.patch @@ -1,7 +1,8 @@ From 29c6177a89963064bee65d75e8c3eb627b59eef3 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 20 Nov 2024 13:58:08 +0000 -Subject: [PATCH 38/51] drm: vc4: dsi: Handle the different command FIFO widths +Subject: [PATCH 38/64] drm: vc4: dsi: Handle the different command FIFO widths +Organization: Wires DSI0 and DSI1 have different widths for the command FIFO (24bit vs 32bit), but the driver was assuming the 32bit width of DSI1 diff --git a/patches/linux/6.18.46/0039-drm-bridge-tc358762-Program-the-DPI-mode-into-the-ch.patch b/patches/linux/6.18.46/0039-drm-bridge-tc358762-Program-the-DPI-mode-into-the-ch.patch index a92d19516..1f395a4c4 100644 --- a/patches/linux/6.18.46/0039-drm-bridge-tc358762-Program-the-DPI-mode-into-the-ch.patch +++ b/patches/linux/6.18.46/0039-drm-bridge-tc358762-Program-the-DPI-mode-into-the-ch.patch @@ -1,8 +1,9 @@ From 28567ab2d86656eb251237c2e724ca3adb7bd990 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Tue, 9 Jan 2024 17:37:00 +0000 -Subject: [PATCH 39/51] drm/bridge: tc358762: Program the DPI mode into the +Subject: [PATCH 39/64] drm/bridge: tc358762: Program the DPI mode into the chip +Organization: Wires The autodetection of resolution/timing by the TC358762 can lead to the display being shifted by a pixel or two. diff --git a/patches/linux/6.18.46/0040-drm-bridge-tc358762-revert-move-ops-to-enable.patch b/patches/linux/6.18.46/0040-drm-bridge-tc358762-revert-move-ops-to-enable.patch index a709ffa4a..35b2e4569 100644 --- a/patches/linux/6.18.46/0040-drm-bridge-tc358762-revert-move-ops-to-enable.patch +++ b/patches/linux/6.18.46/0040-drm-bridge-tc358762-revert-move-ops-to-enable.patch @@ -1,7 +1,8 @@ From 98cae179b9f4aa535686fb10031183b0d7b98294 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Tue, 9 Jan 2024 18:44:49 +0000 -Subject: [PATCH 40/51] drm/bridge: tc358762: revert move ops to enable +Subject: [PATCH 40/64] drm/bridge: tc358762: revert move ops to enable +Organization: Wires Reverts 8a4b2fc9c91a ("drm/bridge: tc358762: Split register programming from pre-enable to enable") as we want the config commands sent before video starts. diff --git a/patches/linux/6.18.46/0041-drm-bridge-tc358762-Set-pre_enabled-on-pre_enable-to.patch b/patches/linux/6.18.46/0041-drm-bridge-tc358762-Set-pre_enabled-on-pre_enable-to.patch index 4796b421e..b6d8f01c6 100644 --- a/patches/linux/6.18.46/0041-drm-bridge-tc358762-Set-pre_enabled-on-pre_enable-to.patch +++ b/patches/linux/6.18.46/0041-drm-bridge-tc358762-Set-pre_enabled-on-pre_enable-to.patch @@ -1,11 +1,12 @@ From df1dd24ec79a6b653484d44a47c2e4856284ca01 Mon Sep 17 00:00:00 2001 From: Mattias Walström Date: Sat, 4 Apr 2026 18:04:19 +0200 -Subject: [PATCH 41/51] drm/bridge: tc358762: Set pre_enabled on pre_enable to +Subject: [PATCH 41/64] drm/bridge: tc358762: Set pre_enabled on pre_enable to prevent regulator imbalance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit +Organization: Wires The RPi cherry-pick moved tc358762_init() to pre_enable but dropped the pre_enabled = true assignment. Without it, post_disable always bails out early and never disables the regulator. diff --git a/patches/linux/6.18.46/0042-net-pcs-add-standalone-PCS-registration-infrastructu.patch b/patches/linux/6.18.46/0042-net-pcs-add-standalone-PCS-registration-infrastructu.patch index 9152e8633..b7ae733b6 100644 --- a/patches/linux/6.18.46/0042-net-pcs-add-standalone-PCS-registration-infrastructu.patch +++ b/patches/linux/6.18.46/0042-net-pcs-add-standalone-PCS-registration-infrastructu.patch @@ -1,7 +1,8 @@ From ba4bf183b4951aef883d3211f20b957367a6870e Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sun, 5 Apr 2026 11:33:00 +0200 -Subject: [PATCH 42/51] net/pcs: add standalone PCS registration infrastructure +Subject: [PATCH 42/64] net/pcs: add standalone PCS registration infrastructure +Organization: Wires Add a simple registration mechanism that allows platform PCS drivers to register their phylink_pcs instances, and consumers (e.g. Ethernet MAC diff --git a/patches/linux/6.18.46/0043-net-pcs-add-MediaTek-MT7988-USXGMII-PCS-driver.patch b/patches/linux/6.18.46/0043-net-pcs-add-MediaTek-MT7988-USXGMII-PCS-driver.patch index 2d84d49f0..a8e541c6e 100644 --- a/patches/linux/6.18.46/0043-net-pcs-add-MediaTek-MT7988-USXGMII-PCS-driver.patch +++ b/patches/linux/6.18.46/0043-net-pcs-add-MediaTek-MT7988-USXGMII-PCS-driver.patch @@ -1,7 +1,8 @@ From 98943e6e990fae82fbfc635daa223ca528173ceb Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Mon, 6 Apr 2026 14:14:23 +0200 -Subject: [PATCH 43/51] net/pcs: add MediaTek MT7988 USXGMII PCS driver +Subject: [PATCH 43/64] net/pcs: add MediaTek MT7988 USXGMII PCS driver +Organization: Wires Add a PCS driver for the USXGMII subsystem found in the MediaTek MT7988 SoC (usxgmiisys0 at 0x10080000, usxgmiisys1 at 0x10081000). The hardware diff --git a/patches/linux/6.18.46/0044-net-ethernet-mediatek-add-USXGMII-support-for-MT7988.patch b/patches/linux/6.18.46/0044-net-ethernet-mediatek-add-USXGMII-support-for-MT7988.patch index f8ff16f44..67a3546dc 100644 --- a/patches/linux/6.18.46/0044-net-ethernet-mediatek-add-USXGMII-support-for-MT7988.patch +++ b/patches/linux/6.18.46/0044-net-ethernet-mediatek-add-USXGMII-support-for-MT7988.patch @@ -1,10 +1,11 @@ From 198e2e4dd0c98e9b97c372503c6a6fd2253d166b Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Mon, 6 Apr 2026 14:15:43 +0200 -Subject: [PATCH 44/51] net: ethernet: mediatek: add USXGMII support for MT7988 +Subject: [PATCH 44/64] net: ethernet: mediatek: add USXGMII support for MT7988 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit +Organization: Wires Add support for the USXGMII path used by gmac1 and gmac2 on the MT7988 SoC (BananaPi BPI-R4). Changes: diff --git a/patches/linux/6.18.46/0045-arm64-dts-mediatek-mt7988a-add-USXGMII-PCS-nodes.patch b/patches/linux/6.18.46/0045-arm64-dts-mediatek-mt7988a-add-USXGMII-PCS-nodes.patch index a5d4affe0..df86aece6 100644 --- a/patches/linux/6.18.46/0045-arm64-dts-mediatek-mt7988a-add-USXGMII-PCS-nodes.patch +++ b/patches/linux/6.18.46/0045-arm64-dts-mediatek-mt7988a-add-USXGMII-PCS-nodes.patch @@ -1,7 +1,8 @@ From c3a1c9134ffd977fde5029ade219b2264be78b6e Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Mon, 6 Apr 2026 14:15:56 +0200 -Subject: [PATCH 45/51] arm64: dts: mediatek: mt7988a: add USXGMII PCS nodes +Subject: [PATCH 45/64] arm64: dts: mediatek: mt7988a: add USXGMII PCS nodes +Organization: Wires Add device nodes for the two USXGMII subsystem blocks (usxgmiisys0 at 0x10080000 and usxgmiisys1 at 0x10081000), each referencing its clock, diff --git a/patches/linux/6.18.46/0046-arm64-dts-mediatek-bananapi-bpi-r4-enable-SFP-ports-.patch b/patches/linux/6.18.46/0046-arm64-dts-mediatek-bananapi-bpi-r4-enable-SFP-ports-.patch index c195e2a6d..7059cdf6a 100644 --- a/patches/linux/6.18.46/0046-arm64-dts-mediatek-bananapi-bpi-r4-enable-SFP-ports-.patch +++ b/patches/linux/6.18.46/0046-arm64-dts-mediatek-bananapi-bpi-r4-enable-SFP-ports-.patch @@ -1,8 +1,9 @@ From 7e489d0c99259d17b6dd92d892afde4193d54efe Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Mon, 6 Apr 2026 14:16:11 +0200 -Subject: [PATCH 46/51] arm64: dts: mediatek: bananapi-bpi-r4: enable SFP+ +Subject: [PATCH 46/64] arm64: dts: mediatek: bananapi-bpi-r4: enable SFP+ ports and WPS button +Organization: Wires Enable the SFP+ cages wired to gmac1 and gmac2. The USXGMII PCS nodes and xfi_tphy SerDes are wired up in mt7988a.dtsi; only status = "okay" diff --git a/patches/linux/6.18.46/0047-net-phy-sfp-add-OEM-SFP-10G-T-I-quirk.patch b/patches/linux/6.18.46/0047-net-phy-sfp-add-OEM-SFP-10G-T-I-quirk.patch index 042ed6da2..a4501dc83 100644 --- a/patches/linux/6.18.46/0047-net-phy-sfp-add-OEM-SFP-10G-T-I-quirk.patch +++ b/patches/linux/6.18.46/0047-net-phy-sfp-add-OEM-SFP-10G-T-I-quirk.patch @@ -1,10 +1,11 @@ From 2c62214c6d20bd98ebb4096f65e4c6dbff4796d0 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Tue, 7 Apr 2026 07:34:52 +0200 -Subject: [PATCH 47/51] net: phy: sfp: add OEM SFP-10G-T-I quirk +Subject: [PATCH 47/64] net: phy: sfp: add OEM SFP-10G-T-I quirk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit +Organization: Wires The industrial-temperature variant of the OEM SFP-10G-T copper module reports vendor PN "SFP-10G-T-I". Unlike the base "SFP-10G-T" which is a diff --git a/patches/linux/6.18.46/0048-net-dsa-mv88e6xxx-Trap-PTP-frames-on-timestamping-po.patch b/patches/linux/6.18.46/0048-net-dsa-mv88e6xxx-Trap-PTP-frames-on-timestamping-po.patch index 5f35c1377..2bd5a1f41 100644 --- a/patches/linux/6.18.46/0048-net-dsa-mv88e6xxx-Trap-PTP-frames-on-timestamping-po.patch +++ b/patches/linux/6.18.46/0048-net-dsa-mv88e6xxx-Trap-PTP-frames-on-timestamping-po.patch @@ -1,8 +1,9 @@ From 4519c34f0aa0fac92c47f13523c11134d4dbf83f Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Fri, 17 Apr 2026 09:13:04 +0000 -Subject: [PATCH 48/51] net: dsa: mv88e6xxx: Trap PTP frames on timestamping +Subject: [PATCH 48/64] net: dsa: mv88e6xxx: Trap PTP frames on timestamping ports, on 6393X +Organization: Wires Similar to the Peridot (6390), the designation of PTP frames as management (and the destination port) must be explicitly diff --git a/patches/linux/6.18.46/0049-wifi-mt76-mt7615-add-MODULE_DEVICE_TABLE-for-mt7622-.patch b/patches/linux/6.18.46/0049-wifi-mt76-mt7615-add-MODULE_DEVICE_TABLE-for-mt7622-.patch index 4dc921e55..e3b836475 100644 --- a/patches/linux/6.18.46/0049-wifi-mt76-mt7615-add-MODULE_DEVICE_TABLE-for-mt7622-.patch +++ b/patches/linux/6.18.46/0049-wifi-mt76-mt7615-add-MODULE_DEVICE_TABLE-for-mt7622-.patch @@ -1,8 +1,9 @@ From bd2d7c32a849c3aae185d6480b8331a53523bd52 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Tue, 28 Apr 2026 15:30:01 +0200 -Subject: [PATCH 49/51] wifi: mt76: mt7615: add MODULE_DEVICE_TABLE for mt7622 +Subject: [PATCH 49/64] wifi: mt76: mt7615: add MODULE_DEVICE_TABLE for mt7622 wmac +Organization: Wires Without MODULE_DEVICE_TABLE(of, ...) the OF compatible alias is never exported to modules.alias, so udev cannot autoload mt7615e when the diff --git a/patches/linux/6.18.46/0050-PCI-mediatek-gen3-Fix-PERST-control-timing-during-sy.patch b/patches/linux/6.18.46/0050-PCI-mediatek-gen3-Fix-PERST-control-timing-during-sy.patch index 71a516ade..6e9013492 100644 --- a/patches/linux/6.18.46/0050-PCI-mediatek-gen3-Fix-PERST-control-timing-during-sy.patch +++ b/patches/linux/6.18.46/0050-PCI-mediatek-gen3-Fix-PERST-control-timing-during-sy.patch @@ -1,11 +1,12 @@ From cfe3cae54505d0b52f2bd314ed3c6492f4a8e0a7 Mon Sep 17 00:00:00 2001 From: Mattias Walström Date: Wed, 22 Apr 2026 10:24:43 +0200 -Subject: [PATCH 50/51] PCI: mediatek-gen3: Fix PERST# control timing during +Subject: [PATCH 50/64] PCI: mediatek-gen3: Fix PERST# control timing during system startup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit +Organization: Wires Some of MediaTek's chips (mt7986 amongst them) stop generating REFCLK if the PCIE_PHY_RSTB signal of the PCIe controller is asserted. diff --git a/patches/linux/6.18.46/0051-net-dsa-mv88e6xxx-Derive-LED-names-from-device-name.patch b/patches/linux/6.18.46/0051-net-dsa-mv88e6xxx-Derive-LED-names-from-device-name.patch index 554e79366..e918b35c1 100644 --- a/patches/linux/6.18.46/0051-net-dsa-mv88e6xxx-Derive-LED-names-from-device-name.patch +++ b/patches/linux/6.18.46/0051-net-dsa-mv88e6xxx-Derive-LED-names-from-device-name.patch @@ -1,10 +1,11 @@ From cbc7109adb79cf7e1f20e1e93421511a93ab9e05 Mon Sep 17 00:00:00 2001 From: Mattias Walström Date: Wed, 12 Aug 2026 10:08:53 +0200 -Subject: [PATCH 51/51] net: dsa: mv88e6xxx: Derive LED names from device name +Subject: [PATCH 51/64] net: dsa: mv88e6xxx: Derive LED names from device name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit +Organization: Wires LED devices were named ":0:0", e.g. "mv88e6390:01:00:port:lednum". Since chip->info->name is the model name, two diff --git a/patches/linux/6.18.46/0052-phy-sparx5-serdes-make-it-selectable-for-ARCH_LAN969.patch b/patches/linux/6.18.46/0052-phy-sparx5-serdes-make-it-selectable-for-ARCH_LAN969.patch new file mode 100644 index 000000000..fecb3e8db --- /dev/null +++ b/patches/linux/6.18.46/0052-phy-sparx5-serdes-make-it-selectable-for-ARCH_LAN969.patch @@ -0,0 +1,33 @@ +From 65ba23bcd8ecebee5cf2a52f09aa617362554b78 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Fri, 31 Oct 2025 13:18:12 +0100 +Subject: [PATCH 52/64] phy: sparx5-serdes: make it selectable for ARCH_LAN969X +Organization: Wires + +LAN969x uses the SparX-5 SERDES driver, so make it selectable for +ARCH_LAN969X. + +Reviewed-by: Daniel Machon +Signed-off-by: Robert Marko +Tested-by: Gabor Juhos +Tested-by: Vladimir Oltean +Link: https://patch.msgid.link/20251031121834.665987-1-robert.marko@sartura.hr +Signed-off-by: Vinod Koul +(cherry picked from commit d543d3eb06873f0ab8edb0d1f8364e9af93544a0) +--- + drivers/phy/microchip/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/phy/microchip/Kconfig b/drivers/phy/microchip/Kconfig +index 2f0045e874ac..2e6d1224711e 100644 +--- a/drivers/phy/microchip/Kconfig ++++ b/drivers/phy/microchip/Kconfig +@@ -6,7 +6,7 @@ + config PHY_SPARX5_SERDES + tristate "Microchip Sparx5 SerDes PHY driver" + select GENERIC_PHY +- depends on ARCH_SPARX5 || COMPILE_TEST ++ depends on ARCH_SPARX5 || ARCH_LAN969X || COMPILE_TEST + depends on OF + depends on HAS_IOMEM + help diff --git a/patches/linux/6.18.46/0053-net-sparx5-fix-wrong-chip-ids-for-TSN-SKUs.patch b/patches/linux/6.18.46/0053-net-sparx5-fix-wrong-chip-ids-for-TSN-SKUs.patch new file mode 100644 index 000000000..43bb11a5b --- /dev/null +++ b/patches/linux/6.18.46/0053-net-sparx5-fix-wrong-chip-ids-for-TSN-SKUs.patch @@ -0,0 +1,53 @@ +From 37170ce9154fe02f4b7c32dc598a8588a863723d Mon Sep 17 00:00:00 2001 +From: Daniel Machon +Date: Wed, 6 May 2026 09:25:38 +0200 +Subject: [PATCH 53/64] net: sparx5: fix wrong chip ids for TSN SKUs +Organization: Wires + +The TSN SKUs in enum spx5_target_chiptype have incorrect IDs: + + SPX5_TARGET_CT_7546TSN = 0x47546, + SPX5_TARGET_CT_7549TSN = 0x47549, + SPX5_TARGET_CT_7552TSN = 0x47552, + SPX5_TARGET_CT_7556TSN = 0x47556, + SPX5_TARGET_CT_7558TSN = 0x47558, + +The value read back from the chip is GCB_CHIP_ID_PART_ID, which is a +GENMASK(27, 12) field, i.e. at most 16 bits wide. It can never match +these IDs, so probing a TSN part fails with a "Target not supported" +error. + +Fix the enum to use the actual 16-bit part IDs returned by the +hardware: 0x0546, 0x0549, 0x0552, 0x0556 and 0x0558. + +Reported-by: Andrew Lunn +Fixes: 3cfa11bac9bb ("net: sparx5: add the basic sparx5 driver") +Signed-off-by: Daniel Machon +Link: https://patch.msgid.link/20260506-misc-fixes-sparx5-lan969x-v2-3-fb236aa96908@microchip.com +Signed-off-by: Jakub Kicinski +(cherry picked from commit b131dc93f7bf1b1461f5bde0c06c4c2384aa5b58) +--- + drivers/net/ethernet/microchip/sparx5/sparx5_main.h | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h +index fe7d8bcc0cd9..2f1b50ba8ad3 100644 +--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h ++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h +@@ -31,11 +31,11 @@ enum spx5_target_chiptype { + SPX5_TARGET_CT_7552 = 0x7552, /* SparX-5-128 Enterprise */ + SPX5_TARGET_CT_7556 = 0x7556, /* SparX-5-160 Enterprise */ + SPX5_TARGET_CT_7558 = 0x7558, /* SparX-5-200 Enterprise */ +- SPX5_TARGET_CT_7546TSN = 0x47546, /* SparX-5-64i Industrial */ +- SPX5_TARGET_CT_7549TSN = 0x47549, /* SparX-5-90i Industrial */ +- SPX5_TARGET_CT_7552TSN = 0x47552, /* SparX-5-128i Industrial */ +- SPX5_TARGET_CT_7556TSN = 0x47556, /* SparX-5-160i Industrial */ +- SPX5_TARGET_CT_7558TSN = 0x47558, /* SparX-5-200i Industrial */ ++ SPX5_TARGET_CT_7546TSN = 0x0546, /* SparX-5-64i Industrial */ ++ SPX5_TARGET_CT_7549TSN = 0x0549, /* SparX-5-90i Industrial */ ++ SPX5_TARGET_CT_7552TSN = 0x0552, /* SparX-5-128i Industrial */ ++ SPX5_TARGET_CT_7556TSN = 0x0556, /* SparX-5-160i Industrial */ ++ SPX5_TARGET_CT_7558TSN = 0x0558, /* SparX-5-200i Industrial */ + SPX5_TARGET_CT_LAN9694 = 0x9694, /* lan969x-40 */ + SPX5_TARGET_CT_LAN9691VAO = 0x9691, /* lan969x-40-VAO */ + SPX5_TARGET_CT_LAN9694TSN = 0x9695, /* lan969x-40-TSN */ diff --git a/patches/linux/6.18.46/0054-net-sparx5-configure-serdes-for-1000BASE-X-in-sparx5.patch b/patches/linux/6.18.46/0054-net-sparx5-configure-serdes-for-1000BASE-X-in-sparx5.patch new file mode 100644 index 000000000..dc4c10bb7 --- /dev/null +++ b/patches/linux/6.18.46/0054-net-sparx5-configure-serdes-for-1000BASE-X-in-sparx5.patch @@ -0,0 +1,44 @@ +From a1a9f763c4760918d035ead954de9a768681e8df Mon Sep 17 00:00:00 2001 +From: Daniel Machon +Date: Wed, 6 May 2026 09:25:39 +0200 +Subject: [PATCH 54/64] net: sparx5: configure serdes for 1000BASE-X in + sparx5_port_init() +Organization: Wires + +sparx5_port_init() only invokes sparx5_serdes_set() and the associated +shadow-device enable and low-speed device switch for SGMII and QSGMII. +On any port with a high-speed primary device (DEV5G/DEV10G/DEV25G) +configured for 1000BASE-X the serdes is therefore left uninitialized, +the DEV2G5 shadow is never enabled, and the port stays pointed at its +high-speed device rather than the DEV2G5. The PCS1G block looks +healthy in isolation, but no frames reach the link partner. + +Add 1000BASE-X to the check so the same three steps run. + +Note: the same issue might apply to 2500BASE-X, but that will, +eventually, be addressed in a separate commit. + +Reported-by: Andrew Lunn +Fixes: 946e7fd5053a ("net: sparx5: add port module support") +Signed-off-by: Daniel Machon +Link: https://patch.msgid.link/20260506-misc-fixes-sparx5-lan969x-v2-4-fb236aa96908@microchip.com +Signed-off-by: Jakub Kicinski +(cherry picked from commit 41ae14071cd7f6a7770e2fe1f8a0859d4c2c6ba4) +--- + drivers/net/ethernet/microchip/sparx5/sparx5_port.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c +index 04bc8fffaf96..62c49893de3c 100644 +--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c ++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c +@@ -1128,7 +1128,8 @@ int sparx5_port_init(struct sparx5 *sparx5, + DEV2G5_PCS1G_SD_CFG(port->portno)); + + if (conf->portmode == PHY_INTERFACE_MODE_QSGMII || +- conf->portmode == PHY_INTERFACE_MODE_SGMII) { ++ conf->portmode == PHY_INTERFACE_MODE_SGMII || ++ conf->portmode == PHY_INTERFACE_MODE_1000BASEX) { + err = sparx5_serdes_set(sparx5, port, conf); + if (err) + return err; diff --git a/patches/linux/6.18.46/0055-dt-bindings-mmc-atmel-sama5d2-sdhci-add-microchip-la.patch b/patches/linux/6.18.46/0055-dt-bindings-mmc-atmel-sama5d2-sdhci-add-microchip-la.patch new file mode 100644 index 000000000..0e759348e --- /dev/null +++ b/patches/linux/6.18.46/0055-dt-bindings-mmc-atmel-sama5d2-sdhci-add-microchip-la.patch @@ -0,0 +1,29 @@ +From 34c5de04a922e37c9caecebf73437c929f5b513b Mon Sep 17 00:00:00 2001 +From: Joachim Wiberg +Date: Wed, 19 Aug 2026 11:35:29 +0200 +Subject: [PATCH 55/64] dt-bindings: mmc: atmel,sama5d2-sdhci: add + microchip,lan969x-sdhci +Organization: Wires + +The LAN969x SDMMC controller has its own base clock divider and, unlike +the SAMA5D2 and SAM9X60 variants, supports HS200 and caps SDR104 at +100 MHz. It therefore needs a compatible of its own rather than a +fallback to microchip,sam9x60-sdhci. + +Signed-off-by: Joachim Wiberg +--- + Documentation/devicetree/bindings/mmc/atmel,sama5d2-sdhci.yaml | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Documentation/devicetree/bindings/mmc/atmel,sama5d2-sdhci.yaml b/Documentation/devicetree/bindings/mmc/atmel,sama5d2-sdhci.yaml +index ba75623b7778..860e6736e2eb 100644 +--- a/Documentation/devicetree/bindings/mmc/atmel,sama5d2-sdhci.yaml ++++ b/Documentation/devicetree/bindings/mmc/atmel,sama5d2-sdhci.yaml +@@ -18,6 +18,7 @@ properties: + oneOf: + - enum: + - atmel,sama5d2-sdhci ++ - microchip,lan969x-sdhci + - microchip,sam9x60-sdhci + - items: + - enum: diff --git a/patches/linux/6.18.46/0056-mmc-sdhci-of-at91-add-LAN969x-support.patch b/patches/linux/6.18.46/0056-mmc-sdhci-of-at91-add-LAN969x-support.patch new file mode 100644 index 000000000..4510e8820 --- /dev/null +++ b/patches/linux/6.18.46/0056-mmc-sdhci-of-at91-add-LAN969x-support.patch @@ -0,0 +1,111 @@ +From 54a84169810b3650c67f51c9b71a4eeb54e9085b Mon Sep 17 00:00:00 2001 +From: Joachim Wiberg +Date: Wed, 19 Aug 2026 11:35:44 +0200 +Subject: [PATCH 56/64] mmc: sdhci-of-at91: add LAN969x support +Organization: Wires + +The LAN969x SDMMC controller is an Atmel SDMMC IP block, but the driver +has no compatible for it, so the eMMC on LAN969x boards never probes. + +Three of the driver's assumptions do not hold on LAN969x: SDR104 is +capped at 100 MHz rather than 120 MHz, HS200 works, and the hclock, +multclk and baseclk must stay enabled across runtime suspend. Move all +three to the SoC data so each variant states its own behaviour, and add +LAN969x. + +Signed-off-by: Joachim Wiberg +--- + drivers/mmc/host/sdhci-of-at91.c | 34 ++++++++++++++++++++++++++------ + 1 file changed, 28 insertions(+), 6 deletions(-) + +diff --git a/drivers/mmc/host/sdhci-of-at91.c b/drivers/mmc/host/sdhci-of-at91.c +index 7c4ac65f247d..5dcb88cba0d9 100644 +--- a/drivers/mmc/host/sdhci-of-at91.c ++++ b/drivers/mmc/host/sdhci-of-at91.c +@@ -39,6 +39,9 @@ struct sdhci_at91_soc_data { + const struct sdhci_pltfm_data *pdata; + bool baseclk_is_generated_internally; + unsigned int divider_for_baseclk; ++ unsigned int max_sdr104_clk; ++ bool hs200_broken; ++ bool pm_runtime_disable_clks; + }; + + struct sdhci_at91_priv { +@@ -149,17 +152,31 @@ static const struct sdhci_pltfm_data sdhci_sama5d2_pdata = { + static const struct sdhci_at91_soc_data soc_data_sama5d2 = { + .pdata = &sdhci_sama5d2_pdata, + .baseclk_is_generated_internally = false, ++ .max_sdr104_clk = 120000000, ++ .hs200_broken = true, ++ .pm_runtime_disable_clks = true, + }; + + static const struct sdhci_at91_soc_data soc_data_sam9x60 = { + .pdata = &sdhci_sama5d2_pdata, + .baseclk_is_generated_internally = true, + .divider_for_baseclk = 2, ++ .max_sdr104_clk = 120000000, ++ .hs200_broken = true, ++ .pm_runtime_disable_clks = true, ++}; ++ ++static const struct sdhci_at91_soc_data soc_data_lan969x = { ++ .pdata = &sdhci_sama5d2_pdata, ++ .baseclk_is_generated_internally = true, ++ .divider_for_baseclk = 2, ++ .max_sdr104_clk = 100000000, + }; + + static const struct of_device_id sdhci_at91_dt_match[] = { + { .compatible = "atmel,sama5d2-sdhci", .data = &soc_data_sama5d2 }, + { .compatible = "microchip,sam9x60-sdhci", .data = &soc_data_sam9x60 }, ++ { .compatible = "microchip,lan969x-sdhci", .data = &soc_data_lan969x }, + {} + }; + MODULE_DEVICE_TABLE(of, sdhci_at91_dt_match); +@@ -216,7 +233,7 @@ static int sdhci_at91_set_clks_presets(struct device *dev) + preset_div = DIV_ROUND_UP(gck_rate, 100000000) - 1; + writew(SDHCI_AT91_PRESET_COMMON_CONF | preset_div, + host->ioaddr + SDHCI_PRESET_FOR_SDR50); +- preset_div = DIV_ROUND_UP(gck_rate, 120000000) - 1; ++ preset_div = DIV_ROUND_UP(gck_rate, priv->soc_data->max_sdr104_clk) - 1; + writew(SDHCI_AT91_PRESET_COMMON_CONF | preset_div, + host->ioaddr + SDHCI_PRESET_FOR_SDR104); + preset_div = DIV_ROUND_UP(gck_rate, 50000000) - 1; +@@ -254,9 +271,11 @@ static int sdhci_at91_runtime_suspend(struct device *dev) + if (host->tuning_mode != SDHCI_TUNING_MODE_3) + mmc_retune_needed(host->mmc); + +- clk_disable_unprepare(priv->gck); +- clk_disable_unprepare(priv->hclock); +- clk_disable_unprepare(priv->mainck); ++ if (priv->soc_data->pm_runtime_disable_clks) { ++ clk_disable_unprepare(priv->gck); ++ clk_disable_unprepare(priv->hclock); ++ clk_disable_unprepare(priv->mainck); ++ } + + return 0; + } +@@ -277,6 +296,9 @@ static int sdhci_at91_runtime_resume(struct device *dev) + goto out; + } + ++ if (!priv->soc_data->pm_runtime_disable_clks) ++ goto out; ++ + ret = clk_prepare_enable(priv->mainck); + if (ret) { + dev_err(dev, "can't enable mainck\n"); +@@ -370,8 +392,8 @@ static int sdhci_at91_probe(struct platform_device *pdev) + pm_runtime_set_autosuspend_delay(&pdev->dev, 50); + pm_runtime_use_autosuspend(&pdev->dev); + +- /* HS200 is broken at this moment */ +- host->quirks2 |= SDHCI_QUIRK2_BROKEN_HS200; ++ if (priv->soc_data->hs200_broken) ++ host->quirks2 |= SDHCI_QUIRK2_BROKEN_HS200; + + ret = sdhci_add_host(host); + if (ret) diff --git a/patches/linux/6.18.46/0057-mmc-sdhci-of-at91-stop-SDCLK-on-reset-and-add-eMMC-h.patch b/patches/linux/6.18.46/0057-mmc-sdhci-of-at91-stop-SDCLK-on-reset-and-add-eMMC-h.patch new file mode 100644 index 000000000..2171881ec --- /dev/null +++ b/patches/linux/6.18.46/0057-mmc-sdhci-of-at91-stop-SDCLK-on-reset-and-add-eMMC-h.patch @@ -0,0 +1,142 @@ +From e3137466bb1335efc719dba3841319438f4bba26 Mon Sep 17 00:00:00 2001 +From: Joachim Wiberg +Date: Wed, 19 Aug 2026 11:37:48 +0200 +Subject: [PATCH 57/64] mmc: sdhci-of-at91: stop SDCLK on reset and add eMMC + hardware reset +Organization: Wires + +The controller is reset, and its signaling mode changed, with SDCLK +still running. Both require the clock to be stopped, otherwise the +block can be left in a state where transfers time out. + +Stop SDCLK around both operations and restore it afterwards. Also wire +up .hw_reset so the MMC core can pulse the eMMC reset line through +MC1R.RSTN, and reset the block on probe for LAN969x, where the +bootloader loads the kernel from eMMC and hands over a running +controller. + +Signed-off-by: Joachim Wiberg +--- + drivers/mmc/host/sdhci-of-at91.c | 50 ++++++++++++++++++++++++++++++++ + 1 file changed, 50 insertions(+) + +diff --git a/drivers/mmc/host/sdhci-of-at91.c b/drivers/mmc/host/sdhci-of-at91.c +index 5dcb88cba0d9..6a9e4a7fa705 100644 +--- a/drivers/mmc/host/sdhci-of-at91.c ++++ b/drivers/mmc/host/sdhci-of-at91.c +@@ -25,6 +25,7 @@ + + #define SDMMC_MC1R 0x204 + #define SDMMC_MC1R_DDR BIT(3) ++#define SDMMC_MC1R_RSTN BIT(6) + #define SDMMC_MC1R_FCD BIT(7) + #define SDMMC_CACR 0x230 + #define SDMMC_CACR_CAPWREN BIT(0) +@@ -42,6 +43,7 @@ struct sdhci_at91_soc_data { + unsigned int max_sdr104_clk; + bool hs200_broken; + bool pm_runtime_disable_clks; ++ bool reset_on_probe; + }; + + struct sdhci_at91_priv { +@@ -103,24 +105,48 @@ static void sdhci_at91_set_clock(struct sdhci_host *host, unsigned int clock) + static void sdhci_at91_set_uhs_signaling(struct sdhci_host *host, + unsigned int timing) + { ++ u16 clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); + u8 mc1r; + ++ /* SDCLK must be disabled while changing the mode */ ++ if (clk & SDHCI_CLOCK_CARD_EN) ++ sdhci_writew(host, clk & ~SDHCI_CLOCK_CARD_EN, ++ SDHCI_CLOCK_CONTROL); ++ + if (timing == MMC_TIMING_MMC_DDR52) { + mc1r = sdhci_readb(host, SDMMC_MC1R); + mc1r |= SDMMC_MC1R_DDR; + sdhci_writeb(host, mc1r, SDMMC_MC1R); + } + sdhci_set_uhs_signaling(host, timing); ++ ++ if (clk & SDHCI_CLOCK_CARD_EN) { ++ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); ++ sdhci_writew(host, clk | SDHCI_CLOCK_CARD_EN, ++ SDHCI_CLOCK_CONTROL); ++ } + } + + static void sdhci_at91_reset(struct sdhci_host *host, u8 mask) + { + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_at91_priv *priv = sdhci_pltfm_priv(pltfm_host); ++ u16 clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); + unsigned int tmp; + ++ /* SDCLK must be disabled while resetting the HW block */ ++ if (clk & SDHCI_CLOCK_CARD_EN) ++ sdhci_writew(host, clk & ~SDHCI_CLOCK_CARD_EN, ++ SDHCI_CLOCK_CONTROL); ++ + sdhci_reset(host, mask); + ++ if (clk & SDHCI_CLOCK_CARD_EN) { ++ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); ++ sdhci_writew(host, clk | SDHCI_CLOCK_CARD_EN, ++ SDHCI_CLOCK_CONTROL); ++ } ++ + if ((host->mmc->caps & MMC_CAP_NONREMOVABLE) + || mmc_gpio_get_cd(host->mmc) >= 0) + sdhci_at91_set_force_card_detect(host); +@@ -137,12 +163,30 @@ static void sdhci_at91_reset(struct sdhci_host *host, u8 mask) + } + } + ++static void sdhci_at91_hw_reset(struct sdhci_host *host) ++{ ++ u8 mc1r; ++ ++ mc1r = readb(host->ioaddr + SDMMC_MC1R); ++ mc1r |= SDMMC_MC1R_RSTN; ++ writeb(mc1r, host->ioaddr + SDMMC_MC1R); ++ ++ udelay(10); ++ ++ mc1r &= ~SDMMC_MC1R_RSTN; ++ writeb(mc1r, host->ioaddr + SDMMC_MC1R); ++ ++ /* JEDEC specifies a minimum of 200us for tRSCA (reset to command) */ ++ usleep_range(200, 500); ++} ++ + static const struct sdhci_ops sdhci_at91_sama5d2_ops = { + .set_clock = sdhci_at91_set_clock, + .set_bus_width = sdhci_set_bus_width, + .reset = sdhci_at91_reset, + .set_uhs_signaling = sdhci_at91_set_uhs_signaling, + .set_power = sdhci_set_power_and_bus_voltage, ++ .hw_reset = sdhci_at91_hw_reset, + }; + + static const struct sdhci_pltfm_data sdhci_sama5d2_pdata = { +@@ -171,6 +215,7 @@ static const struct sdhci_at91_soc_data soc_data_lan969x = { + .baseclk_is_generated_internally = true, + .divider_for_baseclk = 2, + .max_sdr104_clk = 100000000, ++ .reset_on_probe = true, + }; + + static const struct of_device_id sdhci_at91_dt_match[] = { +@@ -347,6 +392,11 @@ static int sdhci_at91_probe(struct platform_device *pdev) + priv = sdhci_pltfm_priv(pltfm_host); + priv->soc_data = soc_data; + ++ if (soc_data->reset_on_probe) { ++ sdhci_at91_reset(host, SDHCI_RESET_ALL); ++ sdhci_at91_hw_reset(host); ++ } ++ + priv->mainck = devm_clk_get(&pdev->dev, "baseclk"); + if (IS_ERR(priv->mainck)) { + if (soc_data->baseclk_is_generated_internally) diff --git a/patches/linux/6.18.46/0058-net-sparx5-lan969x-populate-netdev-of_node.patch b/patches/linux/6.18.46/0058-net-sparx5-lan969x-populate-netdev-of_node.patch new file mode 100644 index 000000000..6dedcea3d --- /dev/null +++ b/patches/linux/6.18.46/0058-net-sparx5-lan969x-populate-netdev-of_node.patch @@ -0,0 +1,30 @@ +From 6d2e708d45f1f1a8a187eef079b1247cf7f60a49 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Mon, 10 Nov 2025 13:42:53 +0100 +Subject: [PATCH 58/64] net: sparx5/lan969x: populate netdev of_node +Organization: Wires + +Populate of_node for the port netdevs, to make the individual ports +of_nodes available in sysfs. + +Signed-off-by: Robert Marko +Link: https://patch.msgid.link/20251110124342.199216-1-robert.marko@sartura.hr +Signed-off-by: Jakub Kicinski +(cherry picked from commit fc6aa0e470e092873eddb213d996a8beee86bf4d) +--- + drivers/net/ethernet/microchip/sparx5/sparx5_main.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c +index 40b1bfc600a7..582145713cfd 100644 +--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c ++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c +@@ -395,6 +395,8 @@ static int sparx5_create_port(struct sparx5 *sparx5, + + spx5_port->phylink = phylink; + ++ spx5_port->ndev->dev.of_node = spx5_port->of_node; ++ + return 0; + } + diff --git a/patches/linux/6.18.46/0059-arm64-dts-microchip-add-LAN969x-clock-header-file.patch b/patches/linux/6.18.46/0059-arm64-dts-microchip-add-LAN969x-clock-header-file.patch new file mode 100644 index 000000000..e9f70bb75 --- /dev/null +++ b/patches/linux/6.18.46/0059-arm64-dts-microchip-add-LAN969x-clock-header-file.patch @@ -0,0 +1,49 @@ +From e222fb4b440eaea1eef4522a440f965e674066fa Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Mon, 2 Mar 2026 12:20:11 +0100 +Subject: [PATCH 59/64] arm64: dts: microchip: add LAN969x clock header file +Organization: Wires + +LAN969x uses hardware clock indexes, so document theses in a header to make +them humanly readable. + +Signed-off-by: Robert Marko +Reviewed-by: Claudiu Beznea +Link: https://lore.kernel.org/r/20260302112153.464422-4-robert.marko@sartura.hr +Signed-off-by: Claudiu Beznea +(cherry picked from commit 229eeb0ad913c1bb2dd6027e5983d1e4c409abd0) +--- + arch/arm64/boot/dts/microchip/clk-lan9691.h | 24 +++++++++++++++++++++ + 1 file changed, 24 insertions(+) + create mode 100644 arch/arm64/boot/dts/microchip/clk-lan9691.h + +diff --git a/arch/arm64/boot/dts/microchip/clk-lan9691.h b/arch/arm64/boot/dts/microchip/clk-lan9691.h +new file mode 100644 +index 000000000000..0f2d7a0f881e +--- /dev/null ++++ b/arch/arm64/boot/dts/microchip/clk-lan9691.h +@@ -0,0 +1,24 @@ ++/* SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) */ ++ ++#ifndef _DTS_CLK_LAN9691_H ++#define _DTS_CLK_LAN9691_H ++ ++#define GCK_ID_QSPI0 0 ++#define GCK_ID_QSPI2 1 ++#define GCK_ID_SDMMC0 2 ++#define GCK_ID_SDMMC1 3 ++#define GCK_ID_MCAN0 4 ++#define GCK_ID_MCAN1 5 ++#define GCK_ID_FLEXCOM0 6 ++#define GCK_ID_FLEXCOM1 7 ++#define GCK_ID_FLEXCOM2 8 ++#define GCK_ID_FLEXCOM3 9 ++#define GCK_ID_TIMER 10 ++#define GCK_ID_USB_REFCLK 11 ++ ++/* Gate clocks */ ++#define GCK_GATE_USB_DRD 12 ++#define GCK_GATE_MCRAMC 13 ++#define GCK_GATE_HMATRIX 14 ++ ++#endif diff --git a/patches/linux/6.18.46/0060-arm64-dts-microchip-add-LAN969x-support.patch b/patches/linux/6.18.46/0060-arm64-dts-microchip-add-LAN969x-support.patch new file mode 100644 index 000000000..c7fd4ba66 --- /dev/null +++ b/patches/linux/6.18.46/0060-arm64-dts-microchip-add-LAN969x-support.patch @@ -0,0 +1,513 @@ +From d72697a81242685f8913222a2769a183f7d8c5bb Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Mon, 2 Mar 2026 12:20:12 +0100 +Subject: [PATCH 60/64] arm64: dts: microchip: add LAN969x support +Organization: Wires + +Add support for Microchip LAN969x switch SoC series by adding the SoC DTSI. + +Signed-off-by: Robert Marko +Reviewed-by: Claudiu Beznea +Acked-by: Daniel Machon +Link: https://lore.kernel.org/r/20260302112153.464422-5-robert.marko@sartura.hr +Signed-off-by: Claudiu Beznea +(cherry picked from commit 1effec9834710ec417861634c32208edcd2fcb2a) +--- + arch/arm64/boot/dts/microchip/lan9691.dtsi | 488 +++++++++++++++++++++ + 1 file changed, 488 insertions(+) + create mode 100644 arch/arm64/boot/dts/microchip/lan9691.dtsi + +diff --git a/arch/arm64/boot/dts/microchip/lan9691.dtsi b/arch/arm64/boot/dts/microchip/lan9691.dtsi +new file mode 100644 +index 000000000000..235e56bebbdb +--- /dev/null ++++ b/arch/arm64/boot/dts/microchip/lan9691.dtsi +@@ -0,0 +1,488 @@ ++// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) ++/* ++ * Copyright (c) 2025 Microchip Technology Inc. and its subsidiaries. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include "clk-lan9691.h" ++ ++/ { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ model = "Microchip LAN969x"; ++ compatible = "microchip,lan9691"; ++ interrupt-parent = <&gic>; ++ ++ clocks { ++ fx100_clk: fx100-clk { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <320000000>; ++ }; ++ ++ cpu_clk: cpu-clk { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <1000000000>; ++ }; ++ ++ ddr_clk: ddr-clk { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <600000000>; ++ }; ++ ++ fabric_clk: fabric-clk { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <250000000>; ++ }; ++ }; ++ ++ cpus { ++ #address-cells = <2>; ++ #size-cells = <0>; ++ ++ cpu0: cpu@0 { ++ compatible = "arm,cortex-a53"; ++ device_type = "cpu"; ++ reg = <0x0 0x0>; ++ next-level-cache = <&l2_0>; ++ }; ++ ++ l2_0: l2-cache { ++ compatible = "cache"; ++ cache-level = <2>; ++ cache-unified; ++ }; ++ }; ++ ++ psci { ++ compatible = "arm,psci-1.0"; ++ method = "smc"; ++ }; ++ ++ pmu { ++ compatible = "arm,cortex-a53-pmu"; ++ interrupts = ; ++ }; ++ ++ timer { ++ compatible = "arm,armv8-timer"; ++ interrupts = , /* Secure Phys IRQ */ ++ , /* Non-secure Phys IRQ */ ++ , /* Virt IRQ */ ++ ; /* Hyp IRQ */ ++ }; ++ ++ axi: axi { ++ compatible = "simple-bus"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ usb: usb@300000 { ++ compatible = "microchip,lan9691-dwc3", "snps,dwc3"; ++ reg = <0x300000 0x80000>; ++ interrupts = ; ++ clocks = <&clks GCK_GATE_USB_DRD>, ++ <&clks GCK_ID_USB_REFCLK>; ++ clock-names = "bus_early", "ref"; ++ assigned-clocks = <&clks GCK_ID_USB_REFCLK>; ++ assigned-clock-rates = <60000000>; ++ maximum-speed = "high-speed"; ++ dr_mode = "host"; ++ status = "disabled"; ++ }; ++ ++ flx0: flexcom@e0040000 { ++ compatible = "microchip,lan9691-flexcom", "atmel,sama5d2-flexcom"; ++ reg = <0xe0040000 0x100>; ++ ranges = <0x0 0xe0040000 0x800>; ++ clocks = <&clks GCK_ID_FLEXCOM0>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ status = "disabled"; ++ ++ usart0: serial@200 { ++ compatible = "microchip,lan9691-usart", "atmel,at91sam9260-usart"; ++ reg = <0x200 0x200>; ++ interrupts = ; ++ dmas = <&dma AT91_XDMAC_DT_PERID(3)>, ++ <&dma AT91_XDMAC_DT_PERID(2)>; ++ dma-names = "tx", "rx"; ++ clocks = <&fabric_clk>; ++ clock-names = "usart"; ++ atmel,fifo-size = <32>; ++ atmel,usart-mode = ; ++ status = "disabled"; ++ }; ++ ++ spi0: spi@400 { ++ compatible = "microchip,lan9691-spi", "atmel,at91rm9200-spi"; ++ reg = <0x400 0x200>; ++ interrupts = ; ++ dmas = <&dma AT91_XDMAC_DT_PERID(3)>, ++ <&dma AT91_XDMAC_DT_PERID(2)>; ++ dma-names = "tx", "rx"; ++ clocks = <&fabric_clk>; ++ clock-names = "spi_clk"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ atmel,fifo-size = <32>; ++ status = "disabled"; ++ }; ++ ++ i2c0: i2c@600 { ++ compatible = "microchip,lan9691-i2c", "microchip,sam9x60-i2c"; ++ reg = <0x600 0x200>; ++ interrupts = ; ++ dmas = <&dma AT91_XDMAC_DT_PERID(3)>, ++ <&dma AT91_XDMAC_DT_PERID(2)>; ++ dma-names = "tx", "rx"; ++ clocks = <&fabric_clk>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ }; ++ ++ flx1: flexcom@e0044000 { ++ compatible = "microchip,lan9691-flexcom", "atmel,sama5d2-flexcom"; ++ reg = <0xe0044000 0x100>; ++ ranges = <0x0 0xe0044000 0x800>; ++ clocks = <&clks GCK_ID_FLEXCOM1>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ status = "disabled"; ++ ++ usart1: serial@200 { ++ compatible = "microchip,lan9691-usart", "atmel,at91sam9260-usart"; ++ reg = <0x200 0x200>; ++ interrupts = ; ++ dmas = <&dma AT91_XDMAC_DT_PERID(3)>, ++ <&dma AT91_XDMAC_DT_PERID(2)>; ++ dma-names = "tx", "rx"; ++ clocks = <&fabric_clk>; ++ clock-names = "usart"; ++ atmel,fifo-size = <32>; ++ atmel,usart-mode = ; ++ status = "disabled"; ++ }; ++ ++ spi1: spi@400 { ++ compatible = "microchip,lan9691-spi", "atmel,at91rm9200-spi"; ++ reg = <0x400 0x200>; ++ interrupts = ; ++ dmas = <&dma AT91_XDMAC_DT_PERID(3)>, ++ <&dma AT91_XDMAC_DT_PERID(2)>; ++ dma-names = "tx", "rx"; ++ clocks = <&fabric_clk>; ++ clock-names = "spi_clk"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ atmel,fifo-size = <32>; ++ status = "disabled"; ++ }; ++ ++ i2c1: i2c@600 { ++ compatible = "microchip,lan9691-i2c", "microchip,sam9x60-i2c"; ++ reg = <0x600 0x200>; ++ interrupts = ; ++ dmas = <&dma AT91_XDMAC_DT_PERID(3)>, ++ <&dma AT91_XDMAC_DT_PERID(2)>; ++ dma-names = "tx", "rx"; ++ clocks = <&fabric_clk>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ }; ++ ++ trng: rng@e0048000 { ++ compatible = "microchip,lan9691-trng", "atmel,at91sam9g45-trng"; ++ reg = <0xe0048000 0x100>; ++ clocks = <&fabric_clk>; ++ status = "disabled"; ++ }; ++ ++ aes: crypto@e004c000 { ++ compatible = "microchip,lan9691-aes", "atmel,at91sam9g46-aes"; ++ reg = <0xe004c000 0x100>; ++ interrupts = ; ++ dmas = <&dma AT91_XDMAC_DT_PERID(12)>, ++ <&dma AT91_XDMAC_DT_PERID(13)>; ++ dma-names = "tx", "rx"; ++ clocks = <&fabric_clk>; ++ clock-names = "aes_clk"; ++ status = "disabled"; ++ }; ++ ++ flx2: flexcom@e0060000 { ++ compatible = "microchip,lan9691-flexcom", "atmel,sama5d2-flexcom"; ++ reg = <0xe0060000 0x100>; ++ ranges = <0x0 0xe0060000 0x800>; ++ clocks = <&clks GCK_ID_FLEXCOM2>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ status = "disabled"; ++ ++ usart2: serial@200 { ++ compatible = "microchip,lan9691-usart", "atmel,at91sam9260-usart"; ++ reg = <0x200 0x200>; ++ interrupts = ; ++ dmas = <&dma AT91_XDMAC_DT_PERID(7)>, ++ <&dma AT91_XDMAC_DT_PERID(6)>; ++ dma-names = "tx", "rx"; ++ clocks = <&fabric_clk>; ++ clock-names = "usart"; ++ atmel,fifo-size = <32>; ++ atmel,usart-mode = ; ++ status = "disabled"; ++ }; ++ ++ spi2: spi@400 { ++ compatible = "microchip,lan9691-spi", "atmel,at91rm9200-spi"; ++ reg = <0x400 0x200>; ++ interrupts = ; ++ dmas = <&dma AT91_XDMAC_DT_PERID(7)>, ++ <&dma AT91_XDMAC_DT_PERID(6)>; ++ dma-names = "tx", "rx"; ++ clocks = <&fabric_clk>; ++ clock-names = "spi_clk"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ atmel,fifo-size = <32>; ++ status = "disabled"; ++ }; ++ ++ i2c2: i2c@600 { ++ compatible = "microchip,lan9691-i2c", "microchip,sam9x60-i2c"; ++ reg = <0x600 0x200>; ++ interrupts = ; ++ dmas = <&dma AT91_XDMAC_DT_PERID(7)>, ++ <&dma AT91_XDMAC_DT_PERID(6)>; ++ dma-names = "tx", "rx"; ++ clocks = <&fabric_clk>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ }; ++ ++ flx3: flexcom@e0064000 { ++ compatible = "microchip,lan9691-flexcom", "atmel,sama5d2-flexcom"; ++ reg = <0xe0064000 0x100>; ++ ranges = <0x0 0xe0064000 0x800>; ++ clocks = <&clks GCK_ID_FLEXCOM3>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ status = "disabled"; ++ ++ usart3: serial@200 { ++ compatible = "microchip,lan9691-usart", "atmel,at91sam9260-usart"; ++ reg = <0x200 0x200>; ++ interrupts = ; ++ dmas = <&dma AT91_XDMAC_DT_PERID(9)>, ++ <&dma AT91_XDMAC_DT_PERID(8)>; ++ dma-names = "tx", "rx"; ++ clocks = <&fabric_clk>; ++ clock-names = "usart"; ++ atmel,fifo-size = <32>; ++ atmel,usart-mode = ; ++ status = "disabled"; ++ }; ++ ++ spi3: spi@400 { ++ compatible = "microchip,lan9691-spi", "atmel,at91rm9200-spi"; ++ reg = <0x400 0x200>; ++ interrupts = ; ++ dmas = <&dma AT91_XDMAC_DT_PERID(9)>, ++ <&dma AT91_XDMAC_DT_PERID(8)>; ++ dma-names = "tx", "rx"; ++ clocks = <&fabric_clk>; ++ clock-names = "spi_clk"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ atmel,fifo-size = <32>; ++ status = "disabled"; ++ }; ++ ++ i2c3: i2c@600 { ++ compatible = "microchip,lan9691-i2c", "microchip,sam9x60-i2c"; ++ reg = <0x600 0x200>; ++ interrupts = ; ++ dmas = <&dma AT91_XDMAC_DT_PERID(9)>, ++ <&dma AT91_XDMAC_DT_PERID(8)>; ++ dma-names = "tx", "rx"; ++ clocks = <&fabric_clk>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ }; ++ ++ dma: dma-controller@e0068000 { ++ compatible = "microchip,lan9691-dma", "microchip,sama7g5-dma"; ++ reg = <0xe0068000 0x1000>; ++ interrupts = ; ++ dma-channels = <16>; ++ #dma-cells = <1>; ++ clocks = <&fabric_clk>; ++ clock-names = "dma_clk"; ++ }; ++ ++ sha: crypto@e006c000 { ++ compatible = "microchip,lan9691-sha", "atmel,at91sam9g46-sha"; ++ reg = <0xe006c000 0xec>; ++ interrupts = ; ++ dmas = <&dma AT91_XDMAC_DT_PERID(14)>; ++ dma-names = "tx"; ++ clocks = <&fabric_clk>; ++ clock-names = "sha_clk"; ++ status = "disabled"; ++ }; ++ ++ timer: timer@e008c000 { ++ compatible = "snps,dw-apb-timer"; ++ reg = <0xe008c000 0x400>; ++ clocks = <&fabric_clk>; ++ clock-names = "timer"; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ watchdog: watchdog@e0090000 { ++ compatible = "snps,dw-wdt"; ++ reg = <0xe0090000 0x1000>; ++ interrupts = ; ++ clocks = <&fabric_clk>; ++ }; ++ ++ cpu_ctrl: syscon@e00c0000 { ++ compatible = "microchip,lan966x-cpu-syscon", "syscon"; ++ reg = <0xe00c0000 0x350>; ++ }; ++ ++ switch: switch@e00c0000 { ++ compatible = "microchip,lan9691-switch"; ++ reg = <0xe00c0000 0x0010000>, ++ <0xe2010000 0x1410000>; ++ reg-names = "cpu", "devices"; ++ interrupt-names = "xtr", "fdma", "ptp"; ++ interrupts = , ++ , ++ ; ++ resets = <&reset 0>; ++ reset-names = "switch"; ++ status = "disabled"; ++ }; ++ ++ clks: clock-controller@e00c00b4 { ++ compatible = "microchip,lan9691-gck"; ++ reg = <0xe00c00b4 0x30>, <0xe00c0308 0x4>; ++ #clock-cells = <1>; ++ clocks = <&cpu_clk>, <&ddr_clk>, <&fx100_clk>; ++ clock-names = "cpu", "ddr", "sys"; ++ }; ++ ++ reset: reset-controller@e201000c { ++ compatible = "microchip,lan9691-switch-reset", ++ "microchip,lan966x-switch-reset"; ++ reg = <0xe201000c 0x4>; ++ reg-names = "gcb"; ++ #reset-cells = <1>; ++ cpu-syscon = <&cpu_ctrl>; ++ }; ++ ++ gpio: pinctrl@e20100d4 { ++ compatible = "microchip,lan9691-pinctrl"; ++ reg = <0xe20100d4 0xd4>, ++ <0xe2010370 0xa8>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ gpio-ranges = <&gpio 0 0 66>; ++ interrupt-controller; ++ interrupts = ; ++ #interrupt-cells = <2>; ++ }; ++ ++ mdio0: mdio@e20101a8 { ++ compatible = "microchip,lan9691-miim", "mscc,ocelot-miim"; ++ reg = <0xe20101a8 0x24>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ clocks = <&fx100_clk>; ++ status = "disabled"; ++ }; ++ ++ mdio1: mdio@e20101cc { ++ compatible = "microchip,lan9691-miim", "mscc,ocelot-miim"; ++ reg = <0xe20101cc 0x24>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ clocks = <&fx100_clk>; ++ status = "disabled"; ++ }; ++ ++ sgpio: gpio@e2010230 { ++ compatible = "microchip,lan9691-sgpio", "microchip,sparx5-sgpio"; ++ reg = <0xe2010230 0x118>; ++ clocks = <&fx100_clk>; ++ resets = <&reset 0>; ++ reset-names = "switch"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ ++ sgpio_in: gpio@0 { ++ compatible = "microchip,lan9691-sgpio-bank", ++ "microchip,sparx5-sgpio-bank"; ++ reg = <0>; ++ gpio-controller; ++ #gpio-cells = <3>; ++ interrupts = ; ++ interrupt-controller; ++ #interrupt-cells = <3>; ++ }; ++ ++ sgpio_out: gpio@1 { ++ compatible = "microchip,lan9691-sgpio-bank", ++ "microchip,sparx5-sgpio-bank"; ++ reg = <1>; ++ gpio-controller; ++ #gpio-cells = <3>; ++ }; ++ }; ++ ++ tmon: hwmon@e2020100 { ++ compatible = "microchip,lan9691-temp", "microchip,sparx5-temp"; ++ reg = <0xe2020100 0xc>; ++ clocks = <&fx100_clk>; ++ #thermal-sensor-cells = <0>; ++ }; ++ ++ serdes: serdes@e3410000 { ++ compatible = "microchip,lan9691-serdes"; ++ reg = <0xe3410000 0x150000>; ++ #phy-cells = <1>; ++ clocks = <&fabric_clk>; ++ }; ++ ++ gic: interrupt-controller@e8c11000 { ++ compatible = "arm,gic-400"; ++ reg = <0xe8c11000 0x1000>, /* Distributor GICD_ */ ++ <0xe8c12000 0x2000>, /* CPU interface GICC_ */ ++ <0xe8c14000 0x2000>, /* Virt interface control */ ++ <0xe8c16000 0x2000>; /* Virt CPU interface */ ++ #interrupt-cells = <3>; ++ interrupt-controller; ++ interrupts = ; ++ }; ++ }; ++}; diff --git a/patches/linux/6.18.46/0061-arm64-dts-microchip-add-EV23X71A-board.patch b/patches/linux/6.18.46/0061-arm64-dts-microchip-add-EV23X71A-board.patch new file mode 100644 index 000000000..47231911e --- /dev/null +++ b/patches/linux/6.18.46/0061-arm64-dts-microchip-add-EV23X71A-board.patch @@ -0,0 +1,793 @@ +From 8f86e07b4ced078e3785534b2da159bd79765c22 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Mon, 2 Mar 2026 12:20:14 +0100 +Subject: [PATCH 61/64] arm64: dts: microchip: add EV23X71A board +Organization: Wires + +Microchip EV23X71A is an LAN9696 based evaluation board. + +Signed-off-by: Robert Marko +Reviewed-by: Claudiu Beznea +Acked-by: Daniel Machon +Tested-by: Daniel Machon +Link: https://lore.kernel.org/r/20260302112153.464422-7-robert.marko@sartura.hr +Signed-off-by: Claudiu Beznea +(cherry picked from commit 711cca0f1cfef57018654b969da4041c2bab68d3) +--- + arch/arm64/boot/dts/microchip/Makefile | 1 + + .../boot/dts/microchip/lan9696-ev23x71a.dts | 756 ++++++++++++++++++ + 2 files changed, 757 insertions(+) + create mode 100644 arch/arm64/boot/dts/microchip/lan9696-ev23x71a.dts + +diff --git a/arch/arm64/boot/dts/microchip/Makefile b/arch/arm64/boot/dts/microchip/Makefile +index c6e0313eea0f..09d16fc1ce9a 100644 +--- a/arch/arm64/boot/dts/microchip/Makefile ++++ b/arch/arm64/boot/dts/microchip/Makefile +@@ -1,4 +1,5 @@ + # SPDX-License-Identifier: GPL-2.0 ++dtb-$(CONFIG_ARCH_LAN969X) += lan9696-ev23x71a.dtb + dtb-$(CONFIG_ARCH_SPARX5) += sparx5_pcb125.dtb + dtb-$(CONFIG_ARCH_SPARX5) += sparx5_pcb134.dtb sparx5_pcb134_emmc.dtb + dtb-$(CONFIG_ARCH_SPARX5) += sparx5_pcb135.dtb sparx5_pcb135_emmc.dtb +diff --git a/arch/arm64/boot/dts/microchip/lan9696-ev23x71a.dts b/arch/arm64/boot/dts/microchip/lan9696-ev23x71a.dts +new file mode 100644 +index 000000000000..4012ea7d07bb +--- /dev/null ++++ b/arch/arm64/boot/dts/microchip/lan9696-ev23x71a.dts +@@ -0,0 +1,756 @@ ++// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) ++/* ++ * Copyright (c) 2025 Microchip Technology Inc. and its subsidiaries. ++ */ ++ ++/dts-v1/; ++ ++#include ++#include ++#include "lan9691.dtsi" ++ ++/ { ++ model = "Microchip EV23X71A"; ++ compatible = "microchip,ev23x71a", "microchip,lan9696", "microchip,lan9691"; ++ ++ aliases { ++ serial0 = &usart0; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ gpio-restart { ++ compatible = "gpio-restart"; ++ gpios = <&gpio 60 GPIO_ACTIVE_LOW>; ++ open-source; ++ priority = <200>; ++ }; ++ ++ i2c-mux { ++ compatible = "i2c-mux-gpio"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ i2c-parent = <&i2c3>; ++ idle-state = <0x8>; ++ mux-gpios = <&sgpio_out 0 1 GPIO_ACTIVE_HIGH>, ++ <&sgpio_out 0 2 GPIO_ACTIVE_HIGH>, ++ <&sgpio_out 0 3 GPIO_ACTIVE_HIGH>; ++ settle-time-us = <100>; ++ ++ i2c_sfp0: i2c@0 { ++ reg = <0x0>; ++ }; ++ ++ i2c_sfp1: i2c@1 { ++ reg = <0x1>; ++ }; ++ ++ i2c_sfp2: i2c@2 { ++ reg = <0x2>; ++ }; ++ ++ i2c_sfp3: i2c@3 { ++ reg = <0x3>; ++ }; ++ ++ i2c_poe: i2c@7 { ++ reg = <0x7>; ++ }; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led-status { ++ color = ; ++ function = LED_FUNCTION_STATUS; ++ gpios = <&gpio 61 GPIO_ACTIVE_LOW>; ++ }; ++ ++ led-sfp1-green { ++ color = ; ++ function = LED_FUNCTION_LAN; ++ function-enumerator = <0>; ++ gpios = <&sgpio_out 6 0 GPIO_ACTIVE_LOW>; ++ default-state = "off"; ++ }; ++ ++ led-sfp1-yellow { ++ color = ; ++ function = LED_FUNCTION_LAN; ++ function-enumerator = <0>; ++ gpios = <&sgpio_out 6 1 GPIO_ACTIVE_LOW>; ++ default-state = "off"; ++ }; ++ ++ led-sfp2-green { ++ color = ; ++ function = LED_FUNCTION_LAN; ++ function-enumerator = <1>; ++ gpios = <&sgpio_out 7 0 GPIO_ACTIVE_LOW>; ++ default-state = "off"; ++ }; ++ ++ led-sfp2-yellow { ++ color = ; ++ function = LED_FUNCTION_LAN; ++ function-enumerator = <1>; ++ gpios = <&sgpio_out 7 1 GPIO_ACTIVE_LOW>; ++ default-state = "off"; ++ }; ++ ++ led-sfp3-green { ++ color = ; ++ function = LED_FUNCTION_LAN; ++ function-enumerator = <2>; ++ gpios = <&sgpio_out 8 0 GPIO_ACTIVE_LOW>; ++ default-state = "off"; ++ }; ++ ++ led-sfp3-yellow { ++ color = ; ++ function = LED_FUNCTION_LAN; ++ function-enumerator = <2>; ++ gpios = <&sgpio_out 8 1 GPIO_ACTIVE_LOW>; ++ default-state = "off"; ++ }; ++ ++ led-sfp4-green { ++ color = ; ++ function = LED_FUNCTION_LAN; ++ function-enumerator = <3>; ++ gpios = <&sgpio_out 9 0 GPIO_ACTIVE_LOW>; ++ default-state = "off"; ++ }; ++ ++ led-sfp4-yellow { ++ color = ; ++ function = LED_FUNCTION_LAN; ++ function-enumerator = <3>; ++ gpios = <&sgpio_out 9 1 GPIO_ACTIVE_LOW>; ++ default-state = "off"; ++ }; ++ }; ++ ++ mux-controller { ++ compatible = "gpio-mux"; ++ #mux-control-cells = <0>; ++ mux-gpios = <&sgpio_out 1 2 GPIO_ACTIVE_LOW>, ++ <&sgpio_out 1 3 GPIO_ACTIVE_LOW>; ++ }; ++ ++ sfp0: sfp0 { ++ compatible = "sff,sfp"; ++ i2c-bus = <&i2c_sfp0>; ++ tx-disable-gpios = <&sgpio_out 6 2 GPIO_ACTIVE_HIGH>; ++ los-gpios = <&sgpio_in 6 0 GPIO_ACTIVE_HIGH>; ++ mod-def0-gpios = <&sgpio_in 6 1 GPIO_ACTIVE_LOW>; ++ tx-fault-gpios = <&sgpio_in 6 2 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ sfp1: sfp1 { ++ compatible = "sff,sfp"; ++ i2c-bus = <&i2c_sfp1>; ++ tx-disable-gpios = <&sgpio_out 7 2 GPIO_ACTIVE_HIGH>; ++ los-gpios = <&sgpio_in 7 0 GPIO_ACTIVE_HIGH>; ++ mod-def0-gpios = <&sgpio_in 7 1 GPIO_ACTIVE_LOW>; ++ tx-fault-gpios = <&sgpio_in 7 2 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ sfp2: sfp2 { ++ compatible = "sff,sfp"; ++ i2c-bus = <&i2c_sfp2>; ++ tx-disable-gpios = <&sgpio_out 8 2 GPIO_ACTIVE_HIGH>; ++ los-gpios = <&sgpio_in 8 0 GPIO_ACTIVE_HIGH>; ++ mod-def0-gpios = <&sgpio_in 8 1 GPIO_ACTIVE_LOW>; ++ tx-fault-gpios = <&sgpio_in 8 2 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ sfp3: sfp3 { ++ compatible = "sff,sfp"; ++ i2c-bus = <&i2c_sfp3>; ++ tx-disable-gpios = <&sgpio_out 9 2 GPIO_ACTIVE_HIGH>; ++ los-gpios = <&sgpio_in 9 0 GPIO_ACTIVE_HIGH>; ++ mod-def0-gpios = <&sgpio_in 9 1 GPIO_ACTIVE_LOW>; ++ tx-fault-gpios = <&sgpio_in 9 2 GPIO_ACTIVE_HIGH>; ++ }; ++}; ++ ++&gpio { ++ emmc_sd_pins: emmc-sd-pins { ++ /* eMMC_SD - CMD, CLK, D0, D1, D2, D3, D4, D5, D6, D7, RSTN */ ++ pins = "GPIO_14", "GPIO_15", "GPIO_16", "GPIO_17", ++ "GPIO_18", "GPIO_19", "GPIO_20", "GPIO_21", ++ "GPIO_22", "GPIO_23", "GPIO_24"; ++ function = "emmc_sd"; ++ }; ++ ++ fan_pins: fan-pins { ++ pins = "GPIO_25", "GPIO_26"; ++ function = "fan"; ++ }; ++ ++ fc0_pins: fc0-pins { ++ pins = "GPIO_3", "GPIO_4"; ++ function = "fc"; ++ }; ++ ++ fc2_pins: fc2-pins { ++ pins = "GPIO_64", "GPIO_65", "GPIO_66"; ++ function = "fc"; ++ }; ++ ++ fc3_pins: fc3-pins { ++ pins = "GPIO_55", "GPIO_56"; ++ function = "fc"; ++ }; ++ ++ mdio_irq_pins: mdio-irq-pins { ++ pins = "GPIO_11"; ++ function = "miim_irq"; ++ }; ++ ++ mdio_pins: mdio-pins { ++ pins = "GPIO_9", "GPIO_10"; ++ function = "miim"; ++ }; ++ ++ ptp_ext_pins: ptp-ext-pins { ++ pins = "GPIO_59"; ++ function = "ptpsync_5"; ++ }; ++ ++ ptp_out_pins: ptp-out-pins { ++ pins = "GPIO_58"; ++ function = "ptpsync_4"; ++ }; ++ ++ sgpio_pins: sgpio-pins { ++ /* SCK, D0, D1, LD */ ++ pins = "GPIO_5", "GPIO_6", "GPIO_7", "GPIO_8"; ++ function = "sgpio_a"; ++ }; ++ ++ usb_over_pins: usb-over-pins { ++ pins = "GPIO_13"; ++ function = "usb_over_detect"; ++ }; ++ ++ usb_power_pins: usb-power-pins { ++ pins = "GPIO_1"; ++ function = "usb_power"; ++ }; ++ ++ usb_rst_pins: usb-rst-pins { ++ pins = "GPIO_12"; ++ function = "usb2phy_rst"; ++ }; ++ ++ usb_ulpi_pins: usb-ulpi-pins { ++ pins = "GPIO_30", "GPIO_31", "GPIO_32", "GPIO_33", ++ "GPIO_34", "GPIO_35", "GPIO_36", "GPIO_37", ++ "GPIO_38", "GPIO_39", "GPIO_40", "GPIO_41"; ++ function = "usb_ulpi"; ++ }; ++}; ++ ++&flx0 { ++ atmel,flexcom-mode = ; ++ status = "okay"; ++}; ++ ++&flx2 { ++ atmel,flexcom-mode = ; ++ status = "okay"; ++}; ++ ++&flx3 { ++ atmel,flexcom-mode = ; ++ status = "okay"; ++}; ++ ++&i2c3 { ++ pinctrl-0 = <&fc3_pins>; ++ pinctrl-names = "default"; ++ i2c-analog-filter; ++ i2c-digital-filter; ++ i2c-digital-filter-width-ns = <35>; ++ i2c-sda-hold-time-ns = <1500>; ++ status = "okay"; ++}; ++ ++&mdio0 { ++ pinctrl-0 = <&mdio_pins>, <&mdio_irq_pins>; ++ pinctrl-names = "default"; ++ reset-gpios = <&gpio 62 GPIO_ACTIVE_LOW>; ++ status = "okay"; ++ ++ phy3: phy@3 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <3>; ++ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&gpio>; ++ }; ++ ++ phy4: phy@4 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <4>; ++ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&gpio>; ++ }; ++ ++ phy5: phy@5 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <5>; ++ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&gpio>; ++ }; ++ ++ phy6: phy@6 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <6>; ++ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&gpio>; ++ }; ++ ++ phy7: phy@7 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <7>; ++ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&gpio>; ++ }; ++ ++ phy8: phy@8 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <8>; ++ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&gpio>; ++ }; ++ ++ phy9: phy@9 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <9>; ++ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&gpio>; ++ }; ++ ++ phy10: phy@10 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <10>; ++ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&gpio>; ++ }; ++ ++ phy11: phy@11 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <11>; ++ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&gpio>; ++ }; ++ ++ phy12: phy@12 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <12>; ++ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&gpio>; ++ }; ++ ++ phy13: phy@13 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <13>; ++ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&gpio>; ++ }; ++ ++ phy14: phy@14 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <14>; ++ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&gpio>; ++ }; ++ ++ phy15: phy@15 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <15>; ++ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&gpio>; ++ }; ++ ++ phy16: phy@16 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <16>; ++ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&gpio>; ++ }; ++ ++ phy17: phy@17 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <17>; ++ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&gpio>; ++ }; ++ ++ phy18: phy@18 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <18>; ++ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&gpio>; ++ }; ++ ++ phy19: phy@19 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <19>; ++ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&gpio>; ++ }; ++ ++ phy20: phy@20 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <20>; ++ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&gpio>; ++ }; ++ ++ phy21: phy@21 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <21>; ++ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&gpio>; ++ }; ++ ++ phy22: phy@22 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <22>; ++ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&gpio>; ++ }; ++ ++ phy23: phy@23 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <23>; ++ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&gpio>; ++ }; ++ ++ phy24: phy@24 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <24>; ++ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&gpio>; ++ }; ++ ++ phy25: phy@25 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <25>; ++ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&gpio>; ++ }; ++ ++ phy26: phy@26 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <26>; ++ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&gpio>; ++ }; ++ ++ phy27: phy@27 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <27>; ++ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&gpio>; ++ }; ++}; ++ ++&serdes { ++ status = "okay"; ++}; ++ ++&sgpio { ++ pinctrl-0 = <&sgpio_pins>; ++ pinctrl-names = "default"; ++ microchip,sgpio-port-ranges = <0 1>, <6 9>; ++ status = "okay"; ++ ++ gpio@0 { ++ ngpios = <128>; ++ }; ++ gpio@1 { ++ ngpios = <128>; ++ }; ++}; ++ ++&spi2 { ++ pinctrl-0 = <&fc2_pins>; ++ pinctrl-names = "default"; ++ cs-gpios = <&gpio 63 GPIO_ACTIVE_LOW>; ++ status = "okay"; ++}; ++ ++&switch { ++ pinctrl-0 = <&ptp_out_pins>, <&ptp_ext_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ ++ ethernet-ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port0: port@0 { ++ reg = <0>; ++ phy-handle = <&phy4>; ++ phy-mode = "qsgmii"; ++ phys = <&serdes 0>; ++ microchip,bandwidth = <1000>; ++ }; ++ ++ port1: port@1 { ++ reg = <1>; ++ phy-handle = <&phy5>; ++ phy-mode = "qsgmii"; ++ phys = <&serdes 0>; ++ microchip,bandwidth = <1000>; ++ }; ++ ++ port2: port@2 { ++ reg = <2>; ++ phy-handle = <&phy6>; ++ phy-mode = "qsgmii"; ++ phys = <&serdes 0>; ++ microchip,bandwidth = <1000>; ++ }; ++ ++ port3: port@3 { ++ reg = <3>; ++ phy-handle = <&phy7>; ++ phy-mode = "qsgmii"; ++ phys = <&serdes 0>; ++ microchip,bandwidth = <1000>; ++ }; ++ ++ port4: port@4 { ++ reg = <4>; ++ phy-handle = <&phy8>; ++ phy-mode = "qsgmii"; ++ phys = <&serdes 1>; ++ microchip,bandwidth = <1000>; ++ }; ++ ++ port5: port@5 { ++ reg = <5>; ++ phy-handle = <&phy9>; ++ phy-mode = "qsgmii"; ++ phys = <&serdes 1>; ++ microchip,bandwidth = <1000>; ++ }; ++ ++ port6: port@6 { ++ reg = <6>; ++ phy-handle = <&phy10>; ++ phy-mode = "qsgmii"; ++ phys = <&serdes 1>; ++ microchip,bandwidth = <1000>; ++ }; ++ ++ port7: port@7 { ++ reg = <7>; ++ phy-handle = <&phy11>; ++ phy-mode = "qsgmii"; ++ phys = <&serdes 1>; ++ microchip,bandwidth = <1000>; ++ }; ++ ++ port8: port@8 { ++ reg = <8>; ++ phy-handle = <&phy12>; ++ phy-mode = "qsgmii"; ++ phys = <&serdes 2>; ++ microchip,bandwidth = <1000>; ++ }; ++ ++ port9: port@9 { ++ reg = <9>; ++ phy-handle = <&phy13>; ++ phy-mode = "qsgmii"; ++ phys = <&serdes 2>; ++ microchip,bandwidth = <1000>; ++ }; ++ ++ port10: port@10 { ++ reg = <10>; ++ phy-handle = <&phy14>; ++ phy-mode = "qsgmii"; ++ phys = <&serdes 2>; ++ microchip,bandwidth = <1000>; ++ }; ++ ++ port11: port@11 { ++ reg = <11>; ++ phy-handle = <&phy15>; ++ phy-mode = "qsgmii"; ++ phys = <&serdes 2>; ++ microchip,bandwidth = <1000>; ++ }; ++ ++ port12: port@12 { ++ reg = <12>; ++ phy-handle = <&phy16>; ++ phy-mode = "qsgmii"; ++ phys = <&serdes 3>; ++ microchip,bandwidth = <1000>; ++ }; ++ ++ port13: port@13 { ++ reg = <13>; ++ phy-handle = <&phy17>; ++ phy-mode = "qsgmii"; ++ phys = <&serdes 3>; ++ microchip,bandwidth = <1000>; ++ }; ++ ++ port14: port@14 { ++ reg = <14>; ++ phy-handle = <&phy18>; ++ phy-mode = "qsgmii"; ++ phys = <&serdes 3>; ++ microchip,bandwidth = <1000>; ++ }; ++ ++ port15: port@15 { ++ reg = <15>; ++ phy-handle = <&phy19>; ++ phy-mode = "qsgmii"; ++ phys = <&serdes 3>; ++ microchip,bandwidth = <1000>; ++ }; ++ ++ port16: port@16 { ++ reg = <16>; ++ phy-handle = <&phy20>; ++ phy-mode = "qsgmii"; ++ phys = <&serdes 4>; ++ microchip,bandwidth = <1000>; ++ }; ++ ++ port17: port@17 { ++ reg = <17>; ++ phy-handle = <&phy21>; ++ phy-mode = "qsgmii"; ++ phys = <&serdes 4>; ++ microchip,bandwidth = <1000>; ++ }; ++ ++ port18: port@18 { ++ reg = <18>; ++ phy-handle = <&phy22>; ++ phy-mode = "qsgmii"; ++ phys = <&serdes 4>; ++ microchip,bandwidth = <1000>; ++ }; ++ ++ port19: port@19 { ++ reg = <19>; ++ phy-handle = <&phy23>; ++ phy-mode = "qsgmii"; ++ phys = <&serdes 4>; ++ microchip,bandwidth = <1000>; ++ }; ++ ++ port20: port@20 { ++ reg = <20>; ++ phy-handle = <&phy24>; ++ phy-mode = "qsgmii"; ++ phys = <&serdes 5>; ++ microchip,bandwidth = <1000>; ++ }; ++ ++ port21: port@21 { ++ reg = <21>; ++ phy-handle = <&phy25>; ++ phy-mode = "qsgmii"; ++ phys = <&serdes 5>; ++ microchip,bandwidth = <1000>; ++ }; ++ ++ port22: port@22 { ++ reg = <22>; ++ phy-handle = <&phy26>; ++ phy-mode = "qsgmii"; ++ phys = <&serdes 5>; ++ microchip,bandwidth = <1000>; ++ }; ++ ++ port23: port@23 { ++ reg = <23>; ++ phy-handle = <&phy27>; ++ phy-mode = "qsgmii"; ++ phys = <&serdes 5>; ++ microchip,bandwidth = <1000>; ++ }; ++ ++ port24: port@24 { ++ reg = <24>; ++ phys = <&serdes 6>; ++ phy-mode = "10gbase-r"; ++ sfp = <&sfp0>; ++ managed = "in-band-status"; ++ microchip,bandwidth = <10000>; ++ microchip,sd-sgpio = <24>; ++ }; ++ ++ port25: port@25 { ++ reg = <25>; ++ phys = <&serdes 7>; ++ phy-mode = "10gbase-r"; ++ sfp = <&sfp1>; ++ managed = "in-band-status"; ++ microchip,bandwidth = <10000>; ++ microchip,sd-sgpio = <28>; ++ }; ++ ++ port26: port@26 { ++ reg = <26>; ++ phys = <&serdes 8>; ++ phy-mode = "10gbase-r"; ++ sfp = <&sfp2>; ++ managed = "in-band-status"; ++ microchip,bandwidth = <10000>; ++ microchip,sd-sgpio = <32>; ++ }; ++ ++ port27: port@27 { ++ reg = <27>; ++ phys = <&serdes 9>; ++ phy-mode = "10gbase-r"; ++ sfp = <&sfp3>; ++ managed = "in-band-status"; ++ microchip,bandwidth = <10000>; ++ microchip,sd-sgpio = <36>; ++ }; ++ ++ port29: port@29 { ++ reg = <29>; ++ phy-handle = <&phy3>; ++ phy-mode = "rgmii-id"; ++ microchip,bandwidth = <1000>; ++ }; ++ }; ++}; ++ ++&tmon { ++ pinctrl-0 = <&fan_pins>; ++ pinctrl-names = "default"; ++}; ++ ++&usart0 { ++ pinctrl-0 = <&fc0_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++}; ++ ++&usb { ++ pinctrl-0 = <&usb_ulpi_pins>, <&usb_rst_pins>, <&usb_over_pins>, <&usb_power_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++}; diff --git a/patches/linux/6.18.46/0062-arm64-dts-microchip-lan969x-add-OTP-node.patch b/patches/linux/6.18.46/0062-arm64-dts-microchip-lan969x-add-OTP-node.patch new file mode 100644 index 000000000..0a9dd3787 --- /dev/null +++ b/patches/linux/6.18.46/0062-arm64-dts-microchip-lan969x-add-OTP-node.patch @@ -0,0 +1,33 @@ +From 09f9fca6457b9967a340d21625727112df82ee2b Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Fri, 15 May 2026 13:59:09 +0200 +Subject: [PATCH 62/64] arm64: dts: microchip: lan969x: add OTP node +Organization: Wires + +Add the required OTP on LAN969x. + +Signed-off-by: Robert Marko +Reviewed-by: Claudiu Beznea +Link: https://lore.kernel.org/r/20260515115954.701155-3-robimarko@gmail.com +Signed-off-by: Claudiu Beznea +(cherry picked from commit 8071815790141d3f05e32b972a6c79fdbbb88cfa) +--- + arch/arm64/boot/dts/microchip/lan9691.dtsi | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/arch/arm64/boot/dts/microchip/lan9691.dtsi b/arch/arm64/boot/dts/microchip/lan9691.dtsi +index 235e56bebbdb..ed997d87dd09 100644 +--- a/arch/arm64/boot/dts/microchip/lan9691.dtsi ++++ b/arch/arm64/boot/dts/microchip/lan9691.dtsi +@@ -100,6 +100,11 @@ usb: usb@300000 { + status = "disabled"; + }; + ++ otp: otp@e0021000 { ++ compatible = "microchip,lan9691-otpc"; ++ reg = <0xe0021000 0x1000>; ++ }; ++ + flx0: flexcom@e0040000 { + compatible = "microchip,lan9691-flexcom", "atmel,sama5d2-flexcom"; + reg = <0xe0040000 0x100>; diff --git a/patches/linux/6.18.46/0063-arm64-dts-microchip-lan969x-add-SDMMC-nodes.patch b/patches/linux/6.18.46/0063-arm64-dts-microchip-lan969x-add-SDMMC-nodes.patch new file mode 100644 index 000000000..27aa978a6 --- /dev/null +++ b/patches/linux/6.18.46/0063-arm64-dts-microchip-lan969x-add-SDMMC-nodes.patch @@ -0,0 +1,48 @@ +From 4ea283cd3f17bcd1ac8bdc1cbcf5f5751fc0a334 Mon Sep 17 00:00:00 2001 +From: Joachim Wiberg +Date: Wed, 19 Aug 2026 11:38:37 +0200 +Subject: [PATCH 63/64] arm64: dts: microchip: lan969x: add SDMMC nodes +Organization: Wires + +The SoC has two SDMMC controllers, neither of which is described, so +boards with eMMC have no way to enable it. Add both, disabled by +default. + +Signed-off-by: Joachim Wiberg +--- + arch/arm64/boot/dts/microchip/lan9691.dtsi | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/arch/arm64/boot/dts/microchip/lan9691.dtsi b/arch/arm64/boot/dts/microchip/lan9691.dtsi +index ed997d87dd09..59a19462a5db 100644 +--- a/arch/arm64/boot/dts/microchip/lan9691.dtsi ++++ b/arch/arm64/boot/dts/microchip/lan9691.dtsi +@@ -396,6 +396,28 @@ clks: clock-controller@e00c00b4 { + clock-names = "cpu", "ddr", "sys"; + }; + ++ sdmmc0: mmc@e0830000 { ++ compatible = "microchip,lan969x-sdhci"; ++ reg = <0xe0830000 0x300>; ++ interrupts = ; ++ clocks = <&clks GCK_ID_SDMMC0>, <&clks GCK_ID_SDMMC0>; ++ clock-names = "hclock", "multclk"; ++ assigned-clocks = <&clks GCK_ID_SDMMC0>; ++ assigned-clock-rates = <100000000>; ++ status = "disabled"; ++ }; ++ ++ sdmmc1: mmc@e0838000 { ++ compatible = "microchip,lan969x-sdhci"; ++ reg = <0xe0838000 0x300>; ++ interrupts = ; ++ clocks = <&clks GCK_ID_SDMMC1>, <&clks GCK_ID_SDMMC1>; ++ clock-names = "hclock", "multclk"; ++ assigned-clocks = <&clks GCK_ID_SDMMC1>; ++ assigned-clock-rates = <45000000>; ++ status = "disabled"; ++ }; ++ + reset: reset-controller@e201000c { + compatible = "microchip,lan9691-switch-reset", + "microchip,lan966x-switch-reset"; diff --git a/patches/linux/6.18.46/0064-arm64-dts-microchip-ev23x71a-enable-eMMC.patch b/patches/linux/6.18.46/0064-arm64-dts-microchip-ev23x71a-enable-eMMC.patch new file mode 100644 index 000000000..b684e647b --- /dev/null +++ b/patches/linux/6.18.46/0064-arm64-dts-microchip-ev23x71a-enable-eMMC.patch @@ -0,0 +1,36 @@ +From c7c0989192e8f3a5be11a3a9f4c230bc28b430f9 Mon Sep 17 00:00:00 2001 +From: Joachim Wiberg +Date: Wed, 19 Aug 2026 11:38:37 +0200 +Subject: [PATCH 64/64] arm64: dts: microchip: ev23x71a: enable eMMC +Organization: Wires + +The board has an 8-bit eMMC on SDMMC0, and defines the emmc_sd pinctrl +group for it, but nothing enables the controller. + +Signed-off-by: Joachim Wiberg +--- + arch/arm64/boot/dts/microchip/lan9696-ev23x71a.dts | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/arch/arm64/boot/dts/microchip/lan9696-ev23x71a.dts b/arch/arm64/boot/dts/microchip/lan9696-ev23x71a.dts +index 4012ea7d07bb..7f12fc5c321f 100644 +--- a/arch/arm64/boot/dts/microchip/lan9696-ev23x71a.dts ++++ b/arch/arm64/boot/dts/microchip/lan9696-ev23x71a.dts +@@ -463,6 +463,17 @@ phy27: phy@27 { + }; + }; + ++&sdmmc0 { ++ pinctrl-0 = <&emmc_sd_pins>; ++ pinctrl-names = "default"; ++ max-frequency = <100000000>; ++ bus-width = <8>; ++ mmc-ddr-1_8v; ++ mmc-hs200-1_8v; ++ non-removable; ++ status = "okay"; ++}; ++ + &serdes { + status = "okay"; + }; diff --git a/patches/uboot/bsp-v2024.04-2026.06/0001-cmd-sleep-Consume-Ctrl-C-when-exiting-early.patch b/patches/uboot/bsp-v2024.04-2026.06/0001-cmd-sleep-Consume-Ctrl-C-when-exiting-early.patch new file mode 100644 index 000000000..18744cc25 --- /dev/null +++ b/patches/uboot/bsp-v2024.04-2026.06/0001-cmd-sleep-Consume-Ctrl-C-when-exiting-early.patch @@ -0,0 +1,52 @@ +From 5a62870ed29983d5286c42733acd26b05ee6cfdb Mon Sep 17 00:00:00 2001 +From: Tobias Waldekranz +Date: Mon, 10 Jun 2024 12:59:21 +0200 +Subject: [PATCH 1/3] cmd/sleep: Consume Ctrl-C when exiting early +Organization: Wires + +When sleep aborts early due to Ctrl-C input from the user, that state +is transferred to the exit status of the program and should therefore +be cleared from the global state. + +Before this change, the lingering global state would lead to very +unintuitive execution flows in scripts due to the U-Boot specific +modification to the hush interpreter which checks for Ctrl-C in all +loop constructs. + +This script, for example... + + if sleep 3; then + echo "Had a good night's sleep" + else + echo "That was a rude awakening! I refuse to go on..." + while true; do + true + done + + echo "...or maybe I will" + fi + +...would just skip over the infinite loop (indeed, all following +loops) when prematurely interrupting the sleep. + +(cherry picked from commit ed733077b87b1f3da6ac956840c927406c268a3d) +--- + cmd/sleep.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/cmd/sleep.c b/cmd/sleep.c +index c741b4aa029..b3511e13b83 100644 +--- a/cmd/sleep.c ++++ b/cmd/sleep.c +@@ -39,8 +39,10 @@ static int do_sleep(struct cmd_tbl *cmdtp, int flag, int argc, + delay += mdelay; + + while (get_timer(start) < delay) { +- if (ctrlc()) ++ if (ctrlc()) { ++ clear_ctrlc(); + return CMD_RET_FAILURE; ++ } + + udelay(100); + } diff --git a/patches/uboot/bsp-v2024.04-2026.06/0002-hush-Remove-Ctrl-C-detection-in-loops.patch b/patches/uboot/bsp-v2024.04-2026.06/0002-hush-Remove-Ctrl-C-detection-in-loops.patch new file mode 100644 index 000000000..c481aed59 --- /dev/null +++ b/patches/uboot/bsp-v2024.04-2026.06/0002-hush-Remove-Ctrl-C-detection-in-loops.patch @@ -0,0 +1,39 @@ +From 0c7f46cb147199ecc649838105ce49f9131a7b2e Mon Sep 17 00:00:00 2001 +From: Tobias Waldekranz +Date: Mon, 10 Jun 2024 13:25:31 +0200 +Subject: [PATCH 2/3] hush: Remove Ctrl-C detection in loops +Organization: Wires + +Assume that the original intent was to emulate SIGINT to a shell. This +only works as expected if the loop in question is the ouermost, and +last, statement. In all other cases, it completely breaks the expected +execution flow. It more or less resurrects Visual Basic's "On Error +Resume Next". + +Disable this behavior and delegate the problem of loop termination to +the writer of the script instead. + +Signed-off-by: Tobias Waldekranz +(cherry picked from commit cde9fed496833b88094ed6e9fea11969a1be8e25) +--- + common/cli_hush.c | 7 ------- + 1 file changed, 7 deletions(-) + +diff --git a/common/cli_hush.c b/common/cli_hush.c +index 9cda97f30e3..45293d8d482 100644 +--- a/common/cli_hush.c ++++ b/common/cli_hush.c +@@ -1796,13 +1796,6 @@ static int run_list_real(struct pipe *pi) + for (; pi; pi = (flag_restore != 0) ? rpipe : pi->next) { + if (pi->r_mode == RES_WHILE || pi->r_mode == RES_UNTIL || + pi->r_mode == RES_FOR) { +-#ifdef __U_BOOT__ +- /* check Ctrl-C */ +- ctrlc(); +- if ((had_ctrlc())) { +- return 1; +- } +-#endif + flag_restore = 0; + if (!rpipe) { + flag_rep = 0; diff --git a/patches/uboot/bsp-v2024.04-2026.06/0003-board-microchip-lan969x-honor-ENV_IS_NOWHERE.patch b/patches/uboot/bsp-v2024.04-2026.06/0003-board-microchip-lan969x-honor-ENV_IS_NOWHERE.patch new file mode 100644 index 000000000..fb62e5f25 --- /dev/null +++ b/patches/uboot/bsp-v2024.04-2026.06/0003-board-microchip-lan969x-honor-ENV_IS_NOWHERE.patch @@ -0,0 +1,43 @@ +From 6b81edd0d7bd3231106757846a8ad0442b0ed3ea Mon Sep 17 00:00:00 2001 +From: Joachim Wiberg +Date: Fri, 21 Aug 2026 14:37:27 +0200 +Subject: [PATCH 3/3] board: microchip: lan969x: honor ENV_IS_NOWHERE +Organization: Wires + +env_get_location() returns the environment location matching the medium +Trusted Firmware booted from, and never ENVL_NOWHERE. A system that +keeps its environment in the control device tree, and therefore builds +no environment driver at all, fails to boot: env_driver_lookup() finds +nothing at prio 0, so env_init() returns -ENODEV. This happens before +the console is up, and the initcall list reports the failure one entry +late, at init_baud_rate, which makes it needlessly hard to place. + +Return ENVL_NOWHERE when no location driver is built, as +board/kontron/sl28/sl28.c already does. + +Signed-off-by: Joachim Wiberg +--- + board/microchip/lan969x/lan969x.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/board/microchip/lan969x/lan969x.c b/board/microchip/lan969x/lan969x.c +index bc357159ecd..2694604ef6d 100644 +--- a/board/microchip/lan969x/lan969x.c ++++ b/board/microchip/lan969x/lan969x.c +@@ -77,6 +77,16 @@ enum env_location env_get_location(enum env_operation op, int prio) + { + boot_source_type_t boot_source = tfa_get_boot_source(); + ++ /* ++ * Systems keeping the environment in the control device tree ++ * build no location driver at all. Asking for one that was ++ * never built fails env_init() with -ENODEV. ++ */ ++ if (!CONFIG_IS_ENABLED(ENV_IS_IN_MMC) && ++ !CONFIG_IS_ENABLED(ENV_IS_IN_SPI_FLASH) && ++ !CONFIG_IS_ENABLED(ENV_IS_IN_FAT)) ++ return prio == 0 ? ENVL_NOWHERE : ENVL_UNKNOWN; ++ + switch(boot_source) { + case BOOT_SOURCE_EMMC: + return prio == 0 ? ENVL_MMC : ENVL_UNKNOWN; diff --git a/src/bin/show/__init__.py b/src/bin/show/__init__.py index 0b3471bd7..4d240c4a9 100755 --- a/src/bin/show/__init__.py +++ b/src/bin/show/__init__.py @@ -544,15 +544,8 @@ def mdns(args: List[str]) -> None: cli_pretty(data, "show-mdns") -# Sensor names that represent the SoC/CPU temperature (not per-port PHYs). -# Matches "cpu"/"soc"/"core", and Marvell CN913x "ap-*" / "cp-*" zones. -# Note the hyphen after "cp" so mangled PHY names like "cp0busbus…" never -# match. -SOC_TEMP_RE = re.compile(r'^(cpu|soc|core|ap-|cp\d+-)') - - def system(args: List[str]) -> None: - # Get system state from sysrepo + """Get system state from sysrepo""" data = get_json("/ietf-system:system-state") if not data: print("No system data retrieved.") @@ -569,21 +562,20 @@ def system(args: List[str]) -> None: fan_rpm = None if hardware_data and "ietf-hardware:hardware" in hardware_data: components = hardware_data.get("ietf-hardware:hardware", {}).get("component", []) + # A sensor says nothing in its name, what it measures follows from + # the component it belongs to, see doc/hardware.md + classes = {c.get("name"): c.get("class") for c in components} soc_temps = [] for component in components: sensor_data = component.get("sensor-data", {}) if not sensor_data: continue - name = component.get("name", "") + parent = classes.get(component.get("parent")) value_type = sensor_data.get("value-type") - # Capture SoC/CPU temperature, ignoring per-port phy, sfp, etc. - # Platforms name the zone differently: a plain "cpu"/"soc"/"core", - # or, on Marvell CN913x, an "ap-*" (application processor) or - # "cp-*" (communication processor) cluster. Collect them all - # and report the hottest as the representative SoC temperature. - if value_type == "celsius" and SOC_TEMP_RE.match(name): + # An SoC may report several dies or clusters, take the hottest + if value_type == "celsius" and parent == "iana-hardware:cpu": soc_temps.append(sensor_data.get("value", 0) / 1000.0) # Capture fan speed if available diff --git a/src/statd/python/cli_pretty/cli_pretty.py b/src/statd/python/cli_pretty/cli_pretty.py index b9eb05157..f098c2734 100755 --- a/src/statd/python/cli_pretty/cli_pretty.py +++ b/src/statd/python/cli_pretty/cli_pretty.py @@ -2253,13 +2253,17 @@ def show_services(json): service_table.print() -def sensor_sort_key(component): - """Natural sort key for sensor names: digit runs compare numerically so - e2 sorts before e10, while keeping ap-cpu/cp0-ic/sfp groups together.""" - name = component.get("name", "") +def natural_key(name): + """Natural sort key: digit runs compare numerically so e2 sorts before + e10, while keeping ap-cpu/cp0-ic/sfp groups together.""" return [int(t) if t.isdigit() else t for t in re.split(r'(\d+)', name)] +def sensor_sort_key(component): + """Natural sort key for a sensor component.""" + return natural_key(component.get("name", "")) + + def show_hardware(json): if not json.get("ietf-hardware:hardware"): print("Error, top level \"ietf-hardware:component\" missing") @@ -2424,23 +2428,19 @@ def show_hardware(json): else: standalone.append(component) - # Get all parent modules (non-sensor components) - modules = [c for c in components if c.get("class") == "iana-hardware:module"] - - # Display modules with their child sensors (indented) - for module in sorted(modules, key=lambda m: m.get("name", "")): - module_name = module.get("name", "unknown") - print(f"\n{module_name}:") + # Anything with sensors of its own heads a group, an SFP module, + # the CPU, a WiFi radio, ... + for parent_name in sorted(children, key=natural_key): + print(f"\n{parent_name}:") - if module_name in children: - for child in sorted(children[module_name], key=sensor_sort_key): - sensor = Sensor(child) - sensor.print(indent=1) + for child in sorted(children[parent_name], key=sensor_sort_key): + sensor = Sensor(child) + sensor.print(indent=1) # Display standalone sensors (no parent), naturally sorted so port # temperatures read e1, e2, ... e28 rather than e1, e10, e11, ... if standalone: - if modules: + if children: print() # Add blank line between modules and standalone for component in sorted(standalone, key=sensor_sort_key): sensor = Sensor(component) diff --git a/src/statd/python/yanger/ietf_hardware.py b/src/statd/python/yanger/ietf_hardware.py index e29f53e37..385e9cf3c 100644 --- a/src/statd/python/yanger/ietf_hardware.py +++ b/src/statd/python/yanger/ietf_hardware.py @@ -3,7 +3,7 @@ import re import sys -from .common import insert, YangDate +from .common import insert, LOG, YangDate from .host import HOST @@ -19,7 +19,10 @@ def vpd_vendor_extensions(data): def vpd_component(vpd): component = {} - component["name"] = vpd.get("board") + # Board authors name these in the device tree, as "cpu", "power", + # "product", short words that collide with everything else sharing + # the component namespace. Say what they are. + component["name"] = f"vpd-{vpd.get('board')}" component["infix-hardware:vpd-data"] = {} if vpd.get("data"): @@ -122,31 +125,69 @@ def normalize_sensor_name(name): sfp_2 -> sfp2 mt7915_phy0 -> phy0 marvell_alaska_tomte_phy7 -> phy7 - cpu_thermal -> cpu + cpu_thermal -> cpu-thermal + s5_temp -> s5-temp pwmfan -> pwmfan Strategy: - 1. Strip common suffixes like -thermal/_thermal - 2. Extract well-known sensor type names (phy, sfp, fan, etc.) from - the end of the name, stripping any vendor/chipset prefix - 3. Remove underscores before trailing numbers (sfp_2 -> sfp2) + 1. Drop the vendor/chipset prefix of a per-port device, where the + type and index are what identify it (mt7915_phy0 -> phy0) + 2. Remove underscores before trailing numbers (sfp_2 -> sfp2) + 3. Keep the rest as one name (s5_temp -> s5-temp) + + A thermal zone and the hwmon device the kernel mirrors it as differ + only in their separators, so this also makes the two spellings of + one sensor come out identical, which is how the mirror is spotted. + + Names are list keys, nothing more. What a sensor measures is + conveyed by the class of the component it belongs to, see + doc/hardware.md, so a name must stay unique rather than descriptive. """ - import re - - # Strip common suffixes - name = name.replace("-thermal", "").replace("_thermal", "") - - # Extract well-known sensor types from end of name, stripping any prefix - # This handles: mt7915_phy0 -> phy0, marvell_alaska_phy7 -> phy7, etc. - sensor_types = r'(phy|sfp|fan|temp|sensor|psu|cpu|gpu|memory|disk)' - match = re.search(rf'.*_({sensor_types}\d*)$', name) + # Per-port devices: mt7915_phy0 -> phy0, marvell_alaska_phy7 -> phy7 + match = re.search(r'.*_((phy|sfp)\d*)$', name) if match: name = match.group(1) # Remove underscores before trailing numbers (sfp_2 -> sfp2) name = re.sub(r'_(\d+)$', r'\1', name) - return name + return name.replace("_", "-") + + +CPU_COMPONENT = "cpu" + +# hwmon device names and thermal zone types that report an SoC die +# temperature, after normalization: a plain cpu/soc/core, Intel and AMD +# (coretemp, k10temp), Microchip SparX-5 and LAN969x (s5-temp), or a +# Marvell CN913x application (ap) or communication (cp) processor +# cluster. +# +# Recognizing vendor names cannot be avoided, but this is the only place +# it happens. Northbound, the sensors are found through the class of +# their parent component, see doc/hardware.md. +SOC_TEMP_SOURCE = re.compile( + r'^(cpu\d*|soc\d*|core\d*|coretemp|k10temp|s5-temp|ap|cp\d+)(-.*)?$') + + +def cpu_component(sensors): + """ + Create the SoC component that die temperature sensors belong to. + + Only created when something references it, boards without a die + sensor have nothing to say about their SoC. + """ + if not any(sensor.get("parent") == CPU_COMPONENT for sensor in sensors): + return [] + + return [{ + "name": CPU_COMPONENT, + "class": "iana-hardware:cpu", + "parent": "mainboard", + "state": { + "admin-state": "unknown", + "oper-state": "enabled" + } + }] def _dt_phandle(path): @@ -234,9 +275,11 @@ def get_wifi_phy_info(): return phy_info -def hwmon_sensor_components(): +def hwmon_sensor_components(mirrored): """ Discover hwmon sensors and create sensor components with parent/child relationships. + + Devices named in "mirrored" are skipped, see the thermal zones. Returns a list of hardware components with sensor-data for temperature, fan, voltage, current, and power sensors. @@ -268,6 +311,13 @@ def add_sensor(base_name, sensor_component): device_name = HOST.read(name_path).strip() + # With THERMAL_HWMON the kernel mirrors every thermal + # zone as an hwmon device, named after the zone with the + # separators changed. Both spell the same sensor, and + # the zone is already accounted for. + if normalize_sensor_name(device_name) in mirrored: + continue + # Check if device/name exists (e.g., for WiFi radios) and use that instead device_name_path = os.path.join(hwmon_path, "device", "name") if HOST.exists(device_name_path): @@ -447,21 +497,24 @@ def create_sensor(sensor_name, value, value_type, value_scale, label=None): # Now create parent/child relationships for base_name, sensors in device_sensors.items(): - if len(sensors) > 1: - # Multiple sensors: create parent component - parent = { + if SOC_TEMP_SOURCE.match(base_name): + # SoC die sensors belong to the CPU, whatever the vendor + # called the hwmon device + parent = CPU_COMPONENT + elif len(sensors) > 1: + # Multi-sensor devices, like SFP modules, head their own + parent = base_name + components.append({ "name": base_name, - "class": "iana-hardware:module", # Use "module" for multi-sensor devices like SFP - } - components.append(parent) - - # Add parent reference to all child sensors - for sensor in sensors: - sensor["parent"] = base_name - components.append(sensor) + "class": "iana-hardware:module", + }) else: - # Single sensor: add without parent - components.extend(sensors) + parent = None + + for sensor in sensors: + if parent: + sensor["parent"] = parent + components.extend(sensors) # Enrich WiFi PHY sensors with descriptive information wifi_info = get_wifi_phy_info() @@ -495,22 +548,13 @@ def thermal_sensor_components(): for zone_path in thermal_zones: try: # Read zone type (e.g., "cpu-thermal", "gpu-thermal") - type_path = os.path.join(zone_path, "type") - if not HOST.exists(type_path): + zone_type = HOST.read(os.path.join(zone_path, "type")) + temp = HOST.read(os.path.join(zone_path, "temp")) + if not zone_type or not temp: continue - zone_type = HOST.read(type_path).strip() - - # Read temperature in millidegrees Celsius - temp_path = os.path.join(zone_path, "temp") - if not HOST.exists(temp_path): - continue - - temp_millidegrees = int(HOST.read(temp_path).strip()) - - # Create component with sensor-data - # Component name: strip "-thermal" suffix for cleaner display - component_name = normalize_sensor_name(zone_type) + temp_millidegrees = int(temp.strip()) + component_name = normalize_sensor_name(zone_type.strip()) component = { "name": component_name, @@ -525,6 +569,9 @@ def thermal_sensor_components(): } } + if SOC_TEMP_SOURCE.match(component_name): + component["parent"] = CPU_COMPONENT + components.append(component) except (FileNotFoundError, ValueError, IOError): @@ -871,19 +918,56 @@ def gps_receiver_components(): return components +def unique_names(components): + """ + Components are keyed by name, so a duplicate is not a cosmetic + problem: it fails every client parsing the tree. Producers avoid + collisions by construction, this is the net under them. + + Note that a renamed component keeps any children pointing at the + original name, so this really is a last resort, not a mechanism to + rely on. + """ + taken = set() + + for component in components: + name = component.get("name") + if name not in taken: + taken.add(name) + continue + + unique = name + seq = 1 + while unique in taken: + unique = f"{name}-{seq}" + seq += 1 + + LOG.warning(f"Duplicate hardware component \"{name}\", renaming " + f"one of them \"{unique}\"") + component["name"] = unique + taken.add(unique) + + return components + + def operational(): systemjson = HOST.read_json("/run/system.json", {}) + # Thermal zones first: the kernel mirrors each one as an hwmon + # device, which carries nothing the zone does not. + thermal = thermal_sensor_components() + sensors = thermal + hwmon_sensor_components({c["name"] for c in thermal}) + inventory = (motherboard_component(systemjson) + + vpd_components(systemjson) + + usb_port_components(systemjson)) return { "ietf-hardware:hardware": { - "component": - motherboard_component(systemjson) + - vpd_components(systemjson) + - usb_port_components(systemjson) + - hwmon_sensor_components() + - thermal_sensor_components() + - wifi_radio_components() + - gps_receiver_components() + - [], + "component": unique_names( + inventory + + cpu_component(sensors) + + sensors + + wifi_radio_components() + + gps_receiver_components() + ), }, } diff --git a/src/webui/internal/handlers/dashboard.go b/src/webui/internal/handlers/dashboard.go index e51dfc11b..7e5351e22 100644 --- a/src/webui/internal/handlers/dashboard.go +++ b/src/webui/internal/handlers/dashboard.go @@ -178,6 +178,7 @@ type filesystemFS struct { // Short forms of hardware-class identities — see shortClass(). Kept here so // the dashboard and Status > Hardware handlers route the same way. const ( + classCPU = "cpu" // ietf-hardware:cpu classChassis = "chassis" // ietf-hardware:chassis classUSB = "usb" // infix-hardware:usb classWiFi = "wifi" // infix-hardware:wifi @@ -707,8 +708,9 @@ func keyVital(c hwComponentJSON, classByName map[string]string) (sensorEntry, bo switch c.SensorData.ValueType { case "celsius": switch { - case c.Name == "cpu", c.Name == "soc", c.Name == "core": - // CPU / SoC / core temperatures. + case classByName[c.Parent] == classCPU: + // SoC die temperatures, however the platform names the + // hwmon device or thermal zone underneath. case classByName[c.Parent] == classWiFi: // WiFi radio temperatures whose sensor-data lives under // the radio component as a child. diff --git a/test/case/statd/all.yaml b/test/case/statd/all.yaml index ee1d006bb..69abe2789 100644 --- a/test/case/statd/all.yaml +++ b/test/case/statd/all.yaml @@ -7,5 +7,7 @@ name: "interfaces-all" - case: journal-retention/test.py name: "journal-retention" +- case: sensors/test + name: "sensors" - case: system/test name: "system" diff --git a/test/case/statd/sensors/cli/show-hardware b/test/case/statd/sensors/cli/show-hardware new file mode 100644 index 000000000..fb22cbb1e --- /dev/null +++ b/test/case/statd/sensors/cli/show-hardware @@ -0,0 +1,15 @@ +HARDWARE COMPONENTS  +────────────────────────────────────────────────────────────── +Board Information +Model : EV23X71A +Manufacturer : Microchip +Base MAC Address : 00:a0:85:00:03:00 +────────────────────────────────────────────────────────────── +Sensors +NAME VALUE STATUS  + +cpu: + Thermal 48.0 °C ok + S5 Temp 59.5 °C ok + +pwmfan 3200 RPM ok diff --git a/test/case/statd/sensors/ietf-hardware.json b/test/case/statd/sensors/ietf-hardware.json new file mode 100644 index 000000000..144df05d7 --- /dev/null +++ b/test/case/statd/sensors/ietf-hardware.json @@ -0,0 +1,74 @@ +{ + "ietf-hardware:hardware": { + "component": [ + { + "name": "mainboard", + "class": "iana-hardware:chassis", + "mfg-name": "Microchip", + "model-name": "EV23X71A", + "infix-hardware:phys-address": "00:a0:85:00:03:00", + "state": { + "admin-state": "unknown", + "oper-state": "enabled" + } + }, + { + "name": "vpd-cpu", + "infix-hardware:vpd-data": { + "product-name": "CPU board", + "serial-number": "0123456789" + }, + "class": "infix-hardware:vpd", + "model-name": "CPU board", + "serial-num": "0123456789" + }, + { + "name": "cpu", + "class": "iana-hardware:cpu", + "parent": "mainboard", + "state": { + "admin-state": "unknown", + "oper-state": "enabled" + } + }, + { + "name": "cpu-thermal", + "class": "iana-hardware:sensor", + "sensor-data": { + "value": 48000, + "value-type": "celsius", + "value-scale": "milli", + "value-precision": 0, + "value-timestamp": "2026-01-02T20:43:23+00:00", + "oper-status": "ok" + }, + "parent": "cpu" + }, + { + "name": "s5-temp", + "class": "iana-hardware:sensor", + "sensor-data": { + "value": 59500, + "value-type": "celsius", + "value-scale": "milli", + "value-precision": 0, + "value-timestamp": "2026-01-02T20:43:23+00:00", + "oper-status": "ok" + }, + "parent": "cpu" + }, + { + "name": "pwmfan", + "class": "iana-hardware:sensor", + "sensor-data": { + "value": 3200, + "value-type": "rpm", + "value-scale": "units", + "value-precision": 0, + "value-timestamp": "2026-01-02T20:43:23+00:00", + "oper-status": "ok" + } + } + ] + } +} diff --git a/test/case/statd/sensors/operational.json b/test/case/statd/sensors/operational.json new file mode 100644 index 000000000..144df05d7 --- /dev/null +++ b/test/case/statd/sensors/operational.json @@ -0,0 +1,74 @@ +{ + "ietf-hardware:hardware": { + "component": [ + { + "name": "mainboard", + "class": "iana-hardware:chassis", + "mfg-name": "Microchip", + "model-name": "EV23X71A", + "infix-hardware:phys-address": "00:a0:85:00:03:00", + "state": { + "admin-state": "unknown", + "oper-state": "enabled" + } + }, + { + "name": "vpd-cpu", + "infix-hardware:vpd-data": { + "product-name": "CPU board", + "serial-number": "0123456789" + }, + "class": "infix-hardware:vpd", + "model-name": "CPU board", + "serial-num": "0123456789" + }, + { + "name": "cpu", + "class": "iana-hardware:cpu", + "parent": "mainboard", + "state": { + "admin-state": "unknown", + "oper-state": "enabled" + } + }, + { + "name": "cpu-thermal", + "class": "iana-hardware:sensor", + "sensor-data": { + "value": 48000, + "value-type": "celsius", + "value-scale": "milli", + "value-precision": 0, + "value-timestamp": "2026-01-02T20:43:23+00:00", + "oper-status": "ok" + }, + "parent": "cpu" + }, + { + "name": "s5-temp", + "class": "iana-hardware:sensor", + "sensor-data": { + "value": 59500, + "value-type": "celsius", + "value-scale": "milli", + "value-precision": 0, + "value-timestamp": "2026-01-02T20:43:23+00:00", + "oper-status": "ok" + }, + "parent": "cpu" + }, + { + "name": "pwmfan", + "class": "iana-hardware:sensor", + "sensor-data": { + "value": 3200, + "value-type": "rpm", + "value-scale": "units", + "value-precision": 0, + "value-timestamp": "2026-01-02T20:43:23+00:00", + "oper-status": "ok" + } + } + ] + } +} diff --git a/test/case/statd/sensors/system/rootfs/run/system.json b/test/case/statd/sensors/system/rootfs/run/system.json new file mode 100644 index 000000000..bd99fa3a0 --- /dev/null +++ b/test/case/statd/sensors/system/rootfs/run/system.json @@ -0,0 +1,16 @@ +{ + "vendor": "Microchip", + "product-name": "EV23X71A", + "mac-address": "00:a0:85:00:03:00", + "vpd": { + "cpu": { + "board": "cpu", + "available": true, + "trusted": true, + "data": { + "product-name": "CPU board", + "serial-number": "0123456789" + } + } + } +} diff --git a/test/case/statd/sensors/system/rootfs/sys/class/hwmon/hwmon0/name b/test/case/statd/sensors/system/rootfs/sys/class/hwmon/hwmon0/name new file mode 100644 index 000000000..0b40a5f51 --- /dev/null +++ b/test/case/statd/sensors/system/rootfs/sys/class/hwmon/hwmon0/name @@ -0,0 +1 @@ +s5_temp diff --git a/test/case/statd/sensors/system/rootfs/sys/class/hwmon/hwmon0/temp1_input b/test/case/statd/sensors/system/rootfs/sys/class/hwmon/hwmon0/temp1_input new file mode 100644 index 000000000..3a4d1c5c9 --- /dev/null +++ b/test/case/statd/sensors/system/rootfs/sys/class/hwmon/hwmon0/temp1_input @@ -0,0 +1 @@ +59500 diff --git a/test/case/statd/sensors/system/rootfs/sys/class/hwmon/hwmon1/fan1_input b/test/case/statd/sensors/system/rootfs/sys/class/hwmon/hwmon1/fan1_input new file mode 100644 index 000000000..a6981b371 --- /dev/null +++ b/test/case/statd/sensors/system/rootfs/sys/class/hwmon/hwmon1/fan1_input @@ -0,0 +1 @@ +3200 diff --git a/test/case/statd/sensors/system/rootfs/sys/class/hwmon/hwmon1/name b/test/case/statd/sensors/system/rootfs/sys/class/hwmon/hwmon1/name new file mode 100644 index 000000000..50d26d52f --- /dev/null +++ b/test/case/statd/sensors/system/rootfs/sys/class/hwmon/hwmon1/name @@ -0,0 +1 @@ +pwmfan diff --git a/test/case/statd/sensors/system/rootfs/sys/class/hwmon/hwmon2/name b/test/case/statd/sensors/system/rootfs/sys/class/hwmon/hwmon2/name new file mode 100644 index 000000000..c82fe532c --- /dev/null +++ b/test/case/statd/sensors/system/rootfs/sys/class/hwmon/hwmon2/name @@ -0,0 +1 @@ +cpu_thermal diff --git a/test/case/statd/sensors/system/rootfs/sys/class/hwmon/hwmon2/temp1_input b/test/case/statd/sensors/system/rootfs/sys/class/hwmon/hwmon2/temp1_input new file mode 100644 index 000000000..22f0d241a --- /dev/null +++ b/test/case/statd/sensors/system/rootfs/sys/class/hwmon/hwmon2/temp1_input @@ -0,0 +1 @@ +48000 diff --git a/test/case/statd/sensors/system/rootfs/sys/class/thermal/thermal_zone0/temp b/test/case/statd/sensors/system/rootfs/sys/class/thermal/thermal_zone0/temp new file mode 100644 index 000000000..22f0d241a --- /dev/null +++ b/test/case/statd/sensors/system/rootfs/sys/class/thermal/thermal_zone0/temp @@ -0,0 +1 @@ +48000 diff --git a/test/case/statd/sensors/system/rootfs/sys/class/thermal/thermal_zone0/type b/test/case/statd/sensors/system/rootfs/sys/class/thermal/thermal_zone0/type new file mode 100644 index 000000000..0744c8e0c --- /dev/null +++ b/test/case/statd/sensors/system/rootfs/sys/class/thermal/thermal_zone0/type @@ -0,0 +1 @@ +cpu-thermal diff --git a/test/case/statd/sensors/system/run/ls_+sys+class+hwmon b/test/case/statd/sensors/system/run/ls_+sys+class+hwmon new file mode 100644 index 000000000..b51997471 --- /dev/null +++ b/test/case/statd/sensors/system/run/ls_+sys+class+hwmon @@ -0,0 +1,3 @@ +hwmon0 +hwmon1 +hwmon2 diff --git a/test/case/statd/sensors/system/run/ls_+sys+class+hwmon+hwmon0 b/test/case/statd/sensors/system/run/ls_+sys+class+hwmon+hwmon0 new file mode 100644 index 000000000..e26f6d2d4 --- /dev/null +++ b/test/case/statd/sensors/system/run/ls_+sys+class+hwmon+hwmon0 @@ -0,0 +1,2 @@ +name +temp1_input diff --git a/test/case/statd/sensors/system/run/ls_+sys+class+hwmon+hwmon1 b/test/case/statd/sensors/system/run/ls_+sys+class+hwmon+hwmon1 new file mode 100644 index 000000000..74e4d3de6 --- /dev/null +++ b/test/case/statd/sensors/system/run/ls_+sys+class+hwmon+hwmon1 @@ -0,0 +1,2 @@ +name +fan1_input diff --git a/test/case/statd/sensors/system/run/ls_+sys+class+hwmon+hwmon2 b/test/case/statd/sensors/system/run/ls_+sys+class+hwmon+hwmon2 new file mode 100644 index 000000000..e26f6d2d4 --- /dev/null +++ b/test/case/statd/sensors/system/run/ls_+sys+class+hwmon+hwmon2 @@ -0,0 +1,2 @@ +name +temp1_input diff --git a/test/case/statd/sensors/system/run/ls_+sys+class+thermal b/test/case/statd/sensors/system/run/ls_+sys+class+thermal new file mode 100644 index 000000000..7dc59779b --- /dev/null +++ b/test/case/statd/sensors/system/run/ls_+sys+class+thermal @@ -0,0 +1,2 @@ +thermal_zone0 +cooling_device0 diff --git a/test/case/statd/sensors/system/timestamp b/test/case/statd/sensors/system/timestamp new file mode 100644 index 000000000..3b0175f96 --- /dev/null +++ b/test/case/statd/sensors/system/timestamp @@ -0,0 +1 @@ +1767386603 \ No newline at end of file diff --git a/test/case/statd/sensors/test b/test/case/statd/sensors/test new file mode 100755 index 000000000..540442dac --- /dev/null +++ b/test/case/statd/sensors/test @@ -0,0 +1,16 @@ +#!/bin/sh +# Synthetic system state, hand written rather than captured from a +# device, to cover sensors no board in the test rig has: an SoC die +# temperature from hwmon (Microchip s5_temp), one from a thermal zone +# (cpu-thermal), and a fan. Verifies that both land under the CPU +# component, and that the fan does not. +# +# The VPD is named "cpu", as on Alder, so the CPU component has to pick +# another name rather than collide with it. + +yang_models="ietf-hardware" + +cli_commands="show-hardware" + +. $(readlink -f $(dirname $0)/../test.sh) +main "$@" diff --git a/test/case/statd/system/ietf-hardware.json b/test/case/statd/system/ietf-hardware.json index e93345405..aedcbb1f5 100644 --- a/test/case/statd/system/ietf-hardware.json +++ b/test/case/statd/system/ietf-hardware.json @@ -13,7 +13,7 @@ } }, { - "name": "product", + "name": "vpd-product", "infix-hardware:vpd-data": {} }, { diff --git a/test/case/statd/system/operational.json b/test/case/statd/system/operational.json index 8a436a9df..f3067f7f2 100644 --- a/test/case/statd/system/operational.json +++ b/test/case/statd/system/operational.json @@ -14,7 +14,7 @@ }, { "infix-hardware:vpd-data": {}, - "name": "product" + "name": "vpd-product" }, { "class": "infix-hardware:usb", diff --git a/test/case/statd/test.sh b/test/case/statd/test.sh index 941981fc8..b00acfdb4 100644 --- a/test/case/statd/test.sh +++ b/test/case/statd/test.sh @@ -212,6 +212,8 @@ cli_exec() cli_gen() { + [ "$cli_commands" ] || return 0 + mkdir -p "$casedir/cli" set $cli_commands @@ -226,6 +228,8 @@ cli_check() local diff= local status= + [ "$cli_commands" ] || return 0 + set $cli_commands while [ $# -gt 0 ]; do diff="$(mktemp)"