Compare commits

...
158 Commits
Author SHA1 Message Date
Joachim Wiberg 009b31d465 modemd: handle preferred-mode set without allowed-mode
Setting just preferred-mode in YANG (no allowed-mode leaf-list) built an
invalid mode string with an empty allowed:

  Mode 'allowed: ; preferred: 4g' is not supported

The empty allowed: can never match anything in the modem's supported-modes
list, so the user got a cryptic 'is not supported' even when their preferred
mode was, in principle, supported.

When only preferred-mode is configured, walk the modem's supported-modes list
for an entry that already has that preferred, and reuse its allowed set.  If
no supported entry has that preferred mode, fail with a message that lists
every combination the modem does support, easier to diagnose than the silent
'empty allowed' case.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-07 20:51:04 +02:00
Joachim Wiberg 36ef190c3d modemd: stop retrying mmcli --reset when the modem rejects it
Some cellular modems (notably Quectel EM05) don't expose a RESET capability
over MBIM/QMI.  Both 'mmcli --reset' and 'mmcli --factory-reset' return
Unsupported immediately, the AT command is never forwarded to the firmware,
and there's nothing modemd can do over the management bus to recover.  Until
now modemd's failed-state retry kept calling --reset every 30 s for the rest
of uptime, producing pure log noise:

    modemd: <error> [modem0] Resetting after being 30s in state failed
    modemd: <info>  [modem0] Resetting
    ModemManager: <wrn> [modem0] failed requesting modem reset: Unsupported
    ModemManager: <wrn> [modem0] failed requesting modem factory reset: Unsupported
    modemd: <error> [modem0] Unable to reset

... and the same five lines again 30 s later, indefinitely.

Mitigate this by caching the Unsupported state per modem per session.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-07 20:51:03 +02:00
Joachim Wiberg 600483c35b modem: route NMEA from cellular modems to gpsd
Cellular modems (Quectel EM05/EM06/EM12, Sierra EM7565, ...) expose
GPS data as NMEA on a dedicated USB serial interface.  Until now we
relied on ModemManager's --location-enable-gps-nmea, which makes MM
hold the NMEA port and parse the stream itself — useful for mmcli
but a dead end for the rest of the system.  The result was that
modem GPS was visible only via 'show modem' and could not act as an
NTP fallback time source on devices without dedicated GPS hardware.

This commit reroutes the NMEA stream into the existing
gpsd → chronyd pipeline so cellular modems behave just like any
other NMEA-over-USB GPS dongle.  No changes to gpsd, chronyd, or
the ietf-hardware:gps component — the user activates it the same
way as for a dedicated receiver, by adding a 'gps' hardware
component that references /dev/gpsN.

This is Phase 2 of the modem GPS / location integration plan
(.notes/modem-gps-plan.md).

udev (src/modemd/77-mm-modem-gps.rules):
  - For known vendor:product:interface tuples, set ID_MM_PORT_IGNORE
    so ModemManager keeps off the NMEA port, and add
    SYMLINK+="gps%n" so gpsd's existing udev hook picks up the
    device automatically.
  - Interface-number match uses ENV{ID_USB_INTERFACE_NUM} rather
    than ATTRS{bInterfaceNumber}: udev requires all ATTRS{} matches
    in a rule to share one parent, but idVendor/idProduct live on
    the USB device while bInterfaceNumber lives on the USB
    interface.  ENV{} matching has no parent constraint and udev
    already populates ID_USB_INTERFACE_NUM from bInterfaceNumber.
  - Initial entries: Quectel EM05 (2c7c:0125), EM06-E (2c7c:0306),
    EM12-G (2c7c:0512), Sierra Wireless EM7565 (1199:9091).
    Easy to extend.

modemd (modemd/__init__.py):
  - GPS_AT_COMMANDS table maps manufacturer -> (enable, disable) AT
    command pair.  prepare_location() issues the vendor AT command
    via 'mmcli --command=AT+QGPS=1' (or AT+CGPS=1 for Sierra)
    instead of --location-enable-gps-{nmea,raw}.  Vendor lookup is
    substring-based ('Quectel' matches both 'Quectel' and 'Quectel
    Incorporated') because ModemManager normalises differently
    across firmware revisions.  For unrecognised vendors the
    high-level MM path is still used as a fallback, so nothing
    regresses for hardware not yet in the table.
  - The AT path runs based on the udev/vendor table, not on MM's
    --location-status capabilities.  Setting ID_MM_PORT_IGNORE on
    the NMEA port removes 'gps' from MM's capability list even
    though the GPS hardware is still there, so a capability gate
    would mistakenly skip GPS for the very modems we're targeting.
  - _location_capabilities() filters MM-managed sources so a single
    unsupported flag (e.g. CDMA on an LTE-only modem) doesn't fail
    the whole batched call.  Sources the modem doesn't support are
    silently skipped; a warning is logged only if the user's YANG
    config explicitly lists one.
  - Subprocess fan-out collapsed: agps-msa, agps-msb, 3gpp and cdma
    flags share a single batched mmcli invocation.
    prepare_location() drops from 5 subprocess calls to 1 (unknown
    vendor) or 2 (known vendor, AT + batched MM).
  - Stringly-typed if/elif source dispatch replaced with a
    dict-driven table (LOCATION_MM_FLAGS).
  - Two helpers eliminate the ['mmcli', '-m', self.path, ...]
    boilerplate at ~30 ModemThread call sites:
      self._mmcli(*args, check=True)   # runcmd wrapper
      self._mmclij(*args)              # runcmdj wrapper

build (package/feature-modem/Config.in):
  - Select BR2_PACKAGE_MODEM_MANAGER_ATVIADBUS so ModemManager
    accepts raw AT commands over D-Bus without being started in
    --debug mode.  Required by the AT path above; without it
    'mmcli --command' is rejected with MM_CORE_ERROR_UNAUTHORIZED.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-07 20:51:03 +02:00
Joachim Wiberg 7b7baa0730 modem: expose location and last-change in operational state
Cellular modem location data (GPS coordinates, 3GPP cell info) was
previously CLI-only — 'show modem modem0' shelled out to modem-info
which queried mmcli on demand and rendered straight to terminal.
NETCONF/RESTCONF clients had no view into modem location, and there
was no way to tell how stale any modem-state field was.

This commit moves both into the YANG operational tree so they are
accessible through every northbound interface, not just the CLI.  It
is Phase 1 of the modem GPS / location integration plan; Phase 2 will
route the modem's NMEA TTY into the existing gpsd → chronyd pipeline
so cellular modems can also serve as an NTP fallback time source.

YANG (infix-hardware.yang, revision 2026-05-10):
  - modem-state/last-change (yang:date-and-time): freshness indicator
    for the modem-state subtree, bumped on each modemd poll cycle
  - modem-state/location-state container: source (gps|3gpp|...),
    latitude/longitude/altitude (decimal64 6/6/1 fraction-digits),
    cell-id/lac/tac/mcc/mnc, and its own last-change

Runtime path:
  - modemd's check_location() now writes
    /run/modemd/modemN/location/data.json with the full location data
    plus an RFC3339 last-change.  Atomic via tmp+rename.  Walks the
    mmcli output once instead of twice.
  - check() touches /run/modemd/modemN/state.json with a fresh
    last-change after each successful state poll.
  - yanger/infix_modem.py reads both files via HOST.read_json and
    folds them into the modem-state operational subtree.
  - cli_pretty show_modem_detail rewritten to consume the operational
    tree (same path as 'show modem' overview), with new 'Last Update'
    lines for both top-level state and location.
  - bin/show/modem() consolidated: both 'show modem' and
    'show modem REF' use get_json('/ietf-hardware:hardware') — no
    more direct modem-info subprocess call.

Cleanup along the way:
  - Removed the legacy /run/modemd/modemN/location/{up,down,disabled,
    failed} marker file writes — they had no readers anywhere in the
    tree.  In-memory self.location['state'] is kept purely as the
    edge-trigger for the 'Retrieved GPS location' log line.
  - Aligned now_rfc3339() output with yanger.common.YangDate (+00:00
    form, not Z) so consumers see one consistent yang:date-and-time
    format regardless of producer.
  - Fixed multi-modem SIM scoping in show_modem_detail: now derives
    sim<N> from modem<N> instead of picking the first SIM globally.

The bearer / hardware-revision / phone-number / supported-carrier
sections of 'show modem REF' are deliberately omitted for now —
those fields are not yet in the YANG tree.  Bearer details in
particular likely belong on the wwan interface
(ietf-interfaces:interfaces-state) rather than on the modem hardware
component, and can be addressed in a follow-up.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-07 20:51:02 +02:00
Joachim Wiberg f41898d325 modemd: add SIGHUP handler for config reload
On SIGHUP, modemd stops all ModemThreads, re-runs sim-setup, then
restarts the modem threads from fresh sysrepo config.  The pidfile is
touched with os.utime() once the reload is complete, satisfying Finit's
default pidfile-based notify so confd can signal a reload and wait for
it to finish before proceeding.

This allows operator and APN changes to take effect without a full
daemon restart.

Also extract start_modem_threads() to remove the duplicated thread
startup loop shared between initial startup and reload, and align
sighandler() to use isinstance(th, ModemThread) consistently with the
rest of the thread-management code.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-07 20:51:02 +02:00
Joachim Wiberg 1168c6c8e2 modemd: package Python scripts for compiled deployment
Python scripts without a .py extension are never cached as bytecode by
CPython — every invocation re-parses the source.  Packaging as a wheel
pre-compiles all modules to .pyc and installs thin import stubs as the
executables, matching the approach used by bin/show and statd.

Restructure the modemd Python scripts into a proper Python package
(src/modemd/modemd/): each script becomes a module with a main() entry
point.  pyproject.toml declares 11 entry points; the Buildroot
MODEMD_BUILD_PYTHON hook builds a wheel via PEP 517, then pyinstaller.py
installs compiled stubs to /usr/libexec/modemd/ and pre-compiled .pyc
modules to site-packages.

/sbin/modemd is now a symlink to the compiled stub.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-07 20:51:01 +02:00
Joachim Wiberg f78f161dbe modem: migrate from infix-modem to ietf-hardware/ietf-interfaces
The initial modem import used a standalone infix-modem YANG module with
an integer-indexed list under /infix-modem:modems carrying a bearer
config mixed in with hardware config.  Infix has adopted the ietf-hardware
model to allow for a clearer separation of concerns, this commit aims to
improve on that situation by refactoring the modem model to use the same
architectural pattern already used for WiFi radios, GPS receivers, and
USB ports:

Hardware:
    /ietf-hardware:hardware/component[class=infix-hardware:modem]
    /ietf-hardware:hardware/component[class=infix-hardware:sim]
Interface:
    /ietf-interfaces:interfaces/interface[type=infix-if-type:modem]

Configuration split:
  modem component — admin-state (enable/disable), radio access mode,
                    frequency bands, location services, probe-timeout
  sim component   — PIN, PUK, carrier profile
  wwan interface  — APN, IP type, roaming, route-preference, auth

This also enables the modem to appear in 'show hardware' alongside
other hardware components, and to be managed over NETCONF/RESTCONF
using the same ietf-hardware RPCs used for USB and WiFi.

YANG changes:
  - infix-modem.yang removed (1089 lines, standalone module)
  - infix-hardware.yang: new modem and sim containers, modem-state and
    sim-state operational state, typedefs for bands/modes/location,
    notification status-update; actions restart/reset/send-sms are
    augmented directly on the component list entry (not inside container
    modem) to work around sysrepo NP-container parent validation — when
    checking a nested action's parent, sysrepo restricts its operational
    data fetch to the container path, excluding the sibling 'class' leaf
    needed to evaluate the container's 'when' condition, so the container
    is never instantiated and the parent check fails
  - infix-if-modem.yang: new submodule (same pattern as wifi/wireguard)
    adds the wwan bearer container to ietf-interfaces
  - infix-if-type.yang: new modem identity for wwan interface type
  - confd version bumped to 1.9

confd:
  - if-modem.c: new file replaces the stub modem_gen() in modem.c;
    generates dagger init scripts with probe-timeout wait loop and
    unconditional dummy wwan creation so downstream IP config succeeds
    when a USB modem is slow to enumerate at boot
  - hardware.c: start/stop/enable/disable modemd (and modem-manager)
    in response to admin-state changes on the modem hardware component;
    use finit_enable/disable consistently
  - hardware_cand_infer_class(): auto-set class for modemN/simN names
  - modem.c: stripped to RPC/notification forwarding only; the old
    genconf() / enable() / disable() logic is gone — hardware.c owns
    the lifecycle now
  - interfaces.c: remove wwan from wait-interface timeout (the modem
    interface appearance is managed by modemd, not confd's init scripts)
  - migrate/1.9: script fully migrates /infix-modem:modems to the new
    split model; each modem[N] becomes a modemN hardware component and
    simN sim component; each bearer becomes a wwanN interface (bearers
    numbered globally across modems); APN, IP type, roaming, preferred-
    mode, bands, location, PIN/PUK/carrier are all carried over; plain-
    text bearer credentials are moved to a named keystore symmetric-key
    (base64-encoded) referenced from bearer/authentication/password;
    apn-type, firewall-enabled, dns-enabled and default-route are
    dropped (no equivalent in the new model)

modemd:
  - load_config() replaces the infix-modem sysrepocfg call; reads from
    ietf-hardware (modem/sim config), ietf-interfaces (bearer config),
    and ietf-keystore (credentials) — three standard modules instead of
    one proprietary one; modems absent from sysrepo config but present
    in system.json are still started (physical detection wins)
  - Default route written to /etc/net.d/<iface>.conf (picked up by
    netd/staticd/zebra) instead of a direct 'ip route add'; routes are
    now visible to FRR for redistribution and metric-based failover
  - Addresses tagged with proto wwan (rt_addrprotos entry 7) for
    precise flush on disconnect without touching other address sources
  - _derive_gateway() handles point-to-point bearers where modem
    reports gateway as "--"; derives peer from link-scope subnet route
  - SimThread exits cleanly on platforms without /dev/simctrl
  - sim-setup, modem-info, modem-udev, modem-rpc, modem-sms all ported
    to the ietf-hardware/ietf-interfaces namespace

statd:
  - infix_modem.py now emits modem-state and sim-state into ietf-hardware
    component entries (modem0, sim0, ...) instead of a separate tree;
    sim-state reports physical slot, lock state, and SIM operator name
  - ietf_hardware.py: hardware component names deduplicated by rename
    (cpu → cpu, cpu1, ...) to prevent LY_EVALID when hwmon and thermal
    sysfs both normalise to the same sensor name
  - show hardware: Cellular Modems and SIM Cards tables added; sensor
    table width now adapts to the widest section in the output
  - 00-probe: USB modem detection writes to system.json["modem"], same
    source as wifi-radios, feeding gen-hardware which emits the
    ietf-hardware component entries at factory config generation time

CLI:
  - 'show modem [ref]': without ref shows Cellular Modems and SIM Cards
    tables (same data subset as 'show hardware'); with ref shows a full
    per-modem dump (hardware info, status, cellular, SIM, bearers, GPS)
  - 'modem restart <ref>': disconnect and reconnect all bearers without
    a full hardware reset
  - 'modem reset <ref>': factory-reset the modem firmware
  - 'modem sms <ref> <number> <message>': send an SMS via the modem
    (uses the signalling plane; no active data bearer required)
  - MODEMS PTYPE provides tab-completion reading modem names from
    /run/system.json

doc:
  - Add initial User Guide for modems
  - Update ChangeLog with modem news
  - Use absolute URLs in ChangeLog.  Relative links only work for in-tree
    references, not in release notes

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-07 20:50:58 +02:00
Joachim Wiberg f0dfc6a8de test: skip defconfig backup files at find time, not mid-loop
defconfig.sh used $# (find result, incl. *~ / *.bak) for the TAP total
but then 'continue'd past backups without decrementing — so a stray
bpi_r4_*_defconfig~ in the tree made TAP see "1..23" followed by only 21
results, and the harness treated the missing 2 as failures.  Filter the
patterns at find instead; $# now matches what the loop iterates over

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-07 20:50:29 +02:00
Joachim Wiberg ffe5ed1e32 statd, show: fix several operational data reporting bugs
Three bugs found while testing modem support on hardware:

ietf_system.py: "interface": null written to DNS server entries when
  no interface is associated, causing LY_EVALID in the ietf-system
  schema validator.  Only include the key when the interface name is
  non-empty.

ietf_system.py: empty list inserts (user [], server [], options [],
  search []) overwrote configured data in the operational store instead
  of leaving it intact.  Guard each insert so operational data only
  shadows configured data when there is something to report.

show system: CPU temperature reported only the first sensor named
  exactly "cpu", "soc", or "core".  Platforms with multiple thermal
  zones (e.g. BPI-R4 exposes cpu and cpu1) always showed only one
  reading.  Collect all sensors whose name matches a CPU/SoC prefix
  and report the maximum.

statd.c: yanger parse errors logged without model name or libyang
  error string, making failures hard to diagnose.  Include both.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-07 20:50:29 +02:00
Joachim Wiberg 314b0b425f Add cellular modem support via modemd daemon
Integrates the modem management subsystem, donated by Avvero Pty Ltd,
adapted to work on any platform without proprietary hardware (simctrl,
modules.json, /sys/class/sim/).

Components:
- package/feature-modem: Buildroot feature package pulling in modemd,
  ModemManager, libmbim, libqmi, and USB serial/MBIM/QMI kernel drivers
- package/modemd: Buildroot package for the modemd daemon and helpers
- src/modemd: modem management daemon — detects modems via ModemManager,
  connects bearers, configures IP addresses, handles SMS and location
- src/confd/src/modem.c: confd plugin — enables/disables modemd and
  modem-manager via sysrepo, forwards RPCs (restart/reset/send-sms)
- src/confd/src/interfaces.{c,h}: IFT_MODEM type for wwan* interfaces;
  confd manages address/route assignment, modem daemon owns link state
- src/confd/yang/confd/infix-modem.yang: YANG model for modem config and
  operational state (bearers, APN, bands, modes, location, SMS)
- src/statd/python/yanger/infix_modem.py: operational state collector
- patches/modem-manager: upstream patches for udev install path,
  multiplexed interface naming, and MBIM port trust from udev hint
  (the last fixes Dell DW5811e / Sierra EM7455 on cold boot)
- patches/libqmi: ignore sysfs in download mode

Platform portability fixes for boards without simctrl hardware:
- modem-info: fall back to /run/modems.json when /run/modules.json is
  absent; discover wwan interfaces via sysfs scan; provide synthetic SIM
  entry when /sys/class/sim/ is not present; fix dbg() to respect flag
- modemd: make --set-allowed-modes=any best-effort (some modems only
  support one mode combination and reject any change); skip mode set
  when current mode already matches requested mode
- sim-setup: guard simctrl open, return None when modules.json absent
  to skip SIM slot switching entirely on non-simctrl hardware

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-07 20:50:28 +02:00
Joachim Wiberg 985b694e51 confd: fix debug mode regression
In the last major refactor of confd to a stand-alone daemon, new command
line options were added, one of which -v <LEVEL>.  Unfortunately opening
up for a few corner cases where the debug flag or the log_level was not
set properly.

This fixes that and also adds a CONFD_ARGS for /etc/default/confd, which
is customary for all daemons.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-07 20:50:28 +02:00
Joachim Wiberg 060e0ea284 board: some sim card help on the bpi-r4
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-07 20:50:28 +02:00
Joachim Wiberg 43bf6358a0 board: add USB2 component to bpi-r4 factory-config
The M.2 LTE slot uses the USB2 bus. Add it as an unlocked component so
the modem hardware is accessible and visible to users in the config.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-07 20:50:27 +02:00
Mattias WalströmandGitHub f4fd538a58 Merge pull request #1529 from kernelkit/wifi-followup
hostapd: Do not limit BSSID
2026-06-07 17:30:52 +02:00
Mattias Walström 5cdabe555f hostapd: Do not limit BSSID
hostapd limit hard what BSSID to use, this since hosatpd is desinged
to use radio-mac+n as default. We demand the user to select the MAC
address, if having multiple BSS.
2026-06-07 11:53:09 +02:00
Mattias Walström 60afb15488 Changelog: Add note about firewall changes
Enable NAT no longer enable forwarding on *all* interfaces.
2026-06-07 11:52:15 +02:00
Joachim WibergandGitHub ba010c0117 Merge pull request #1527 from kernelkit/wifi-roaming
Wi-Fi: Add mesh (802.11s) and roaming (802.11k,v,r)
2026-06-05 16:29:35 +02:00
Mattias Walström 61b5c8954d firewalld: Do not enable global ip_forward when enable masqurade
Infix controlls the ip_forwad (ipv4/ipv6) per interface, enable it
globally just mess things up.
2026-06-05 14:54:53 +02:00
Mattias Walström 40147a5265 Wi-Fi: Add configuration option to enable legacy rates
Normally you don't want this, but there may be cases with
stupid IoT devices. They are therefore disabled by default.
2026-06-05 14:54:53 +02:00
Mattias Walström be6cf4dcd5 Add new Wi-Fi features in Changelog 2026-06-05 14:54:53 +02:00
Mattias Walström bbea2bceae confd: wifi: Refactor to use one hostapd for all radios
This is how hostapd should be used, this enables real
band steering, since the daemon has knownledge about
all bands.
2026-06-05 14:54:53 +02:00
Mattias Walström 69fbf9e854 Document mesh and roaming 2026-06-05 14:54:53 +02:00
Mattias Walström 61d4325d2c Wi-Fi: Add support for mesh-point (802.11s) 2026-06-05 14:54:53 +02:00
Mattias Walström 44ade8b761 Wi-Fi: Add support for band steering 2026-06-05 14:54:50 +02:00
Mattias Walström 4e50c96567 Wi-Fi: Add roaming support (802.11k,v,r)
Useful feature if running multiple radios on single AP with
the same SSIDs or multiple APs to get good area coverage.
2026-06-05 14:54:35 +02:00
Joachim WibergandGitHub c0225b7096 Merge pull request #1528 from saba8814/fix/gh-action-node20-deprecation-warnings
Fix/gh action node20 deprecation warnings
2026-06-05 09:31:17 +02:00
Joachim WibergandGitHub c31c80c154 Merge pull request #1526 from kernelkit/test-action
test: infamy: add optional argument to rpc/actions
2026-06-05 09:25:45 +02:00
Ejub Sabic 91fc7466c2 fix: gh-action node 20 deprecation warnings
Resolves: #1519
Signed-off-by: Ejub Sabic <ejub1946@outlook.com>
2026-06-05 08:12:37 +02:00
Joachim Wiberg 5286c16480 test: infamy: add optional argument to rpc/actions
For example setting DUT date-time using ietf-system RPC.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-04 13:35:02 +00:00
Mattias WalströmandGitHub fc7083dd86 Merge pull request #1525 from kernelkit/remove-put-config-dict
test: Remove function put_config_dict and convert tests to use put_config_dicts
2026-06-03 15:05:51 +02:00
Mattias Walström 8e5d49665b test: Remove function put_config_dict and convert tests to use put_config_dicts
This fix #1237
2026-06-02 16:59:28 +02:00
Tobias WaldekranzandGitHub 46fb3a061c Merge pull request #1522 from kernelkit/kernel-upgrade-7e6339d1-6e5d-4575-9a42-e3a332ca8165
Upgrade to kernel 6.18.34
2026-06-02 07:59:36 +02:00
ael-bot 74dcd5889f Upgrade Linux kernel to 6.18.34 2026-06-01 17:06:17 +00:00
Joachim WibergandGitHub 9a2f143d31 Merge pull request #1518 from kernelkit/releng
Prepare for v26.05.0
2026-05-29 10:24:27 +02:00
Joachim Wiberg 76cc1e8061 Update ChangeLog for v26.05.0 release
[skip ci]

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-29 10:18:56 +02:00
Joachim Wiberg 762915b703 doc: restyle mkdocs site after Chirpy blog theme
Material's defaults (Roboto, bluish slate dark mode) looked dull next
to the Chirpy-based kernelkit.org blog. Match its typography and colors
via extra.css, no engine change:

- Lato headings + Source Sans 3 body + system monospace for code
- Dark mode: neutral near-black background, soft-gray text, darker code
  blocks, Chirpy blue links (replacing Material's high-contrast slate)
- Light mode: warmer body text, blue links, tinted sidebars
- Keep the orange brand on the masthead; links use Chirpy blue

Set theme.font: false so Material no longer also fetches Roboto.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-29 10:07:56 +02:00
Joachim Wiberg 5fd5d1254a doc: fix missing images in test system arch.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-29 10:07:52 +02:00
Joachim WibergandGitHub 1012759a41 Merge pull request #1495 from kernelkit/speed-duplex 2026-05-27 23:40:29 +02:00
Joachim Wiberg 925a43dead cli: add 'show operational [path /X]' and path filter to config views
Extend the existing 'show <running|startup|factory>-config' family with an
optional 'path /XPATH' argument that maps straight to the underlying 'copy
-x' flag, and add 'show operational [path /XPATH]' for symmetry with the
configuration datastores.

  admin@example:/> show running-config path /ietf-interfaces:interfaces
  admin@example:/> show operational path /ietf-system:system-state

Also, improve error feedback from the copy command slightly.

Before:
  admin@example:~$ copy running -x /foo
  Error: (null) (5)
  Error: failed retrieving running-config data

After:
  admin@example:~$ copy running -x /foo
  Error: Couldn't parse path "/foo": Prefix "foo" not defined. (5)
  Error: failed retrieving running-config data

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-27 20:53:31 +02:00
Joachim Wiberg 6958c9bb1a show: relay cli-pretty's user-facing error messages
cli-pretty prints a friendly message on stdout before any sys.exit(1)
— 'Interface "w" not found', 'Error, top level "ietf-routing:routing"
missing', etc.  The wrapper used subprocess.run(..., check=True) and
on non-zero exit caught CalledProcessError, throwing away the captured
stdout and printing the generic exception message instead.

Drop the check=True / try-except dance, always relay stdout, and only
fall back to the generic 'Error running cli-pretty' line when the
subprocess crashed without producing any output.

Before:
  admin@bpi:/> show interface w
  Error running cli-pretty: Command '['/usr/libexec/statd/cli-pretty',
  'show-interfaces', '-n', 'w']' returned non-zero exit status 1.

After:
  admin@bpi:/> show interface w
  Interface "w" not found

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-27 20:53:31 +02:00
Joachim Wiberg 65eb4c072a cli: tighten 'show interface' detail-view alignment
The Ethernet packet/RMON counters at the bottom of 'show interface
<name>' were appended with a wider label column than the operational
data above them, breaking visual alignment.  Group them under an
"Ethernet Statistics" section heading (Decore.title), same convention
as 'Available Networks' in the wifi scan view.

Narrow the operational-data label column from 20 to 19 chars so the
title bar exactly matches the heading text — a tighter and more
deliberately aligned look.  All labels in pr_iface fit within 19
chars except 'lacp system priority' (20); rename it to 'lacp sys
priority' for consistency with the other 'lacp ...' labels (lacp
aggregate id, lacp partner mac, ...) so the new field width works
universally.

Refresh CLI snapshots and doc samples to match.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-27 20:53:30 +02:00
Joachim Wiberg c3d17586fd doc: add vlan.md, update ChangeLog for the branch
Fix #1506: restore the VLAN interface documentation that was lost when
networking.md was split into per-topic pages.  Content adapted from the
v25.11.0 networking.md VLAN section, plus a new "Stacked (Q-in-Q)"
section showing `eth0.10.20`-style nesting and the layered `show
interface` rendering of the parent chain.

Update the interface-type table in networking.md to point at the new
vlan.md instead of the dangling ethernet.md#vlan-interfaces anchor.

ChangeLog: document the user-facing changes on this branch (YANG model
upgrade, layered show interface output, auto-negotation typo fix) and
the new VLAN documentation.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-27 20:53:30 +02:00
Joachim Wiberg 4c17a79de6 doc: refresh show interface samples and rename plural form
Update CLI samples across the documentation to the new layered
presentation: physical-medium row when linked (1000baseT/...), bare
MACs, and key: value DATA tokens.  Add a short prose block in
ethernet.md and iface.md explaining the layering.

Drop the historical 'show interfaces' (plural) form — removed from
klish years ago — from all user-facing examples and the landing page.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-27 20:53:29 +02:00
Joachim Wiberg 7fa141178f cli: layered show interface, IEEE 802.3.2-2025 ethernet model
Import ieee802-ethernet-interface@2025-09-10.yang, from IEEE 802.3.2-2025,
and companion ieee802-ethernet-phy-type.yang, replacing the 2019 revision.
Operational interface speed moves to ietf-interfaces:speed, RFC 8343,
eth:speed is now obsolete.  Bump infix-interfaces.yang revision to track
the upgrade.

The CLI 'show interface' command renders interfaces as bottom-up layered
protocol rows.  Ethernet interfaces a new IEEE link-mode row (1000baseT,
10GbaseLR, ...) is added with 'duplex: full|half' in the DATA column.
Without link the ethernet row is the first row.  Tunnels and wifi follow
the same layering: gre/vxlan rows carry remote:/vni: tokens with optional
ethernet sub-row for the L2-bearing variants; wifi rows carry 'station' or
'access-point' ssid:, signal:, stations: tokens.

admin@bpi-76-8f-c2:/> show interface
⚑ INTERFACE   PROTOCOL      STATE       DATA
⇅ lo          loopback      UP
              ipv4                      127.0.0.1/8 (static)
              ipv6                      ::1/128 (static)
⇅ br0         bridge        DOWN
  │           ethernet                  32:2e:3f:76:8f:c2
  │           ipv4                      192.168.0.1/24 (static)
⇅ ├ lan0      bridge        LOWER-DOWN
⇅ ├ lan1      bridge        LOWER-DOWN
⇅ ├ lan2      bridge        LOWER-DOWN
⇅ └ lan3      bridge        LOWER-DOWN
⇅ gre0        gre           UP          remote: 198.51.100.7
              ipv4                      10.255.0.1/30 (static)
⇅ sfp1        ethernet      DOWN        ca:59:f0:77:80:5b
⇅ wan         1000baseT     UP          duplex: full
              ethernet                  32:2e:3f:76:8f:c2
              ipv4                      192.168.0.235/24 (dhcp)
              ipv6                      fe80::302e:3fff:fe76:8fc2/64 (link-layer)
⇅ wan.10      vlan          UP          vid: 10
  │           ipv4                      10.0.10.1/24 (static)
  └ wan
⇅ wan.10.20   vlan          UP          vid: 20
  │           ipv4                      10.0.10.20/28 (static)
  └ wan.10
⇅ wifi0       wifi          UP          station ssid: corp-net signal: good
              ethernet                  dc:a6:32:00:11:22
              ipv4                      192.168.7.42/24 (dhcp)

yanger populates phy-type and pmd-type from a static ETHTOOL link-mode
identity table keyed on (port, speed, duplex).  Both leaves are populated
for unambiguous media (copper, DAC, copper-T); for generic fiber where
the (port, speed, duplex) tuple can map to multiple PMDs (SR vs LR vs
ER, etc.) only the phy-type family identity is emitted — guessing the
PMD would be misleading.  cli_pretty prefers pmd-type (specific) and
falls back to phy-type (family) for display.

yanger also emits ietf-interfaces:speed and fixes a long-standing
'auto-negotation' typo (yanger had never matched ethtool's correctly-
spelled JSON field, so operational auto-negotiation always read
'unknown').

Filling the WG's gap on fixed-speed config
------------------------------------------

IEEE Std 802.3.2-2025 obsoleted the eth:speed leaf without providing a
config-true replacement; the standards-correct way to express what
older Infix configurations called 'fixed speed' is to restrict the set
of PMDs auto-negotiation may advertise.  Augment auto-negotiation with
two leaf-lists:

  auto-negotiation/advertised-pmd-types  config-true,  leaf-list of pmd-type
  ethernet/supported-pmd-types           config-false, leaf-list of pmd-type

Pinning a port to a single mode is now expressed as a single-entry
advertised-pmd-types list.  The kernel-supported set is exposed as
operational state for diagnosis — SFP/SFP+ cages report the inserted
module's capabilities, narrowing the list to a single PMD when the
optic only supports one mode (as suggested by @wkz in PR review).
When the supported list collapses to a single entry, yanger uses it
to refine the operational pmd-type leaf — more accurate than the
(port, speed, duplex) lookup for fiber.

confd C apply path (src/confd/src/ieee802-ethernet-interface.c)
translates each advertised pmd-type identity to the corresponding
ETHTOOL_LINK_MODE_*_BIT_*, ORs them into a mask, and emits
'ethtool --change <if> autoneg on advertise 0x<mask>'.  An empty
list keeps the historical default of advertising every supported
mode.  The (legacy) 'auto-negotiation/enable = false' + speed/duplex
branch is removed — it has no model representation any more.

cli_pretty's detail view gains 'advertised' and 'supported' rows
listing the PMDs in each set.  A new _pr_label_list() helper unifies
multi-row rendering across these new rows and the pre-existing
ipv4/ipv6 address rows.

The detailed interface view also gains a 'link mode' row carrying the
pmd-type / phy-type-derived label.

Migration of existing startup configurations
--------------------------------------------

Bump confd version 1.8 → 1.9 to trigger the migration on upgrade.
share/migrate/1.9/10-ethernet-advertise.sh translates old configs of
the form

  ethernet { auto-negotiation { enable false; } speed S; duplex D; }

into

  ethernet { auto-negotiation { advertised-pmd-types [PMD]; } duplex D; }

mapping (S, D) → PMD via a static lookup covering the copper-T speeds
the deprecated speed leaf historically supported (10/100/1000/2.5G/
5G/10G).  Interfaces that don't disable auto-negotiation, or that
lack a speed leaf, are passed through untouched.

Closes #530
Closes #805

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-27 20:53:29 +02:00
Mattias WalströmandGitHub f7236fd59c Merge pull request #1517 from kernelkit/yanger-fix 2026-05-26 22:21:04 +02:00
Mattias Walström aecb4546f8 yanger: expand VLAN ranges from bridge global output
bridge -j vlan global show can return VLAN ranges as
{"vlan": 1, "vlanEnd": 3} instead of individual entries.
The vlans dict was only keyed on the start value, causing
port VLANs 2 and 3 to be reported as "Unexpected".

Also fix typo in error message (brpvlans -> brpvlan).
2026-05-26 17:19:42 +02:00
Joachim WibergandGitHub 9b0837100c Merge pull request #1516 from kernelkit/bump-buildroot
Bump buildroot to 2025.02.14
2026-05-25 17:10:04 +02:00
Mattias Walström b650d91895 Bump buildroot to 2025.02.14
Just a lot of CVE fixes, full changelog:
https://github.com/buildroot/buildroot/blob/2025.02.x/CHANGES
2026-05-25 11:02:36 +02:00
Joachim WibergandGitHub 68e4dc3e9b Merge pull request #1514 from kernelkit/kernel-upgrade-668755b5-46cf-4c96-aff5-d1eea93ea004
Upgrade to kernel 6.18.33
2026-05-23 20:04:14 +02:00
ael-bot e8f14e1a06 Upgrade Linux kernel to 6.18.33 2026-05-23 16:23:53 +00:00
Joachim WibergandGitHub 230bd77623 Merge pull request #1513 from kernelkit/acer-license
Add missing license for new board
2026-05-23 18:10:07 +02:00
Joachim Wiberg 0bc998c24a board/aarch64: add missing license for new board
[skip ci]

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-23 16:05:10 +00:00
Joachim WibergandGitHub 6618bcdf1e Merge pull request #1511 from kernelkit/refactor-confd-deps
Refactor confd deps
2026-05-23 14:59:20 +02:00
Mattias Walström cf4de78d29 confd: move dhcp-client hostname dependency to core tracker
Move the hostname-triggers-dhcp-client logic from dhcp-client.c into
the centralized dep_hostname() dependency tracker.  When the hostname
changes, all interfaces with DHCP client configured are now added to
the diff by the core dependency resolver, so dhcp_client_change() picks
them up through its normal diff-based interface iteration.
2026-05-22 16:20:45 +02:00
Mattias Walström 555de63fd6 confd: add wireguard key dependency tracking
When keystore keys change, trigger regeneration of wireguard
interfaces that reference them:

 - Asymmetric key change: triggers interfaces using it as private-key
 - Symmetric key change: triggers interfaces using it as preshared-key
   (both at peers bag-level and individual peer-level)
2026-05-22 16:20:45 +02:00
Mattias Walström 9d4d521fa2 confd: split handle_dependencies() into focused helpers
Extract the monolithic handle_dependencies() into five smaller
functions, each handling one dependency type:

 - dep_symmetric_keys()    - key -> wifi secret
 - dep_asymmetric_keys()   - key -> ssh hostkey/web cert
 - dep_hostname()          - hostname -> dhcp-server/mdns
 - dep_wifi_interfaces()   - interface wifi -> radio hardware
 - dep_radio_components()  - radio hardware -> interface wifi

Also fixes a potential NULL dereference of dwifi before accessing
its access-point child, and removes redundant NULL checks for
YANG-guaranteed mandatory leaves (list keys, mandatory true).
2026-05-22 16:20:25 +02:00
Mattias WalströmandGitHub e994d976ff Merge pull request #1510 from kernelkit/fix-acer-connect
aarch64: board: Acer Connect Vero rename board
2026-05-20 12:50:16 +02:00
Mattias Walström 3fdbe15585 aarch64: board: Acer Connect Vero rename board
Fix so the board actually build when selected and rename the board
to the actual name `Acer Connect Vero W6m`
2026-05-20 11:19:12 +02:00
Tobias WaldekranzandGitHub eb2135bd15 Merge pull request #1509 from kernelkit/fix-flaky-container-tests
Fix operational get-data crash on containers with shell chars
2026-05-20 08:12:21 +02:00
Mattias WalströmandGitHub 5cf180b4d7 Merge pull request #1507 from kernelkit/add-vero
Add Acer Connect Vero W6m support
2026-05-19 20:10:37 +02:00
Richard Alpe bcc2df7e20 statd: yanger: stop overwriting infix-containers 'command' leaf
The 'command' leaf is config, with a strict pattern that doesn't allow
'&', quotes or pipes.  Yanger was populating it from podman's full,
untruncated container command -- so any container whose entrypoint
uses shell metacharacters (e.g. sh -c "... && ...") failed YANG
validation.

The symptom: every operational read of /infix-containers:containers
returns SR_ERR_INTERNAL, which in turn fails the whole get-data on
the operational datastore.  This breaks case/misc/operational_all and
any RESTCONF/NETCONF read that touches containers.

This was introduced in 59028c4 ("Fix #1466: 'show container' shows no
output"), which added the operational, pattern-less 'cmdline' leaf
but left the old 'command' assignment in place.  Drop it -- 'cmdline'
already carries the full command line, and 'command' belongs to
running config.

Note: the failure can look intermittent across test runs because
podman storage is persistent.  It only triggers once a container with
a bad-pattern command ends up in 'podman ps -a', including stale or
exited leftovers from earlier runs.

Signed-off-by: Richard Alpe <richard@bit42.se>
2026-05-19 19:49:29 +02:00
Mattias Walström 02a5079c6a doc: Changelog: Update with channel-width and the Acer Connect Vero W6m 2026-05-19 15:51:20 +02:00
Mattias Walström f39e62fdb1 feature-wifi: Only install files in romfs if enabled
Move from board romfs directory, to inside feature-wifi
2026-05-19 15:51:20 +02:00
Mattias Walström 87c2d3fc77 CI: Refactor build-image workflow
Reduce the number of duplication and try to simplify the flow.
2026-05-19 13:45:25 +02:00
Mattias WalströmandGitHub ab3594e124 Merge pull request #1508 from kernelkit/kernel-upgrade-c22791e9-8a8a-4420-a254-a84c8b6395ae
Upgrade to kernel 6.18.32
2026-05-19 13:40:06 +02:00
ael-bot 01cb60d125 Upgrade Linux kernel to 6.18.32 2026-05-19 07:01:40 +00:00
Mattias Walström 0c35a90841 doc: wifi: Document channel-width and security mode auto 2026-05-19 06:38:32 +02:00
Mattias Walström bfbf08943b mt7986: Add Acer Connect Vero w6 2026-05-19 06:38:32 +02:00
Mattias Walström 21fd80a71d confd: wifi: Fix WiFi 6E support
Was not correct handled before, a few assumptions was made,
but did not work in reality.

* Fix correct channels for WiFi 6E
* Add missing parameters required for 6ghz to work
2026-05-18 21:52:22 +02:00
Mattias Walström 64819075d5 WiFi: Add support for setting channel width 2026-05-18 09:27:03 +02:00
Joachim WibergandGitHub 2885112da8 Merge pull request #1502 from kernelkit/upgrade-frr
Upgrade FRR to 10.5.4

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-18 03:06:30 +02:00
Mattias Walström 48a1df4c67 confd: yang: Put some limits on custom mac addresses
Not correct MAC address for example multicast bit set,
caused `ip` to exit with failure code, resulting in
that configuration was not applied.
2026-05-17 18:27:45 +02:00
Mattias Walström ed6171f920 Upgrade FRR to 10.5.4
Summary of Changes:

bfdd:
    - cap IPv6 echo reflection to declared length
    - account for FP offset in echo length checks
    - fix recv errno filter logic in a few places
    - tighten SBFD reflector packet sanity checks
    - gate IPv6 echo reflection on known sessions
    - tighten auth header parsing skeleton
    - validate control packet length before session lookup

bgpd:
    - Fix memleak when configuring rd
    - Validate if NHC BGPID TLV value is non-zero
    - Avoid having a dangling pointer after we free NHC attribute
    - Check if BGPID NHC TLV exists when IPv6 next-hop is link-local
    - Do not allocate NHC TLV with an extra trailer
    - migrate timers during peer_xfer_conn to fix stale route cleanup
    - honor 'no activate' for dynamic neighbors in peer-group
    - Return immediately when dynamic capability action is not valid
    - Validate BGP role capability when handling it dynamically
    - fix neighbor IP comparison for IPv6 memcmp return values
    - Don't mark nexthop as changed if a set next-hop unchanged is applied
    - Return BGP_PEER_INTERNAL when first peer's as type is set to auto
    - Update peer sort cache when remote-as auto is used and AS number changed
    - Check dynamic capability action before validating ENHE capability
    - Do not allocate stream if route-refresh capability is not received
    - Move rpki strict check to bgp_accept()
    - Fix memory leak for nhc attribute if ipv6 is link-local address
    - Fix compilation for Debian 11 when printing uint64 values
    - Return zero labels if no BOS found and it's not a withdraw label
    - Fix signed overflow in hexstr2num()
    - Check the length also when parsing ENCAP attr sub-TLVs
    - Validate prefixlen before subtracting when parsing labeled unicast NLRI
    - Reset the stream to attr_start + attribute_len when WITHDRAWN
    - Revalidate locally originated routes against RPKI changes
    - Check if prefixlen is not 0 when parsing flowspec stuff
    - Prevent len_string going negative when trying to display flowspec entries
    - fix import vrf on non existing vrf
    - fix no vrf import command
    - Free hostname for FQDN capability if the parsing goes wrong
    - Validate MP_REACH_NLRI attribute against incorrect next-hop
    - Fix dynamic FQDN capability handling
    - Check if the remaining length for subtracting TLV length is enough
    - Fix the end pointer boundaries for dynamic graceful restart capability
    - Add missing returns when parsing enhanced route-refresh
    - Return original as-path when reconciling AS versus AS4
    - Do not process route-refresh for AFI/SAFI if it's not negotiated
    - Check if we are not overusing error_data buffer when unknown cap received
    - fix NHT for explicit link-local BGP peers
    - improve packet parsing for EVPN and ENCAP/VNC
    - Prevent heap use-after-free for tunnel encapsulation attribute
    - Return 0 if AS4 capability is malformed
    - close dynamic peer socket in ttl error path
    - fix logic handling EVPN_FLAG_DEFAULT_GW
    - avoid early return in MPLSVPN NLRI processing
    - remove unneeded asserts in packet reads

eigrpd:
    - fix byte order in Hello TLV decode functions
    - Handling for malformed update packets
    - enforce minimum TLV length in Hello handler
    - reject invalid prefix mask len
    - skip unknown and ignored TLVs
    - Improve packet validation

isisd:
    - Reject SRv6 Locator TLV with Loc-Size of zero
    - consume leftover bytes after FAD sub-sub-TLV loop
    - use correct min size values for srv6 subtlvs
    - improve validation of flex-algo decoder
    - Fix missing neighbor address Sub-TLVs after link-params change
    - add unit test for remove_excess_adjs() memory leak fix
    - fix memory leak in remove_excess_adjs()
    - fix edge condition in max_lsp_count computation

ldpd:
    - improve tlv validation in several places

lib:
    - Report IPv6 MTU and not IPv4 for if_update_state_mtu6
    - disable warning in zlog.c to match master

nhrpd:
    - stop debugging auth credentials
    - fix byte-order when comparing error code in shortcut path
    - guard against zbuf_pulln NULL on truncated packets
    - require auth for all received packet types
    - harden debug packet parsing against malformed input
    - validate AFI index in extension replies

ospf6d:
    - move log call out of priv block
    - remove asserts in packet-handling paths
    - fix issues in ospf6 auth trailer code

ospfd:
    - add LSA validation in the apiserver path
    - add validation in several places before accessing

pceplib:
    - validate during of_list TLV decoding

pimd:
    - fix NOCACHE MFC resync detection log, add vrf name too
    - use upstream-owned pim pointer in register and upstream timers
    - use upstream-owned pim pointer in MSDP update paths
    - avoid JP build deref through channel OIL
    - guard RP RPF-failure mroute delete on detached OIL
    - avoid null deref in upstream delete debug path
    - guard channel OIL detach against stale pointers
    - fix crash due to double free
    - Ensure igmp message is of proper size
    - Reject pim packets with a malformed header length
    - Fix out of bounds read in AutoRP code
    - igmpv3 never checks packet length and trusts the num-sources field
    - Do not allow a register-stop message if not received from the RP
    - Prevent received msg length from being larger than buffer
    - Remove unnecessary asserts
    - When receiving a register stop ensure we have enough data to read
    - Ensure a register packet has enough space to read S,G data
    - Ensure that header has space on packet

ripngd:
    - fix data handling in several places

tests:
    - Check if route-map with set nexthop unchanged does not prevent outgoing
    - Check if mixed peer-group remote-as types can be used with auto
    - Verify neighbor addr Sub-TLVs after link-params reset
    - Expect return code being 0, not -1 when AS4 is empty or ASN is 0

vrrpd:

    - replace some asserts
    - only support ethernet in GARP code
    - limit advertised timers to 12-bits

Signed-off-by: Mattias Walström <lazzer@gmail.com>
2026-05-16 20:56:56 +02:00
Joachim WibergandGitHub 689bd64b4d Merge pull request #1504 from kernelkit/kernel-upgrade-0ff65ffb-97d3-47f9-b02a-9328148ba88b
Upgrade to kernel 6.18.31
2026-05-16 10:29:49 +02:00
ael-bot dbdf5d9b78 Upgrade Linux kernel to 6.18.31 2026-05-16 06:06:55 +00:00
Joachim WibergandGitHub f13ee49f3c Merge pull request #1503 from kernelkit/kernel-upgrade-25c8ae89-19b4-443b-8ab6-78768210e119 2026-05-15 16:38:55 +02:00
ael-bot 1b34874d3d Upgrade Linux kernel to 6.18.30 2026-05-15 05:26:08 +00:00
Joachim WibergandGitHub 081491a380 Merge pull request #1500 from kernelkit/bump-9pm
Bump 9pm submodule
2026-05-12 14:50:40 +02:00
Joachim WibergandGitHub a19684c15c Merge pull request #1501 from kernelkit/misc
Misc
2026-05-12 14:47:33 +02:00
Joachim Wiberg f3183cd911 doc: update changelog
[skip ci]

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-12 13:39:18 +02:00
Joachim Wiberg e4203b0c9e package/finit: backport stale-pidfile and death-log fixes
Backport two fixes addressing a critical failure reported by a customer:
an unclean dbus-daemon exit leaves a lingering /run/messagebus.pid, the
daemon then refuse to start, and Finit's restart loop gives up.

0001 service: clean stale pidfile after unclean daemon exit
     Drop a daemon-owned (pid:!) pidfile when it still names the
     just-reaped PID and that PID is no longer alive.

0002 service: log signal name and core dumps in death message
     "by signal: 9" -> "killed by SIGKILL", with ", core dumped"
     when applicable.  Stronger breadcrumb for sudden deaths.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-12 13:38:49 +02:00
Joachim Wiberg 3be640409a confd: cache progress description and reprint on final status
The \r-overwrite of an in-progress line breaks when something else
writes to stderr between conout(3) and the final call, leaving blank
"[ OK ]" lines.  Cache the description and reprint it whole, so the
final status line is robust to intervening output.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-12 13:38:48 +02:00
Joachim Wiberg d393a10994 confd: skip neighbor/address flush for interfaces in container netns
When an interface has been handed off to a container it lives in
another netns, so `ip neigh/addr flush dev FOO` fails on the host.
The failure aborts dagger, and since interfaces_change() runs before
containers_change() in change_cb(), the container delete path is
never reached -- the stale container keeps the interface trapped in
its netns, breaking the next reconfiguration.

Guard both the neighbor and address flush exit scripts with
`if_nametoindex(ifname)` -- true exactly when the interface is in
the host netns, false for both "in a container" and "already gone".
This replaces the pre-existing `!cni_find(ifname) && if_nametoindex(
ifname)` guard at the addr site: cni_find() added no information
for this check and would popen(container find) for nothing when the
interface had been deleted entirely.

Also harden wrap() in /usr/sbin/container so a stale setup pidfile
doesn't short-circuit Finit's stop attempt -- kill the setup PID and
still ask podman to stop the container.

Fixes #1493

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-12 13:38:47 +02:00
Richard Alpe 5e6183eb4f Bump 9pm submodule
Signed-off-by: Richard Alpe <richard@bit42.se>
2026-05-12 11:49:45 +02:00
Mattias WalströmandGitHub 562435fac9 Merge pull request #1499 from kernelkit/kernel-upgrade-75b15a6e-2a9a-426d-acd1-6b77c0f9df19
Upgrade to kernel 6.18.29
2026-05-11 13:03:05 +02:00
ael-bot 21c070b928 Upgrade Linux kernel to 6.18.29 2026-05-11 07:13:25 +00:00
Joachim WibergandGitHub 23da086976 Merge pull request #1492 from kernelkit/kernel-upgrade-b951c1e9-f9f0-4f1f-be17-4ff16f7bb9c6
Upgrade to kernel 6.18.27
2026-05-09 10:04:12 +02:00
ael-bot 3c0c456bba Upgrade Linux kernel to 6.18.27 2026-05-07 06:22:32 +00:00
Mattias WalströmandGitHub f539da7e99 Merge pull request #1489 from kernelkit/disable-release-tests
Temporarily disable release regression tests
2026-05-04 10:05:45 +02:00
Joachim Wiberg 3a6e70ba26 .github: temporarily disable release regression tests
The regression tests do not pass for some reason, could be faulty test
runner (Lifeboat) -- container and DHCP tests failing since Apr 30), so
tests are disabled until the runner is fixed.

[skip ci]

Issue #1392

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-04 09:33:46 +02:00
Joachim WibergandGitHub 9406fd0e04 Merge pull request #1487 from kernelkit/releng 2026-04-30 18:53:48 +02:00
Joachim Wiberg 52ef3e2ded .github: set INFIX_RELEASE when running release tests
Without INFIX_RELEASE, make test resolves INFIX_ARTIFACT to the
unversioned infix-x86_64, but release builds produce versioned
artifacts (infix-x86_64-v26.04.0-rc1.qcow2 etc.), causing the
test environment to fail with "No such file or directory".

[skip ci]

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-30 18:34:35 +02:00
Joachim WibergandGitHub 3d1d73543e Merge pull request #1486 from kernelkit/release-tests
Run regression tests as part of release workflow
2026-04-30 16:08:51 +02:00
Tobias WaldekranzandGitHub 4c0996b52b Merge pull request #1483 from saba8814/fix/uboot-aux-env-first-var-import
fix: import first variable from auxiliary environment
2026-04-30 14:45:44 +02:00
Joachim Wiberg e49682645c .github: run regression tests as part of release workflow
Add an x86_64 regression test job to release.yml that runs after the
build and gates publishing — the release job now requires both build
and test to succeed.

Update test.yml's artifact restore step to use a glob so it handles
both the unversioned CI artifact name (infix-x86_64.tar.gz) and the
versioned release artifact name (infix-x86_64-26.04.0.tar.gz).

Fixes #1392

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-30 13:45:35 +02:00
Joachim WibergandGitHub a3c6ec0cd5 Merge pull request #1484 from kernelkit/releng
Release preparations
2026-04-30 13:14:04 +02:00
Joachim Wiberg 25fcfba0cb doc: update ChangeLog for v26.04.0 release
[skip ci]

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-30 11:08:02 +02:00
Joachim Wiberg 5defdfdeac doc: add section on dummy interfaces
Fixes #769

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-30 11:08:02 +02:00
Joachim Wiberg 624bfd927c doc: add section on static mutlicast filters
Fixes #790

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-30 11:08:01 +02:00
Joachim Wiberg 4d8b2e5370 confd: warn if multicast flooding is disabled
Fixes #520

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-30 11:08:01 +02:00
Joachim Wiberg 6aed1f7df4 confd: add support for static ARP and neighbor cache
Add support for static ARP (IPv4) and neighbor cache (IPv6) entries per
interface.  Static entries are installed as permanent kernel neighbor
table entries that are never evicted by normal ARP/NDP aging.

Fixes #819

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-30 11:08:00 +02:00
Joachim Wiberg 7dd746d586 Fix BPi-R64 onboard WiFi probing
The mt7622 soc has a built-in wmac, same driver as the mt7615, but
it lacked MODULE_DEVICE_TABLE() so udev could not autoload driver
and firmware.

This commit also adds the wmac+bluetooth specific firmware.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-30 11:07:31 +02:00
Joachim Wiberg b1ad0f1656 package/mcd: bump and add support for per-bridge mcast router ports
Fixes #395

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-30 11:02:56 +02:00
Ejub Sabic 29222e18e9 uboot: import first variable from auxiliary environment
The U-Boot env file is generated by
mkenvimage, which prefixes the variable data with a 4-byte CRC32 by default.
ixpreboot.sh previously imported it with `env import -b` as per uboot docs(-b assume binary format (’0’ separated, “00” terminated).),
which treats the buffer as raw binary and does not strip the CRC.
As a result the first variable's name is parsed a part of CRC.
Later variables import correctly because by then the parser is past the CRC.
Switching to `env import -c` as per uboot docs (-c assume checksum protected environment format.)
makes U-Boot validate and strip the CRC before parsing, so the first variable imports under its real name.

Tested on:
- QEMU

Signed-off-by: Ejub Sabic <ejub1946@outlook.com>
2026-04-29 23:27:37 +02:00
Joachim Wiberg f9ea5567c4 package/finit: bump to v4.17
https://github.com/finit-project/finit/releases/tag/4.17

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-29 17:33:14 +02:00
Joachim WibergandGitHub 413d8e4599 Merge pull request #1485 from kernelkit/bpi-r3-pcifixes
Bpi r3 pcifixes
2026-04-29 17:22:23 +02:00
Mattias Walström 507bb38bdc feature-wifi: Enable 802.11 mesh (802.11s) 2026-04-29 15:47:30 +02:00
Mattias Walström 5cb17d69d4 bpi-r3: Enable the PCI clock in device tree 2026-04-29 15:43:24 +02:00
Joachim WibergandGitHub 6c6dc7711e Merge pull request #1480 from saba8814/test/dhcp-client-hostname-not-resent
test & fix: add DHCPv4 client hostname resend regression test, fix  hostname resend
2026-04-28 19:46:47 +02:00
Ejub Sabic 4f2683090e doc: updated documentation for issue #1439
Signed-off-by: Ejub Sabic <ejub1946@outlook.com>
2026-04-28 18:06:49 +02:00
Ejub Sabic 08ca47fdab fix: dhcp client host name resend
Signed-off-by: Ejub Sabic <ejub1946@outlook.com>
2026-04-28 18:00:32 +02:00
Ejub Sabic 17965bf4cc test: add DHCPv4 client hostname resend regression test
Signed-off-by: Ejub Sabic <ejub1946@outlook.com>
2026-04-28 18:00:28 +02:00
Joachim WibergandGitHub 82ffb0f4bc Merge pull request #1481 from kernelkit/kernel-upgrade-28e7d3e7-b875-4444-a0ed-a6c18cefd76d
Upgrade to kernel 6.18.25
2026-04-28 12:39:25 +02:00
Joachim WibergandGitHub 2788eb6d1a Merge pull request #1482 from kernelkit/random-infamy-id-in-ci
test: avoid infamy0 race in CI by using random container names
2026-04-28 11:43:58 +02:00
Richard Alpe ba05c2e56d test: avoid infamy0 race in CI by using random container names
GitHub Actions sets $CI=true; treat it like -r so parallel jobs
don't all try to claim "infamy0" and clobber each other.
2026-04-28 10:06:04 +02:00
ael-bot c7cdf6b018 Upgrade Linux kernel to 6.18.25 2026-04-27 16:47:37 +00:00
Tobias WaldekranzandGitHub efa665de9c Merge pull request #1472 from kernelkit/gptp
ptp: initial support for IEEE 1588/802.1AS PTP/gPTP
2026-04-25 23:15:45 +02:00
Joachim Wiberg 4ece445c44 doc: update ChangeLog
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-24 14:30:09 +02:00
Joachim Wiberg e1e2ada4b4 confd: fix review comments and code cleanup
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-24 14:30:09 +02:00
Joachim Wiberg 95bd795347 test: add some basic ptp tests
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-24 14:29:58 +02:00
Joachim Wiberg 3426c2527b Add phc2sys companion service for BC/TC instances
On multi-chip DSA hardware (e.g., boards with multiple mv88e6xxx
chips), each switch chip has its own independent PHC device.  With
boundary_clock_jbod enabled, ptp4l starts but only disciplines the
active slave port's PHC — the others drift.

Automatically start phc2sys -a alongside any BC or TC instance using
hardware timestamping.  It subscribes to ptp4l's UDS socket, tracks
BMCA, and disciplines all non-active PHCs to match the active one.
On single-chip hardware it is a harmless no-op.

CLOCK_REALTIME is intentionally left untouched.  Syncing the system
clock to PTP (phc2sys -rr), feeding the PHC from GPS/NTP (ts2phc,
phc2sys reverse), and full multi-source coordination (timemaster) are
planned as follow-on phases; see the issue tracker for the roadmap.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-23 14:19:10 +02:00
Joachim Wiberg 45b06dd670 Initial support for IEEE 1588/802.1AS PTP/gPTP
Remaining work:
- phc2sys YANG model (infix-phc2sys.yang, instance-index + servo params)
- ts2phc YANG model (GPS/PPS → PHC → ptp4l GM path)
- timemaster coordination (Phase 3, after phc2sys YANG is stable)
- show ptp network (YANG action or background-polled topology container)
- CMLDS (requires upstream linuxptp + 802.1ASdm foundation)
- Full 12-bit sdoId, fault log, performance monitoring

Backported patches from linuxptp master:
- port: fix unicast negotiation recovery after FAULT_DETECTED
- udp: fix port-specific ptp/p2p_dst_ipv4 configuration
- pmc: avoid race conditions in agent update
- phc2sys: wait until pmc agent is subscribed (startup race)
- fix MAC driver incorrect SIOCGHWTSTAMP adjustment flags
- pmc_agent: longer update interval when not subscribed
- phc2sys: don't disable pmc agent with -s/-d/-w options
- port_signaling: respect ptp_minor_version in message header
- port: refresh link status on faults
- uds: copy server socket ownership in pmc clients (non-root pmc)
- uds: don't call chmod() on client socket
- port: allow mixing wildcard and exact clock identities
- Add pidfile support to ptp4l, phc2sys, and timemaster

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-23 14:19:09 +02:00
Joachim Wiberg 73b6e5cc91 patches/ethtool: backport support for --json -T (show time stamping)
This is used by the next commit that adds initial support for PTP/gPTP.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-23 14:19:09 +02:00
Joachim Wiberg b93795c0aa board/common: add rauc upgrade bundle for ext4 images
NOTE: this is intended only for use on devboards like EspressoBin where
      the onboard bootloader only understands fat and ext2 file systems.
      To enable, use 'make apply-ext4'

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-23 14:19:09 +02:00
Joachim Wiberg 5979f4e3c9 board/aarch64: fix bpi-r4 dip switch values
Inverted values for eMMC and SPI NAND.  Also use ABCD instead of
Position as column name to match board markings.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-23 14:19:08 +02:00
Joachim Wiberg 2397e7684c board/aarch64: drag Marvell ESPRESSObin in from the cold
- Add a board README to explain how to get Infix running
- Update mkimage.sh to allow creating images without boot loader

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-23 14:19:07 +02:00
Joachim WibergandGitHub 43d6dbc63f Merge pull request #1478 from kernelkit/upgrade-buildroot 2026-04-23 13:00:41 +02:00
Mattias Walström 8ebdf9f119 Upgrade Buildroot to 2025.02.13 (LTS)
A lot of CVEs fixed.

Full changelog: https://github.com/buildroot/buildroot/blob/2025.02.x/CHANGES

Signed-off-by: Mattias Walström <lazzer@gmail.com>
2026-04-23 10:44:43 +02:00
Mattias WalströmandGitHub 3aef9930fe Merge pull request #1479 from kernelkit/kernel-upgrade-39c18ac9-3f99-4a96-bc62-daf538881c51
Upgrade to kernel 6.18.24
2026-04-23 09:50:44 +02:00
ael-bot 3ea1161f5f Upgrade Linux kernel to 6.18.24 2026-04-23 05:42:15 +00:00
Joachim WibergandGitHub 091618c527 Merge pull request #1476 from kernelkit/misc
Fix two regressions and add developer build helpers
2026-04-22 16:27:47 +02:00
Joachim WibergandGitHub 7647d2a542 Merge pull request #1477 from kernelkit/cosmetic-test-name-changes
test: normalize test case names
2026-04-21 21:47:49 +02:00
Richard Alpe f996dbd6ef test: lowercase minor words in test case names
Signed-off-by: Richard Alpe <richard@bit42.se>
2026-04-21 14:20:58 +02:00
Richard Alpe ff02190df8 test: normalize suite/case names to title case
Signed-off-by: Richard Alpe <richard@bit42.se>
2026-04-21 11:06:59 +02:00
Richard Alpe c6f7b61683 test: add names to cases called from top level suite
Signed-off-by: Richard Alpe <richard@bit42.se>
2026-04-21 11:06:57 +02:00
Joachim Wiberg dbc3ba0c83 doc: update ChangeLog
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-20 13:03:29 +02:00
Joachim Wiberg d039af7234 Fix #1458: 'show ntp tracking' does not show reference id properly
admin@gateway:~$ chronyc tracking
Reference ID    : C23ACD14 (svl1.ntp.netnod.se)
Stratum         : 2
Ref time (UTC)  : Sun Apr 19 20:28:40 2026
System time     : 0.000000000 seconds fast of NTP time
Last offset     : -17.822519302 seconds
RMS offset      : 17.822519302 seconds
Frequency       : 1064.750 ppm slow
Residual freq   : +0.581 ppm
Skew            : 0.794 ppm
Root delay      : 0.018065268 seconds
Root dispersion : 0.000200240 seconds
Update interval : 0.0 seconds
Leap status     : Normal

vs

admin@gateway:/> show ntp tracking
Reference ID        : 194.58.205.20
Stratum             : 2
Ref time (UTC)      : Sun Apr 19 20:28:40 2026
System time         : 0.000000 seconds slow of NTP time
Last offset         : -17.822519302 seconds
RMS offset          : 17.822519302 seconds
Frequency           : 1064.750 ppm slow
Residual freq       : +0.581 ppm
Skew                : 0.794 ppm
Root delay          : 0.018065 seconds
Root dispersion     : 0.000188 seconds
Update interval     : 0.0 seconds
Leap status         : Normal

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-20 13:03:28 +02:00
Joachim Wiberg 59028c4800 Fix #1466: 'show container' shows no output
A container's command line, as reported by podman, may comtain environment
variables, which the current regexp (added in ed4fe58) does not support.

Extend the regexp to allow environment variables and add an operational,
config false, 'cmdline' leaf node to allow any characters to be reported
for the full command line in the operational output.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-20 13:02:37 +02:00
Joachim Wiberg 2603b0ea1b Add support for developer config snippets
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-19 22:31:15 +02:00
Joachim Wiberg 4212a38c3b .github: bump GitHub Actions to Node.js 24 compatible versions
Fixes #1437

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-19 22:31:15 +02:00
Joachim Wiberg bb72cfd8e3 doc: add missing image to device discovery section
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-19 22:31:14 +02:00
Joachim WibergandGitHub a06786d36c Merge pull request #1475 from kernelkit/kernel-upgrade-dfbe850e-9e05-4f30-b9b5-bd9399c6b718
Upgrade to kernel 6.18.23
2026-04-18 15:22:29 +02:00
ael-bot 16a173e20b Upgrade Linux kernel to 6.18.23 2026-04-18 10:07:02 +00:00
Mattias WalströmandGitHub 6c38666229 Merge pull request #1473 from kernelkit/add-qualcomm 2026-04-17 18:59:32 +02:00
Mattias Walström b940e14eb7 Add Qualcomm WiFi 6E support
And replace lspci from busybox with pci-utils (for all platforms
except arm (32bit).
2026-04-17 13:32:16 +02:00
Joachim WibergandGitHub 1774e08219 Merge pull request #1471 from kernelkit/kernel-upgrade-f52bac45-222b-4dda-86d4-50b617297422 2026-04-11 23:47:16 +02:00
ael-bot 5950e665ab Upgrade Linux kernel to 6.18.22 2026-04-11 13:23:07 +00:00
Joachim WibergandGitHub fadffef6cd Merge pull request #1470 from kernelkit/bpi-r4-support
Add support for Banana Pi BPI-R4
2026-04-10 14:05:07 +02:00
Joachim Wiberg 69d599e2ab board/aarch64: add missing mmc partconf command to BPi-R64 U-Boot
Also, simplify board README a bit now that we know that you don't need
to flip the boot switch to program eMMC.

[skip ci]

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-10 11:19:35 +02:00
Joachim Wiberg 6c879d81d1 configs/sama7g54: fix U-Boot build system selection
Missing BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y caused Buildroot to default
to legacy Makefile build system, which requires BR2_TARGET_UBOOT_BOARDNAME
instead of BR2_TARGET_UBOOT_BOARD_DEFCONFIG, resulting in a build error.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-10 11:19:35 +02:00
Joachim Wiberg e5b5b6203b legal: add missing hash files and fix date-cpp hash filename
Add missing *.hash files for all board packages using the ix-board macro;
they declare LICENSE_FILES = LICENSE but had no hash file, producing a
warning during make legal-info.

Fix the date-cpp package where the hash file was named date.hash instead
of date-cpp.hash (package name is derived from the directory, not the mk
filename), causing Buildroot to skip the hash check entirely.

Add hash files for local-site packages confd-test-mode, netd, and
onieprom that declared LICENSE_FILES but provided no hash.

Also, rename package/date-cpp/date.mk to date-cpp.mk.  Buildroot derives
the package name from the directory name, so the mk file must match. To
handle the archive name different we set DATE_CPP_SOURCE.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-10 11:19:34 +02:00
Joachim Wiberg 31df56308b board: add support for Banana Pi BPI-R4
Add board support for the BananaPi BPI-R4 router board, based on the
MediaTek MT7988A (Filogic 880) SoC with quad-core Cortex-A73 CPU.

The BPI-R4 is the successor to the BPI-R3 but uses entirely different
silicon: the internal switch runs at 2.5 GbE per port, the two SFP+
uplinks use native USXGMII at up to 10 Gbps, and WiFi is provided by
a MediaTek MT7996E PCIe module supporting tri-band WiFi 7 (2.4/5/6 GHz).

Two board variants, BPI-R4-2g5 and BPI-R4P, replace one SFP+ cage with
a 2.5 GbE RJ45 port (using the MT7988A internal 2.5G PHY); the R4P adds
an optional PoE daughterboard on that port.  Both use the upstream
mt7988a-bananapi-bpi-r4-2g5 device tree.

Interfaces:
- Standard R4:  eth1 (gmac1/sfp2 LAN cage) → sfp2, eth2 (gmac2/sfp1 WAN cage) → sfp1
- R4-2g5/R4P:  eth1 (2.5G PHY) → wan, eth2 (gmac2/sfp1 WAN cage) → sfp1

Factory reset / WPS button (GPIO14, active-low): detected by U-Boot at
boot for factory reset; reused by Linux as KEY_WPS_BUTTON at runtime.

eMMC install note: the MT7988A eMMC (pins 38-49) and SD card (pins 32-37)
use separate physical pads so there is no electrical bus sharing, unlike
some BPi-R3 configurations.  However, a single MMC controller
(mmc@11230000) handles both, so only one is active per boot session.
The eMMC install procedure therefore still requires an intermediate SPI
NAND bootloader step until a Linux-side install path is tested.

SD card build (bpi_r4_sd_boot_defconfig) now uses the new
mt7988a_bpir4_sd U-Boot defconfig with cap-sd-highspeed enabled,
giving 50 MHz SD transfers instead of the previous 25 MHz legacy mode.

Also adds MT7988/MT7996 firmware support to the buildroot linux-firmware
package, for 2.5 GbE port PHY and WiFi7 extension board, and updates the
aarch64_defconfig, aarch64_minimal_defconfig, the arch README, CI
boot/image workflows, mkimage.sh, and the ChangeLog.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-10 11:19:34 +02:00
Joachim WibergandGitHub 19c8c80294 Merge pull request #1468 from kernelkit/fix-rpi-display
linux: Fix stability of Raspberry pi display 1
2026-04-05 05:55:02 +02:00
Mattias Walström db422ecc5e Update Changelog for new release cycle 2026-04-04 20:04:43 +02:00
Mattias Walström 5b870a273e aarch64: dts: rpi-4: Add correct syntax to change GPU mem 2026-04-04 20:04:43 +02:00
Mattias Walström e29e2093ab linux: Fix stability of Raspberry pi display 1
This fix the instability of the display on soft reboots,
previous it required a powercycle to get display to work properly

Add patches from rpi-linux, and a small fixup from me.

Signed-off-by: Mattias Walström <lazzer@gmail.com>
2026-04-04 20:04:43 +02:00
Mattias WalströmandGitHub d5df85afad Merge pull request #1467 from kernelkit/kernel-upgrade-ab8a1129-6fcc-4662-a366-1f0a309d1c13 2026-04-02 18:29:25 +02:00
ael-bot 003aee9b53 Upgrade Linux kernel to 6.18.21 2026-04-02 11:57:37 +00:00
597 changed files with 40788 additions and 4397 deletions
+1 -1
View File
@@ -10,7 +10,7 @@ jobs:
name: Add issue to project Infix&co
runs-on: ubuntu-latest
steps:
- uses: actions/add-to-project@v1.0.2
- uses: actions/add-to-project@v2
with:
project-url: https://github.com/orgs/kernelkit/projects/3
github-token: ${{ secrets.ADD_TO_PROJECT }}
+3 -3
View File
@@ -16,7 +16,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Validate release version format
id: validate
@@ -170,7 +170,7 @@ jobs:
fi
- name: Upload signed artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: signed-infix-${{ steps.validate.outputs.file_version }}
path: ${{ steps.download_signed.outputs.signed_filename }}
@@ -212,4 +212,4 @@ jobs:
---
**Next Steps:** The signed release can now be distributed with cryptographic verification of authenticity.
EOF
EOF
+5 -3
View File
@@ -19,6 +19,8 @@ jobs:
- aarch64_qemu_boot
- bpi_r3_sd_boot
- bpi_r3_emmc_boot
- bpi_r4_sd_boot
- bpi_r4_emmc_boot
- bpi_r64_sd_boot
- bpi_r64_emmc_boot
- cn9130_crb_boot
@@ -39,7 +41,7 @@ jobs:
ls -la ./
- name: Checkout infix repo
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
ref: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.branch || github.ref }}
clean: true
@@ -94,7 +96,7 @@ jobs:
mv images ${{ steps.vars.outputs.dirname }}
tar cfz ${{ steps.vars.outputs.archive }} ${{ steps.vars.outputs.dirname }}/
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
with:
path: output/${{ steps.vars.outputs.archive }}
name: artifact-${{ matrix.defconfig }}
@@ -106,7 +108,7 @@ jobs:
permissions:
contents: write
steps:
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v8
with:
pattern: "artifact-*"
merge-multiple: true
+126 -191
View File
@@ -1,4 +1,4 @@
name: Create SD Card & eMMC Images
name: Create Images
on:
workflow_dispatch:
@@ -11,18 +11,20 @@ on:
- raspberrypi-rpi2
- raspberrypi-rpi64
- bananapi-bpi-r3
- bananapi-bpi-r4
- bananapi-bpi-r64
- friendlyarm-nanopi-r2s
- microchip-sama7g54-ek
- acer-connect-vero-w
default: 'raspberrypi-rpi64'
jobs:
create-image:
name: Create SD Card Image for ${{ inputs.board }}
name: Create images for ${{ inputs.board }}
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
clean: true
fetch-depth: 0
@@ -49,228 +51,171 @@ jobs:
mkdir -p output/images
mkdir -p build
- name: Set bootloader and target based on board
- name: Set bootloaders and targets based on board
run: |
arch=
targets=
bootloader_sdcard=
bootloader_emmc=
case "${{ inputs.board }}" in
raspberrypi-rpi2)
echo "BOOTLOADER=rpi2-boot" >> $GITHUB_ENV
echo "ARCH=arm" >> $GITHUB_ENV
echo "BUILD_EMMC=false" >> $GITHUB_ENV
arch=arm
targets="sdcard"
bootloader_sdcard=rpi2-boot
;;
raspberrypi-rpi64)
echo "BOOTLOADER=rpi64-boot" >> $GITHUB_ENV
echo "ARCH=aarch64" >> $GITHUB_ENV
echo "BUILD_EMMC=false" >> $GITHUB_ENV
arch=aarch64
targets="sdcard"
bootloader_sdcard=rpi64-boot
;;
bananapi-bpi-r3)
echo "BOOTLOADER_SD=bpi-r3-sd-boot" >> $GITHUB_ENV
echo "BOOTLOADER_EMMC=bpi-r3-emmc-boot" >> $GITHUB_ENV
echo "ARCH=aarch64" >> $GITHUB_ENV
echo "BUILD_EMMC=true" >> $GITHUB_ENV
arch=aarch64
targets="sdcard emmc"
bootloader_sdcard=bpi-r3-sd-boot
bootloader_emmc=bpi-r3-emmc-boot
;;
bananapi-bpi-r4)
arch=aarch64
targets="sdcard emmc"
bootloader_sdcard=bpi-r4-sd-boot
bootloader_emmc=bpi-r4-emmc-boot
;;
bananapi-bpi-r64)
echo "BOOTLOADER_SD=bpi-r64-sd-boot" >> $GITHUB_ENV
echo "BOOTLOADER_EMMC=bpi-r64-emmc-boot" >> $GITHUB_ENV
echo "ARCH=aarch64" >> $GITHUB_ENV
echo "BUILD_EMMC=true" >> $GITHUB_ENV
arch=aarch64
targets="sdcard emmc"
bootloader_sdcard=bpi-r64-sd-boot
bootloader_emmc=bpi-r64-emmc-boot
;;
acer-connect-vero-w)
arch=aarch64
targets="emmc"
bootloader_emmc=bpi-r3-emmc-boot
;;
friendlyarm-nanopi-r2s)
echo "BOOTLOADER=nanopi-r2s-boot" >> $GITHUB_ENV
echo "ARCH=aarch64" >> $GITHUB_ENV
echo "BUILD_EMMC=false" >> $GITHUB_ENV
arch=aarch64
targets="sdcard"
bootloader_sdcard=nanopi-r2s-boot
;;
microchip-sama7g54-ek)
echo "BOOTLOADER_SD=sama7g54-ek-sd-boot" >> $GITHUB_ENV
echo "BOOTLOADER_EMMC=sama7g54-ek-emmc-boot" >> $GITHUB_ENV
echo "ARCH=arm" >> $GITHUB_ENV
echo "BUILD_EMMC=true" >> $GITHUB_ENV
arch=arm
targets="sdcard emmc"
bootloader_sdcard=sama7g54-ek-sd-boot
bootloader_emmc=sama7g54-ek-emmc-boot
;;
*)
echo "Error: Unknown board ${{ inputs.board }}"
exit 1
;;
esac
echo "Arch: $ARCH for board: ${{ inputs.board }}"
if [ "$BUILD_EMMC" = "true" ]; then
echo "Building both SD and eMMC images"
echo "SD Bootloader: $BOOTLOADER_SD"
echo "eMMC Bootloader: $BOOTLOADER_EMMC"
else
echo "Building SD image only"
echo "Bootloader: $BOOTLOADER"
fi
echo "ARCH=$arch" >> $GITHUB_ENV
echo "TARGETS=$targets" >> $GITHUB_ENV
[ -n "$bootloader_sdcard" ] && echo "BOOTLOADER_SDCARD=$bootloader_sdcard" >> $GITHUB_ENV
[ -n "$bootloader_emmc" ] && echo "BOOTLOADER_EMMC=$bootloader_emmc" >> $GITHUB_ENV
echo "Arch: $arch for board: ${{ inputs.board }}"
echo "Targets: $targets"
[ -n "$bootloader_sdcard" ] && echo "SD bootloader: $bootloader_sdcard"
[ -n "$bootloader_emmc" ] && echo "eMMC bootloader: $bootloader_emmc"
- name: Download bootloader artifacts
run: |
# Download bootloader from latest-boot release tag
if [ "$BUILD_EMMC" = "true" ]; then
# Download both SD and eMMC bootloaders for boards that support both
echo "Downloading SD bootloader: ${BOOTLOADER_SD}"
gh release download latest-boot --pattern "*${BOOTLOADER_SD}*" --dir temp_bootloader_sd/
mkdir -p output_sd/images
cd temp_bootloader_sd/
tar -xzf *.tar.gz --strip-components=1 -C ../output_sd/images/
cd ../
rm -rf temp_bootloader_sd/
for target in $TARGETS; do
upper=$(printf '%s' "$target" | tr '[:lower:]' '[:upper:]')
bootloader_var="BOOTLOADER_${upper}"
bootloader="${!bootloader_var}"
temp_dir="temp_bootloader_${target}"
out_dir="output_${target}/images"
echo "Downloading eMMC bootloader: ${BOOTLOADER_EMMC}"
gh release download latest-boot --pattern "*${BOOTLOADER_EMMC}*" --dir temp_bootloader_emmc/
mkdir -p output_emmc/images
cd temp_bootloader_emmc/
tar -xzf *.tar.gz --strip-components=1 -C ../output_emmc/images/
cd ../
rm -rf temp_bootloader_emmc/
echo "Downloading ${target} bootloader: ${bootloader}"
mkdir -p "$out_dir"
gh release download latest-boot --pattern "*${bootloader}*" --dir "$temp_dir/"
tar -xzf "$temp_dir"/*.tar.gz --strip-components=1 -C "$out_dir/"
rm -rf "$temp_dir"
echo "SD bootloader files:"
ls -la output_sd/images/
echo "eMMC bootloader files:"
ls -la output_emmc/images/
else
# Single bootloader for boards that only support SD
gh release download latest-boot --pattern "*${BOOTLOADER}*" --dir temp_bootloader/
# Extract bootloader directly to output/images
cd temp_bootloader/
tar -xzf *.tar.gz --strip-components=1 -C ../output/images/
cd ../
rm -rf temp_bootloader/
echo "Bootloader files extracted to output/images:"
ls -la output/images/
fi
echo "${target} bootloader files:"
ls -la "$out_dir/"
done
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Download Infix artifacts
run: |
# Download from latest Kernelkit Trigger workflow for main branch
gh run list --workflow=164295764 --branch=main --limit=1 --status=success --json databaseId --jq '.[0].databaseId' > latest_infix_run_id
INFIX_RUN_ID=$(cat latest_infix_run_id)
if [ "$BUILD_EMMC" = "true" ]; then
# Copy Infix artifacts to both SD and eMMC output directories
gh run download ${INFIX_RUN_ID} --name artifact-${ARCH} --dir temp_infix/
gh run download ${INFIX_RUN_ID} --name artifact-${ARCH} --dir temp_infix/
cd temp_infix/
tar -xzf *.tar.gz --strip-components=1 -C ../output_sd/images/
tar -xzf *.tar.gz --strip-components=1 -C ../output_emmc/images/
cd ../
rm -rf temp_infix/
for target in $TARGETS; do
out_dir="output_${target}/images"
mkdir -p "$out_dir"
tar -xzf temp_infix/*.tar.gz --strip-components=1 -C "$out_dir/"
echo "Infix files extracted to output_sd/images:"
ls -la output_sd/images/
echo "Infix files extracted to output_emmc/images:"
ls -la output_emmc/images/
else
# Single output directory for SD-only boards
gh run download ${INFIX_RUN_ID} --name artifact-${ARCH} --dir temp_infix/
echo "Infix files extracted to ${out_dir}:"
ls -la "$out_dir/"
done
# Extract Infix directly to output/images
cd temp_infix/
tar -xzf *.tar.gz --strip-components=1 -C ../output/images/
cd ../
rm -rf temp_infix/
echo "Infix files extracted to output/images:"
ls -la output/images/
fi
rm -rf temp_infix/
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Verify extracted files
run: |
if [ "$BUILD_EMMC" = "true" ]; then
echo "Files available for SD image:"
ls -la output_sd/images/
for target in $TARGETS; do
echo "Files available for ${target} image:"
ls -la "output_${target}/images/"
echo ""
echo "Files available for eMMC image:"
ls -la output_emmc/images/
else
echo "Files available for mkimage.sh:"
ls -la output/images/
echo ""
echo "File types:"
file output/images/* || true
fi
done
- name: Create SD card image
- name: Create images
run: |
if [ "$BUILD_EMMC" = "true" ]; then
export BINARIES_DIR=$PWD/output_sd/images
export BUILD_DIR=$PWD/build
export BR2_EXTERNAL_INFIX_PATH=$PWD
export RELEASE=""
export INFIX_ID="infix"
./utils/mkimage.sh -t sdcard ${{ inputs.board }}
else
export BINARIES_DIR=$PWD/output/images
export BUILD_DIR=$PWD/build
export BR2_EXTERNAL_INFIX_PATH=$PWD
export RELEASE=""
export INFIX_ID="infix"
./utils/mkimage.sh -t sdcard ${{ inputs.board }}
fi
- name: Create eMMC image
if: ${{ env.BUILD_EMMC == 'true' }}
run: |
export BINARIES_DIR=$PWD/output_emmc/images
export BUILD_DIR=$PWD/build
export BR2_EXTERNAL_INFIX_PATH=$PWD
export RELEASE=""
export INFIX_ID="infix"
./utils/mkimage.sh -t emmc ${{ inputs.board }}
for target in $TARGETS; do
export BINARIES_DIR=$PWD/output_${target}/images
./utils/mkimage.sh -t "$target" ${{ inputs.board }}
done
- name: Verify created images
run: |
if [ "$BUILD_EMMC" = "true" ]; then
echo "SD card image:"
ls -lh output_sd/images/*-sdcard.img* 2>/dev/null || true
if ls output_sd/images/*-sdcard.img 1> /dev/null 2>&1; then
for img in output_sd/images/*-sdcard.img; do
echo "- $(basename $img)"
file "$img"
fdisk -l "$img" 2>/dev/null | head -20
done
fi
mkdir -p output/images
echo ""
echo "eMMC image:"
ls -lh output_emmc/images/*-emmc.img* 2>/dev/null || true
if ls output_emmc/images/*-emmc.img 1> /dev/null 2>&1; then
for img in output_emmc/images/*-emmc.img; do
echo "- $(basename $img)"
file "$img"
fdisk -l "$img" 2>/dev/null | head -20
done
fi
for target in $TARGETS; do
src_dir="output_${target}/images"
found=false
# Copy both images to output/images for artifact upload
mkdir -p output/images
cp output_sd/images/*-sdcard.img* output/images/ 2>/dev/null || true
cp output_emmc/images/*-emmc.img* output/images/ 2>/dev/null || true
else
echo "Contents of output/images after mkimage.sh:"
ls -lh output/images/
echo "${target} image:"
ls -lh "$src_dir"/*-"$target".img* 2>/dev/null || true
# Look for SD card image with pattern: *-sdcard.img
if ls output/images/*-sdcard.img 1> /dev/null 2>&1; then
echo "Found SD card image(s):"
for img in output/images/*-sdcard.img; do
echo "- $(basename $img)"
file "$img"
fdisk -l "$img" 2>/dev/null || true
done
else
echo "No SD card image found matching pattern: *-sdcard.img"
echo "Available files:"
ls -la output/images/
for img in "$src_dir"/*-"$target".img; do
[ -e "$img" ] || continue
found=true
echo "- $(basename "$img")"
file "$img"
fdisk -l "$img" 2>/dev/null || true
done
if [ "$found" = false ]; then
echo "No ${target} image found matching pattern: *-${target}.img"
echo "Available files in ${src_dir}:"
ls -la "$src_dir/"
exit 1
fi
fi
for artifact in "$src_dir"/*-"$target".img*; do
[ -e "$artifact" ] || continue
cp "$artifact" output/images/
done
echo ""
done
- name: Upload images as artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: images-${{ inputs.board }}
path: |
@@ -301,37 +246,27 @@ jobs:
- name: Generate summary
run: |
if [ "$BUILD_EMMC" = "true" ]; then
cat <<EOF >> $GITHUB_STEP_SUMMARY
# SD Card & eMMC Image Build Complete! 🚀
cat <<EOF >> $GITHUB_STEP_SUMMARY
# Image Build Complete! 🚀
**Board:** ${{ inputs.board }}
**Arch:** ${{ env.ARCH }}
**SD Bootloader:** ${{ env.BOOTLOADER_SD }}
**eMMC Bootloader:** ${{ env.BOOTLOADER_EMMC }}
**Targets:** ${{ env.TARGETS }}
**Bootloader Source:** latest-boot release
**Infix Source:** Latest workflow run on main
## Bootloaders
$(for target in $TARGETS; do
case "$target" in
sdcard) bootloader="$BOOTLOADER_SDCARD" ;;
emmc) bootloader="$BOOTLOADER_EMMC" ;;
esac
printf -- '- %s: %s\n' "$target" "$bootloader"
done)
## Created Images
$(find output/images/ -name "*.img" -o -name "*.img.bmap" | xargs ls -lh 2>/dev/null | awk '{print "- " $9 " (" $5 ")"}' || echo "- No images found")
## Download
Both SD card and eMMC images are available as workflow artifacts above and in the latest-boot release.
The generated images are available as workflow artifacts above and in the latest-boot release.
EOF
else
cat <<EOF >> $GITHUB_STEP_SUMMARY
# SD Card Image Build Complete! 🚀
**Board:** ${{ inputs.board }}
**Arch:** ${{ env.ARCH }}
**Bootloader:** ${{ env.BOOTLOADER }}
**Bootloader Source:** latest-boot release
**Infix Source:** Latest workflow run on main
## Created Images
$(find output/images/ -name "*.img" -o -name "*.img.bmap" | xargs ls -lh 2>/dev/null | awk '{print "- " $9 " (" $5 ")"}' || echo "- No images found")
## Download
The SD card image is available as a workflow artifact above.
EOF
fi
+3 -3
View File
@@ -23,7 +23,7 @@ jobs:
target: [aarch64, arm, x86_64]
fail-fast: false
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
clean: true
submodules: recursive
@@ -86,12 +86,12 @@ jobs:
ln -s ${{ steps.vars.outputs.dir }} images
tar cfz ${{ steps.vars.outputs.tgz }} ${{ steps.vars.outputs.dir }}
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
with:
name: artifact-${{ matrix.target }}
path: output/*.tar.gz
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
with:
name: artifact-disk-image-${{ matrix.target }}
path: output/images/*.qcow2
+2 -2
View File
@@ -80,7 +80,7 @@ jobs:
ls -la ./
- name: Checkout infix repo
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
repository: ${{ env.INFIX_REPO }}
ref: ${{ env.INFIX_BRANCH != '' && env.INFIX_BRANCH || github.ref }}
@@ -178,7 +178,7 @@ jobs:
ln -s ${{ steps.vars.outputs.dir }} images
tar cfz ${{ steps.vars.outputs.tgz }} ${{ steps.vars.outputs.dir }}
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
with:
path: output/${{ steps.vars.outputs.tgz }}
name: artifact-${{ env.TARGET }}
+2 -2
View File
@@ -12,7 +12,7 @@ jobs:
steps:
- name: Check out infix repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
fetch-depth: 0
token: ${{ secrets.KERNEL_UPDATE_TOKEN }}
@@ -103,7 +103,7 @@ jobs:
- name: Create pull request
if: steps.check.outputs.new_release == 'true'
uses: actions/github-script@v7
uses: actions/github-script@v9
with:
github-token: ${{ secrets.KERNEL_UPDATE_TOKEN }}
script: |
+3 -3
View File
@@ -16,7 +16,7 @@ jobs:
if: ${{github.repository_owner == 'kernelkit'}}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Fetch latest Coverity Scan MD5
id: var
env:
@@ -27,7 +27,7 @@ jobs:
-O coverity-latest.tar.gz.md5
echo "md5=$(cat coverity-latest.tar.gz.md5)" | tee -a $GITHUB_OUTPUT
- uses: actions/cache@v4
- uses: actions/cache@v5
id: cache
with:
path: coverity-latest.tar.gz
@@ -98,7 +98,7 @@ jobs:
https://scan.coverity.com/builds?project=${PROJECT_NAME}
- name: Upload build.log
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: coverity-build.log
path: cov-int/build-log.txt
+2 -2
View File
@@ -24,12 +24,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Python
uses: actions/setup-python@v4
uses: actions/setup-python@v6
with:
python-version: '3.x'
+2 -2
View File
@@ -33,7 +33,7 @@ jobs:
mtools
- name: Checkout infix repo
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
repository: ${{ github.repository }}
ref: ${{ github.ref }}
@@ -77,7 +77,7 @@ jobs:
ln -s Infix-x86_64 images
tar cfz Infix-x86_64.tar.gz Infix-x86_64
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
with:
path: output/Infix-x86_64.tar.gz
name: artifact-x86_64
+1 -1
View File
@@ -44,7 +44,7 @@ jobs:
checkout:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- uses: kernelkit/actions/cache-restore@v1
with:
target: x86_64
+1 -1
View File
@@ -11,7 +11,7 @@ jobs:
permissions:
contents: write
steps:
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v8
with:
pattern: "artifact-*"
merge-multiple: true
+2 -2
View File
@@ -48,7 +48,7 @@ jobs:
contents: write
discussions: write
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
submodules: 'true'
@@ -78,7 +78,7 @@ jobs:
echo "pre=${{ steps.rel.outputs.pre }}"
echo "latest=${{ steps.rel.outputs.latest }}"
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v8
with:
pattern: "artifact-*"
merge-multiple: true
+14 -6
View File
@@ -43,6 +43,11 @@ on:
type: string
default: ''
description: 'Optional script to run after checkout (for spin customization)'
release:
required: false
type: string
default: ''
description: 'Release version (e.g. v26.04.0), sets INFIX_RELEASE so make test finds versioned artifacts'
secrets:
CHECKOUT_TOKEN:
required: false
@@ -61,7 +66,7 @@ jobs:
runs-on: [self-hosted, regression]
steps:
- name: Checkout infix repo
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
repository: ${{ env.INFIX_REPO }}
ref: ${{ env.INFIX_BRANCH != '' && env.INFIX_BRANCH || github.ref }}
@@ -93,7 +98,7 @@ jobs:
run: |
make ${{ env.TARGET }}_defconfig
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v8
with:
pattern: "artifact-*"
merge-multiple: true
@@ -105,12 +110,15 @@ jobs:
ls -l
mkdir -p output
mv ${name}-${target}.tar.gz output/
tarfile=$(ls ${name}-${target}*.tar.gz | head -1)
mv "$tarfile" output/
cd output/
tar xf ${name}-${target}.tar.gz
ln -s ${name}-${target} images
tar xf "$tarfile"
ln -s "${tarfile%.tar.gz}" images
- name: Regression Test ${{ env.TARGET }}
env:
INFIX_RELEASE: ${{ inputs.release }}
run: |
if [ -n "$NINEPM_CONF" ]; then
export NINEPM_PROJ_CONFIG="${GITHUB_WORKSPACE}/$NINEPM_CONF"
@@ -131,7 +139,7 @@ jobs:
make test-dir="$(pwd)/$TEST_PATH" test-report
- name: Upload Test Report as Artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: test-report
path: output/images/test-report.pdf
+1 -1
View File
@@ -78,7 +78,7 @@ jobs:
ls -la ./
- name: Checkout infix repo
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
repository: ${{ env.INFIX_REPO }}
ref: ${{ env.INFIX_BRANCH != '' && env.INFIX_BRANCH || github.ref }}
+1 -1
View File
@@ -22,7 +22,7 @@ jobs:
permissions:
contents: write
steps:
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v8
with:
pattern: "artifact-*"
merge-multiple: true
+22 -3
View File
@@ -9,8 +9,10 @@ O ?= output
# otherwise treat it as relative to ./buildroot.
override O := $(if $(filter /%,$O),$O,$(CURDIR)/$O)
config := $(O)/.config
bmake = $(MAKE) -C buildroot O=$(O) $1
config := $(O)/.config
bmake = $(MAKE) -C buildroot O=$(O) $1
SNIPPETS_DIR := $(CURDIR)/configs/snippets
MERGE_CONFIG := $(CURDIR)/buildroot/support/kconfig/merge_config.sh
all: $(config) buildroot/Makefile
@@ -26,6 +28,23 @@ $(config):
@echo "'make <board>_defconfig' before building an image."
@exit 1
apply-%: $(SNIPPETS_DIR)/%.conf | $(config)
@KCONFIG_CONFIG=$(config) $(MERGE_CONFIG) -m $(config) $<
@+$(call bmake,olddefconfig)
@echo "Applied snippet: $<"
list-snippets:
@echo "Available snippets (use 'make apply-<name>'):"
@ls $(SNIPPETS_DIR)/*.conf 2>/dev/null | sed 's|.*/||; s|\.conf$$||; s|^| |'
dev: | $(config)
@for s in $(SNIPPETS_DIR)/*.conf; do \
KCONFIG_CONFIG=$(config) $(MERGE_CONFIG) -m $(config) $$s; \
echo "Applied snippet: $$s"; \
done
@+$(call bmake,olddefconfig)
@+$(call bmake,all)
%: | buildroot/Makefile
@+$(call bmake,$@)
@@ -44,4 +63,4 @@ test:
buildroot/Makefile:
@git submodule update --init
.PHONY: all check coverity dep test cyclonedx
.PHONY: all check coverity dep test cyclonedx list-snippets dev
+2
View File
@@ -1,7 +1,9 @@
if BR2_aarch64
source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/alder-alder/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/acer-connect-vero-w6m/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/bananapi-bpi-r3/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/bananapi-bpi-r4/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/bananapi-bpi-r64/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/freescale-imx8mp-evk/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/friendlyarm-nanopi-r2s/Config.in"
+9 -6
View File
@@ -4,9 +4,12 @@ aarch64
Board Specific Documentation
----------------------------
- [Banana Pi BPi-R3](banana-pi-r3/)
- [Banana Pi BPi-R64](banana-pi-r64/)
- [Marvell CN9130-CRB](cn9130-crb/)
- [Microchip SparX-5i PCB135 (eMMC)](sparx5-pcb135/)
- [NanoPi R2S](r2s/)
- [Raspberry Pi 64-bit](raspberry-pi64/)
- [Acer Connect Vero W6m](acer-connect-vero-w6m/)
- [Banana Pi BPi-R3](bananapi-bpi-r3/)
- [Banana Pi BPi-R4](bananapi-bpi-r4/)
- [Banana Pi BPi-R64](bananapi-bpi-r64/)
- [Marvell CN9130-CRB](marvell-cn9130-crb/)
- [Marvell ESPRESSObin](marvell-espressobin/)
- [Microchip SparX-5i PCB135 (eMMC)](microchip-sparx5-pcb135/)
- [NanoPi R2S](friendlyarm-nanopi-r2s/)
- [Raspberry Pi 64-bit](raspberrypi-rpi64/)
@@ -0,0 +1,6 @@
config BR2_PACKAGE_ACER_CONNECT_VERO_W6M
bool "Acer Connect Vero W6m"
depends on BR2_aarch64
select BR2_PACKAGE_BANANAPI_BPI_R3
help
Build Acer Connect Vero W6m
@@ -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.
@@ -0,0 +1,131 @@
# Acer Connect Vero W6m
<img src="connect_vero_w6m_case.jpg" alt="Acer Connect Vero W6m" width=400 padding=10>
## Overview
The Acer Connect Vero W6m is a compact WiFi 6/6E router platform based
on the MediaTek MT7986A SoC. In Infix it is supported as an eMMC-based
target that reuses the factory secure boot chain while replacing the
system partitions with an Infix installation.
The Acer Connect Vero W6m is based on the same MT7986a SoC as the
BPI-R3, with tri-band WiFi (2.4 GHz + 5 GHz + 6 GHz) using a PCIe
MT7916 module and the SoC's built-in MT7976 DBDC radio.
## Default WiFi Layout
The factory configuration on this branch enables all three radios in AP
mode and bridges them into the default LAN bridge `br0`:
- `radio0` / `wifi0-ap`: 2.4 GHz, SSID `Infix`
- `radio1` / `wifi1-ap`: 6 GHz, SSID `Infix6G`
- `radio2` / `wifi2-ap`: 5 GHz, SSID `Infix5G`
6 GHz operation is enabled in the MT7915e driver configuration, and all
three APs use the same default passphrase `infixinfix` from the factory
configuration.
Secure boot is enabled on this device, so the factory bootloader
(partitions 1-4: bl2, u-boot-env, factory, fip) must not be modified.
Infix is installed by replacing partitions 5+ while keeping the
factory bootloader intact. The stock U-Boot chainloads the Infix
U-Boot from the first partition after fip.
## Prerequisites
- Serial console access (115200 8N1) — required to interrupt U-Boot.
Disassembly is needed to reach the UART header. See the [OpenWrt
Vero W6m page][vero-openwrt] for details.
- TFTP server on the local network with `u-boot.bin` for the initial
RAM boot.
- SSH access from the running Infix system to a host that stores
`infix-vero-w-emmc.img`.
- Ethernet cable connected between the PC and the Vero Internet/WAN
port.
- DHCP server running on the PC, serving addresses on that link during
installation.
- **Save the MAC addresses** from the stock U-Boot environment before
installing. Interrupt autoboot and run `printenv` to note down:
`2gMAC`, `5gMAC`, `6gMAC`, `LANMAC`, and `WANMAC`.
## Required Files
Prepare these files on a host reachable from the Vero:
1. **Infix Vero image:**
- [infix-vero-w-emmc.img][1] (Complete system image)
2. **eMMC bootloader** (extracted from):
- [bpi-r3-emmc-boot-2025.01-latest.tar.gz][2]
- Extract `u-boot.bin` from the tarball to your TFTP server
## Installing Infix
Connect the PC directly to the Vero Internet/WAN port before starting
the installation. The PC should provide DHCP service on that link so
the stock U-Boot and the temporary Infix system can reach the TFTP/SSH
host.
1. **RAM-load Infix U-Boot** from the stock U-Boot serial console
(hit any key to stop autoboot):
```
setenv serverip <TFTP_SERVER_IP>
setenv ipaddr <VERO_IP>
setenv bootmenu_default 7
tftpboot 0x46000000 u-boot.bin
go 0x46000000
```
`serverip` must point to your TFTP server and `ipaddr` must be a free
address for the Vero on the same subnet. `bootmenu_default 7`
bypasses secure boot verification. The Infix U-Boot will
automatically netboot the Infix system.
2. **From running Infix**, stream the image directly to eMMC:
```bash
ssh <USER>@<HOST> "dd if=/path/to/infix-vero-w-emmc.img bs=512 skip=17408 status=none" | \
dd of=/dev/mmcblk0 bs=512 seek=17408 conv=fsync
sync
```
This writes only the Infix partitions (starting after fip at sector
17408), leaving the factory bootloader and calibration data intact.
Do not interrupt the transfer; if it fails, rerun the command from
the beginning.
3. **Update the GPT** to replace stock partitions 5+ with the Infix
layout:
```bash
sudo sgdisk --zap-all /dev/mmcblk0
sudo sgdisk -a 1 \
-n2:8192:9215 -c2:u-boot-env \
-n3:9216:13311 -c3:factory \
-n4:13312:17407 -c4:fip \
-n5:17408:+32M -c5:infix-uboot \
-n6:0:+8M -c6:aux \
-n7:0:+250M -c7:primary \
-n8:0:+250M -c8:secondary \
-n9:0:+128M -c9:cfg \
-n10:0:+128M -c10:var \
-p /dev/mmcblk0
```
4. **Configure U-Boot to chainload Infix permanently** — reboot and
interrupt stock U-Boot again:
```
setenv bootmenu_default 7
setenv bootcmd 'mmc read 0x46000000 0x4400 0x10000; go 0x46000000'
saveenv
reset
```
The `bootcmd` reads the Infix U-Boot (at sector 0x4400/17408)
into RAM and jumps to it. After `reset`, Infix boots from eMMC.
[vero-openwrt]: https://openwrt.org/toh/acer/predator_vero_w6m
[1]: https://github.com/kernelkit/infix/releases/download/latest-boot/infix-vero-w-emmc.img
[2]: https://github.com/kernelkit/infix/releases/download/latest-boot/bpi-r3-emmc-boot-2025.01-latest.tar.gz
@@ -0,0 +1,2 @@
# Locally calculated
sha256 d48246c717b505cc11df95171f2fd548b389e1a463f1af4c68d0b69fe0d1009b LICENSE
@@ -0,0 +1,2 @@
$(eval $(ix-board))
$(eval $(generic-package))
Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

@@ -0,0 +1 @@
dtb-y += mediatek/mt7986a-acer-connect-vero-w6m.dtb
@@ -0,0 +1,425 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
#include <dt-bindings/input/input.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/leds/common.h>
#include <dt-bindings/pinctrl/mt65xx.h>
#include <arm64/mediatek/mt7986a.dtsi>
/ {
chosen {
stdout-path = "serial0:115200n8";
infix {
/* Default admin user password: 'admin' */
factory-password-hash = "$5$mI/zpOAqZYKLC2WU$i7iPzZiIjOjrBF3NyftS9CCq8dfYwHwrmUK097Jca9A";
};
};
memory@40000000 {
reg = <0 0x40000000 0 0x20000000>;
device_type = "memory";
};
reg_1p8v: regulator-1p8v {
compatible = "regulator-fixed";
regulator-name = "fixed-1.8V";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-boot-on;
regulator-always-on;
};
reg_3p3v: regulator-3p3v {
compatible = "regulator-fixed";
regulator-name = "fixed-3.3V";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-boot-on;
regulator-always-on;
};
reg_5v: regulator-5v {
compatible = "regulator-fixed";
regulator-name = "fixed-5V";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
regulator-boot-on;
regulator-always-on;
};
gpio-keys {
compatible = "gpio-keys";
factory {
label = "factory";
linux,code = <KEY_RESTART>;
gpios = <&pio 9 GPIO_ACTIVE_LOW>;
};
wps {
label = "wps";
linux,code = <KEY_WPS_BUTTON>;
gpios = <&pio 10 GPIO_ACTIVE_LOW>;
};
};
};
&watchdog {
status = "okay";
};
&pio {
wifi_rst_hog: wifi-reset-hog {
gpio-hog;
gpios = <6 GPIO_ACTIVE_LOW>;
output-low;
line-name = "wifi-reset";
};
mmc0_pins_default: mmc0-pins {
mux {
function = "emmc";
groups = "emmc_51";
};
conf-cmd-dat {
pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2",
"EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5",
"EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD";
input-enable;
drive-strength = <MTK_DRIVE_4mA>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
};
conf-clk {
pins = "EMMC_CK";
drive-strength = <MTK_DRIVE_6mA>;
bias-pull-down = <MTK_PUPD_SET_R1R0_10>; /* pull-down 50K */
};
conf-ds {
pins = "EMMC_DSL";
bias-pull-down = <MTK_PUPD_SET_R1R0_10>; /* pull-down 50K */
};
conf-rst {
pins = "EMMC_RSTB";
drive-strength = <MTK_DRIVE_4mA>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
};
};
mmc0_pins_uhs: mmc0-uhs-pins {
mux {
function = "emmc";
groups = "emmc_51";
};
conf-cmd-dat {
pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2",
"EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5",
"EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD";
input-enable;
drive-strength = <MTK_DRIVE_4mA>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
};
conf-clk {
pins = "EMMC_CK";
drive-strength = <MTK_DRIVE_6mA>;
bias-pull-down = <MTK_PUPD_SET_R1R0_10>; /* pull-down 50K */
};
conf-ds {
pins = "EMMC_DSL";
bias-pull-down = <MTK_PUPD_SET_R1R0_10>; /* pull-down 50K */
};
conf-rst {
pins = "EMMC_RSTB";
drive-strength = <MTK_DRIVE_4mA>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
};
};
pcie_pins: pcie-pins {
mux {
function = "pcie";
groups = "pcie_pereset";
};
};
wf_2g_5g_pins: wf_2g_5g-pins {
mux {
function = "wifi";
groups = "wf_2g", "wf_5g";
};
conf {
pins = "WF0_HB1", "WF0_HB2", "WF0_HB3", "WF0_HB4",
"WF0_HB0", "WF0_HB0_B", "WF0_HB5", "WF0_HB6",
"WF0_HB7", "WF0_HB8", "WF0_HB9", "WF0_HB10",
"WF0_TOP_CLK", "WF0_TOP_DATA", "WF1_HB1",
"WF1_HB2", "WF1_HB3", "WF1_HB4", "WF1_HB0",
"WF1_HB5", "WF1_HB6", "WF1_HB7", "WF1_HB8",
"WF1_TOP_CLK", "WF1_TOP_DATA";
drive-strength = <MTK_DRIVE_4mA>;
};
};
wf_dbdc_pins: wf-dbdc-pins {
mux {
function = "wifi";
groups = "wf_dbdc";
};
conf {
pins = "WF0_HB1", "WF0_HB2", "WF0_HB3", "WF0_HB4",
"WF0_HB0", "WF0_HB0_B", "WF0_HB5", "WF0_HB6",
"WF0_HB7", "WF0_HB8", "WF0_HB9", "WF0_HB10",
"WF0_TOP_CLK", "WF0_TOP_DATA", "WF1_HB1",
"WF1_HB2", "WF1_HB3", "WF1_HB4", "WF1_HB0",
"WF1_HB5", "WF1_HB6", "WF1_HB7", "WF1_HB8",
"WF1_TOP_CLK", "WF1_TOP_DATA";
drive-strength = <MTK_DRIVE_4mA>;
};
};
i2c_pins: i2c-pins {
mux {
function = "i2c";
groups = "i2c";
};
};
};
&trng {
status = "okay";
};
&crypto {
status = "okay";
};
&uart0 {
status = "okay";
};
&i2c0 {
pinctrl-names = "default";
pinctrl-0 = <&i2c_pins>;
status = "okay";
};
&mmc0 {
status = "okay";
pinctrl-names = "default", "state_uhs";
pinctrl-0 = <&mmc0_pins_default>;
pinctrl-1 = <&mmc0_pins_uhs>;
bus-width = <0x08>;
max-frequency = <200000000>;
cap-mmc-highspeed;
mmc-hs200-1_8v;
mmc-hs400-1_8v;
hs400-ds-delay = <0x14014>;
vmmc-supply = <&reg_3p3v>;
vqmmc-supply = <&reg_1p8v>;
non-removable;
no-sd;
no-sdio;
#address-cells = <1>;
#size-cells = <0>;
card@0 {
compatible = "mmc-card";
reg = <0>;
block {
compatible = "block-device";
partitions {
block-partition-factory {
partname = "factory";
nvmem: nvmem-layout {
compatible = "fixed-layout";
#address-cells = <1>;
#size-cells = <1>;
eeprom_factory_0: eeprom@0 {
reg = <0x0 0x1000>;
};
precal_factory_1010: precal@1010 {
reg = <0x1010 0x62810>;
};
};
};
};
};
};
};
&pcie {
pinctrl-names = "default";
pinctrl-0 = <&pcie_pins>;
num-lanes = <1>;
status = "okay";
slot0: pcie@0,0 {
reg = <0x0000 0 0 0 0>;
#address-cells = <0x03>;
#size-cells = <0x02>;
pcie_wifi: wifi@0,0 {
compatible = "mediatek,mt76";
reg = <0x0000 0 0 0 0>;
};
};
};
&pcie_phy {
status = "okay";
};
&pcie_port {
clocks = <&clk40m>, <&topckgen CLK_TOP_PCIE_PHY_SEL>;
clock-names = "ref", "da_ref";
};
&eth {
status = "okay";
gmac0: mac@0 {
compatible = "mediatek,eth-mac";
reg = <0>;
phy-mode = "2500base-x";
fixed-link {
speed = <2500>;
full-duplex;
pause;
};
};
mdio: mdio-bus {
#address-cells = <1>;
#size-cells = <0>;
switch: switch@1f {
compatible = "mediatek,mt7531";
reg = <31>;
reset-gpios = <&pio 5 GPIO_ACTIVE_HIGH>;
ports {
#address-cells = <1>;
#size-cells = <0>;
swport0: port@0 {
reg = <0>;
phy-handle = <&swphy0>;
};
port@1 {
reg = <1>;
label = "lan1";
phy-handle = <&swphy1>;
};
port@2 {
reg = <2>;
label = "lan2";
phy-handle = <&swphy2>;
};
port@3 {
reg = <3>;
label = "lan3";
phy-handle = <&swphy3>;
};
port@6 {
reg = <6>;
label = "cpu";
ethernet = <&gmac0>;
phy-mode = "2500base-x";
fixed-link {
speed = <2500>;
full-duplex;
pause;
};
};
};
mdio {
#address-cells = <1>;
#size-cells = <0>;
swphy0: phy@0 {
reg = <0>;
mediatek,led-config = <
0x21 0x8008 /* BASIC_CTRL */
0x22 0x0c00 /* ON_DURATION */
0x23 0x1400 /* BLINK_DURATION */
0x24 0xc001 /* LED0_ON_CTRL */
0x25 0x0003 /* LED0_BLINK_CTRL */
0x26 0xc006 /* LED1_ON_CTRL */
0x27 0x003c /* LED1_BLINK_CTRL */
>;
};
swphy1: phy@1 {
reg = <1>;
mediatek,led-config = <
0x21 0x8008 /* BASIC_CTRL */
0x22 0x0c00 /* ON_DURATION */
0x23 0x1400 /* BLINK_DURATION */
0x24 0xc001 /* LED0_ON_CTRL */
0x25 0x0003 /* LED0_BLINK_CTRL */
0x26 0xc006 /* LED1_ON_CTRL */
0x27 0x003c /* LED1_BLINK_CTRL */
>;
};
swphy2: phy@2 {
reg = <2>;
mediatek,led-config = <
0x21 0x8008 /* BASIC_CTRL */
0x22 0x0c00 /* ON_DURATION */
0x23 0x1400 /* BLINK_DURATION */
0x24 0xc001 /* LED0_ON_CTRL */
0x25 0x0003 /* LED0_BLINK_CTRL */
0x26 0xc006 /* LED1_ON_CTRL */
0x27 0x003c /* LED1_BLINK_CTRL */
>;
};
swphy3: phy@3 {
reg = <3>;
mediatek,led-config = <
0x21 0x8008 /* BASIC_CTRL */
0x22 0x0c00 /* ON_DURATION */
0x23 0x1400 /* BLINK_DURATION */
0x24 0xc001 /* LED0_ON_CTRL */
0x25 0x0003 /* LED0_BLINK_CTRL */
0x26 0xc006 /* LED1_ON_CTRL */
0x27 0x003c /* LED1_BLINK_CTRL */
>;
};
};
};
};
};
&wifi {
nvmem-cells = <&eeprom_factory_0>, <&precal_factory_1010>;
nvmem-cell-names = "eeprom", "precal";
pinctrl-names = "default", "dbdc";
pinctrl-0 = <&wf_2g_5g_pins>;
pinctrl-1 = <&wf_dbdc_pins>;
status = "okay";
};
@@ -0,0 +1,263 @@
/* Factory EEPROM for MT7976 WMAC (DBDC) - Acer Connect Vero W */
/* Band 1 patched from 5GHz-only to 5GHz+6GHz selectable */
&wifi {
mediatek,eeprom-data = <
0x86790100 0x000c4326 0x60100000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x01000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000800 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x12525353 0x003c003f 0x3a100700 0x15030000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x0000be00 0x00000000
0x0000c100 0x00000000 0x00000000 0xc3000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000009 0x00000000 0x00000000
0x00000000 0x00000303 0x03030303 0x03030303
0x03030303 0x03030303 0x03040303 0x03040303
0x03040303 0x03040000 0x00161b18 0x1b1a1a1a
0x1a0d0008 0x0f0d0209 0x0e0d0209 0x0e0d0209
0x0e0c020a 0x0e0c020a 0x0e0c020a 0x0e0b020b
0x0e2b2b2b 0x2b222222 0x22222222 0x22222222
0x22222222 0x22222222 0x22000000 0x00000000
0x00000000 0x002a2a2a 0x2a282828 0x282a2a2a
0x2a282828 0x282a2a2a 0x2a282828 0x282a2a2a
0x2a282828 0x28000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x007f7f20 0x2530363c 0x41014847 0x4c52575c
0x7f7f7f7f 0x1b222a33 0x3a40014d 0x464c525a
0x5e7f7f7f 0x7f252834 0x3c424a01 0x4a4f555d
0x636e7f7f 0x7f7f202a 0x303b444a 0x014a5158
0x5f666e7f 0x7f7f7f7f 0x8080c5c5 0xd1d1dddd
0xe5e5f3f3 0x40408080 0xcfcfdbdb 0xe3e3efef
0xf7f74040 0x8080bfbf 0xcbcbd9d9 0xe5e5eded
0x40408080 0xb9b9c5c5 0xd3d3dfdf 0xe7e74040
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0xc0a0c0e0 0xfcfcafe0 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x02200220 0x02200220 0x02300230 0x02300230
0x02300230 0x02300230 0x02300230 0x02300230
0x02240224 0x02240224 0x02240224 0x02240224
0x02240224 0x02240224 0x02240224 0x02240224
0x000000c4 0xc4c4c4c4 0x0000c4c4 0xc4c4c1c1
0x008282c3 0xc3000000 0x00838300 0xc4c4c4c1
0xc1008282 0x8383c3c3 0xc2c10000 0x83838484
0xc4c4c4c1 0xc1008282 0x8383c4c4 0xc4c1c100
0x82828383 0xc4c4c4c1 0xc1008282 0x8383c4c4
0xc3c100c4 0x81c4c3c2 0x00818181 0xc4c4c3c2
0x00818282 0x00c4c4c2 0xc2008182 0x8200c4c4
0xc3c20081 0x82828484 0xc4c4c3c2 0x00818282
0x8484c4c4 0xc2c20081 0x82828484 0xc4c4c2c1
0x81828383 0x8585c4c4 0xc3c20081 0x82828484
0xc4c4c3c2 0x00818282 0x8484c4c4 0xc3c20081
0x82828484 0xc6c5c3c1 0x00c5c5c3 0xc2008182
0x828484c5 0xc5c3c200 0x81828284 0x84c4c4c3
0xc2008182 0x828484c4 0xc4c2c181 0x82838385
0x85c5c5c3 0xc2008182 0x828484c5 0xc5c3c200
0x81828284 0x84c5c5c3 0xc2008182 0x82848400
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x378a6e05 0x0ae64a6c 0x00000000 0x50050000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00b40000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x86828786 0x87c8cb8a 0x8380c982 0x00c8ca86
0x8383c583 0x83c1c58c 0x8883c78b 0x8780c28c
0x8485c682 0xc3c4c4c4 0xc5c6c7c8 0xcfcecdcc
0xcccdcec1 0xc1c1c1c2 0xc4c6c7ce 0xcecfcfcf
0xcecec6c7 0xc8c9caca 0xcbcbd2d2 0xd2d2d0ce
0xcc8100c1 0xc3c5c6c7 0xc8d0d0d1 0xd1d1d0cf
0xdeee6be7 0x5fede2eb 0xce08ce09 0xce0ace0a
0x4e0b4f0b 0x4f0c4f0c 0x4f0d4f0d 0x540a540b
0x540c540b 0x540c510a 0x510b510c 0xd10c510d
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0xde0fde10 0xde115e12
0xde12de12 0xde135e14 0x5e0cde0d 0xde0e5e10
0x5e105e10 0x5e11de11 0xde0ede0f 0xde10de11
0x5e12de12 0x5e135e13 0xde0f5e11 0x5e12de13
0x5e13de13 0xde14de14 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00848484 0x84848484 0x84000000 0x00e4d5d4
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
>;
};
@@ -0,0 +1,263 @@
/* Factory EEPROM for PCIe MT7916 radio - Acer Connect Vero W */
/* Offset 0xa0000 in the "factory" GPT partition on eMMC */
&pcie_wifi {
mediatek,eeprom-data = <
0x16790000 0x000c4326 0x60000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x50750000 0x07670700 0x00000400 0x50710000
0x00000000 0x00000400 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0xb101e748 0xf57f5e99
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000800 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x12924848 0x003e003f 0x3a100000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x81a3a380
0xa4910091 0x00910091 0x00910000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x000a0000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x0000c500 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000013 0x12120000 0x00000000
0x00000000 0x00000303 0x03030303 0x03030303
0x03030303 0x03030505 0x05050505 0x05050505
0x05050505 0x05050000 0x001b1919 0x19181818
0x180f0006 0x1c0e080a 0x170e080a 0x170d0809
0x170d020a 0x0e0d020a 0x0e0d020a 0x0e0b020a
0x0e22222c 0x2c2b2b2b 0x2b2b2b2b 0x2b2b2b2b
0x2b2b2b2b 0x2b2b2b2b 0x2b000000 0x00000000
0x00000000 0x001e201e 0x201e2020 0x201e201e
0x20201e20 0x20272929 0x29272727 0x27272929
0x29272727 0x27000000 0x00000000 0x00000000
0x00000000 0x00cdcfcf 0xcfcfcf00 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x007f7f20 0x2530363c 0x41014347 0x4c52575c
0x7f7f0000 0x00000000 0x00000000 0x00000000
0x0000007f 0x7f252834 0x3c424a01 0x4d4f555f
0x636e7f7f 0x7f7f202a 0x303b444a 0x014d5158
0x5f666e7f 0x7f7f7f7f 0x8080c5c5 0xcbcbd9d9
0xe1e1ebeb 0x40408080 0xcfcfdbdb 0xe3e3efef
0xf7f74040 0x8080c1c1 0xcdcdd5d5 0xe1e1eded
0x40408080 0xbbbbc7c7 0xcfcfdbdb 0xe7e74040
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0xb0900000 0x0000c0f0 0xf8000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x02000200 0x02000200 0x02000200 0x02000200
0x02000200 0x02000200 0x02000200 0x02000200
0x02000200 0x02000200 0x02000200 0x02000200
0x02000200 0x02000200 0x02000200 0x02000200
0x000000c6 0xc6c6c6c4 0x0000c5c5 0xc5c4c1c1
0x818383c3 0xc3c2c100 0x81848400 0xc5c5c4c1
0xc1818383 0x8585c3c3 0xc2c10081 0x84848686
0xc5c5c4c1 0xc1818383 0x8585c5c5 0xc4c1c181
0x83838585 0xc5c5c4c1 0xc1818383 0x8585c6c6
0xc4c300c6 0x00c6c4c3 0xc1008181 0xc6c6c4c3
0xc1008181 0x00c5c5c3 0xc2008182 0x8200c6c6
0xc4c3c100 0x81818686 0xc6c6c4c3 0xc1008181
0x8686c5c5 0xc3c20081 0x82828787 0xc5c5c3c2
0x00818282 0x8787c6c6 0xc4c3c100 0x81818686
0xc6c6c4c3 0xc1008181 0x8686c6c6 0xc4c3c100
0x81818686 0xc6c6c4c3 0x00c6c6c4 0xc3c10081
0x818686c6 0xc6c4c3c1 0x00818186 0x86c5c5c3
0xc2008182 0x828787c5 0xc5c3c281 0x82838388
0x88c6c6c4 0xc3c10081 0x818686c6 0xc6c4c3c1
0x00818186 0x86c6c6c4 0xc3c10081 0x81868600
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00b70000 0x00b70000 0x00000000 0x00000000
0x01000000 0x0000c400 0xb8008700 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0xc7c60000 0x89898987 0x87858381 0x898a8b8b
0x8a898785 0x88898988 0x87868584 0x00000000
0x00000000 0xcccfcecd 0xcdcacecd 0xcbcfcece
0xcfcfcfc7 0xcececdce 0xc7cfcec7 0xcfcfcfcf
0xcfcf0000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x7fe2f0e4 0x00000000 0xa4de24df 0xa4e0a4e1
0xa4e1a4de 0x24dfa4e0 0xa4e1a4e1 0xa4dea4df
0xa4e0a4e1 0xa4e1a4de 0xa4df24e0 0xa4e1a4e1
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0xde0fde0f 0xde0fde10
0xde11de11 0x5e12de12 0xde10de10 0xde10de11
0xde12de12 0xde13de13 0x5a085a09 0x5a0a5a0a
0x5a0a5a0a 0x5a0a5a0a 0x5a055a06 0x5a075a08
0x5a085a09 0x5a095a09 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00ded453
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
>;
};
@@ -0,0 +1,63 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
/dts-v1/;
#include "mt7986a-acer-connect-vero-w6m-common.dtsi"
#include "mt7986a-acer-connect-vero-w6m-pcie-eeprom.dtsi"
/ {
model = "Acer Connect Vero W6m";
compatible = "acer,connect-vero-w", "mediatek,mt7986a";
aliases {
serial0 = &uart0;
led-boot = &led_status;
led-failsafe = &led_status;
led-running = &led_status;
led-upgrade = &led_status;
};
};
&i2c0 {
led-controller@30 {
compatible = "kinetic,ktd2026";
reg = <0x30>;
vin-supply = <&reg_5v>;
vio-supply = <&reg_3p3v>;
led_status: multi-led {
color = <LED_COLOR_ID_RGB>;
function = LED_FUNCTION_STATUS;
#address-cells = <1>;
#size-cells = <0>;
led@0 {
reg = <0>;
color = <LED_COLOR_ID_RED>;
};
led@1 {
reg = <1>;
color = <LED_COLOR_ID_GREEN>;
};
led@2 {
reg = <2>;
color = <LED_COLOR_ID_BLUE>;
};
};
};
};
&nvmem {
eeprom_factory_a0000: eeprom@a0000 {
reg = <0xa0000 0x1000>;
};
precal_factory_a1010: precal@a1010 {
reg = <0xa1010 0x62810>;
};
};
&swport0 {
label = "internet";
};
@@ -0,0 +1,86 @@
image cfg.ext4 {
empty = true
temporary = true
size = 128M
ext4 {
label = "cfg"
use-mke2fs = true
features = "uninit_bg"
extraargs = "-m 0 -i 4096"
}
}
image var.ext4 {
empty = true
temporary = true
size = 128M
ext4 {
label = "var"
use-mke2fs = true
features = "uninit_bg"
extraargs = "-m 0 -i 4096"
}
}
image #INFIX_ID##VERSION#-vero-w-#TARGET#.img {
hdimage {
partition-table-type = "gpt"
gpt-no-backup = true
}
/*
* Factory partitions (1-4) -- secure boot, do not overwrite.
* Offsets and sizes match the stock Acer GPT exactly.
* No image data is written, preserving factory content.
*/
partition u-boot-env {
offset = 8192s
size = 1024s
}
partition factory {
offset = 9216s
size = 4096s
}
partition fip {
offset = 13312s
size = 4096s
}
/* Infix U-Boot, chainloaded by stock bootloader */
partition infix-uboot {
offset = 17408s
image = "u-boot.bin"
size = 32M
}
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"
}
}
@@ -0,0 +1,488 @@
{
"ieee802-dot1ab-lldp:lldp": {
"infix-lldp:enabled": true
},
"ietf-hardware:hardware": {
"component": [
{
"name": "USB",
"class": "infix-hardware:usb",
"state": {
"admin-state": "unlocked"
}
},
{
"class": "infix-hardware:usb",
"name": "USB2",
"state": {
"admin-state": "unlocked"
}
},
{
"name": "radio0",
"class": "infix-hardware:wifi",
"infix-hardware:wifi-radio": {
"country-code": "DE",
"band": "2.4GHz",
"channel": "auto"
}
},
{
"name": "radio1",
"class": "infix-hardware:wifi",
"infix-hardware:wifi-radio": {
"country-code": "DE",
"band": "6GHz",
"channel": "auto"
}
},
{
"name": "radio2",
"class": "infix-hardware:wifi",
"infix-hardware:wifi-radio": {
"country-code": "DE",
"band": "5GHz",
"channel": "auto"
}
}
]
},
"ietf-interfaces:interfaces": {
"interface": [
{
"name": "br0",
"type": "infix-if-type:bridge",
"ietf-ip:ipv4": {
"address": [
{
"ip": "192.168.0.1",
"prefix-length": 24
}
]
}
},
{
"name": "lan1",
"type": "infix-if-type:ethernet",
"ietf-ip:ipv6": {},
"infix-interfaces:bridge-port": {
"bridge": "br0"
}
},
{
"name": "lan2",
"type": "infix-if-type:ethernet",
"ietf-ip:ipv6": {},
"infix-interfaces:bridge-port": {
"bridge": "br0"
}
},
{
"name": "lan3",
"type": "infix-if-type:ethernet",
"ietf-ip:ipv6": {},
"infix-interfaces:bridge-port": {
"bridge": "br0"
}
},
{
"name": "lo",
"type": "infix-if-type:loopback",
"ietf-ip:ipv4": {
"address": [
{
"ip": "127.0.0.1",
"prefix-length": 8
}
]
},
"ietf-ip:ipv6": {
"address": [
{
"ip": "::1",
"prefix-length": 128
}
]
}
},
{
"name": "internet",
"type": "infix-if-type:ethernet",
"ietf-ip:ipv4": {
"infix-dhcp-client:dhcp": {
"option": [
{
"id": "ntp-server"
},
{
"id": "broadcast"
},
{
"id": "domain"
},
{
"id": "hostname",
"value": "auto"
},
{
"id": "dns-server"
},
{
"id": "router"
},
{
"id": "netmask"
},
{
"id": "vendor-class",
"value": "Acer Connect Vero W"
}
]
}
},
"ietf-ip:ipv6": {
"infix-dhcpv6-client:dhcp": {
"option": [
{
"id": "ntp-server"
},
{
"id": "client-fqdn"
},
{
"id": "domain-search"
},
{
"id": "dns-server"
}
]
}
}
},
{
"name": "wifi0-ap",
"type": "infix-if-type:wifi",
"infix-interfaces:wifi": {
"radio": "radio0",
"access-point": {
"ssid": "Infix",
"security": {
"secret": "wifi"
}
}
},
"infix-interfaces:bridge-port": {
"bridge": "br0"
}
},
{
"name": "wifi1-ap",
"type": "infix-if-type:wifi",
"infix-interfaces:wifi": {
"radio": "radio1",
"access-point": {
"ssid": "Infix6G",
"security": {
"secret": "wifi"
}
}
},
"infix-interfaces:bridge-port": {
"bridge": "br0"
}
},
{
"name": "wifi2-ap",
"type": "infix-if-type:wifi",
"infix-interfaces:wifi": {
"radio": "radio2",
"access-point": {
"ssid": "Infix5G",
"security": {
"secret": "wifi"
}
}
},
"infix-interfaces:bridge-port": {
"bridge": "br0"
}
}
]
},
"ietf-keystore:keystore": {
"asymmetric-keys": {
"asymmetric-key": [
{
"name": "genkey",
"public-key-format": "infix-crypto-types:ssh-public-key-format",
"public-key": "",
"private-key-format": "infix-crypto-types:rsa-private-key-format",
"cleartext-private-key": "",
"certificates": {}
}
]
},
"symmetric-keys": {
"symmetric-key": [
{
"name": "wifi",
"cleartext-symmetric-key": "aW5maXhpbmZpeA==",
"key-format": "infix-crypto-types:passphrase-key-format"
}
]
}
},
"ietf-netconf-acm:nacm": {
"enable-nacm": true,
"read-default": "permit",
"write-default": "permit",
"exec-default": "permit",
"groups": {
"group": [
{
"name": "admin",
"user-name": [
"admin"
]
},
{
"name": "operator",
"user-name": []
},
{
"name": "guest",
"user-name": []
}
]
},
"rule-list": [
{
"name": "admin-acl",
"group": [
"admin"
],
"rule": [
{
"name": "permit-all",
"module-name": "*",
"access-operations": "*",
"action": "permit",
"comment": "Allow 'admin' group complete access to all operations and data."
}
]
},
{
"name": "operator-acl",
"group": [
"operator"
],
"rule": [
{
"name": "permit-system-rpcs",
"module-name": "ietf-system",
"rpc-name": "*",
"access-operations": "exec",
"action": "permit",
"comment": "Operators can reboot, shutdown, and set system time."
}
]
},
{
"name": "guest-acl",
"group": [
"guest"
],
"rule": [
{
"name": "deny-all-write+exec",
"module-name": "*",
"access-operations": "create update delete exec",
"action": "deny",
"comment": "Guests cannot change anything or exec rpcs."
}
]
},
{
"name": "default-deny-all",
"group": [
"*"
],
"rule": [
{
"name": "deny-password-access",
"path": "/ietf-system:system/authentication/user/password",
"access-operations": "*",
"action": "deny",
"comment": "No user except admins can access password hashes."
},
{
"name": "deny-keystore-access",
"module-name": "ietf-keystore",
"access-operations": "*",
"action": "deny",
"comment": "No user except admins can access cryptographic keys."
},
{
"name": "deny-truststore-access",
"module-name": "ietf-truststore",
"access-operations": "*",
"action": "deny",
"comment": "No user except admins can access trust store."
}
]
}
]
},
"ietf-netconf-server:netconf-server": {
"listen": {
"endpoints": {
"endpoint": [
{
"name": "default-ssh",
"ssh": {
"tcp-server-parameters": {
"local-bind": [
{
"local-address": "::"
}
]
},
"ssh-server-parameters": {
"server-identity": {
"host-key": [
{
"name": "default-key",
"public-key": {
"central-keystore-reference": "genkey"
}
}
]
}
}
}
}
]
}
}
},
"ietf-system:system": {
"hostname": "acer-connect-%m",
"ntp": {
"server": [
{
"name": "default",
"udp": {
"address": "pool.ntp.org"
}
}
]
},
"authentication": {
"user": [
{
"name": "admin",
"password": "$factory$",
"infix-system:shell": "bash"
}
]
},
"infix-system:motd-banner": "Li0tLS0tLS0uCnwgIC4gLiAgfCBJbmZpeCBPUyDigJQgSW1tdXRhYmxlLkZyaWVuZGx5LlNlY3VyZQp8LS4gdiAuLXwgaHR0cHM6Ly9rZXJuZWxraXQub3JnCictJy0tLSctJwo="
},
"infix-dhcp-server:dhcp-server": {
"option": [
{
"id": "ntp-server",
"address": "auto"
},
{
"id": "dns-server",
"address": "auto"
},
{
"id": "router",
"address": "auto"
}
],
"subnet": [
{
"subnet": "192.168.0.0/24",
"pool": {
"start-address": "192.168.0.100",
"end-address": "192.168.0.250"
}
}
]
},
"infix-firewall:firewall": {
"default": "wan",
"zone": [
{
"name": "lan",
"action": "accept",
"interface": [
"br0"
]
},
{
"name": "wan",
"action": "drop",
"interface": [
"internet"
],
"service": [
"dhcpv6-client"
]
}
],
"policy": [
{
"name": "lan-to-wan",
"action": "accept",
"ingress": [
"lan"
],
"egress": [
"wan"
],
"masquerade": true
}
]
},
"infix-meta:meta": {
"version": "1.7"
},
"infix-services:mdns": {
"enabled": true
},
"infix-services:ssh": {
"enabled": true,
"hostkey": [
"genkey"
],
"listen": [
{
"name": "ipv4",
"address": "0.0.0.0",
"port": 22
},
{
"name": "ipv6",
"address": "::",
"port": 22
}
]
},
"infix-services:web": {
"enabled": true,
"console": {
"enabled": true
},
"netbrowse": {
"enabled": true
},
"restconf": {
"enabled": true
}
}
}
@@ -0,0 +1,2 @@
# Locally calculated
sha256 d2f96418893ac66156d0e691cda189b0d85ae1d814065d1d9aa1845383100f46 LICENSE
+1
View File
@@ -6,6 +6,7 @@ config BR2_PACKAGE_BANANAPI_BPI_R3
select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK
select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7986
select BR2_PACKAGE_LINUX_FIRMWARE_AIROHA_EN8811H
select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7916
select SDCARD_AUX
help
Build Banana PI R3 support
+7 -5
View File
@@ -70,11 +70,11 @@ The BPI-R3 has a 4-position DIP switch that controls boot media:
<img align="right" src="bootstrap-switch.webp" alt="DIP switches" width=200 padding=10>
| Position | Mode | Description |
|----------|-------------|---------------------------------------|
| 0000 | SD card | Boot from microSD card |
| 0110 | eMMC | Boot from internal eMMC (recommended) |
| 1010 | SPI NAND | Boot from SPI NAND (advanced users) |
| ABCD | Mode | Description |
|------|----------|---------------------------------------|
| 0000 | SD card | Boot from microSD card |
| 0101 | SPI NAND | Boot from SPI NAND (advanced users) |
| 1001 | eMMC | Boot from internal eMMC (recommended) |
> [!NOTE]
> Switch position is read from left to right: "0" = OFF, "1" = ON.
@@ -150,6 +150,7 @@ From the U-Boot prompt:
usb start
fatload usb 0:1 0x50000000 infix-bpi-r3-emmc.img
setexpr blocks ${filesize} / 0x200
mmc dev 0
mmc write 0x50000000 0x0 ${blocks}
```
@@ -211,6 +212,7 @@ sync
2. Set boot switches to eMMC mode (see image above)
3. Power on
## Troubleshooting
### Board won't boot
@@ -0,0 +1,2 @@
# Locally calculated
sha256 dbe4eae8debbba8135297e15f24aeefef0b4c03781f3f9328db4398d58a728b3 LICENSE
@@ -19,4 +19,34 @@ possible to use dtbo in sysboot unless present in syslinux.conf
no-sd;
no-sdio;
status = "okay";
#address-cells = <1>;
#size-cells = <0>;
card@0 {
compatible = "mmc-card";
reg = <0>;
partitions {
compatible = "gpt-partitions";
partition-factory {
partname = "factory";
nvmem-layout {
compatible = "fixed-layout";
#address-cells = <1>;
#size-cells = <1>;
eeprom_factory_wmac: eeprom@0 {
reg = <0x0 0x1000>;
};
eeprom_factory_pcie: eeprom@a0000 {
reg = <0xa0000 0x1000>;
};
};
};
};
};
};
@@ -24,6 +24,18 @@ https://github.com/openwrt/openwrt/blob/main/target/linux/mediatek/patches-6.12/
&secmon_reserved {
reg = <0 0x43000000 0 0x40000>;
};
/*
* The T-PHY's pcie-phy sub-node only claims clk40m ("ref") in the SoC
* dtsi. CLK_TOP_PCIE_PHY_SEL ("da_ref") is left unclaimed, so the
* kernel's clk_disable_unused late_initcall gates it — killing the
* PCIe REFCLK output to the endpoint mid-probe. Wire it here so the
* clock stays enabled while the PHY is active.
*/
&pcie_port {
clocks = <&clk40m>, <&topckgen CLK_TOP_PCIE_PHY_SEL>;
clock-names = "ref", "da_ref";
};
&cpu_thermal {
/delete-node/ trips;
/delete-node/ cooling-maps;
@@ -4,7 +4,7 @@ CONFIG_BOOTDELAY=2
CONFIG_ENV_IS_NOWHERE=y
# CONFIG_ENV_IS_IN_MMC is not set
CONFIG_MULTI_DTB_FIT=y
CONFIG_OF_LIST="mt7986a-bpi-r3-sd mt7986a-bpi-r3-emmc mt7986a-bpi-r3-mini"
CONFIG_OF_LIST="mt7986a-bpi-r3-sd mt7986a-bpi-r3-emmc mt7986a-bpi-r3-mini mt7986a-acer-connect-vero-w6m"
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
+11
View File
@@ -0,0 +1,11 @@
config BR2_PACKAGE_BANANAPI_BPI_R4
bool "Banana Pi R4"
depends on BR2_aarch64
select BR2_PACKAGE_FEATURE_WIFI
select BR2_PACKAGE_LINUX_FIRMWARE
select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK
select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7988
select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7996
select SDCARD_AUX
help
Build Banana PI R4 support
+13
View File
@@ -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.
+402
View File
@@ -0,0 +1,402 @@
# Banana Pi BPI-R4 / BPI-R4-2g5 / BPI-R4P
<img src="banana_pi_bpi-r4_poe.jpg" alt="The board" width=800 padding=10>
## Overview
The Banana Pi BPI-R4 is a high-performance networking board built around the
MediaTek MT7988A SoC (Filogic 880). It is a successor to the BPI-R3 and
represents a significant step up: the CPU switches from in-order Cortex-A53
cores to out-of-order Cortex-A73 cores, and the MT7531 switch is now part of
the SOC. The base model comes with two SFP+ cages supporting 1.25/2.5/5/10
Gbps, and the R4P model comes with one SFP+ cage and one 2.5 Gbps RJ45 jack,
which with an optional PoE board means the board can act as PD. Unlike the
BPi-R3, however, there is no on-board WiFi support, that requires an external
tri-band WiFi 7 (IEEE 802.11be) card.
### Variants
| **Feature** | **BPI-R4** | **BPI-R4-2g5** | **BPI-R4P** |
|------------------|------------------|-------------------|---------------------------|
| 1G switch ports | wan, lan1lan3 | lan0lan3 | lan0lan3 |
| 2.5G RJ45 (WAN) | — | wan | wan (PoE input) |
| SFP+ port(s) | sfp1, sfp2 (10G) | sfp1 (10G) | sfp1 (10G) |
| Linux DT | bpi-r4 | bpi-r4-2g5 | bpi-r4-2g5 (same) |
On the standard BPI-R4 the four 1G switch ports are labeled `wan`, `lan1`, `lan2`,
and `lan3`. On the R4-2g5 and R4P, the port that would otherwise be `wan` on the
switch is relabeled `lan0` via a device tree overlay, since the actual WAN port on
those variants is the dedicated 2.5G internal PHY on the separate RJ45 jack.
The BPI-R4P is mechanically and electrically identical to the BPI-R4-2g5
with an additional PoE daughterboard header. From a Linux kernel and
Infix perspective the two boards are treated identically.
### SoC: MediaTek MT7988A vs MT7986 (BPI-R3)
The MT7988A (Filogic 880) and MT7986 (Filogic 820) may look similar from
their part numbers, but they are built on entirely different silicon with
distinct system architectures:
| **Aspect** | **MT7988A (BPI-R4)** | **MT7986 (BPI-R3)** |
|------------------|--------------------------|---------------------------|
| CPU cores | 4x Cortex-A73 @ 1.8 GHz | 4x Cortex-A53 @ 2.0 GHz |
| CPU architecture | ARMv8-A, out-of-order | ARMv8-A, in-order |
| Internal switch | 1 Gbps per port | 1 Gbps per port |
| Uplinks | USXGMII (native 10 Gbps) | USXGMII (native 2.5 Gbps) |
| WiFi | MT7996E PCIe module | MT7915E (built-in) |
| WiFi standard | WiFi 7 (802.11be) | WiFi 6 (802.11ax) |
| WiFi bands | 2.4 / 5 / 6 GHz | 2.4 / 5 GHz |
| Hardware crypto | EIP-197 NPU | EIP-93 |
| PCIe slots | 4 (2x mPCIe, 2x M.2) | 1 mPCIe |
| Boot ROM offset | Sector 1024 (0x80000) | Sector 1024 (0x80000) |
### Hardware Features
- **SoC:** MediaTek MT7988A (Filogic 880)
- **CPU:** Quad-core ARM Cortex-A73, up to 1.8 GHz
- **RAM:** 4 GB DDR4
- **Storage:** 8 GB eMMC, microSD card slot, SPI NAND flash
- **Ethernet switch:** 4-port 1 GbE (10/100/1000) internal DSA switch
- **SFP+ ports:** 2x 10 Gbps USXGMII (standard R4) or 1x SFP+ (R4-2g5/R4P)
- **WiFi:** optional MediaTek MT7996E PCIe module — tri-band WiFi 7 (2.4/5/6 GHz)
- **USB:** 1x USB 3.0 (xHCI)
- **PCIe:** 2x mPCIe (SIM2/SIM3), 1x M.2 Key-B (SIM1), 1x M.2 Key-M (SSD)
- **RTC:** PCF8563 on I2C
- **Fan:** PWM-controlled cooling with thermal management
- **Console:** UART at 115200 8N1 (3.3 V, USB-to-serial adapter required)
### Default Network Configuration
Infix ships with the following factory defaults.
**Standard BPI-R4:**
- **LAN bridge** (`br0`, 192.168.0.1/24): `lan1`, `lan2`, `lan3` (1G switch ports)
- **WAN port** (`wan`): DHCP client, used for internet uplink (1G switch port)
- **SFP+ ports** (`sfp1`, `sfp2`): Present but unconfigured
**BPI-R4-2g5 and BPI-R4P:**
- **LAN bridge** (`br0`, 192.168.0.1/24): `lan0`, `lan1`, `lan2`, `lan3` (1G switch ports)
- **WAN port** (`wan`): DHCP client, used for internet uplink (2.5G internal PHY)
- **SFP+ port** (`sfp1`): Present but unconfigured
> [!NOTE]
> If an optional WiFi 7 (MT7996E) PCIe card is installed, the radio interfaces
> are bridged into the LAN as access points. WiFi is not included with the board
> and is not part of the factory default configuration.
## SIM Card Installation
The BPI-R4 has three SIM holders, one per PCIe slot:
| Slot | PCIe socket | Typical use |
|----------|-------------|--------------------------|
| **SIM1** | M.2 Key-B | 4G/5G WWAN modem |
| **SIM2** | mPCIe #1 | Cellular or other modem |
| **SIM3** | mPCIe #2 | Cellular or other modem |
All three take **nano-SIM (4FF)** cards.
> [!NOTE]
> The official Banana Pi pages show an older board revision with a sliding
> "sled" holder. Newer boards ship with a fixed friction-fit holder instead:
> there is no lid to lift and no spring eject. The [closest matching photo on
> bananapi.org][15] shows the current mechanism.
### Inserting a SIM
1. Orient the card with the gold contacts facing the PCB (printed
side up) and the cut corner pointing toward the M.2/mPCIe socket,
which on this board is also toward the outer edge. The silkscreen
next to each holder shows the same outline.
2. Push the SIM straight in until it is fully seated. There is no
click and the holder is not spring-loaded, so press firmly until
the contacts engage and the rear edge of the card sits flush with
the holder.
3. A SIM that still protrudes is not fully inserted; push again.
### Removing a SIM
The friction grip on these holders is tight. Gently pry the card out
with a fingernail or a thin plastic spudger. Avoid metal tweezers
near the contacts. Removing the front panel of the metal case is
absolutely necessary to access the SIM holder.
For software configuration once the modem is recognised, see the
[Cellular Modem User's Guide][16].
## Getting Started
<img align="right" src="console-header.png" alt="Console header pins" width=200 padding=10>
### Quick Start with SD Card
1. **Download the SD card image:** [infix-bpi-r4-sdcard.img][2]
2. **Flash the image to an SD card:** see [this guide][0]
3. **Set boot switches to SD card mode** (see Boot Switch Reference below)
4. **Insert the SD card, connect power and a serial console (115200 8N1)**
5. Default login: `admin` / `admin`
### Boot Switch Reference
<img align="right" src="bootstrap-sw3.png" alt="DIP switches" width=140 padding=10>
The BPI-R4 has a 2-position DIP switch (SW3) that selects the boot media.
Switch positions are printed on the board near the SD card slot.
| A | B | Boot media (SW3) |
|-----|-----|------------------|
| OFF | ON | SPI NAND |
| ON | OFF | eMMC |
| ON | ON | SD card |
> [!NOTE]
> "OFF" = switch in the UP position = logical 0.
## Installing to eMMC
For production use or better reliability, install Infix to the internal
eMMC storage.
> [!IMPORTANT]
> The MT7988A has a single MMC controller that can only operate in one mode
> (SD or eMMC) per boot session. The SD card U-Boot cannot switch to eMMC
> mode mid-session, so an intermediate NAND bootloader step is required to
> write the eMMC — the same approach as BPi-R3.
>
> The MT7988A boot chain is: **BROM → BL2 → FIP (BL31 + U-Boot)**. The FIP
> (Firmware Image Package) bundles ARM Trusted Firmware (BL31) and U-Boot
> together; it is not just a U-Boot binary. When BL2 runs, it loads the FIP
> from a fixed offset and hands off to BL31, which then jumps into U-Boot.
>
> The factory SPI NAND contains a minimal recovery U-Boot that only supports
> TFTP — it has no USB command. You cannot use it to load files from a USB
> drive. Similarly, the factory eMMC ships with a basic OpenWRT image.
> You must first flash a full-featured U-Boot (from Frank-W) to SPI NAND via
> the SD card U-Boot before you can write the eMMC.
>
> This process involves three boot mode changes and multiple flash operations.
> Take your time and verify each step carefully.
### Prerequisites
- USB-to-serial adapter (3.3 V) for console access
- USB flash drive (FAT32 formatted)
- microSD card with Infix SD image, for initial boot
- Downloaded files (see below)
### Required Files
Place these files on a FAT32-formatted USB drive:
1. **Infix eMMC image:** [infix-bpi-r4-emmc.img][3]
2. **eMMC bootloader** (from): [bpi-r4-emmc-boot-2026.01-latest.tar.gz][4]
- Extract `bl2.img` from the tarball to your USB drive
3. **Intermediate NAND bootloader** from Frank-W's U-Boot (for BPI-R4, SPI NAND):
- [bpi-r4_spim-nand_bl2.img][13] — BL2 first-stage loader
- [bpi-r4_spim-nand_fip.bin][14] — FIP image (BL31 + U-Boot)
### Step 1: Boot from SD card
1. Set boot switches to **SD card mode** (SW3: A=ON, B=ON)
2. Insert the SD card with the Infix image
3. Power on and break into U-Boot (press Ctrl-C during countdown)
### Step 2: Flash intermediate NAND bootloader
This installs a full-featured U-Boot to SPI NAND so the board can load files
from USB in the next step. From the SD card U-Boot prompt:
```
usb start
mtd erase spi-nand0
fatload usb 0:1 0x50000000 bpi-r4_spim-nand_bl2.img
mtd write spi-nand0 0x50000000 0x0 0x100000
fatload usb 0:1 0x50000000 bpi-r4_spim-nand_fip.bin
mtd write spi-nand0 0x50000000 0x580000 0x200000
```
### Step 3: Boot from NAND
1. Power off the board
2. Set boot switches to **SPI NAND mode** (SW3: A=OFF, B=ON)
3. Power on — you should boot into U-Boot again
### Step 4: Write Infix image to eMMC
From the U-Boot prompt:
```
usb start
fatload usb 0:1 0x50000000 infix-bpi-r4-emmc.img
setexpr blocks ${filesize} / 0x200
mmc write 0x50000000 0x0 ${blocks}
```
### Step 5: Configure eMMC boot partition
Write the BL2 bootloader to the eMMC boot partition:
```
mmc partconf 0 1 1 1
mmc erase 0x0 0x400
fatload usb 0:1 0x50000000 bl2.img
mmc write 0x50000000 0x0 0x400
mmc partconf 0 1 1 0
```
### Step 6: Boot from eMMC
1. Power off the board
2. Set boot switches to **eMMC mode** (SW3: A=ON, B=OFF)
3. Remove the SD card (optional, recommended to verify eMMC boot)
4. Power on
Your BPI-R4 should now boot Infix from internal eMMC storage.
## Troubleshooting
### Board won't boot
- Verify boot switch positions — double-check against the wiki
- Ensure the power supply provides adequate current (12 V / 3 A recommended)
- Check the serial console output at 115200 8N1
### Can't break into U-Boot
- Connect the serial console before powering on
- Press Ctrl-C immediately when boot messages appear
- Try power cycling and pressing Ctrl-C repeatedly during the countdown
### eMMC boot fails after installation
- Boot from NAND (SW3=ON) and verify the eMMC write completed without errors
- Re-run the `mmc partconf` sequence — a missed step is the most common
cause of failure
- Use `mmc info` to confirm the eMMC is detected
### No network connectivity
The interface names on BPI-R4 differ from BPI-R3. Confirm what Linux
has created with `ip link` and compare with the factory configuration:
- `wan`, `lan1``lan3`: 1G switch ports (standard R4)
- `wan`, `lan0``lan3`: on R4-2g5/R4P, `wan` is the 2.5G internal PHY; `lan0``lan3` are 1G switch ports
- `sfp1` (and `sfp2` on standard R4): 10G SFP+ cage(s)
If interface renames look wrong, check `dmesg | grep renamed` and if
you spot any errors, please report as an issue to the Infix tracker
on GitHub.
## Board Variants
### BPI-R4
The base model BPi-R4 ports look like this, the `wan` port is the same physical
switch port as `lan0` on the R4-2g5/R4P, but here it serves as the WAN port in
the factory default configuration.
```
.-.
| | .-----.-----.-----.-----.
| | _______ _______ | | | | | .---.
| | | | | | | | | | | | | .-----.
'-' '-------' '-------' '-----'-----'-----'-----' '---' '-----'
USB1 sfp1 sfp2 wan lan1 lan2 lan3 DC12V PD20V
```
### BPI-R4-2g5 and BPI-R4P
These variants substitute one SFP+ cage for an internal 2.5 Gbps PHY
connected to a standard RJ45 jack. From a kernel perspective they use
the `mt7988a-bananapi-bpi-r4-2g5` device tree.
The BPI-R4P additionally supports an optional PoE input daughterboard on
the 2.5 Gbps RJ45 port. The PoE circuitry is passive with respect to
Linux — no special kernel driver is required for basic operation.
For these board variants, the WAN role moves to the dedicated 2.5G internal PHY,
so all four switch ports become LAN ports (`lan0``lan3`) instead of three:
```
.-.
| | .-----. .-----.-----.-----.-----.
| | _______ | | | | | | | .---.
| | | | | | | | | | | | | .-----.
'-' '-------' '-----' '-----'-----'-----'-----' '---' '-----'
USB1 sfp1 wan lan0 lan1 lan2 lan3 DC12V PD20V
```
### Selecting the Board Variant
U-Boot cannot automatically distinguish the standard R4 from the R4-2g5/R4P at
boot time (the on-board EEPROM is not programmed from factory). Instead, the
variant is read from the persistent U-Boot environment on the `aux` partition,
and you have to set it manually using `fw_setenv` from a UNIX shell:
```bash
# For BPI-R4-2g5 or BPI-R4P (1x SFP+ + 1x 2.5 Gbps RJ45):
sudo fw_setenv BOARD_VARIANT 2g5
# To revert to the standard BPI-R4 (2x SFP+) clear the setting:
sudo fw_setenv BOARD_VARIANT
```
> [!IMPORTANT]
> The change takes effect on the next reboot. No re-flashing is required, but
> you may want to do a factory reset to activate the changes in your system
> `startup-config`: `sudo factory -y` from shell, or the CLI.
`fw_setenv` writes to the `uboot.env` file on the aux partition. U-Boot
reads this at every boot (before loading the kernel) and selects the
matching device tree:
| `BOARD_VARIANT` | Device tree loaded |
|-----------------|-----------------------------------|
| *(unset)* | `mt7988a-bananapi-bpi-r4.dtb` |
| `2g5` | `mt7988a-bananapi-bpi-r4-2g5.dtb` |
## Additional Resources
- [Infix Documentation][1]
- [Official BPI-R4 Page][7]
- [BPI-R4 Forum][8]
- [Frank-W's site][9]
- [Release Downloads][10]
- [Bootloader Builds][11]
## Building Custom Images
```bash
# Build bootloaders for SD and eMMC
make x-bpi-r4-sd-boot
make x-bpi-r4-emmc-boot
# Build main system
make aarch64
# Create SD card image
./utils/mkimage.sh -od bananapi-bpi-r4
# Create eMMC image
./utils/mkimage.sh -odt emmc bananapi-bpi-r4
```
[0]: https://www.kernelkit.org/posts/flashing-sdcard/
[1]: https://www.kernelkit.org/infix/latest/
[2]: https://github.com/kernelkit/infix/releases/download/latest-boot/infix-bpi-r4-sdcard.img
[3]: https://github.com/kernelkit/infix/releases/download/latest-boot/infix-bpi-r4-emmc.img
[4]: https://github.com/kernelkit/infix/releases/download/latest-boot/bpi-r4-emmc-boot-2026.01-latest.tar.gz
[7]: https://docs.banana-pi.org/en/BPI-R4/BananaPi_BPI-R4
[8]: https://forum.banana-pi.org/
[9]: https://wiki.fw-web.de/doku.php?id=en:bpi-r4:start
[10]: https://github.com/kernelkit/infix/releases/tag/latest
[11]: https://github.com/kernelkit/infix/releases/tag/latest-boot
[12]: https://github.com/frank-w/u-boot/releases
[13]: https://github.com/frank-w/u-boot/releases/download/CI-BUILD-2026-01-bpi-2026.01-2026-01-15_2013/bpi-r4_spim-nand_bl2.img
[14]: https://github.com/frank-w/u-boot/releases/download/CI-BUILD-2026-01-bpi-2026.01-2026-01-15_2013/bpi-r4_spim-nand_fip.bin
[15]: https://docs.banana-pi.org/bpi-r4/bpi-r4_4g5g_2.jpg
[16]: https://www.kernelkit.org/infix/latest/modem/
Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

@@ -0,0 +1,2 @@
# Locally calculated
sha256 d48246c717b505cc11df95171f2fd548b389e1a463f1af4c68d0b69fe0d1009b LICENSE
@@ -0,0 +1,49 @@
define BANANAPI_BPI_R4_LINUX_CONFIG_FIXUPS
$(call KCONFIG_ENABLE_OPT,CONFIG_ARCH_MEDIATEK)
$(call KCONFIG_ENABLE_OPT,CONFIG_MACH_MT7988)
$(call KCONFIG_ENABLE_OPT,CONFIG_PINCTRL_MT7988)
$(call KCONFIG_ENABLE_OPT,CONFIG_SERIAL_8250_MT6577)
$(call KCONFIG_SET_OPT,CONFIG_I2C_GPIO,y)
$(call KCONFIG_SET_OPT,CONFIG_MTK_THERMAL,m)
$(call KCONFIG_SET_OPT,CONFIG_MTK_LVTS_THERMAL,m)
$(call KCONFIG_ENABLE_OPT,CONFIG_MTK_UART)
$(call KCONFIG_ENABLE_OPT,CONFIG_MEDIATEK_WATCHDOG)
$(call KCONFIG_ENABLE_OPT,CONFIG_MEDIATEK_GE_PHY)
$(call KCONFIG_ENABLE_OPT,CONFIG_MEDIATEK_GE_SOC_PHY)
$(call KCONFIG_ENABLE_OPT,CONFIG_NET_VENDOR_MEDIATEK)
$(call KCONFIG_ENABLE_OPT,CONFIG_NET_MEDIATEK_SOC)
$(call KCONFIG_SET_OPT,CONFIG_NET_DSA_MT7530,m)
$(call KCONFIG_SET_OPT,CONFIG_MT7996E,m)
$(call KCONFIG_SET_OPT,CONFIG_PCIE_MEDIATEK_GEN3,m)
$(call KCONFIG_ENABLE_OPT,CONFIG_MTK_SCPSYS)
$(call KCONFIG_ENABLE_OPT,CONFIG_MMC_MTK)
$(call KCONFIG_SET_OPT,CONFIG_I2C_MT65XX,m)
$(call KCONFIG_SET_OPT,CONFIG_USB_XHCI_MTK,m)
$(call KCONFIG_SET_OPT,CONFIG_PHY_MTK_TPHY,m)
$(call KCONFIG_SET_OPT,CONFIG_PHY_MTK_XSPHY,m)
$(call KCONFIG_SET_OPT,CONFIG_PHY_MTK_XFI_TPHY,m)
$(call KCONFIG_SET_OPT,CONFIG_PCS_STANDALONE,y)
$(call KCONFIG_SET_OPT,CONFIG_PCS_MTK_USXGMII,y)
$(call KCONFIG_SET_OPT,CONFIG_PWM_MEDIATEK,m)
$(call KCONFIG_SET_OPT,CONFIG_SENSORS_PWM_FAN,m)
$(call KCONFIG_SET_OPT,CONFIG_NVMEM_MTK_EFUSE,m)
$(call KCONFIG_SET_OPT,CONFIG_MEDIATEK_2P5GE_PHY,m)
$(call KCONFIG_SET_OPT,CONFIG_CRYPTO_DEV_SAFEXCEL,m)
endef
LINUX_DTS_MT7988 = $(LINUX_DIR)/arch/arm64/boot/dts/mediatek
define BANANAPI_BPI_R4_KERNEL_DTBS_INSTALL_TARGET
@$(call MESSAGE,"Installing kernel DTBs and DTBOs for BPI-R4")
$(foreach f, \
mt7988a-bananapi-bpi-r4.dtb \
mt7988a-bananapi-bpi-r4-2g5.dtb \
mt7988a-bananapi-bpi-r4-sd.dtbo \
mt7988a-bananapi-bpi-r4-emmc.dtbo, \
$(INSTALL) -D $(LINUX_DTS_MT7988)/$(f) \
$(TARGET_DIR)/boot/mediatek/$(f)$(sep))
endef
BANANAPI_BPI_R4_POST_INSTALL_TARGET_HOOKS += BANANAPI_BPI_R4_KERNEL_DTBS_INSTALL_TARGET
$(eval $(ix-board))
$(eval $(generic-package))
Binary file not shown.

After

Width:  |  Height:  |  Size: 348 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 KiB

@@ -0,0 +1,2 @@
dtb-y += infix/bananapi,bpi-r4.dtbo
dtb-y += infix/bananapi,bpi-r4-2g5.dtbo
@@ -0,0 +1,32 @@
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/dts-v1/;
/plugin/;
/ {
compatible = "bananapi,bpi-r4-2g5";
};
/*
* On the 2g5 variant, GMAC1 uses the internal 2.5G PHY (eth1 renamed to
* "wan" by udev). The switch's port0, which is labeled "wan" in the base
* DTS, would cause a name collision when the switch driver registers it.
* Rename it to "lan0" here so the kernel names it correctly from the start.
*/
&gsw_port0 {
label = "lan0";
};
/*
* The upstream mt7988a.dtsi sets compatible = "ethernet-phy-ieee802.3-c45"
* on the internal 2.5G PHY node. That gives genphy_c45 (built-in) OF-match
* priority over the PHY-ID-based mtk-2p5ge driver, leaving the PHY powered
* down and unclaimed. Replace it with the standard ethernet-phy-idXXXX.XXXX
* form so of_get_phy_id() registers the PHY as C22 with explicit ID 0x00339c11.
* mtk-2p5ge then matches via PHY_ID_MATCH_VENDOR(0x00339c00) instead of
* genphy_c45 winning via OF-match.
* Note: /delete-property/ is not used because U-Boot fdt apply does not
* implement property deletion in overlays.
*/
&int_2p5g_phy {
compatible = "ethernet-phy-id0033.9c11";
};
@@ -0,0 +1,28 @@
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/dts-v1/;
/plugin/;
/ {
compatible = "bananapi,bpi-r4", "mediatek,mt7988a";
};
/*
* The upstream mt7988a-bananapi-bpi-r4.dtsi sets stdout-path = "serial0:..."
* but the aliases node there only has ethernet entries. Linux resolves
* stdout-path by looking in /aliases, so we must add serial0 here.
* Path references in overlay aliases cannot use &label, so use the full path.
*/
&{/} {
aliases {
serial0 = "/soc/serial@11000000";
};
chosen {
infix {
/* Default admin user password: 'admin' */
factory-password-hash = "$5$mI/zpOAqZYKLC2WU$i7iPzZiIjOjrBF3NyftS9CCq8dfYwHwrmUK097Jca9A";
usb-ports = <&ssusb1>;
usb-port-names = "USB";
};
};
};
@@ -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 SD-card or eMMC media.
image var.ext4 {
empty = true
temporary = true
size = 128M
ext4 {
label = "var"
use-mke2fs = true
features = "uninit_bg"
extraargs = "-m 0 -i 4096"
}
}
image #INFIX_ID##VERSION#-bpi-r4-#TARGET#.img {
hdimage {
partition-table-type = "gpt"
gpt-no-backup = true
}
# BL2 bootloader partition (MediaTek official location)
partition bl2 {
image = "bl2.img"
offset = 1024s # 0x80000 = sector 1024
size = 4M # 0x400000
bootable = true
}
# Factory/calibration data (sectors 9216-13311)
partition factory {
offset = 4608K # 0x480000
size = 2M # 0x200000
}
# FIP partition - BL31 + U-Boot (sectors 13312-17407)
partition fip {
image = "fip.bin"
offset = 13312s
size = 4096s
}
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"
}
}
@@ -0,0 +1,5 @@
label Infix (aarch64)
kernel /boot/Image
fdtdir /boot
fdtoverlays /boot/mediatek/mt7988a-bananapi-bpi-r4-emmc.dtbo /boot/infix/bananapi,bpi-r4.dtbo /boot/infix/bananapi,bpi-r4-2g5.dtbo
append ${bootargs_root} ${bootargs_log} usbcore.authorized_default=2 -- ${bootargs_user}
@@ -0,0 +1,5 @@
label Infix (aarch64)
kernel /boot/Image
fdtdir /boot
fdtoverlays /boot/mediatek/mt7988a-bananapi-bpi-r4-sd.dtbo /boot/infix/bananapi,bpi-r4.dtbo /boot/infix/bananapi,bpi-r4-2g5.dtbo
append ${bootargs_root} ${bootargs_log} usbcore.authorized_default=2 -- ${bootargs_user}
@@ -0,0 +1,5 @@
label Infix (aarch64)
kernel /boot/Image
fdtdir /boot
fdtoverlays /boot/mediatek/mt7988a-bananapi-bpi-r4-emmc.dtbo /boot/infix/bananapi,bpi-r4.dtbo
append ${bootargs_root} ${bootargs_log} usbcore.authorized_default=2 -- ${bootargs_user}
@@ -0,0 +1,5 @@
label Infix (aarch64)
kernel /boot/Image
fdtdir /boot
fdtoverlays /boot/mediatek/mt7988a-bananapi-bpi-r4-sd.dtbo /boot/infix/bananapi,bpi-r4.dtbo
append ${bootargs_root} ${bootargs_log} usbcore.authorized_default=2 -- ${bootargs_user}
@@ -0,0 +1,411 @@
{
"ieee802-dot1ab-lldp:lldp": {
"infix-lldp:enabled": true
},
"ietf-hardware:hardware": {
"component": [
{
"name": "USB",
"class": "infix-hardware:usb",
"state": {
"admin-state": "unlocked"
}
},
{
"name": "USB2",
"class": "infix-hardware:usb",
"state": {
"admin-state": "unlocked"
}
}
]
},
"ietf-interfaces:interfaces": {
"interface": [
{
"name": "br0",
"type": "infix-if-type:bridge",
"ietf-ip:ipv4": {
"address": [
{
"ip": "192.168.0.1",
"prefix-length": 24
}
]
}
},
{
"name": "lan0",
"type": "infix-if-type:ethernet",
"ietf-ip:ipv6": {},
"infix-interfaces:bridge-port": {
"bridge": "br0"
}
},
{
"name": "lan1",
"type": "infix-if-type:ethernet",
"ietf-ip:ipv6": {},
"infix-interfaces:bridge-port": {
"bridge": "br0"
}
},
{
"name": "lan2",
"type": "infix-if-type:ethernet",
"ietf-ip:ipv6": {},
"infix-interfaces:bridge-port": {
"bridge": "br0"
}
},
{
"name": "lan3",
"type": "infix-if-type:ethernet",
"ietf-ip:ipv6": {},
"infix-interfaces:bridge-port": {
"bridge": "br0"
}
},
{
"name": "lo",
"type": "infix-if-type:loopback",
"ietf-ip:ipv4": {
"address": [
{
"ip": "127.0.0.1",
"prefix-length": 8
}
]
},
"ietf-ip:ipv6": {
"address": [
{
"ip": "::1",
"prefix-length": 128
}
]
}
},
{
"name": "wan",
"type": "infix-if-type:ethernet",
"ietf-ip:ipv4": {
"infix-dhcp-client:dhcp": {
"option": [
{
"id": "ntp-server"
},
{
"id": "broadcast"
},
{
"id": "domain"
},
{
"id": "hostname",
"value": "auto"
},
{
"id": "dns-server"
},
{
"id": "router"
},
{
"id": "netmask"
},
{
"id": "vendor-class",
"value": "Banana Pi BPI-R4"
}
]
}
},
"ietf-ip:ipv6": {
"infix-dhcpv6-client:dhcp": {
"option": [
{
"id": "ntp-server"
},
{
"id": "client-fqdn"
},
{
"id": "domain-search"
},
{
"id": "dns-server"
}
]
}
}
}
]
},
"ietf-keystore:keystore": {
"asymmetric-keys": {
"asymmetric-key": [
{
"name": "genkey",
"public-key-format": "infix-crypto-types:ssh-public-key-format",
"public-key": "",
"private-key-format": "infix-crypto-types:rsa-private-key-format",
"cleartext-private-key": "",
"certificates": {}
}
]
}
},
"ietf-netconf-acm:nacm": {
"enable-nacm": true,
"read-default": "permit",
"write-default": "permit",
"exec-default": "permit",
"groups": {
"group": [
{
"name": "admin",
"user-name": [
"admin"
]
},
{
"name": "operator",
"user-name": []
},
{
"name": "guest",
"user-name": []
}
]
},
"rule-list": [
{
"name": "admin-acl",
"group": [
"admin"
],
"rule": [
{
"name": "permit-all",
"module-name": "*",
"access-operations": "*",
"action": "permit",
"comment": "Allow 'admin' group complete access to all operations and data."
}
]
},
{
"name": "operator-acl",
"group": [
"operator"
],
"rule": [
{
"name": "permit-system-rpcs",
"module-name": "ietf-system",
"rpc-name": "*",
"access-operations": "exec",
"action": "permit",
"comment": "Operators can reboot, shutdown, and set system time."
}
]
},
{
"name": "guest-acl",
"group": [
"guest"
],
"rule": [
{
"name": "deny-all-write+exec",
"module-name": "*",
"access-operations": "create update delete exec",
"action": "deny",
"comment": "Guests cannot change anything or exec rpcs."
}
]
},
{
"name": "default-deny-all",
"group": [
"*"
],
"rule": [
{
"name": "deny-password-access",
"path": "/ietf-system:system/authentication/user/password",
"access-operations": "*",
"action": "deny",
"comment": "No user except admins can access password hashes."
},
{
"name": "deny-keystore-access",
"module-name": "ietf-keystore",
"access-operations": "*",
"action": "deny",
"comment": "No user except admins can access cryptographic keys."
},
{
"name": "deny-truststore-access",
"module-name": "ietf-truststore",
"access-operations": "*",
"action": "deny",
"comment": "No user except admins can access trust store."
}
]
}
]
},
"ietf-netconf-server:netconf-server": {
"listen": {
"endpoints": {
"endpoint": [
{
"name": "default-ssh",
"ssh": {
"tcp-server-parameters": {
"local-bind": [
{
"local-address": "::"
}
]
},
"ssh-server-parameters": {
"server-identity": {
"host-key": [
{
"name": "default-key",
"public-key": {
"central-keystore-reference": "genkey"
}
}
]
}
}
}
}
]
}
}
},
"ietf-system:system": {
"hostname": "bpi-%m",
"ntp": {
"server": [
{
"name": "default",
"udp": {
"address": "pool.ntp.org"
}
}
]
},
"authentication": {
"user": [
{
"name": "admin",
"password": "$factory$",
"infix-system:shell": "bash"
}
]
},
"infix-system:motd-banner": "Li0tLS0tLS0uCnwgIC4gLiAgfCBJbmZpeCBPUyDigJQgSW1tdXRhYmxlLkZyaWVuZGx5LlNlY3VyZQp8LS4gdiAuLXwgaHR0cHM6Ly9rZXJuZWxraXQub3JnCictJy0tLSctJwo="
},
"infix-dhcp-server:dhcp-server": {
"option": [
{
"id": "ntp-server",
"address": "auto"
},
{
"id": "dns-server",
"address": "auto"
},
{
"id": "router",
"address": "auto"
}
],
"subnet": [
{
"subnet": "192.168.0.0/24",
"pool": {
"start-address": "192.168.0.100",
"end-address": "192.168.0.250"
}
}
]
},
"infix-firewall:firewall": {
"default": "wan",
"zone": [
{
"name": "lan",
"action": "accept",
"interface": [
"br0"
]
},
{
"name": "wan",
"action": "drop",
"interface": [
"wan"
],
"service": [
"dhcpv6-client"
]
}
],
"policy": [
{
"name": "lan-to-wan",
"action": "accept",
"ingress": [
"lan"
],
"egress": [
"wan"
],
"masquerade": true
}
]
},
"infix-meta:meta": {
"version": "1.8"
},
"infix-services:mdns": {
"enabled": true
},
"infix-services:ssh": {
"enabled": true,
"hostkey": [
"genkey"
],
"listen": [
{
"name": "ipv4",
"address": "0.0.0.0",
"port": 22
},
{
"name": "ipv6",
"address": "::",
"port": 22
}
]
},
"infix-services:web": {
"enabled": true,
"console": {
"enabled": true
},
"netbrowse": {
"enabled": true
},
"restconf": {
"enabled": true
}
}
}
@@ -0,0 +1,5 @@
# The mtk-2p5ge PHY driver uses MDIO PHY ID matching, not OF compatible
# matching. udev auto-loading is based on MODALIAS, which for DT-described
# devices is "of:N...C<compatible>" — a format that never matches the driver's
# "mdio:..." module alias. Match on OF_COMPATIBLE_0 explicitly instead.
ACTION=="add", SUBSYSTEM=="mdio_bus", ENV{OF_COMPATIBLE_0}=="ethernet-phy-id0033.9c11", RUN+="/sbin/modprobe -b mtk-2p5ge"
@@ -0,0 +1,2 @@
ACTION=="add", SUBSYSTEM=="net", DEVPATH=="/devices/platform/soc/15100000.ethernet/net/eth1", NAME="wan"
ACTION=="add", SUBSYSTEM=="net", DEVPATH=="/devices/platform/soc/15100000.ethernet/net/eth2", NAME="sfp1"
@@ -0,0 +1,403 @@
{
"ieee802-dot1ab-lldp:lldp": {
"infix-lldp:enabled": true
},
"ietf-hardware:hardware": {
"component": [
{
"name": "USB",
"class": "infix-hardware:usb",
"state": {
"admin-state": "unlocked"
}
},
{
"name": "USB2",
"class": "infix-hardware:usb",
"state": {
"admin-state": "unlocked"
}
}
]
},
"ietf-interfaces:interfaces": {
"interface": [
{
"name": "br0",
"type": "infix-if-type:bridge",
"ietf-ip:ipv4": {
"address": [
{
"ip": "192.168.0.1",
"prefix-length": 24
}
]
}
},
{
"name": "lan1",
"type": "infix-if-type:ethernet",
"ietf-ip:ipv6": {},
"infix-interfaces:bridge-port": {
"bridge": "br0"
}
},
{
"name": "lan2",
"type": "infix-if-type:ethernet",
"ietf-ip:ipv6": {},
"infix-interfaces:bridge-port": {
"bridge": "br0"
}
},
{
"name": "lan3",
"type": "infix-if-type:ethernet",
"ietf-ip:ipv6": {},
"infix-interfaces:bridge-port": {
"bridge": "br0"
}
},
{
"name": "lo",
"type": "infix-if-type:loopback",
"ietf-ip:ipv4": {
"address": [
{
"ip": "127.0.0.1",
"prefix-length": 8
}
]
},
"ietf-ip:ipv6": {
"address": [
{
"ip": "::1",
"prefix-length": 128
}
]
}
},
{
"name": "wan",
"type": "infix-if-type:ethernet",
"ietf-ip:ipv4": {
"infix-dhcp-client:dhcp": {
"option": [
{
"id": "ntp-server"
},
{
"id": "broadcast"
},
{
"id": "domain"
},
{
"id": "hostname",
"value": "auto"
},
{
"id": "dns-server"
},
{
"id": "router"
},
{
"id": "netmask"
},
{
"id": "vendor-class",
"value": "Banana Pi BPI-R4"
}
]
}
},
"ietf-ip:ipv6": {
"infix-dhcpv6-client:dhcp": {
"option": [
{
"id": "ntp-server"
},
{
"id": "client-fqdn"
},
{
"id": "domain-search"
},
{
"id": "dns-server"
}
]
}
}
}
]
},
"ietf-keystore:keystore": {
"asymmetric-keys": {
"asymmetric-key": [
{
"name": "genkey",
"public-key-format": "infix-crypto-types:ssh-public-key-format",
"public-key": "",
"private-key-format": "infix-crypto-types:rsa-private-key-format",
"cleartext-private-key": "",
"certificates": {}
}
]
}
},
"ietf-netconf-acm:nacm": {
"enable-nacm": true,
"read-default": "permit",
"write-default": "permit",
"exec-default": "permit",
"groups": {
"group": [
{
"name": "admin",
"user-name": [
"admin"
]
},
{
"name": "operator",
"user-name": []
},
{
"name": "guest",
"user-name": []
}
]
},
"rule-list": [
{
"name": "admin-acl",
"group": [
"admin"
],
"rule": [
{
"name": "permit-all",
"module-name": "*",
"access-operations": "*",
"action": "permit",
"comment": "Allow 'admin' group complete access to all operations and data."
}
]
},
{
"name": "operator-acl",
"group": [
"operator"
],
"rule": [
{
"name": "permit-system-rpcs",
"module-name": "ietf-system",
"rpc-name": "*",
"access-operations": "exec",
"action": "permit",
"comment": "Operators can reboot, shutdown, and set system time."
}
]
},
{
"name": "guest-acl",
"group": [
"guest"
],
"rule": [
{
"name": "deny-all-write+exec",
"module-name": "*",
"access-operations": "create update delete exec",
"action": "deny",
"comment": "Guests cannot change anything or exec rpcs."
}
]
},
{
"name": "default-deny-all",
"group": [
"*"
],
"rule": [
{
"name": "deny-password-access",
"path": "/ietf-system:system/authentication/user/password",
"access-operations": "*",
"action": "deny",
"comment": "No user except admins can access password hashes."
},
{
"name": "deny-keystore-access",
"module-name": "ietf-keystore",
"access-operations": "*",
"action": "deny",
"comment": "No user except admins can access cryptographic keys."
},
{
"name": "deny-truststore-access",
"module-name": "ietf-truststore",
"access-operations": "*",
"action": "deny",
"comment": "No user except admins can access trust store."
}
]
}
]
},
"ietf-netconf-server:netconf-server": {
"listen": {
"endpoints": {
"endpoint": [
{
"name": "default-ssh",
"ssh": {
"tcp-server-parameters": {
"local-bind": [
{
"local-address": "::"
}
]
},
"ssh-server-parameters": {
"server-identity": {
"host-key": [
{
"name": "default-key",
"public-key": {
"central-keystore-reference": "genkey"
}
}
]
}
}
}
}
]
}
}
},
"ietf-system:system": {
"hostname": "bpi-%m",
"ntp": {
"server": [
{
"name": "default",
"udp": {
"address": "pool.ntp.org"
}
}
]
},
"authentication": {
"user": [
{
"name": "admin",
"password": "$factory$",
"infix-system:shell": "bash"
}
]
},
"infix-system:motd-banner": "Li0tLS0tLS0uCnwgIC4gLiAgfCBJbmZpeCBPUyDigJQgSW1tdXRhYmxlLkZyaWVuZGx5LlNlY3VyZQp8LS4gdiAuLXwgaHR0cHM6Ly9rZXJuZWxraXQub3JnCictJy0tLSctJwo="
},
"infix-dhcp-server:dhcp-server": {
"option": [
{
"id": "ntp-server",
"address": "auto"
},
{
"id": "dns-server",
"address": "auto"
},
{
"id": "router",
"address": "auto"
}
],
"subnet": [
{
"subnet": "192.168.0.0/24",
"pool": {
"start-address": "192.168.0.100",
"end-address": "192.168.0.250"
}
}
]
},
"infix-firewall:firewall": {
"default": "wan",
"zone": [
{
"name": "lan",
"action": "accept",
"interface": [
"br0"
]
},
{
"name": "wan",
"action": "drop",
"interface": [
"wan"
],
"service": [
"dhcpv6-client"
]
}
],
"policy": [
{
"name": "lan-to-wan",
"action": "accept",
"ingress": [
"lan"
],
"egress": [
"wan"
],
"masquerade": true
}
]
},
"infix-meta:meta": {
"version": "1.8"
},
"infix-services:mdns": {
"enabled": true
},
"infix-services:ssh": {
"enabled": true,
"hostkey": [
"genkey"
],
"listen": [
{
"name": "ipv4",
"address": "0.0.0.0",
"port": 22
},
{
"name": "ipv6",
"address": "::",
"port": 22
}
]
},
"infix-services:web": {
"enabled": true,
"console": {
"enabled": true
},
"netbrowse": {
"enabled": true
},
"restconf": {
"enabled": true
}
}
}
@@ -0,0 +1,2 @@
ACTION=="add", SUBSYSTEM=="net", DEVPATH=="/devices/platform/soc/15100000.ethernet/net/eth1", NAME="sfp2"
ACTION=="add", SUBSYSTEM=="net", DEVPATH=="/devices/platform/soc/15100000.ethernet/net/eth2", NAME="sfp1"
@@ -0,0 +1 @@
CONFIG_DEVICE_TREE_INCLUDES="infix-env.dtsi infix-key.dtsi mt7988-emmc-env.dtsi"
@@ -0,0 +1,40 @@
CONFIG_AUTOBOOT=y
CONFIG_BOOTDELAY=2
# CONFIG_MMC_PCI is not set
CONFIG_ENV_IS_NOWHERE=y
# CONFIG_ENV_IS_IN_MMC is not set
CONFIG_MULTI_DTB_FIT=y
CONFIG_OF_LIST="mt7988a-bananapi-bpi-r4 mt7988a-bananapi-bpi-r4-2g5"
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_MTK=y
CONFIG_USB_MTU3=y
CONFIG_PHY=y
CONFIG_PHY_MTK_TPHY=y
CONFIG_MTK_SPIM=y
CONFIG_SPI=y
CONFIG_DM_SPI=y
CONFIG_SPI_FLASH=y
CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH_MTD=y
CONFIG_SPI_FLASH_MACRONIX=y
CONFIG_SPI_FLASH_WINBOND=y
CONFIG_SPI_FLASH_GIGADEVICE=y
CONFIG_MTD=y
CONFIG_DM_MTD=y
CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_SPI_NAND=y
CONFIG_MTK_SPIM=y
CONFIG_MTK_SNOR=y
CONFIG_BUTTON=y
CONFIG_BUTTON_CMD=y
CONFIG_BUTTON_GPIO=y
CONFIG_CMD_SF=y
CONFIG_CMD_USB=y
CONFIG_CMD_MTD=y
CONFIG_CMD_MTDPARTS=y
CONFIG_CMD_DM=y
@@ -0,0 +1,7 @@
#include <mt7988-env.dtsi>
&env {
fdtfile = "mediatek/mt7988a-bananapi-bpi-r4.dtb";
board = "bananapi,bpi-r4-emmc";
ixvariant = "if test \"${BOARD_VARIANT}\" = \"2g5\"; then setenv fdtfile mediatek/mt7988a-bananapi-bpi-r4-2g5.dtb; setenv board bananapi,bpi-r4-2g5-emmc; fi";
};
@@ -0,0 +1,27 @@
/ {
config {
env: environment {
bootcmd = "run ixboot";
boot_targets = "mmc0";
ethprime = "eth0";
fdt_addr_r = "0x43f00000";
kernel_addr_r = "0x44000000";
fdtoverlay_addr_r = "0x47f00000";
scriptaddr = "0x48000000";
ramdisk_addr_r = "0x4A000000";
/*
* Apply BOARD_VARIANT from aux uboot.env.
* Infix writes BOARD_VARIANT=2g5 via fw_setenv on
* BPI-R4-2g5 / BPI-R4P boards to select the correct
* device tree. Unset = standard R4 (2x SFP+).
*/
ixvariant = "if test \"${BOARD_VARIANT}\" = \"2g5\"; then setenv fdtfile mediatek/mt7988a-bananapi-bpi-r4-2g5.dtb; fi";
/* This is a development platform, keep
* developer mode statically enabled.
*/
ixbtn-devmode = "setenv dev_mode yes; echo Enabled";
};
};
};
@@ -0,0 +1,7 @@
#include <mt7988-env.dtsi>
&env {
fdtfile = "mediatek/mt7988a-bananapi-bpi-r4.dtb";
board = "bananapi,bpi-r4-sdmmc";
ixvariant = "if test \"${BOARD_VARIANT}\" = \"2g5\"; then setenv fdtfile mediatek/mt7988a-bananapi-bpi-r4-2g5.dtb; setenv board bananapi,bpi-r4-2g5-sdmmc; fi";
};
@@ -0,0 +1,2 @@
CONFIG_DEVICE_TREE_INCLUDES="infix-env.dtsi infix-key.dtsi mt7988-sd-env.dtsi"
CONFIG_OF_LIST="mt7988a-bananapi-bpi-r4-sd"
+30 -25
View File
@@ -14,7 +14,7 @@ The Banana Pi BPI-R64 is a networking board based on the MediaTek MT7622
- 8 GB eMMC storage
- microSD card slot
- MT7531 Gigabit Ethernet switch (4x LAN + 1x WAN)
- MT7603E built-in 2.4 GHz WiFi
- MT7622 WMAC built-in 2.4 GHz 802.11ac WiFi
- USB 3.0 port
- 2x Mini PCIe slots
@@ -24,26 +24,21 @@ Infix comes preconfigured with:
- **LAN ports** (lan0-lan3): Bridged for internal networking
- **WAN port**: DHCP client enabled for internet connectivity
- **WiFi** (wifi0-ap): Bridged to LAN (MT7615 PCIe card if fitted, otherwise MT7603E)
- **WiFi** (wifi0-ap): Bridged to LAN (MT7622 WMAC, 2.4 GHz; or MT7615 PCIe card if fitted)
## Boot Switch Reference
<img align="right" src="bpi-r64-sw1.png" alt="SW1 Boot Switch" width=90 padding=10>
The BPI-R64 uses a 2-position DIP switch (SW1) to select the boot device
order. The MT7622 Boot ROM tries devices in the order listed and falls
back to the next if no valid BL2 is found at the expected location.
The BPI-R64 has a 2-position DIP switch (SW1) for selecting the boot device.
The MT7622 Boot ROM always tries SD first if a card is present, so you can
leave SW1 in the OFF (eMMC) position and simply insert or remove an SD card
to control boot device selection.
| SW1 | Boot device | Use case |
|-----|-------------|----------------------------|
| OFF | eMMC | Production eMMC boot |
| ON | SD card | SD card boot / development |
> [!NOTE]
> SinoVoip has exposed only one bit of the MT7622's two-bit `BOOT_SEL[1:0]`
> strapping field via SW1, with `BOOT_SEL[1]` hardwired high. This limits the
> board to eMMC (`10b`) and SD (`11b`) boot; the SPI-NOR and SPI-NAND modes
> available on the MT7622 reference board (`00b`, `01b`) are not selectable.
| SW1 | Boot device |
|-----|-------------|
| OFF | eMMC |
| ON | SD card |
## Getting Started
@@ -58,11 +53,10 @@ back to the next if no valid BL2 is found at the expected location.
dd if=infix-*-bpi-r64-sdcard.img of=/dev/sdX bs=4M status=progress
```
2. **Set boot switch:** SW1 ON (SD card boot)
3. **Insert SD card and power on**
4. **Connect console:** 115200 8N1 — use the dedicated Debug UART header
2. **Insert SD card and power on**
3. **Connect console:** 115200 8N1 — use the dedicated Debug UART header
just below the 40-pin GPIO header; pins are labeled GND, RX, TX on the board
5. **Default login:** `admin` / `admin`
4. **Default login:** `admin` / `admin`
## Installing to eMMC
@@ -84,9 +78,8 @@ drive.
#### Step 1: Boot from SD card
1. Set SW1 to ON (SD boot)
2. Insert SD card with Infix
3. Power on and break into U-Boot (press Ctrl-C during boot)
1. Insert SD card with Infix
2. Power on and break into U-Boot (press Ctrl-C during boot)
#### Step 2: Write the eMMC image from U-Boot
@@ -115,12 +108,24 @@ mmc partconf 0 1 1 0
#### Step 4: Boot from eMMC
1. Power off the board
2. Set SW1 to OFF (eMMC boot)
3. Remove SD card and USB drive
4. Power on
2. Remove SD card and USB drive
3. Power on
## Platform Notes
### WiFi
The MT7622 SoC includes a built-in WMAC that provides 2.4 GHz 802.11b/g/n/ac
(2×2) — there is no 5 GHz capability from the onboard radio.
For dual-band operation, a PCIe card can be fitted in one of the two Mini PCIe
slots. The [Banana Pi BPI-MT7615][bpi-mt7615] is a purpose-built dual-band
(2.4 + 5 GHz, 802.11ac 4×4) module designed for BPI router boards and is a
natural fit. With it installed, Infix will use it in preference to the onboard
WMAC for the `wifi0-ap` interface.
[bpi-mt7615]: https://docs.banana-pi.org/en/BPI-MT7615/BananaPi_MT7615
### mmc0 = eMMC, mmc1 = SD
On MT7622, MSDC0 (mmc0) is the 8-bit eMMC controller and MSDC1 (mmc1) is the
@@ -0,0 +1,2 @@
# Locally calculated
sha256 d48246c717b505cc11df95171f2fd548b389e1a463f1af4c68d0b69fe0d1009b LICENSE
@@ -1,2 +1,3 @@
CONFIG_DEVICE_TREE_INCLUDES="infix-env.dtsi infix-key.dtsi mt7622-emmc-env.dtsi"
CONFIG_SUPPORT_EMMC_BOOT=y
CONFIG_CMD_MMC_PARTCONF=y
@@ -1 +1,3 @@
CONFIG_DEVICE_TREE_INCLUDES="infix-env.dtsi infix-key.dtsi mt7622-sd-env.dtsi"
CONFIG_SUPPORT_EMMC_BOOT=y
CONFIG_CMD_MMC_PARTCONF=y
@@ -0,0 +1,2 @@
# Locally calculated
sha256 d2f96418893ac66156d0e691cda189b0d85ae1d814065d1d9aa1845383100f46 LICENSE
@@ -0,0 +1,2 @@
# Locally calculated
sha256 dbe4eae8debbba8135297e15f24aeefef0b4c03781f3f9328db4398d58a728b3 LICENSE
@@ -0,0 +1,2 @@
# Locally calculated
sha256 d2f96418893ac66156d0e691cda189b0d85ae1d814065d1d9aa1845383100f46 LICENSE
+232
View File
@@ -0,0 +1,232 @@
# Marvell ESPRESSObin
<img src="espressobin.png" alt="The board" width=800 padding=10>
The [ESPRESSObin][0] is a single-board computer based on the [Marvell Armada
3720][1] (dual Cortex-A53, AArch64) SoC and the [Marvell 88E6341][2] (Topaz)
switch, oriented toward networking applications.
The board design is old but the switch offers full Linux support, including
advanced TSN features for [IEEE 1588-2019][3] (PTP) and [IEEE 802.1AS-2020][4]
(gPTP).
## Board Variants
The board has gone through several hardware revisions:
| Revision | Storage | Notes |
|------------|---------------------|--------------------------------|
| v1, v3, v5 | SPI NOR only | Obsolete; U-Boot always in SPI |
| v7 | SPI NOR + 4 GB eMMC | Current; SD and eMMC usable |
| Ultra | SPI NOR + 4 GB eMMC | High-end variant |
On **all revisions** the Boot ROM is hardwired to load U-Boot from SPI NOR
flash. There is no strap or jumper to make the Boot ROM load directly from an
SD card. The SD card (or eMMC on v7/Ultra) is used only for the operating
system.
## Building
The ESPRESSObin uses ext4 for its rootfs partitions rather than the default
squashfs, because the stock SPI U-Boot lacks squashfs and `blkmap` support.
The `ext4` configuration snippet enables this. Apply it once after selecting
the defconfig, then build and compose the SD card image:
```sh
make O=x-aarch64 aarch64_defconfig
make O=x-aarch64 apply-ext4
make O=x-aarch64
utils/mkimage.sh -r x-aarch64 marvell-espressobin
```
The resulting image (`x-aarch64/images/infix-espressobin-sdcard.img`) contains
a GPT disk with the standard Infix partition layout, using ext4 instead of the
read-only squashfs:
| Partition | Label | Contents |
|-----------|-----------|------------------------------|
| 1 | aux | RAUC upgrade state (ext4) |
| 2 | primary | Rootfs slot primary (ext4) |
| 3 | secondary | Rootfs slot secondary (ext4) |
| 4 | cfg | Persistent config (ext4) |
| 5 | var | Runtime data (ext4) |
## Writing to SD Card
```sh
dd if=infix-espressobin-sdcard.img of=/dev/sdX bs=4M status=progress conv=fsync
```
## Upgrading
The build produces `x-aarch64/images/infix-aarch64-ext4.pkg`, a RAUC bundle
containing the ext4 rootfs. Once the board is running Infix, upgrade over the
network in the usual way:
```
upgrade ftp://192.168.1.1/infix-aarch64-ext4.pkg
```
RAUC writes the new rootfs to the inactive slot, updates `BOOT_ORDER` in
`/mnt/aux/uboot.env`, and the next boot picks it up automatically.
> [!NOTE]
> Use `infix-aarch64-ext4.pkg`, not the standard `infix-aarch64.pkg`. The
> standard bundle contains a squashfs rootfs which the stock U-Boot cannot
> boot.
## Booting with the Stock SPI U-Boot
The stock Marvell U-Boot has `ext4load` and the standard variables
(`$kernel_addr`, `$fdt_addr`, `$loadaddr`, `$console`, `$image_name`,
`$fdt_name`) already set sensibly. Connect to the board's console port, the
micro USB connector, at 115200 8N1, interrupt autoboot, and paste the commands
below.
### Environment Variable Reference
These variables are pre-set in the stock U-Boot environment. Restore them
with these values if they are ever lost or corrupted:
```
setenv kernel_addr 0x5000000
setenv fdt_addr 0x4f00000
setenv loadaddr 0x5000000
setenv console 'console=ttyMV0,115200 earlycon=ar3700_uart,0xd0012000'
setenv image_name boot/Image
setenv extra_params quiet
```
`$fdt_name` selects the device tree for your specific board revision:
| Board revision | `fdt_name` value |
|----------------|-----------------------------------------------------|
| v3 / v5 | `boot/marvell/armada-3720-espressobin.dtb` |
| v7 | `boot/marvell/armada-3720-espressobin-v7.dtb` |
| Ultra | `boot/marvell/armada-3720-espressobin-ultra.dtb` |
| v3/v5 eMMC | `boot/marvell/armada-3720-espressobin-emmc.dtb` |
| v7 eMMC | `boot/marvell/armada-3720-espressobin-v7-emmc.dtb` |
```
setenv fdt_name boot/marvell/armada-3720-espressobin.dtb # adjust for your board
```
### Simple Boot
Fixed boot from the primary slot, useful for initial bring-up:
```
setenv bootcmd 'mmc dev 0; \
ext4load mmc 0:2 $kernel_addr $image_name; \
ext4load mmc 0:2 $fdt_addr $fdt_name; \
setenv bootargs $console root=PARTLABEL=primary rw rootwait $extra_params rauc.slot=primary; \
booti $kernel_addr - $fdt_addr'
saveenv
```
### Automatic Slot Selection (RAUC Integration)
The CLI `upgrade` command writes to the inactive slot and updates `uboot.env`
on the `aux` partition with the new boot order. On the next boot U-Boot reads
`BOOT_ORDER` from the aux partition and selects the appropriate slot. The
setup below also defines `bootcmd_primary`, `bootcmd_secondary`, and
`bootcmd_net` for manual use (see [Manual Slot Selection](#manual-slot-selection)
and [Netbooting](#netbooting)):
```
setenv bootcmd_boot \
'mmc dev 0; \
ext4load mmc 0:$bootpart $kernel_addr $image_name; \
ext4load mmc 0:$bootpart $fdt_addr $fdt_name; \
setenv bootargs $console root=PARTLABEL=$bootslot rw rootwait $extra_params rauc.slot=$bootslot; \
booti $kernel_addr - $fdt_addr'
setenv bootcmd_primary 'setenv bootpart 2; setenv bootslot primary; run bootcmd_boot'
setenv bootcmd_secondary 'setenv bootpart 3; setenv bootslot secondary; run bootcmd_boot'
setenv bootcmd_net \
'dhcp $kernel_addr $image_name; \
tftpboot $fdt_addr $fdt_name; \
setenv bootargs $console root=PARTLABEL=primary rw rootwait $extra_params rauc.slot=primary; \
booti $kernel_addr - $fdt_addr'
setenv bootcmd \
'setenv bootpart 2; setenv bootslot primary; setenv auxpart 1; \
if ext4load mmc 0:$auxpart $loadaddr /uboot.env; then \
env import -c $loadaddr $filesize BOOT_ORDER; \
fi; \
if test "$BOOT_ORDER" = "secondary primary" || \
test "$BOOT_ORDER" = "secondary primary net"; then \
setenv bootpart 3; setenv bootslot secondary; \
fi; \
if test "$BOOT_ORDER" = "net" || \
test "$BOOT_ORDER" = "net primary" || \
test "$BOOT_ORDER" = "net secondary primary"; then \
run bootcmd_net; \
fi; \
echo ">> Booting $bootslot from mmc 0:$bootpart ..."; \
run bootcmd_boot'
saveenv
```
### Manual Slot Selection
To boot a specific slot without waiting for the autoboot countdown, interrupt
the bootloader (press any key) and run one of the convenience commands defined
above:
```
run bootcmd_primary # boot from primary (partition 2)
run bootcmd_secondary # boot from secondary (partition 3)
run bootcmd_net # netboot via DHCP/TFTP
```
You can also force a permanent change to which slot boots next by setting
`BOOT_ORDER` directly from Linux (the change persists across reboots):
```sh
fw_setenv BOOT_ORDER "secondary primary" # next boot: secondary
fw_setenv BOOT_ORDER "primary secondary" # next boot: primary (default)
```
### Netbooting
The stock U-Boot supports TFTP. This is useful for testing a new kernel or
device tree without reflashing the SD card. Set up a TFTP server with the
contents of the Infix `boot/` directory (from the built rootfs at
`x-aarch64/target/boot/`) and configure the variables:
```
setenv serverip 192.168.1.1 # IP of your TFTP server
setenv ipaddr 192.168.1.100 # board IP (omit if using dhcp)
saveenv
```
Then netboot manually:
```
run bootcmd_net
```
`bootcmd_net` uses `dhcp` to obtain an IP address and the `$serverip` from
the DHCP server (option 66), then downloads `$image_name` and `$fdt_name`
via TFTP. The kernel mounts the primary SD card slot as root, so the SD
card must still be present.
To make netbooting the default on next boot (e.g. for iterative kernel
development), set `BOOT_ORDER` from Linux:
```sh
fw_setenv BOOT_ORDER "net primary secondary"
```
This causes `bootcmd` to attempt netboot first; on failure it falls through
to the primary slot on the SD card.
[0]: https://wiki.espressobin.net/
[1]: https://www.marvell.com/content/dam/marvell/en/public-collateral/embedded-processors/marvell-embedded-processors-armada-37xx-hardware-specifications.pdf
[2]: https://www.marvell.com/content/dam/marvell/en/public-collateral/switching/marvell-link-street-88E6341-product-brief.pdf
[3]: https://standards.ieee.org/ieee/1588/6825/
[4]: https://standards.ieee.org/ieee/802.1AS/7121/
Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

@@ -1,25 +0,0 @@
image cfg.ext4 {
ext4 {
label = "cfg"
}
empty = true
size = 16M
}
image sdcard.img {
hdimage {
}
partition rootfs {
partition-type = 0x83
image = "rootfs.ext4"
}
partition cfg {
partition-type = 0x83
image = "cfg.ext4"
}
}
# Silence genimage warnings
config {}
@@ -0,0 +1,61 @@
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 SD-card.
image var.ext4 {
empty = true
temporary = true
size = 128M
ext4 {
label = "var"
use-mke2fs = true
features = "uninit_bg"
extraargs = "-m 0 -i 4096"
}
}
image #INFIX_ID##VERSION#-espressobin-#TARGET#.img {
hdimage {
partition-table-type = "gpt"
}
# No bootloader partition: U-Boot lives in SPI NOR flash on all
# ESPRESSObin board revisions. The SD card carries the OS only.
partition aux {
partition-uuid = D4EF35A0-0652-45A1-B3DE-D63339C82035
image = "aux.ext4"
}
partition primary {
partition-type-uuid = 0FC63DAF-8483-4772-8E79-3D69D8477DE4
bootable = true
image = "rootfs.ext2"
}
partition secondary {
partition-type-uuid = 0FC63DAF-8483-4772-8E79-3D69D8477DE4
bootable = true
image = "rootfs.ext2"
}
partition cfg {
partition-uuid = 7aa497f0-73b5-47e5-b2ab-8752d8a48105
image = "cfg.ext4"
}
partition var {
partition-uuid = 8046A06A-E45A-4A14-A6AD-6684704A393F
image = "var.ext4"
}
}
@@ -0,0 +1,2 @@
# Locally calculated
sha256 d2f96418893ac66156d0e691cda189b0d85ae1d814065d1d9aa1845383100f46 LICENSE
@@ -0,0 +1,2 @@
# Locally calculated
sha256 d2f96418893ac66156d0e691cda189b0d85ae1d814065d1d9aa1845383100f46 LICENSE
@@ -2,29 +2,18 @@
#include "infix.dtsi"
/ {
/* Dynamic GPU reservation */
gpu-reserved {
size = <0x0 0x10000000>; /* 256MB */
alignment = <0x0 0x1000000>; /* 16MB aligned */
alloc-ranges = <0x0 0x10000000 0x1 0x00000000>; /* Allow anywhere in RAM */
no-map;
};
/* CMA pool */
cma-reserved {
compatible = "shared-dma-pool";
size = <0x0 0x10000000>; /* 256MB */
alignment = <0x0 0x1000000>; /* 16MB aligned */
linux,cma-default;
reusable;
};
chosen {
/* 8250 auxiliary UART instead of pl011 */
stdout-path = "serial1:115200n8";
};
};
/* Override upstream 64MB CMA with 256MB for vc4 GPU */
&rmem {
cma: linux,cma {
size = <0x10000000>; /* 256MB */
};
};
&vc4 {
status = "okay";
@@ -0,0 +1,2 @@
# Locally calculated
sha256 dbe4eae8debbba8135297e15f24aeefef0b4c03781f3f9328db4398d58a728b3 LICENSE
@@ -0,0 +1,2 @@
# Locally calculated
sha256 d2f96418893ac66156d0e691cda189b0d85ae1d814065d1d9aa1845383100f46 LICENSE
@@ -0,0 +1,2 @@
# Locally calculated
sha256 d48246c717b505cc11df95171f2fd548b389e1a463f1af4c68d0b69fe0d1009b LICENSE
@@ -0,0 +1,2 @@
# Locally calculated
sha256 dbe4eae8debbba8135297e15f24aeefef0b4c03781f3f9328db4398d58a728b3 LICENSE
+1
View File
@@ -5,6 +5,7 @@ source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-itb-aux/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-itb-qcow/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-itb-gns3a/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-itb-rauc/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-ext4-rauc/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-itb-dl-release/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-readme/Config.in"
@@ -0,0 +1,27 @@
config IMAGE_EXT4_RAUC
bool "RAUC upgrade bundle (ext4)"
depends on BR2_TARGET_ROOTFS_EXT2
select BR2_PACKAGE_HOST_RAUC
help
Create a RAUC upgrade bundle for targets using an ext4 rootfs
image. Intended for development boards whose bootloader does
not support squashfs.
config IMAGE_EXT4_RAUC_KEY
string "signing key"
depends on IMAGE_EXT4_RAUC
default "${BR2_EXTERNAL_INFIX_PATH}/board/common/signing-keys/development/infix.key"
help
Path to the private key, in PKCS#8 format, used to sign
the RAUC bundle; or a PKCS#11 URI.
config IMAGE_EXT4_RAUC_CERT
string "signing certificate"
depends on IMAGE_EXT4_RAUC
default "${BR2_EXTERNAL_INFIX_PATH}/board/common/signing-keys/development/infix.crt"
help
Path to the X509 certificate which will be associated with
the bundle signature.
NOTE: This cert MUST be included in the trust store of the
system on which this bundle is to be installed.
+27
View File
@@ -0,0 +1,27 @@
#!/bin/sh
set -e
ext2="${BINARIES_DIR}/rootfs.ext2"
pkg="${BINARIES_DIR}/${ARTIFACT}-ext4.pkg"
# RAUC internally uses the file extension to find a suitable install
# handler, hence the name must be .img
cp -f "${ext2}" "${WORKDIR}/rootfs.img"
cat >"${WORKDIR}/manifest.raucm" <<EOF
[update]
compatible=${COMPATIBLE}
version=${VERSION}
[bundle]
format=verity
[image.rootfs]
filename=rootfs.img
EOF
rauc --cert="${CERT}" --key="${KEY}" \
bundle "${WORKDIR}" "${pkg}.next"
mv "${pkg}.next" "${pkg}"
@@ -0,0 +1,10 @@
################################################################################
#
# image-ext4-rauc
#
################################################################################
IMAGE_EXT4_RAUC_DEPENDENCIES := host-rauc
IMAGE_EXT4_RAUC_CONFIG_VARS := KEY CERT
$(eval $(ix-image))
+4
View File
@@ -1 +1,5 @@
CONFD_TIMEOUT=60
#DEBUG=1
# -v debug
CONFD_ARGS=""
@@ -1,3 +0,0 @@
service <!> name:hostapd :%i \
[2345] hostapd -P/var/run/hostapd-%i.pid /etc/hostapd-%i.conf \
-- Wi-Fi Access Point @%i
@@ -0,0 +1,3 @@
service name:wpa_supplicant :%i \
[2345] wpa_supplicant -s -i %i -c /etc/wpa_supplicant-%i.conf -P/var/run/wpa_supplicant-%i.pid \
-- Wi-Fi Mesh @%i
@@ -0,0 +1,3 @@
service <!> name:phc2sys :%i log:prio:daemon,tag:phc2sys-%i \
[2345] phc2sys -a -z /var/run/ptp4l-%i \
-- PHC synchronization for PTP instance %i
@@ -0,0 +1,3 @@
service <!> name:ptp4l :%i log:prio:daemon,tag:ptp4l-%i \
[2345] ptp4l -f /etc/linuxptp/ptp4l-%i.conf \
-- PTP instance %i
@@ -5,3 +5,4 @@
4 static
5 dhcp
6 random
7 wwan
@@ -567,6 +567,126 @@ def probe_wifi_radios(out):
out["wifi-radios"].append(info)
def probe_ptp_capabilities(out):
"""Probe PTP timestamping capabilities per physical interface via ethtool --json -T.
Only physical interfaces (those with a 'device' sysfs symlink) are probed;
virtual interfaces such as bridges, VLANs, and tun/tap devices are skipped.
Results are stored under out["interfaces"][<ifname>]["ptp-capabilities"].
"""
net_base = "/sys/class/net"
if not os.path.exists(net_base):
return
ifaces = {}
for ifname in sorted(os.listdir(net_base)):
if ifname == "lo":
continue
# Physical interfaces have a 'device' symlink; virtual ones do not.
if not os.path.exists(os.path.join(net_base, ifname, "device")):
continue
try:
result = subprocess.run(
["ethtool", "--json", "-T", ifname],
capture_output=True, text=True, timeout=5
)
if result.returncode != 0:
continue
data = json.loads(result.stdout)[0]
except Exception:
continue
caps = {
"capabilities": data.get("capabilities", []),
"tx-types": data.get("tx-types", []),
"rx-filters": data.get("rx-filters", []),
}
# phc-index is -1 when no PHC is present; omit in that case.
phc = data.get("phc-index", -1)
if phc >= 0:
caps["phc-index"] = phc
# hwtstamp provider fields are present only on newer kernels/hardware.
if (idx := data.get("hwtstamp-provider-index")) is not None:
caps["hwtstamp-provider-index"] = idx
if (qual := data.get("hwtstamp-provider-qualifier")) is not None:
caps["hwtstamp-provider-qualifier"] = qual
ifaces[ifname] = {"ptp-capabilities": caps}
if ifaces:
out.setdefault("interfaces", {}).update(ifaces)
def _usb_root_from_sysfs(dev_path):
p = dev_path
while p not in ("/", "/sys"):
parent = os.path.realpath(os.path.join(p, ".."))
basename = os.path.basename(parent)
if basename.startswith("usb") and basename[3:].isdigit():
return parent
p = parent
return None
def _read_usb_vid_pid(dev_path):
p = dev_path
while p not in ("/", "/sys"):
try:
vid = open(os.path.join(p, "idVendor")).read().strip()
pid = open(os.path.join(p, "idProduct")).read().strip()
return vid, pid
except OSError:
pass
p = os.path.dirname(p)
return "", ""
def probe_modems(out):
"""devpath is the USB bus root; ModemManager matches by path prefix.
seen_roots deduplicates cdc-wdm and ttyUSB ports of the same physical modem."""
seen_roots = set()
modems = []
idx = 0
def add_modem(dev_path):
nonlocal idx
usb_root = _usb_root_from_sysfs(dev_path)
if usb_root is None or usb_root in seen_roots:
return
seen_roots.add(usb_root)
vid, pid = _read_usb_vid_pid(dev_path)
modems.append({
"index": idx,
"name": "modem%d" % idx,
"devpath": usb_root,
"vid": vid,
"pid": pid,
})
idx += 1
for cls_dir, prefix in (("/sys/class/usbmisc", "cdc-wdm"),
("/sys/class/tty", "ttyUSB")):
try:
entries = os.listdir(cls_dir)
except OSError:
continue
for entry in entries:
if not entry.startswith(prefix):
continue
try:
dev_path = os.path.realpath(
os.path.join(cls_dir, entry, "device"))
add_modem(dev_path)
except OSError:
pass
if modems:
out["modem"] = modems
def main():
out = {
"vendor": None,
@@ -593,6 +713,8 @@ def main():
return err
probe_wifi_radios(out)
probe_ptp_capabilities(out)
probe_modems(out)
if not out["factory-password-hash"]:
sys.stdout.write("\n\n\033[31mCRITICAL BOOTSTRAP ERROR\n" +
+49 -5
View File
@@ -257,15 +257,15 @@ def parse_interface_info(ifname):
for line in output.splitlines():
stripped = line.strip()
# Interface type
# Interface type (can be multi-word, e.g. "mesh point")
if stripped.startswith('type '):
result['iftype'] = stripped.split()[1]
result['iftype'] = ' '.join(stripped.split()[1:])
# MAC address
elif stripped.startswith('addr '):
result['mac'] = stripped.split()[1]
# SSID
# SSID (AP mode) or mesh-id (mesh point mode) — kernel uses same attr
elif stripped.startswith('ssid '):
result['ssid'] = decode_iw_ssid(' '.join(stripped.split()[1:]))
@@ -538,6 +538,43 @@ def parse_link(ifname):
return result
def parse_phy_caps(phy_name):
"""
Parse 'iw phy <name> info' for HT and VHT capability bitmasks.
Returns: {ht_cap: int, vht_cap: int}
iw phy info output format:
Capabilities: 0x1ef
...
VHT Capabilities (0x339071b2):
...
"""
actual_phy = normalize_phy_name(phy_name)
output = run_iw('phy', actual_phy, 'info')
if not output:
output = run_iw(actual_phy, 'info')
if not output:
return {'ht_cap': 0, 'vht_cap': 0}
ht_cap = 0
vht_cap = 0
for line in output.splitlines():
stripped = line.strip()
# HT Capabilities: "Capabilities: 0x1ef"
ht_match = re.match(r'Capabilities:\s+(0x[0-9a-fA-F]+)', stripped)
if ht_match:
ht_cap = int(ht_match.group(1), 16)
# VHT Capabilities: "VHT Capabilities (0x339071b2):"
vht_match = re.match(r'VHT Capabilities\s+\((0x[0-9a-fA-F]+)\)', stripped)
if vht_match:
vht_cap = int(vht_match.group(1), 16)
return {'ht_cap': ht_cap, 'vht_cap': vht_cap}
def main():
if len(sys.argv) < 2:
print(json.dumps({
@@ -548,7 +585,8 @@ def main():
'info': 'Get PHY or interface information (requires device)',
'survey': 'Get channel survey data (requires interface)',
'station': 'Get connected stations in AP mode (requires interface)',
'link': 'Get link info in station mode (requires interface)'
'link': 'Get link info in station mode (requires interface)',
'caps': 'Get HT/VHT capability bitmasks (requires PHY/radio)'
},
'examples': [
'iw.py list',
@@ -557,7 +595,8 @@ def main():
'iw.py info wlan0',
'iw.py station wifi0',
'iw.py link wlan0',
'iw.py survey wlan0'
'iw.py survey wlan0',
'iw.py caps radio0'
]
}, indent=2))
sys.exit(1)
@@ -594,6 +633,11 @@ def main():
data = {'error': 'survey command requires interface argument'}
else:
data = parse_survey(sys.argv[2])
elif command == 'caps':
if len(sys.argv) < 3:
data = {'error': 'caps command requires PHY/radio argument'}
else:
data = parse_phy_caps(sys.argv[2])
else:
data = {'error': f'Unknown command: {command}'}
+4 -3
View File
@@ -652,7 +652,9 @@ wrap()
if [ "$cmd" = "stop" ]; then
# The setup phase may run forever in the background trying to fetch
# the image. It saves its PID in /run/containers/${name}.pid
# the image. It saves its PID in /run/containers/${name}.pid. Kill
# any in-flight setup, then fall through to podman stop -- a stale
# pidfile is not proof the container isn't running.
if [ -f "$pidfile" ]; then
pid=$(cat "$pidfile")
@@ -663,10 +665,9 @@ wrap()
fi
rm -f "$pidfile"
return 0
fi
# Only the 'podman stop' command takes -i and --timeout
# Only the 'podman stop' command takes -i (ignore missing) and --timeout
args="-i --timeout $timeout"
fi
+1
View File
@@ -14,6 +14,7 @@
boot_targets = "virtio mmc";
bootcmd = "run ixboot";
ixvariant = "";
ixpreboot = /incbin/("scripts/ixpreboot.sh");
ixbtn-devmode = /incbin/("scripts/ixbtn-devmode.sh");
ixbtn-factory = /incbin/("scripts/ixbtn-factory.sh");
+2 -1
View File
@@ -33,7 +33,8 @@ for tgt in "${boot_targets}"; do
setexpr ixmenu_n ${ixmenu_n} + 1
if load ${devtype} ${devnum}:${auxpart} ${loadaddr} /uboot.env; then
env import -b ${loadaddr} ${filesize} BOOT_ORDER DEBUG ethact
env import -c ${loadaddr} ${filesize} BOOT_ORDER DEBUG ethact BOARD_VARIANT
run ixvariant
fi
if test -n "${DEBUG}"; then

Some files were not shown because too many files have changed in this diff Show More