Compare commits

...
91 Commits
Author SHA1 Message Date
Joachim Wiberg 85a1bfc999 .github: add support for manually starting a release build
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-31 11:29:36 +01:00
Joachim Wiberg 5ebd473972 Update ChangeLog for Infix v23.10 [skip ci]
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-31 10:09:01 +01:00
Richard AlpeandJoachim Wiberg 12462d5b17 statd: add more ethtool counters to op datastore
Add counters from Ethtool groups to the operational datastore. The
mapping from Linux / Ethtool to YANG is described in the included
document eth-counters.md.

Signed-off-by: Richard Alpe <richard@bit42.se>
2023-10-31 10:01:55 +01:00
Joachim WibergandTobias Waldekranz afbf92c07e configs: drop x86_64_minimal_defconfig
Replaced with full build in GitHub Actions.  No other use-cases for it,
and too much of a hassle to maintain, so remove.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-31 09:28:28 +01:00
Joachim WibergandTobias Waldekranz 552550495a configs: reenable lost bash for netconf builds
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-31 09:28:28 +01:00
Joachim WibergandTobias Waldekranz 6503face19 package/finit: bump to v4.5
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-31 09:28:28 +01:00
Mattias Walström 90d94fe255 Remove ietf-if-vlan-encapsulation, it is replaced by infix-if-vlan
This is a followup for 941fc3158
2023-10-31 09:16:58 +01:00
Joachim WibergandTobias Waldekranz fc5310b3fd confd: adjust path to failure-config
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-30 12:48:14 +01:00
Joachim WibergandTobias Waldekranz 120e87ac99 confd: sort interfaces according to length and name
A list of interfaces: x10 x9 x8 x7 x6 x5 x4 x1 x2 x3 should be sorted in
order with x10 last.  Using the common 'sort -n' would generate: x1 x10
x2 ... so we use version sort.  This way we can ensure that the order of
bridge ports is natural and what end users expect.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-30 12:48:14 +01:00
Joachim WibergandTobias Waldekranz 7fd7a2e430 confd: regenerate failure-config and factory-config on each boot
Operational experience shows that the current Infix Fail Secure mode,
introduced in ca9daef, does not work in practice.

The factory datastore in sysrepo is created at boot with the YANG models
and the factory-config file.  When the factory-config file is generated
from older versions of these models, the resulting datastore may fail to
pass the validation and system will end up in an unrecoverable state.

Instead, both the factory-config and failure-config must be created at
every boot to match the YANG models in the active Linux image.  This
ensures loading the YANG models will always work and the system can
proceed to attempt to load startup-config to the running datastore.

If loading startup-config fails we can fall back to failure-config,
which like factory-config, will then provide a way to log in an dianose
the system.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-30 12:48:14 +01:00
Tobias WaldekranzandJoachim Wiberg c385e2e9c2 uboot: Import latest patches from u-boot-2023.07.y-kkit
Adds enough support for 6393X switchcore to enable netbooting from a
single port.
2023-10-30 11:24:18 +01:00
Tobias WaldekranzandJoachim Wiberg 97747a95ea common/uboot: Use factory-reset and dev-mode buttons, if available
If the bootloader knows about a factory-reset or dev-mode button, use
them to allow stopping the boot process, and to signal the
factory-reset condition to infix.
2023-10-30 11:24:18 +01:00
Tobias WaldekranzandJoachim Wiberg 01e43896df common/uboot: Explicitly separate kernel/user arguments
This way, we avoid arguments intended for userspace to be accidentally
parsed by the kernel.
2023-10-30 11:24:18 +01:00
Tobias WaldekranzandJoachim Wiberg 60c777fb41 common/uboot: If no valid boot media exists, fall back to netboot
This means that a device with a valid bootloader, but a completely
empty eMMC is still salvageable.
2023-10-30 11:24:18 +01:00
Tobias WaldekranzandJoachim Wiberg 194aa5de8a common/uboot: Use correct name of netboot in default order 2023-10-30 11:24:18 +01:00
Tobias WaldekranzandJoachim Wiberg 47fe0529f4 arm-trusted-firmware: Default to 16-bit DDR4 on CN9130 boards 2023-10-30 11:24:18 +01:00
Mattias WalströmandJoachim Wiberg 941fc31581 infix-vlan: Create a custom vlan model
This implements the new model infix-if-vlan.
The new CLI is:

root@infix-00-00-00:/config/interfaces/interface/vlan10/> set vlan id 10 lower-layer-if eth0

with an possible extra option for tag-type, default tag-type is c-vlan.
2023-10-27 10:53:55 +02:00
Joachim Wiberg be8bad9885 doc: add Versioning section to branding document
[skip ci]

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-24 13:51:27 +02:00
Joachim Wiberg e03ab9c81b board/common: add help text for Qemu interface model
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-24 13:37:28 +02:00
Mattias WalströmandJoachim Wiberg f224d0d03d ietf-factory-default: Implement factory reset
fixes #157, fixes #156
2023-10-24 12:25:38 +02:00
Mattias WalströmandJoachim Wiberg d66740250c confd: Add support for timezone-utc-offset
Some deviations has been done the yang model to comply with tzdata
on linux.

This fixes #106
2023-10-20 12:55:02 +02:00
Mattias WalströmandJoachim Wiberg 0db65846c3 Add tzset() before localtime
Without it, the offset generated will always be zero.
But over netconf it will still be correct, most likely
because due to how libyang handles the date-and-time type.
2023-10-20 12:55:02 +02:00
Richard AlpeandJoachim Wiberg 4471c45d3c .github: use defconfig instead of minimal_defconfig
The issues seen in the regression tests looks related to files
missing from minimal defconfig.

Fixes #127.

Signed-off-by: Richard Alpe <richard@bit42.se>
2023-10-17 18:18:19 +02:00
Richard AlpeandJoachim Wiberg 5639e5bdd4 statd: ignore interfaces with group = internal
Don't add any info about interfaces which has "group" = "internal" to
the operational datastore.

Signed-off-by: Richard Alpe <richard@bit42.se>
2023-10-17 18:17:59 +02:00
Richard AlpeandJoachim Wiberg 1654773bc6 statd: ignore parent interface for kind dsa
DSA ports such as pX has "link" (parent) set to dsaY. We don't see it
that way from an networking perspective. In this commit we avoid
adding parent to the statd data structure if the linkinfo -> info_kind
is dsa. This means the ports shows up as regular interfaces, which is
what we want.

Signed-off-by: Richard Alpe <richard@bit42.se>
2023-10-17 18:17:59 +02:00
Richard AlpeandJoachim Wiberg 4a84ab95d0 statd: dsa ifaces has type infix-if-type:ethernet
Signed-off-by: Richard Alpe <richard@bit42.se>
2023-10-17 18:17:59 +02:00
Richard AlpeandJoachim Wiberg f643b4f9dc statd: break out parent interface code (cosmetic)
A non functional change to prepare for upcoming patches.

Signed-off-by: Richard Alpe <richard@bit42.se>
2023-10-17 18:17:59 +02:00
Richard AlpeandJoachim Wiberg d6152ce6ea cli: add graceful error for missing json in cli-pretty
Print a graceful error message if the json data is missing of invalid.

Signed-off-by: Richard Alpe <richard@bit42.se>
2023-10-17 18:17:59 +02:00
Richard AlpeandJoachim Wiberg 1a3105c06d cli: pretty print existing Ethernet frame stats
Pretty print all Ethernet frame statistics from the operational
datastore. Only in the detailed interface view.

Signed-off-by: Richard Alpe <richard@bit42.se>
2023-10-17 18:17:59 +02:00
Richard AlpeandJoachim Wiberg 14dc3cf8a0 statd: add ethtool frame counters to op datastore
This patch adds the framework for reading ethtool statistics and
inserting it into the operational datastore.

The ethtool data we rely on is "group data" such as "eth-mac" or
"rmon".

This data can be displayed using:
ethtool --json -S e0 --all-groups

The "group data" is still missing for most common drivers, so testing
this will require a firmware which has support for it.

Signed-off-by: Richard Alpe <richard@bit42.se>
2023-10-17 18:17:54 +02:00
Joachim Wiberg 9292231674 .github: switch to ncipollo/release-action for latest build
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-17 18:08:07 +02:00
Joachim Wiberg 52023e918a confd: regenerate factory-config if factory-config.gen is missing
Regenerate if either factory-config.gen or failure-config.gen is missing.
This should not happen, but is better to check for the result rather than
the intermediate result.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-17 16:32:41 +02:00
Joachim Wiberg c6fae88268 Fix #166: drop SSDP entirely from Infix
mDNS-SD was added in Windows 10 Creators Update[1] (build 1703), relased
April 11, 2017.  This makes SSDP no longer critical for finding an Infix
device in Windows, both ping infix-01-02-03.local and using Chrome work.

Since all major operating systems now support mDNS-SD[2] we've decided
to standardize on that and LLDP for Infix and its derivatives.  Other
reasons for dropping it include, but is not limited to: lack of IPv6 in
the implementation we use, and potential security implications[3].

[1]: https://en.wikipedia.org/wiki/Windows_10,_version_1703
[2]: https://techcommunity.microsoft.com/t5/networking-blog/mdns-in-the-enterprise/ba-p/3275777
[3]: https://blog.cloudflare.com/ssdp-100gbps/

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-17 16:32:41 +02:00
Joachim Wiberg aa655abdc7 Fix #159: hacky generation of /etc/resolv.conf at boot
To be able to run "resolvconf -u" at boot we need dnsmasq up and running
and startup-config having been loaded successfully.  (No point when we
hare in fail secure mode.)

If this bugs out it can be pinpointed by an empty /etc/resolv.conf

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-17 13:26:26 +02:00
Joachim Wiberg cefe24c467 confd: support mixed bridge/router use-case in inteface generator
Fix #160

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-17 13:26:26 +02:00
Joachim Wiberg b4d760906f .github: disable actions by default [skip ci]
Enable actions by setting local variables in your fork of Infix.

Fix #170

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-17 13:26:26 +02:00
Joachim Wiberg acecbe7e5d Allow custom image filename being set in menuconfig
This adds support for the two /etc/os-release variables:

 - IMAGE_ID
 - IMAGE_VERSION

The former is configurable, with fallback to name-arch, and the latter
is only set for relase builds.  During releae builds the release will
be appended to the image name.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-17 13:26:26 +02:00
Joachim WibergandGitHub f6acc44104 doc: add Integration section [skip ci]
Detail operational experience with integrating 3rd party software, PROFINET.
2023-10-17 13:20:11 +02:00
Henrik NordstromandJoachim Wiberg 7b09b2524d greenpak-programmer: Bump to v1.1 which adds LICENSE.txt 2023-10-16 15:07:03 +02:00
Henrik NordstromandJoachim Wiberg 62131528ba Use single-word for CONFIG_PACKAGE.. bool 2023-10-16 15:07:03 +02:00
Henrik NordstromandJoachim Wiberg 5eb25e968b Add greenpak-programmer package 2023-10-16 15:07:03 +02:00
Joachim Wiberg 1698c6645c Disable bridge multicast snooping (IGMP/MLD) by default
The Marvell mv88e6xxx switch driver currently used in active projects do
not support multicast router ports properly yet.  Considering that Infix
do not yet have YANG support for configuring IGMP/MLD snooping, we have
decided to disable it in bridge setups by default.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-13 13:38:09 +02:00
Joachim Wiberg 830c885c2e confd: minor, fix comment
[skip ci]

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-13 12:50:02 +02:00
Joachim Wiberg 17b6c234c1 confd: fix copy-paste error in runtime condition [skip ci]
We should only call 'error' in case loading failure-config fails, not if
loading startup-config fails. Unclear how this passed testing, must have
been a last minute change that got untested.

Found during integration in customer's br2-external.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-12 17:22:49 +02:00
Joachim Wiberg b44e303775 board/common: basic feature probe
Currently does not need any conditions, but may later need to check for
loaded modules and other capabilities.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-12 16:35:00 +02:00
Joachim Wiberg 3a3274c371 confd: ensure "word splitting" otherwise gen-interfaces fails
Overzealous shellcheck application lead to gen-intefaces not creating a
bridge when GEN_IFACE_OPTS was uncommented in /etc/confdrc

Verified in customer br2-external.

[skip ci]

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-12 14:56:00 +02:00
Joachim Wiberg 46bd3df13e board/common: fix string comparison operator [skip ci]
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-12 14:28:18 +02:00
Joachim WibergandTobias Waldekranz 138c9f3378 Update board/common/mkgns3a.sh
As @wkz says, better to use this construct if/when we add more archs.

[skip ci]

Co-authored-by: Tobias Waldekranz <tobias@waldekranz.com>
2023-10-12 11:22:55 +02:00
Joachim Wiberg 8c20bb2829 configs: enable disk image and update metadata for /etc/os-release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-12 11:22:55 +02:00
Joachim Wiberg 606b87b4b3 configs: sync aarch64 classic build with changes from cbaa599 & C:o
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-12 11:22:55 +02:00
Joachim Wiberg 230c2adae7 board/common: rename disk.img and update .gns3a
- Create per-arch unique distribution file names
 - Source .gns3a information from /etc/os-release

Instead of attempting to create unique file names by hard-coding an
'infix-' prefix and extracting the "board" or "arch" part from the
defconfig, let's use the branding information from /etc/os-release
along with $BR2_ARCH.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-12 11:22:55 +02:00
Joachim Wiberg 09d48b35ee board/common: parameterized branding using menuconfig
This makes it possible for projects using Infix as a br2-external to
override lots of OS-specific strings and contact information that
previously was hard coded.

The generated /etc/os-release now takes most of its data from .config
Worth noting is the changes in VERSION and BUILD_ID fields.  The former
will be INFIX_RELEASE, during release builds, and the latter is always
the output from `git descibe ...`, or rather GIT_VERSION.  This variable
can be overloaded as well.

See the help text and the new doc/branding.md document for details.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-12 11:22:55 +02:00
Joachim Wiberg f2e30943ee board/common: generate images/Config.in and reduce x86 ram
The default arch and disk image filename needs to be generated
to be unique per, at least, each architecture build.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-12 11:22:55 +02:00
Joachim Wiberg f852afc9c6 Enable GNS3 appliance file for all builds
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-12 11:22:55 +02:00
Joachim Wiberg c6d4fbf341 board/common: generate a simplified .gns3a for aarch64 builds
Due to problems with using u-boot as loader¹ we decided to start the
system by calling the kernel image directly.  The downside to that is
that, even though RAUC upgrades would work, the kernel would remain
the same.

Improvements to this are of course welcome.

________
¹) Must extract the built-in .dtb and merge with the Qemu .dtb at runtime
   to be able to boot primary (or secondry) image.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-12 11:22:55 +02:00
Joachim Wiberg b40484e262 board/common: fix load_cfg key=value extraction
Calling `load_cfg BR2_EXTERNAL_INFIX_PATH` from post-image.sh caused
warnings due to multiple hits in the .config file:

post-image.sh: 12: /tmp/tmp.5a3xhQQVc8: BR2_EXTERNAL_INFIX_PATH: not found
post-image.sh: 13: /tmp/tmp.5a3xhQQVc8: BR2_EXTERNAL_INFIX_PATH: not found

Let's grep for a "key.*=" instead of "key" to drop those warnings, while
still acting as a catch-all for partial matches.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-12 11:22:55 +02:00
Richard AlpeandJoachim Wiberg 7d8b876cc7 cli: handle missing oper-status
Use known data from .self to avoid crashing if the oper-status is
missing for a interface.

Signed-off-by: Richard Alpe <richard@bit42.se>
2023-10-12 10:10:30 +02:00
Jon-Olov VatnandJoachim Wiberg fdcc6d35a4 Doc: Fixing hostname in examples
Fixing hostname to state admin@example where this was missed.
And some typos.
2023-10-11 13:17:11 +02:00
Jon-Olov VatnandJoachim Wiberg 2c21943ebf Doc: Updating IP address config examples after origin fixes
Fixes to IPv6 address origin (type 'random' rather than 'other')
now reflected in documentation.
Also using 'admin' instead of 'root' user in examples.
2023-10-11 13:17:11 +02:00
Tobias WaldekranzandJoachim Wiberg 2f1c383602 board/aarch64: alder: Initial add
- Device tree
- Enable needed drivers
- Include in aarch64_defconfig
- 88X3310P Firmware
2023-10-10 14:54:50 +02:00
Tobias WaldekranzandJoachim Wiberg 5f37b8acd3 board/aarch64: Build kernel and modules with debug info
This costs nothing on target, and it means that we always have debug
symbols ready when we need them, without having to do a complete
rebuild.
2023-10-10 14:54:50 +02:00
Tobias WaldekranzandJoachim Wiberg 5891c0f2b3 board/aarch64: Build all network related drivers as modules
As we may need to load firmware to the PHYs, we can't load those
modules until we have access to the rootfs. In order for that to work,
the MDIO driver must not be built-in, as that will cause the kernel to
bind devices with missing (built-in) drivers to bind to the genphy
driver.

Therefore, build everything as modules and let udev load it during
boot.
2023-10-10 14:54:50 +02:00
Tobias WaldekranzandJoachim Wiberg 7d1580ca21 board/common: nameif: Make switch port marking more robust
Let's operate on JSON data, so that we're less vulnerable to output
changes in devlink.
2023-10-10 14:54:50 +02:00
Tobias WaldekranzandJoachim Wiberg c5eed505fe board/common: Add convenience macros 'hd' and 'llping'
'hd':
    Hexdump, in canonical format

'llping':
    Ping any IPv6 neighbors using the link-local all-nodes group

    Usage: llping <IFACE>
2023-10-10 14:54:50 +02:00
Tobias WaldekranzandJoachim Wiberg cbaa599c68 aarch64: Use DTS overlay directory
Now that buildroot supports overlay directories for DT sources, use it
in the aarch64 build.
2023-10-10 14:54:50 +02:00
Tobias WaldekranzandJoachim Wiberg a485f15468 buildroot: DTS overlay directories 2023-10-10 14:54:50 +02:00
Tobias WaldekranzandJoachim Wiberg 558c2a40ee kernel: Bump to 6.5.6 + kkit-linux-6.5.y
In order get the ONIE EEPROM support and some mv88e6xxx related fixes,
move to 6.5.6, with the intention of upgrading again, to the next
longterm kernel, as soon as one becomes available.

Also, import patches from kkit-linux-6.5.y.
2023-10-10 14:54:50 +02:00
Joachim WibergandTobias Waldekranz db1d7f41e7 confd: rename Finit sysrepo.conf -> confd.conf
Everything else is named confd, even syslog messages are logged as
confd, and we've talked about not using sysrepo-plugind one day, so
let's prepare for a world where everthing is like that.

Also, and even more importantly, fix the sysrepo-plugind condition.
We cannot use <pid/syslogd>, because it can be restarted and thus
consequently Finit will stop sysrepo-plugind.  This first caused a
bit of head scratching because it cause a lot of very odd errors in
the execution of sysrepo-plugind, transactions being abruptly aborted
for instace.

Whatt we can do, however, is use a static condition, which Finit has
support for since a few releases now.  We want to guard the start of
our sysrepo-plugind service behind YANG /usr/libexec/confd/bootstrap.
So we can use <run/bootstrap/success>.  In case the bootstrap fails,
we catch that in the row before using if:<run/bootstrap/failure> to
trigger the /usr/libexec/confd/error script (described previously).

The other run/task/services can be guarded behind <pid/confd> and now
everything suddenly makes sense.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-09 10:41:46 +02:00
Joachim WibergandTobias Waldekranz 787955d877 confd: add error handling in case of failed bootstrap or load
- New script 'error' that can be overridden by a br2-external
 - Call 'error' if YANG model bootstap or factory-config.gen fails
 - Call 'error' if loading startup-config or failure-config fails

The 'error' script calls syslog¹ to log the error messge:

    The device has reached an unrecoverable error, please RMA.
____
¹ to get a timestamp log message, and send remote in case a
  br2-external has somehow hard-coded network for remote syslog

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-09 10:41:46 +02:00
Joachim WibergandTobias Waldekranz f357b1df3b confd: log [PID] to syslog
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-09 10:41:46 +02:00
Joachim WibergandTobias Waldekranz ca9daef15a confd: add support for generating /cfg/failure-config.cfg
This rather huge change is a refactor of the factory-config generataion to add
support for also generating a failure-config.

The confd bootstrap script has been given an rc file.  This both eases manual
testing, when modifying the script(s), and also makes it easier to override
from a br2-external.  Infix default is router/end-device, but a br2-external
may be a switch firmware and want to default to all ports in a bridge.

The generated failure-config creates a fail-safe "do no harm" config to boot
with in case startup-config for some reason is broken or cannot be applied,
e.g., bug in confd.  Meaning, for both the router and switch use-cases the
device will start up with all interfaces isolated¹, with an IPv6 SLAAC (EUI64)
address per interface.

Services enabled in this fail-safe mode are: LLDP, mDNS/SD, SSH, and NETCONF.
All to facilitate diagnostics, troubleshooting and device recovery.

Other noteworthy changes include:

 - rename factory/failure directories again -> factory.d/failure.d.  Use
   same naming as we do on target for directories holding generated files
 - The bootstrap script no longer regenerates /cfg/factory.d on each boot
 - The bootstrap script copies all static templates to /cfg/factory.d in
   case a newer image changes the contents of them.  For troubleshooting
 - Support for overriding the 20-interfaces.json generation by br2-external
 - Support for additional 30-config.json (ovrride/extend) by br2-external
 - Expand gen-interfaces to support bridge use-case.
_____
¹ For a switch this means "no switchport", i.e., no switching between ports
  otherwise connected to a switchcore (or bridge) in startup-config.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-09 10:41:46 +02:00
Joachim WibergandTobias Waldekranz 3e48af6c36 confd: relocate auto-factory templates and prepare fail secure mode
The template and scripts for generating per-device factory-config have
been spread out across the repo.  This is an attempt to gather all the
pieces to a single location for better overview.

Parts of factory-config will be reused for the new fail secure mode, in
the file failure-config.  The beginnings of which are in this commit.

Other changes:
 - cfg-bootstrap and confd-bootstrap have been collapsed into one
 - let gen-hostname + gen-interfaces save to /cfg instead of /etc,
   we've moved the /etc directory to read-only storage in /usr/share
 - delay start of bootstrap and sysrepo-plugind after syslogd barrier
 - set 'norestart' when loading startup-confg and failure-config,
   no point in retrying if that fails, just go to error immediately

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-09 10:41:46 +02:00
Joachim WibergandTobias Waldekranz b7c4c251ca board/common: Finit dbus.conf override behind <pid/syslogd>
This ensures dbus is not started before any udevadm call has completed.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-09 10:41:46 +02:00
Joachim WibergandTobias Waldekranz 5bad7f472f Guard system critical bootstrap services behind <pid/syslogd>
This ensures they do not start earlier than the system log daemon.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-09 10:41:46 +02:00
Joachim WibergandTobias Waldekranz fd366e78f6 package/skeleton-init-finit: rename condition set by sysklogd -> syslogd
The sysklogd and BusyBox syslogd can not run at the same time.  Since they
provide the same service we standardize on them providing <pid/syslogd>.

Also, ensure syslogd does not start until the fifth udevadm has completed.
This creates a barrier preventing other run/task/services from starting
too early.  Thus guaranteeing a proper boot order.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-09 10:41:46 +02:00
Joachim WibergandTobias Waldekranz 0103b1a491 Ensure /bin/sh is a plain POSIX shell (BusyBox /bin/ash)
This commit fixes a regression introduced in 15572e9e where /bin/bash
was unintentionally set as the defalt /bin/sh in the system. This cause
several warnings and errors when a Bash-based /bin/sh tries to sources
/etc/profile because $SHELL identifies it as /bin/bash.

The ietf-system.yang model, with the infix-system.yang extensions,
declare a per-user SHELL that allow /bin/clish, /bin/bash, /bin/sh
and /bin/false.  There should be a clear distinction between them.

This change also helps us keep bashisms away.  If a script needs
Bash features, declare: #!/usr/bin/env bash

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-09 10:41:46 +02:00
Joachim WibergandTobias Waldekranz 11c157116b sec: drop sulogin and disable rescue mode in Finit (NETCONF)
This commit drops sulogin from BusyBox, as well as the Finit replacement,
in the NETCONF builds.  The classic builds retain the Finit sulogin.

Furthermore, the Finit rescue mode is disabled (which uses sulogin), so
in case of trouble at boot, e.g. missing fstab or failure to fsck, the
system will no longer go to sulogin but instead log error to console and
reboot.

  NOTE: the bootloader still needs to be locked down, otherwise a user
        could just as easily change kernel cmdline to 'shell=/bin/sh'

Misc. reshuffle and defaults updated are due to make foo-update-defconfig.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-09 10:41:46 +02:00
Joachim WibergandTobias Waldekranz 3686401a7b configs: drop finit modprobe plugin, handled by udevd now
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-09 10:41:46 +02:00
Joachim WibergandTobias Waldekranz 17665dc962 package/finit: bump to v4.5-rc5
- with conditional execution support
 - fixes to udevd and udevadm calls in renamed 10-hotplug.conf
 - support for overriding internal services, e.g. dbus, keventd

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-09 10:41:46 +02:00
Joachim WibergandTobias Waldekranz acd33d4fa5 board/common: drop duplicate sshd.config and ssh-hostkeys
Instead, use the version from package/skeleton-init-finit, including the
ssh-hostkeys (previously ssh-genhostkeys) from the same package, because
it include extensive error handling and logging on failure.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-09 10:41:46 +02:00
Joachim WibergandTobias Waldekranz e85bc8223b confd: load startup-config with a new wrapper to detect errors
The new confd-load.sh script handles bootstrapping Infix using startup-config
or a failure-config (see later commits) on error.

When used with the -b (bootstrap) option, and failure to load the give file,
the script sets a Finit condition and goes to runlevel 9.  The condition can
be used to trigger loading of a failure-config to go to a Fail Secure mode.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-09 10:41:46 +02:00
Joachim WibergandTobias Waldekranz 8152df445b confd: save boot time by not loading startup-config twice
Only create a default startup-config from factory-config if one is missing.
Do not load an existing startup-config, that is handled by a later step in
the boot process, which needs to be monitored (and displayed) separately to
fail over to a Fail Secure mode on error.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-09 10:41:46 +02:00
Joachim WibergandTobias Waldekranz 17e748a129 confd: log to syslog when user is created/deleted/modifed or error
Changes to the system concerning access rights, like users, should always
be logged, in particular when creating new users or failure to create or
modify their properties.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-09 10:41:46 +02:00
Joachim WibergandTobias Waldekranz b46849520e libsrx: add NOTE() log macro for default log level, LOG_NOTICE
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-09 10:41:46 +02:00
Joachim WibergandTobias Waldekranz d4820b598b Fix SSH hostkey generation and verification
This change addresses a problem accessing Infix over SSH.  The root cause
turned out to be the hostkeys, which live in /var/lib/ssh and not in /etc
on Infix, were corrupt.

The corruption was interesting in that they all existed, but had size 0.
This state was not caught by our ssh-genhostkeys script and that is what
this change attempts to fix.

As before this change, the script starts by calling `sshd -t` to verify
they hostkeys.  Unlike before we now check for 'invalid format' in the
output of that command.  If any file with invalid format is found, we
remove them and regenerate the hostkeys.

In this investigation it was found that the 'ssh-keygen -A' command that
generates hostkeys does not use the directories specified for the given
files in sshd_config, instead it always saves the files to /etc/ssh.

Also, since there is no panic in getting the hostkeys generated we can
allow the script to wait for syslogd to start before we run, even though
it all happens in runlevel S.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-09 10:41:46 +02:00
Joachim Wiberg 6583b1e451 .github: simplify Bob's workflow and don't move latest tag [skip ci]
We only want Bob to run when PR's have been merged to main, this means
when something is pushed to main.  (Took a while to figure this one out
actually.)  See the following community discussion for details:

https://github.com/orgs/community/discussions/26724#discussioncomment-3253102

Also, we've seen that moving the 'latest' tag messes up any push/pull/sync
operation between clones and forks, so let's skip it and see how that works.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-03 13:39:56 +02:00
Richard AlpeandRichard Alpe e11c46dc94 statd: handle IP origin for IPv6 RA
Handle IPv6 Router Advertisement (RA) based addresses.

If the last 64 bits of a link-local address is generated using the
local MAC address of the interface, i.e. a EUI-64 based address. Then
the origin is set to "link-layer".

If the addrgenmode is set to "random" instead of "eui64", then the
device will generate the interface identifier portion of the address
(the last 64 bits) randomly rather than deriving it from the MAC
address using the EUI-64 process. This will result in a "random"
origin.

Signed-off-by: Richard Alpe <richard@bit42.se>
2023-10-03 11:13:21 +02:00
Joachim Wiberg d8494e30d2 Add support for setting and fetching IPv4/IPv6 interface MTU
Setting the link MTU in Linux changes the sysctl IPV6 MTU, so we have to
set the IPv6 MTU on each run in case the IPv4 MTU changes.  Hence, this
also means the IPv6 MTU must be set *after* the IPv4 (link) MTU.

statd has been updated to read the sysctl setting for IPv6 MTU.

Notice how the loopback interface is unsupported for config + status.

Fixes issue #151

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-03 10:46:17 +02:00
Joachim Wiberg 1b58114891 configs: update minimal defconfig, add pwgen + python
We should really drop minimal defconfig entirely, see issue #127.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-03 10:46:17 +02:00
Richard AlpeandJoachim Wiberg 7ee49e60a5 .github: use gh result file in separate run cmd
Use the new fancy result-gh.md file which as github emojis. Also,
split result publishing to its own run command to simplify the YAML
file.

Signed-off-by: Richard Alpe <richard@bit42.se>
2023-10-02 11:22:47 +02:00
Richard AlpeandJoachim Wiberg ac0ef1d179 Bump 9pm submodule
> 9pm: add new result file with github emojis
> 9pm.py: expose ROOT_PATH to tests via env
> lib_tcl: improve handling of extra ssh args from test
> 9pm: fix evaluation of <base> option in nested suite
> .github: publish test result md in github
> 9pm: resolve <scratch> in suite option

Signed-off-by: Richard Alpe <richard@bit42.se>
2023-10-02 11:22:47 +02:00
149 changed files with 6452 additions and 1662 deletions
+18 -8
View File
@@ -1,16 +1,20 @@
# To enable this workflow of your Infix fork, set the repoistory or
# organisation variable (not secret):
#
# LATEST_BUILD = true
#
# https://docs.github.com/en/actions/learn-github-actions/variables#creating-configuration-variables-for-a-repository
name: Bob the Builder
on:
pull_request:
push:
branches:
- main
types:
- closed
workflow_dispatch:
jobs:
build:
if: ${{github.ref_name == 'main' && github.event_name == 'push'}} || github.event_name == 'workflow_dispatch'
if: ${{ vars.LATEST_BUILD == 'true' }}
name: Build ${{ matrix.platform }} ${{ matrix.variant }}
runs-on: ubuntu-latest
strategy:
@@ -76,14 +80,20 @@ jobs:
name: Upload Latest Build
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/download-artifact@v3
- uses: pyTooling/Actions/releaser@main
- uses: ncipollo/release-action@v1
with:
tag: latest
rm: true
allowUpdates: true
omitName: true
omitBody: true
omitBodyDuringUpdate: true
prerelease: true
tag: "latest"
token: ${{ secrets.GITHUB_TOKEN }}
files: artifact/*
artifacts: "artifact/*"
- name: Summary
run: |
cat <<EOF >> $GITHUB_STEP_SUMMARY
+17 -8
View File
@@ -1,3 +1,9 @@
# To enable this workflow of your Infix fork, set the repoistory or
# organisation variable (not secret):
#
# REGRESSION_TEST = true
#
# https://docs.github.com/en/actions/learn-github-actions/variables#creating-configuration-variables-for-a-repository
name: Reggie Regression
on:
@@ -15,6 +21,7 @@ concurrency:
jobs:
build:
if: ${{ vars.REGRESSION_TEST == 'true' }}
name: Regression Testing
runs-on: ubuntu-latest
steps:
@@ -24,7 +31,7 @@ jobs:
- name: Set Build Variables
id: vars
run: |
target=x86_64-minimal
target=x86_64
echo "dir=infix-$target" >> $GITHUB_OUTPUT
echo "tgz=infix-$target.tar.gz" >> $GITHUB_OUTPUT
- name: Restore Cache of dl/
@@ -45,9 +52,9 @@ jobs:
ccache-x86_64-netconf-
ccache-x86_64-
ccache-
- name: Configure Minimal NETCONF
- name: Configure NETCONF
run: |
make x86_64_minimal_defconfig
make x86_64_defconfig
- name: Build
run: |
make
@@ -61,9 +68,11 @@ jobs:
uses: actions/upload-artifact@v3
with:
path: output/${{ steps.vars.outputs.tgz }}
- name: Regression Test
run: |
rc=true
make test-qeneth || rc=false
cat test/.log/last/result.md >> $GITHUB_STEP_SUMMARY
eval $rc
run: make test-qeneth
- name: Publish Test Result
# Ensure this runs even if Regression Test fails
if: always()
run: cat test/.log/last/result-gh.md >> $GITHUB_STEP_SUMMARY
+10 -1
View File
@@ -4,6 +4,11 @@ on:
push:
tags:
- 'v[0-9]*.*'
workflow_dispatch:
inputs:
version:
required: false
type: string
jobs:
build:
@@ -20,7 +25,11 @@ jobs:
- name: Set Release Variables
id: build
run: |
ver=${GITHUB_REF#refs/tags/v}
if [ -n "${{ inputs.version }}" ]; then
ver=${{ inputs.version }}
else
ver=${GITHUB_REF#refs/tags/v}
fi
echo "ver=${ver}" >> $GITHUB_OUTPUT
if echo $ver | grep -qE '[0-9.]+(-alpha|-beta|-rc)[0-9]*'; then
echo "pre=true" >> $GITHUB_OUTPUT
+1 -1
View File
@@ -1,7 +1,7 @@
# To enable automatic sync of your Infix fork every day, or on dispatch,
# set the repoistory or organisation variable (not secret):
#
# SYNC_FORK = 'true'
# SYNC_FORK = true
#
# You also need a GH_SYNC_REPO token allowed to update workflows. For
# more information on variables and secrets, see the GitHub docs.
+1 -1
Submodule 9pm updated: f494f6b052...d80f8cfc7d
+105
View File
@@ -1,3 +1,108 @@
menu "Branding"
config INFIX_VENDOR
string "Vendor name"
default "KernelKit"
help
The name of the operating system vendor. This is the name of the
organization or company which produces the OS.
This name is intended to be exposed in "About this system" UIs or
software update UIs when needed to distinguish the OS vendor from
the OS itself. It is intended to be human readable.
Used for VENDOR_NAME in /etc/os-release and GNS3 appliance files.
config INFIX_VENDOR_HOME
string "Vendor URL"
help
The homepage of the OS vendor. The value should be in RFC3986
format, and should be "http:" or "https:" URLs. Only one URL shall
be listed in the setting.
Optional, used for VENDOR_HOME in /etc/os-release
config INFIX_NAME
string "Operating system name"
default "Infix"
help
Mandatory. Used for identifying the OS as NAME in /etc/os-release
and product_name in GNS3 appliance files.
config INFIX_ID
string "Operating system identifier"
default "infix"
help
A lower-case string (no spaces or other characters outside of 09,
az, '.', '_' and '-') identifying the operating system, excluding
any version information and suitable for processing by scripts or
usage in generated filenames.
Mandatory. Used for identifying the OS as ID in /etc/os-release and
in the generated image name: ID-ARCH-VERSION.img
config INFIX_IMAGE_ID
string "Operating system image name"
default "${INFIX_ID}-${BR2_ARCH}"
help
A lower-case string (no spaces or other characters outside of 09,
az, ".", "_" and "-"), for naming critical image files, directories
and archives containting the operating system.
Mandatory. When INFIX_RELEASE is set, this string is appended to
the IMAGE_ID with a '-' separator.
config INFIX_TAGLINE
string "Operating system tagline"
default "Infix — a Network Operating System"
help
Mandatory. Used for identifying the OS, e.g. as PRETTY_NAME in
/etc/os-release and description in the GNS3 appliance.
This is also show at boot when the system init process starts.
config INFIX_DESC
string "Operating system description"
help
Optional. Used for long description texts about the OS. E.g.,
the GNS3 appliance file description field. Saved in the file
/etc/os-release as INFIX_DESC.
config INFIX_HOME
string "Operating system URL"
help
Used for identifying the OS, e.g. as HOME_URL in /etc/os-release
config INFIX_DOC
string "Operating system docs"
help
Optional. Main documentation URL, will be shown in /etc/os-release
as DOCUMENTATION_URL.
config INFIX_SUPPORT
string "Operating system support"
help
Main support page for the operating system, if there is any. This
is primarily intended for operating systems which vendors provide
support for. May be a http:, https:, or mailto: URI.
Optional. Shown, e.g., as SUPPORT_URL in /etc/os-release or
maintainer_email in .gns3a.
config INFIX_OEM_PATH
string "Path to OEM br2-external"
help
A br2-external using Infix will likely want to version the branded
OS using their own GIT tags. Set this variable to point to the base
directory (absolute path) and the Infix post-build.sh will call `git
describe -C $INFIX_OEM_PATH`.
Note: for release builds the global variable INFIX_RELEASE overrides
the version information derived from `git describe`. However, the
GIT version is always saved as the BUILD_ID in /etc/os-releases.
endmenu
# For /etc/os-release, uses CondtionArchitechture= from systemd.unit(5)
config INFIX_ARCH
string
+76
View File
@@ -0,0 +1,76 @@
#ifndef _ALDER_MPP_H
#define _ALDER_MPP_H
#define CP_SMI_MDIO(X) X( "mpp0", none, 0, 0)
#define CP_SMI_MDC(X) X( "mpp1", none, 0, 0)
#define CP_XSMI_MDIO(X) X( "mpp2", none, 0, 0)
#define CP_XSMI_MDC(X) X( "mpp3", none, 0, 0)
/* mpp4: Unused */
/* mpp5: Unused */
/* mpp6: Unused */
#define SFP9_TX_FAULT(X) X( "mpp7", cp0_gpio1, 7, GPIO_ACTIVE_HIGH)
#define SFP9_TX_DISABLE(X) X( "mpp8", cp0_gpio1, 8, GPIO_ACTIVE_HIGH)
#define SFP9_MOD_ABS(X) X( "mpp9", cp0_gpio1, 9, GPIO_ACTIVE_LOW)
#define SW_RESETn(X) X("mpp10", cp0_gpio1, 10, GPIO_ACTIVE_LOW)
#define SFP9_RS0(X) X("mpp11", cp0_gpio1, 11, GPIO_ACTIVE_HIGH)
/* mpp12: Unused */
#define CP_SPI1_MISO(X) X("mpp13", none, 0, 0)
#define CP_SPI1_CS0(X) X("mpp14", none, 0, 0)
#define CP_SPI1_MOSI(X) X("mpp15", none, 0, 0)
#define CP_SPI1_SCK(X) X("mpp16", none, 0, 0)
#define WDT_TICKLE(X) X("mpp17", cp0_gpio1, 17, GPIO_ACTIVE_HIGH)
/* mpp18: Unused */
/* mpp19: Unused */
/* mpp20: Unused */
/* mpp21: Unused */
/* mpp22: Unused */
/* mpp23: Unused */
#define SFP9_RX_LOS(X) X("mpp24", cp0_gpio1, 24, GPIO_ACTIVE_HIGH)
#define ETH9_RESETn(X) X("mpp25", cp0_gpio1, 25, GPIO_ACTIVE_LOW)
#define SW_INTn(X) X("mpp26", cp0_gpio1, 26, IRQ_TYPE_LEVEL_LOW)
#define SFP9_RS1(X) X("mpp27", cp0_gpio1, 27, GPIO_ACTIVE_HIGH)
#define SFP10_TX_FAULT(X) X("mpp28", cp0_gpio1, 28, GPIO_ACTIVE_HIGH)
#define CP_UA0_RXD(X) X("mpp29", none, 0, 0)
#define CP_UA0_TXD(X) X("mpp30", none, 0, 0)
#define SFP10_TX_DISABLE(X) X("mpp31", cp0_gpio1, 31, GPIO_ACTIVE_HIGH)
#define SFP10_MOD_ABS(X) X("mpp32", cp0_gpio2, 0, GPIO_ACTIVE_LOW)
#define I2C_IRQ(X) X("mpp33", cp0_gpio2, 1, GPIO_ACTIVE_HIGH)
#define SFP10_RS0(X) X("mpp34", cp0_gpio2, 2, GPIO_ACTIVE_HIGH)
#define CP_I2C1_SDA(X) X("mpp35", none, 0, 0)
#define CP_I2C1_SCK(X) X("mpp36", none, 0, 0)
#define CP_I2C0_SCK(X) X("mpp37", none, 0, 0)
#define CP_I2C0_SDA(X) X("mpp38", none, 0, 0)
#define SFP10_RX_LOS(X) X("mpp39", cp0_gpio2, 7, GPIO_ACTIVE_HIGH)
#define SFP10_RS1(X) X("mpp40", cp0_gpio2, 8, GPIO_ACTIVE_HIGH)
#define CP_SD_CRD_PWR_OFF(X) X("mpp41", none, 0, 0)
#define CP_SD_HST_18_EN(X) X("mpp42", none, 0, 0)
#define CP_SD_CRD_DT(X) X("mpp43", none, 0, 0)
#define ETH9_INTn(X) X("mpp44", cp0_gpio2, 12, GPIO_ACTIVE_LOW)
/* mpp45: Unused */
#define ETH10_RESETn(X) X("mpp46", cp0_gpio2, 14, GPIO_ACTIVE_LOW)
#define I2C_RESETn(X) X("mpp47", cp0_gpio2, 15, GPIO_ACTIVE_LOW)
#define ETH10_INTn(X) X("mpp48", cp0_gpio2, 16, GPIO_ACTIVE_LOW)
#define DEV_MODEn(X) X("mpp49", cp0_gpio2, 17, GPIO_ACTIVE_LOW)
#define USB1_VBUS_ENABLE(X) X("mpp50", cp0_gpio2, 18, GPIO_ACTIVE_HIGH)
#define USB1_VBUS_ERROR_OC(X) X("mpp51", cp0_gpio2, 19, GPIO_ACTIVE_HIGH)
/* mpp52: Unused */
/* mpp53: Unused */
/* mpp54: Unused */
#define CP_SD_LED(X) X("mpp55", none, 0, 0)
#define CP_SD_CLK(X) X("mpp56", none, 0, 0)
#define CP_SD_CMD(X) X("mpp57", none, 0, 0)
#define CP_SD_D0(X) X("mpp58", none, 0, 0)
#define CP_SD_D1(X) X("mpp59", none, 0, 0)
#define CP_SD_D2(X) X("mpp60", none, 0, 0)
#define CP_SD_D3(X) X("mpp61", none, 0, 0)
#define DDR_TEN(X) X("mpp62", cp0_gpio2, 30 GPIO_ACTIVE_HIGH)
/* Macros to extract MPP info in different formats */
#define MPP_ID(_mpp, _chip, _no, _flags) _mpp
#define MPP_GPIO_CHIP(_mpp, _chip, _no, _flags) _chip
#define MPP_GPIO_REF(_mpp, _chip, _no, _flags) <&_chip _no _flags>
#define MPP_GPIO_REF_NO_CHIP(_mpp, _chip, _no, _flags) <_no _flags>
#define MPP_IRQ_REF(_mpp, _chip, _no, _flags) <&_chip _no _flags>
#endif /* _ALDER_MPP_H */
+9
View File
@@ -0,0 +1,9 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (C) 2021 Marvell International Ltd.
* Copyright (C) 2023 Addiva Elektronik AB
*
* Device tree for Alder board
*/
#include "alder.dtsi"
+611
View File
@@ -0,0 +1,611 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (C) 2021 Marvell International Ltd.
* Copyright (C) 2023 Addiva Elektronik AB
*
* Device tree for Alder board
*/
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/leds/common.h>
#include "../marvell/cn9130-patched.dtsi"
#include "alder-mpp.h"
/ {
model = "Alder";
compatible = "alder,alder",
"marvell,armada-ap807-quad",
"marvell,armada-ap807";
chosen {
stdout-path = "serial0:115200n8";
};
memory@0 {
device_type = "memory";
reg = <0x0 0x0 0x0 0x80000000>;
};
};
/* UART0 (Console) */
&cp0_pinctrl {
cp0_uart0_pins: cp0-uart0-pins {
marvell,pins = CP_UA0_RXD(MPP_ID), CP_UA0_TXD(MPP_ID);
marvell,function = "uart0";
};
};
&uart0 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&cp0_uart0_pins>;
};
/* GPIO */
&cp0_gpio1 {
status = "okay";
};
&cp0_gpio2 {
status = "okay";
};
/* I2C0 (EEPROM) */
&cp0_pinctrl {
cp0_i2c0_pins: cp0-i2c0-pins {
marvell,pins = CP_I2C0_SCK(MPP_ID), CP_I2C0_SDA(MPP_ID);
marvell,function = "i2c0";
};
};
&cp0_i2c0 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&cp0_i2c0_pins>;
eeprom@50 {
// AT24C256C-MAHL-T
compatible = "atmel,24c256";
reg = <0x50>;
};
};
/* I2C1 (Mux) */
&cp0_pinctrl {
cp0_i2c1_pins: cp0-i2c1-pins {
marvell,pins = CP_I2C1_SCK(MPP_ID), CP_I2C1_SDA(MPP_ID);
marvell,function = "i2c1";
};
};
&cp0_i2c1 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&cp0_i2c1_pins>;
i2cmux@70 {
compatible = "nxp,pca9548";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x70>;
reset-gpios = I2C_RESETn(MPP_GPIO_REF);
i2c_sysmgmt: i2c@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
};
i2c_pwr: i2c@1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
};
i2c_sw: i2c@2 {
#address-cells = <1>;
#size-cells = <0>;
reg = <2>;
};
i2c_sfp9: i2c@3 {
#address-cells = <1>;
#size-cells = <0>;
reg = <3>;
};
i2c_sfpa: i2c@4 {
#address-cells = <1>;
#size-cells = <0>;
reg = <4>;
};
i2c@5 {
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
reg = <5>;
};
i2c@6 {
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
reg = <6>;
};
i2c@7 {
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
reg = <7>;
};
};
};
/* System Management */
&i2c_sysmgmt {
eeprom@b {
label = "vpd";
reg = <0x0b>;
compatible = "atmel,24c02";
read-only;
nvmem-layout {
compatible = "onie,tlv-layout";
base_mac: mac-address {
#nvmem-cell-cells = <1>;
};
};
};
};
/* AP SDHCI (eMMC) */
&ap_sdhci0 {
status = "okay";
pinctrl-names = "default";
/* pinctrl-0 = <&ap_emmc_pins>; No pinctrl in Linux? */
bus-width = <8>;
mmc-ddr-1_8v;
mmc-hs400-1_8v;
};
/* CP SDHCI (Micro-SD) */
/ {
cp0_reg_sd_vccq: cp0_sd_vccq@0 {
compatible = "regulator-gpio";
regulator-name = "cp0_sd_vccq";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
/* gpios = <&CP_SD_HST_18_EN>; */
states = <1800000 0x1
3300000 0x0>;
};
cp0_reg_sd_vcc: cp0_sd_vcc@0 {
compatible = "regulator-fixed";
regulator-name = "cp0_sd_vcc";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
/* gpio = <&CP_SD_CRD_PWR_OFF>; */
enable-active-high;
regulator-always-on;
};
};
&cp0_pinctrl {
cp0_sdhci_pins: cp0-sdhi-pins-0 {
marvell,pins = \
CP_SD_CRD_PWR_OFF(MPP_ID), CP_SD_HST_18_EN(MPP_ID), \
CP_SD_CRD_DT(MPP_ID), CP_SD_LED(MPP_ID), \
CP_SD_CLK(MPP_ID), CP_SD_CMD(MPP_ID), \
CP_SD_D0(MPP_ID), CP_SD_D1(MPP_ID), \
CP_SD_D2(MPP_ID), CP_SD_D3(MPP_ID);
marvell,function = "sdio";
};
};
&cp0_sdhci0 {
status = "disabled";
pinctrl-names = "default";
pinctrl-0 = <&cp0_sdhci_pins>;
bus-width = <4>;
/* cd-gpios = <&CP_SD_CRD_DT>; */
vqmmc-supply = <&cp0_reg_sd_vccq>;
vmmc-supply = <&cp0_reg_sd_vcc>;
};
/* SPI1 (Boot FLASH) */
&cp0_pinctrl {
cp0_spi1_pins: cp0-spi-pins-0 {
marvell,pins = \
CP_SPI1_MISO(MPP_ID), CP_SPI1_CS0(MPP_ID), \
CP_SPI1_MOSI(MPP_ID), CP_SPI1_SCK(MPP_ID);
marvell,function = "spi1";
};
};
&cp0_spi1 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&cp0_spi1_pins>;
/* Boot flash */
spi-flash@0 {
#address-cells = <0x1>;
#size-cells = <0x1>;
compatible = "jedec,spi-nor", "spi-flash";
reg = <0x0>;
/* On-board MUX does not allow higher frequencies */
spi-max-frequency = <40000000>;
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
boot0@0 {
label = "boot0";
reg = <0x0 0x200000>;
};
boot1@200000 {
label = "boot1";
reg = <0x200000 0x200000>;
};
};
};
};
/* USB1 */
/ {
cp0_usb3_0_phy1: cp0_usb3_phy {
compatible = "usb-nop-xceiv";
vcc-supply = <&reg_cp0_usb3_vbus1>;
};
reg_cp0_usb3_vbus1: reg_cp0_usb3_vbus1 {
compatible = "regulator-fixed";
regulator-name = "cp0-xhci1-vbus";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
enable-active-high;
gpio = USB1_VBUS_ENABLE(MPP_GPIO_REF);
};
};
&cp0_utmi {
status = "okay";
};
&cp0_utmi1 {
status = "okay";
};
&cp0_usb3_1 {
status = "disabled";
usb-phy = <&cp0_usb3_0_phy1>;
phys = <&cp0_utmi1>, <&cp0_comphy3 1>;
phy-names = "usb", "usb3";
dr_mode = "host";
};
/* ETH0 (DSA connection to switch) */
&cp0_crypto {
status = "okay";
};
&cp0_ethernet {
status = "okay";
};
&cp0_eth0 {
status = "okay";
phy-mode = "10gbase-r";
phys = <&cp0_comphy4 0>;
managed = "in-band-status";
nvmem-cells = <&base_mac 0>;
nvmem-cell-names = "mac-address";
};
/* MDIO (Switch) */
&cp0_pinctrl {
cp0_mdio_pins: cp0-mdio-pins-0 {
marvell,pins = CP_SMI_MDIO(MPP_ID), CP_SMI_MDC(MPP_ID);
marvell,function = "ge";
};
};
&cp0_mdio {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&cp0_mdio_pins>;
sw: switch@0 {
compatible = "marvell,mv88e6190";
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
reset-gpios = SW_RESETn(MPP_GPIO_REF);
interrupts-extended = SW_INTn(MPP_IRQ_REF);
interrupt-controller;
dsa,member = <0 0>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0x0>;
label = "cpu";
ethernet = <&cp0_eth0>;
phy-mode = "10gbase-r";
fixed-link {
speed = <10000>;
full-duplex;
};
};
#define SWP(_n, _label, _mac_offs, _phymode, _phy) \
port@_n { \
reg = <0x ## _n>; \
label = _label; \
phy-mode = _phymode; \
phy-handle = <&_phy>; \
\
nvmem-cells = <&base_mac _mac_offs>; \
nvmem-cell-names = "mac-address"; \
}
SWP(9, "x1", 1, "usxgmii", xphy9);
SWP(a, "x2", 2, "usxgmii", xphya);
SWP(8, "x3", 3, "gmii", swphy8);
SWP(7, "x4", 4, "gmii", swphy7);
SWP(6, "x5", 5, "gmii", swphy6);
SWP(5, "x6", 6, "gmii", swphy5);
SWP(4, "x7", 7, "gmii", swphy4);
SWP(3, "x8", 8, "gmii", swphy3);
SWP(2, "x9", 9, "gmii", swphy2);
SWP(1, "x10", 10, "gmii", swphy1);
#undef SWP
};
mdio {
#address-cells = <1>;
#size-cells = <0>;
swphy1: ethernet-phy@1 { reg = <0x1>; };
swphy2: ethernet-phy@2 { reg = <0x2>; };
swphy3: ethernet-phy@3 { reg = <0x3>; };
swphy4: ethernet-phy@4 { reg = <0x4>; };
swphy5: ethernet-phy@5 { reg = <0x5>; };
swphy6: ethernet-phy@6 { reg = <0x6>; };
swphy7: ethernet-phy@7 { reg = <0x7>; };
swphy8: ethernet-phy@8 { reg = <0x8>; };
};
};
};
/* XMDIO (88X3310P 10G PHYs) */
&cp0_pinctrl {
cp0_xmdio_pins: cp0-xmdio-pins-0 {
marvell,pins = CP_XSMI_MDIO(MPP_ID), CP_XSMI_MDC(MPP_ID);
marvell,function = "xg";
};
};
&ETH9_RESETn(MPP_GPIO_CHIP) {
xphy9-reset-hog {
gpio-hog;
gpios = ETH9_RESETn(MPP_GPIO_REF_NO_CHIP);
output-low;
line-name = "x1-phy-reset";
};
};
&ETH10_RESETn(MPP_GPIO_CHIP) {
xphya-reset-hog {
gpio-hog;
gpios = ETH10_RESETn(MPP_GPIO_REF_NO_CHIP);
output-low;
line-name = "x2-phy-reset";
};
};
&cp0_xmdio {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&cp0_xmdio_pins>;
/* 88X3310 specifices 35ns minimum MDC period (28.57 MHz). */
clock-frequency = <28571428>;
xphy9: ethernet-phy@4 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <4>;
sfp = <&sfp9>;
};
xphya: ethernet-phy@5 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <5>;
sfp = <&sfpa>;
};
};
/ {
sfp9: sfp@9 {
compatible = "sff,sfp";
i2c-bus = <&i2c_sfp9>;
mod-def0-gpios = SFP9_MOD_ABS(MPP_GPIO_REF);
los-gpios = SFP9_RX_LOS(MPP_GPIO_REF);
tx-disable-gpios = SFP9_TX_DISABLE(MPP_GPIO_REF);
tx-fault-gpios = SFP9_TX_FAULT(MPP_GPIO_REF);
rate-select0-gpios = SFP9_RS0(MPP_GPIO_REF);
rate-select1-gpios = SFP9_RS1(MPP_GPIO_REF);
maximum-power-milliwatt = <3000>;
};
sfpa: sfp@a {
compatible = "sff,sfp";
i2c-bus = <&i2c_sfpa>;
mod-def0-gpios = SFP10_MOD_ABS(MPP_GPIO_REF);
los-gpios = SFP10_RX_LOS(MPP_GPIO_REF);
tx-disable-gpios = SFP10_TX_DISABLE(MPP_GPIO_REF);
tx-fault-gpios = SFP10_TX_FAULT(MPP_GPIO_REF);
rate-select0-gpios = SFP10_RS0(MPP_GPIO_REF);
rate-select1-gpios = SFP10_RS1(MPP_GPIO_REF);
maximum-power-milliwatt = <3000>;
};
};
/* Power Board */
&i2c_pwr {
// Shared IRQ on I2C_IRQ
// 0x26 U13 PCF8574 GPIO I/O
gpio_pwr1: gpio@26 {
compatible = "nxp,pcf8574a";
#gpio-cells = <2>;
gpio-controller;
reg = <0x26>;
#define GPIO_PWR1_UNUSED0 gpio_pwr1 0 GPIO_ACTIVE_HIGH
#define GPIO_PWR1_UNUSED1 gpio_pwr1 1 GPIO_ACTIVE_HIGH
#define GPIO_POE_PGOOD gpio_pwr1 2 GPIO_ACTIVE_HIGH
#define GPIO_RESET_BUTTON gpio_pwr1 3 GPIO_ACTIVE_LOW
#define GPIO_VIN1_PGOOD gpio_pwr1 4 GPIO_ACTIVE_LOW
#define GPIO_LED_VIN1_ALERT gpio_pwr1 5 GPIO_ACTIVE_LOW
#define GPIO_VIN2_PGOOD gpio_pwr1 6 GPIO_ACTIVE_LOW
#define GPIO_LED_VIN2_ALERT gpio_pwr1 7 GPIO_ACTIVE_LOW
};
//0x27 U3 PCF8574 GPIO LED
gpio_pwr2: gpio@27 {
compatible = "nxp,pcf8574a";
#gpio-cells = <2>;
gpio-controller;
reg = <0x27>;
#define GPIO_LED2G gpio_pwr2 0 GPIO_ACTIVE_LOW
#define GPIO_LED2R gpio_pwr2 1 GPIO_ACTIVE_LOW
#define GPIO_LED1G gpio_pwr2 2 GPIO_ACTIVE_LOW
#define GPIO_LED1R gpio_pwr2 3 GPIO_ACTIVE_LOW
#define GPIO_LED4G gpio_pwr2 4 GPIO_ACTIVE_LOW
#define GPIO_LED4R gpio_pwr2 5 GPIO_ACTIVE_LOW
#define GPIO_LED3G gpio_pwr2 6 GPIO_ACTIVE_LOW
#define GPIO_LED3R gpio_pwr2 7 GPIO_ACTIVE_LOW
};
//0x28* U5 TPS23861PWR PoE Controller
//0x30 U5 TPS23861PWR PoE Controller broadcast
//0x50 U15 AT24C256C EEPROM
eeprom@50 {
// AT24C256C-MAHL-T
compatible = "atmel,24c256";
reg = <0x50>;
};
};
/* System LEDs */
/ {
leds: leds {
compatible = "gpio-leds";
led-statg {
function = LED_FUNCTION_STATUS;
color = <LED_COLOR_ID_GREEN>;
gpios = <&GPIO_LED1G>;
};
led-statr {
function = LED_FUNCTION_STATUS;
color = <LED_COLOR_ID_RED>;
gpios = <&GPIO_LED1R>;
};
led-faultg {
function = LED_FUNCTION_FAULT;
color = <LED_COLOR_ID_GREEN>;
gpios = <&GPIO_LED2G>;
};
led-faultr {
function = LED_FUNCTION_FAULT;
color = <LED_COLOR_ID_RED>;
gpios = <&GPIO_LED2R>;
};
led-lang {
function = LED_FUNCTION_LAN;
color = <LED_COLOR_ID_GREEN>;
gpios = <&GPIO_LED3G>;
};
led-lanr {
function = LED_FUNCTION_LAN;
color = <LED_COLOR_ID_RED>;
gpios = <&GPIO_LED3R>;
};
led-dbgg {
function = LED_FUNCTION_DEBUG;
color = <LED_COLOR_ID_GREEN>;
gpios = <&GPIO_LED4G>;
};
led-dbgr {
function = LED_FUNCTION_DEBUG;
color = <LED_COLOR_ID_RED>;
gpios = <&GPIO_LED4R>;
};
led-vin1_alert {
function = "power-1";
color = <LED_COLOR_ID_RED>;
gpios = <&GPIO_LED_VIN1_ALERT>;
};
led-vin2_alert {
function = "power-2";
color = <LED_COLOR_ID_RED>;
gpios = <&GPIO_LED_VIN2_ALERT>;
};
};
};
@@ -0,0 +1,8 @@
#include "cn9130.dtsi"
&cp0_syscon0 {
cp0_pinctrl: pinctrl {
/* For some reason, this is missing from cn9130.dtsi */
compatible = "marvell,cp115-standalone-pinctrl";
};
};
@@ -5,7 +5,7 @@
*/
/dts-v1/;
#include "microchip/sparx5_pcb135_emmc.dts"
#include "sparx5_pcb135_emmc.dts"
&cpu0 {
enable-method = "spin-table";
+11 -5
View File
@@ -262,7 +262,7 @@ CONFIG_VETH=m
CONFIG_VIRTIO_NET=y
CONFIG_NLMON=y
CONFIG_NET_VRF=y
CONFIG_NET_DSA_MV88E6XXX=y
CONFIG_NET_DSA_MV88E6XXX=m
CONFIG_NET_DSA_MV88E6XXX_PTP=y
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_NET_VENDOR_ADAPTEC is not set
@@ -287,8 +287,8 @@ CONFIG_NET_DSA_MV88E6XXX_PTP=y
# CONFIG_NET_VENDOR_GOOGLE is not set
# CONFIG_NET_VENDOR_HISILICON is not set
# CONFIG_NET_VENDOR_HUAWEI is not set
CONFIG_MVNETA=y
CONFIG_MVPP2=y
CONFIG_MVNETA=m
CONFIG_MVPP2=m
# CONFIG_NET_VENDOR_MELLANOX is not set
# CONFIG_NET_VENDOR_MICREL is not set
CONFIG_SPARX5_SWITCH=y
@@ -326,15 +326,16 @@ CONFIG_8139CP=y
# CONFIG_NET_VENDOR_XILINX is not set
CONFIG_SFP=y
CONFIG_MARVELL_PHY=y
CONFIG_MARVELL_10G_PHY=y
CONFIG_MARVELL_10G_PHY=m
CONFIG_MICREL_PHY=y
CONFIG_MICROCHIP_PHY=y
CONFIG_MICROCHIP_T1_PHY=y
CONFIG_MICROSEMI_PHY=y
CONFIG_MICROSEMI_PHY=m
CONFIG_MDIO_BITBANG=y
CONFIG_MDIO_MVUSB=y
CONFIG_MDIO_MSCC_MIIM=y
CONFIG_MDIO_BUS_MUX_MMIOREG=y
CONFIG_USB_RTL8152=y
CONFIG_USB_USBNET=y
CONFIG_USB_NET_CDC_EEM=y
# CONFIG_USB_NET_CDC_NCM is not set
@@ -371,6 +372,7 @@ CONFIG_I2C_SLAVE=y
CONFIG_SPI=y
CONFIG_SPI_ARMADA_3700=y
CONFIG_SPI_NXP_FLEXSPI=y
CONFIG_SPI_ORION=y
CONFIG_SPI_PL022=y
CONFIG_SPI_MUX=y
CONFIG_SPI_SPIDEV=m
@@ -458,6 +460,7 @@ CONFIG_MMC_SPI=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_EXYNOS=y
CONFIG_MMC_DW_K3=y
CONFIG_MMC_CQHCI=y
CONFIG_MMC_SDHCI_XENON=y
CONFIG_SCSI_UFSHCD=y
CONFIG_SCSI_UFSHCD_PLATFORM=y
@@ -498,7 +501,9 @@ CONFIG_TI_ADC081C=y
CONFIG_PWM=y
CONFIG_PHY_XGENE=y
CONFIG_PHY_MVEBU_CP110_COMPHY=y
CONFIG_PHY_MVEBU_CP110_UTMI=y
CONFIG_PHY_SAMSUNG_USB2=y
CONFIG_NVMEM_LAYOUT_ONIE_TLV=y
CONFIG_MUX_MMIO=y
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
@@ -533,6 +538,7 @@ CONFIG_IRQ_POLL=y
CONFIG_PRINTK_TIME=y
CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
CONFIG_DEBUG_FS=y
CONFIG_DETECT_HUNG_TASK=y
# CONFIG_SCHED_DEBUG is not set
@@ -1,4 +1,4 @@
label Infix (aarch64)
kernel /boot/Image
fdtdir /boot
append ${bootargs_root} ${bootargs_rauc} ${bootargs_log}
append ${bootargs_root} ${bootargs_log} -- ${bootargs_user}
+1
View File
@@ -0,0 +1 @@
x33x0fw_0_3_11_0_11832.hdr
+5 -11
View File
@@ -415,17 +415,11 @@ a printer can publish IPP records with meta data on the printer type and model
or donwload URL for drivers. Switches and routers usually publish how they
can be reached: HTTP/HTTPS and SSH.
Note: there are other mechanisms for device discovery. Microsoft have been
slow to adopt mDNS, having relied on their own SSDP protocol. For the
full experince Apple's "Bonjour" can be installed in Windows.
mDNS is supported in this product and should be enabled by default. To
verify it works, open the Windows File Explorer (Win+E) and scroll to
Network in the left-hand menu. An icon with a matching hostname can be
found there which, when clicked, opens up the device's Web Interface.
macOS users have mDNS fully integrated by default. Linux users can use
'mdns-scan' or Avahi, as shown above. The latter two can also just set
their web browsers to https://hostname-01-02-03.local
mDNS is supported in this product and should be enabled by default. To
verify that it works, in Windows, macOS, or Linux, open your web browser
and point it to <https://hostname-01-02-03.local>. This is the hostname
and three last octets of the device's base MAC address. You can also use
mDNS browsers or command line tools like mdns-scan
$(h2 "VLAN Interfaces")
+1 -1
View File
@@ -100,7 +100,7 @@ config DISK_IMAGE_RELEASE_URL
menuconfig GNS3_APPLIANCE
bool "GNS3 Appliance"
select DISK_IMAGE
default y if BR2_x86_64
default y
help
Create a GNS3 appliance description that, together with the
disk image, can be imported into GNS3.
+3 -3
View File
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Busybox version: 1.36.0
# Fri Jul 7 17:59:34 2023
# Tue Oct 3 18:00:40 2023
#
CONFIG_HAVE_DOT_CONFIG=y
@@ -538,7 +538,7 @@ CONFIG_LAST_ID=60000
CONFIG_FIRST_SYSTEM_ID=100
CONFIG_LAST_SYSTEM_ID=999
# CONFIG_CHPASSWD is not set
CONFIG_FEATURE_DEFAULT_PASSWD_ALGO="md5"
CONFIG_FEATURE_DEFAULT_PASSWD_ALGO="sha512"
CONFIG_CRYPTPW=y
CONFIG_MKPASSWD=y
CONFIG_DELUSER=y
@@ -556,7 +556,7 @@ CONFIG_SU=y
CONFIG_FEATURE_SU_SYSLOG=y
CONFIG_FEATURE_SU_CHECKS_SHELLS=y
# CONFIG_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY is not set
CONFIG_SULOGIN=y
# CONFIG_SULOGIN is not set
CONFIG_VLOCK=y
#
+1 -1
View File
@@ -30,7 +30,7 @@ image var.ext4 {
}
}
image disk.img {
image @DISKIMG@ {
size = @TOTALSIZE@
hdimage {
partition-table-type = "gpt"
+13 -4
View File
@@ -9,11 +9,20 @@ die()
exit 1
}
# Find all matching key=value assignments in output/.config
# E.g., load_cfg DISK_IMAGE sets the following variables:
#
# DISK_IMAGE=y
# DISK_IMAGE_SIZE="512"
# etc.
#
# shellcheck disable=SC1090
load_cfg()
{
local tmp=$(mktemp -p /tmp)
tmp=$(mktemp -p /tmp)
grep "$1" $BR2_CONFIG >$tmp
. $tmp
rm $tmp
grep -E "${1}.*=" "$BR2_CONFIG" >"$tmp"
. "$tmp"
rm "$tmp"
}
+7 -2
View File
@@ -123,10 +123,11 @@ tmp=$BUILD_DIR/genimage.tmp
total=$((512 << M))
bootoffs=$((32 << K))
bootdata=
diskimg=disk.img
bootimg=
bootpart=
while getopts "a:b:B:s:" opt; do
while getopts "a:b:B:n:s:" opt; do
case ${opt} in
a)
arch=$OPTARG
@@ -137,6 +138,9 @@ while getopts "a:b:B:s:" opt; do
B)
bootoffs=$(($OPTARG))
;;
n)
diskimg=${OPTARG}
;;
s)
total=$(size2int $OPTARG)
;;
@@ -158,6 +162,7 @@ awk \
-vimgsize=$imgsize \
-vcfgsize=$cfgsize \
-vvarsize=$varsize \
-vdiskimg=$diskimg \
-vbootimg="$bootimg" -vbootpart="$bootpart" \
'{
sub(/@TOTALSIZE@/, total);
@@ -166,7 +171,7 @@ awk \
sub(/@IMGSIZE@/, imgsize);
sub(/@CFGSIZE@/, cfgsize);
sub(/@VARSIZE@/, varsize);
sub(/@DISKIMG@/, diskimg);
sub(/@BOOTIMG@/, bootimg);
sub(/@BOOTPART@/, bootpart);
}1' \
+63 -20
View File
@@ -1,26 +1,66 @@
#!/bin/sh
# shellcheck disable=SC1091
. "$TARGET_DIR/etc/os-release"
if [ -n "$INFIX_RELEASE" ]; then
rel="-${INFIX_RELEASE}"
fi
NM="${1:-custom}${rel}"
RAM=${2:-512}
IFNUM=${3:-1}
ARCH=$1
NM="${2:-custom}${rel}"
DISK=$3
RAM=${4:-512}
IFNUM=${5:-1}
# The aarch64 build currently has no "loader" but instead starts Linux
# directly, so we need to add a basic cmdline.
loader_args()
{
if [ "$ARCH" = "aarch64" ]; then
cat <<EOF
"kernel_command_line": "console=ttyAMA0 root=PARTLABEL=primary quiet",
EOF
fi
}
loader_img()
{
if [ "$ARCH" = "x86_64" ]; then
cat <<EOF
"bios_image": "$loader",
EOF
else
cat <<EOF
"kernel_image": "$loader",
EOF
fi
}
if [ "$ARCH" = "x86_64" ]; then
loader=OVMF.fd
accel=allow
opts=
else
loader=Image
accel=disable
opts="-M virt -cpu cortex-a72"
fi
echo ">> Disk image MD5: $(md5sum "$BINARIES_DIR/$DISK" | awk '{print $1}')"
cat <<EOF >"$BINARIES_DIR/${NM}.gns3a"
{
"name": "$NM",
"category": "router",
"description": "Infix is a Network Operating System based on Linux. It can be set up both as a switch, with offloading using switchdev, and a router with firewalling.",
"vendor_name": "KernelKit",
"vendor_url": "https://github.com/kernelkit/",
"product_name": "Infix",
"description": "$INFIX_DESC",
"vendor_name": "$VENDOR_NAME",
"vendor_url": "$VENDOR_HOME",
"product_name": "$NAME",
"registry_version": 6,
"status": "stable",
"maintainer": "KernelKit",
"maintainer_email": "kernelkit@googlegroups.com",
"usage": "Default console login is 'root', no password. For remote login, default user/pass: admin/admin also works.\n\nType 'help' for an overview of commands and relevant configuration files.\n\nThe /etc directory is writable, use the passwd tool after login as part of your set up.\nFor networking, classify interfaces as switchports with /etc/mactab, syntax: 'MAC-address eN', where N is the port number (1-MAX).\nTo set up bridging and management interfaces, use /etc/network/interfaces, and /etc/network/interfaces.d/",
"maintainer": "$VENDOR_NAME",
"maintainer_email": "${SUPPORT_URL#mailto:}",
"usage": "Default login, user/pass: admin/admin\n\nType 'help' for an overview of commands and relevant configuration files.\n\nFor Classic builds the following applies: the /etc directory is writable, use the passwd tool after login as part of your set up.\nFor networking, classify interfaces as switchports with /etc/mactab, syntax: 'MAC-address eN', where N is the port number (1-MAX).\nTo set up bridging and management interfaces, use /etc/network/interfaces, and /etc/network/interfaces.d/",
"port_name_format": "eth{0}",
"linked_clone": true,
"qemu": {
@@ -29,21 +69,24 @@ cat <<EOF >"$BINARIES_DIR/${NM}.gns3a"
"ram": ${RAM},
"cpus": 1,
"hda_disk_interface": "virtio",
"arch": "x86_64",
"arch": "$ARCH",
"console_type": "telnet",
"kvm": "allow"
$(loader_img)
$(loader_args)
"kvm": "$accel",
"options": "$opts"
},
"images": [
{
"filename": "OVMF.fd",
"filesize": $(stat --printf='%s' "$BINARIES_DIR/OVMF.fd"),
"md5sum": "$(md5sum "$BINARIES_DIR/OVMF.fd" | awk '{print $1}')",
"filename": "$loader",
"filesize": $(stat --printf='%s' "$BINARIES_DIR/$loader"),
"md5sum": "$(md5sum "$BINARIES_DIR/$loader" | awk '{print $1}')",
"version": "0.0"
},
{
"filename": "disk.img",
"filesize": $(stat --printf='%s' "$BINARIES_DIR/disk.img"),
"md5sum": "$(md5sum "$BINARIES_DIR/disk.img" | awk '{print $1}')",
"filename": "$DISK",
"filesize": $(stat --printf='%s' "$BINARIES_DIR/$DISK"),
"md5sum": "$(md5sum "$BINARIES_DIR/$DISK" | awk '{print $1}')",
"version": "0.0"
}
],
@@ -51,8 +94,8 @@ cat <<EOF >"$BINARIES_DIR/${NM}.gns3a"
{
"name": "0.0",
"images": {
"bios_image": "OVMF.fd",
"hda_disk_image": "disk.img"
$(loader_img)
"hda_disk_image": "$DISK"
}
}
]
+44 -20
View File
@@ -7,19 +7,39 @@ if [ -n "${ID_LIKE}" ]; then
ID="${ID} ${ID_LIKE}"
fi
GIT_VERSION=$(git -C "$BR2_EXTERNAL_INFIX_PATH" describe --always --dirty --tags)
if [ -z "$GIT_VERSION" ]; then
infix_path="$BR2_EXTERNAL_INFIX_PATH"
if [ -n "$INFIX_OEM_PATH" ]; then
# Use version from br2-external OEM:ing Infix
infix_path="$INFIX_OEM_PATH"
fi
GIT_VERSION=$(git -C "$infix_path" describe --always --dirty --tags)
fi
# Override VERSION in /etc/os-release and filenames for release builds
if [ -n "$INFIX_RELEASE" ]; then
VERSION="$INFIX_RELEASE"
else
VERSION=$GIT_VERSION
fi
# This is a symlink to /usr/lib/os-release, so we remove this to keep
# original Buildroot information.
rm -f "$TARGET_DIR/etc/os-release"
{
echo "NAME=\"Infix\""
echo "VERSION=${GIT_VERSION}"
echo "ID=infix"
echo "NAME=\"$INFIX_NAME\""
echo "ID=$INFIX_ID"
echo "PRETTY_NAME=\"$INFIX_TAGLINE\""
echo "ID_LIKE=\"${ID}\""
echo "VERSION_ID=${GIT_VERSION}"
echo "BUILD_ID=\"${NAME} ${VERSION}\""
echo "PRETTY_NAME=\"Infix by KernelKit\""
echo "VERSION=\"${VERSION}\""
echo "VERSION_ID=${VERSION}"
echo "BUILD_ID=\"${GIT_VERSION}\""
if [ -n "$INFIX_IMAGE_ID" ]; then
echo "IMAGE_ID=\"$INFIX_IMAGE_ID\""
fi
if [ -n "$INFIX_RELEASE" ]; then
echo "IMAGE_VERSION=\"$INFIX_RELEASE\""
fi
if [ "$INFIX_VARIANT_NETCONF" = "y" ]; then
echo "VARIANT=\"Managed NETCONF\""
echo "VARIANT_ID=netconf"
@@ -28,11 +48,25 @@ rm -f "$TARGET_DIR/etc/os-release"
echo "VARIANT_ID=classic"
fi
echo "ARCHITECTURE=\"${INFIX_ARCH}\""
echo "HOME_URL=https://github.com/KernelKit"
echo "HOME_URL=$INFIX_HOME"
if [ -n "$INFIX_VENDOR" ]; then
echo "VENDOR_NAME=\"$INFIX_VENDOR\""
fi
if [ -n "$INFIX_VENDOR_HOME" ]; then
echo "VENDOR_HOME=\"$INFIX_VENDOR_HOME\""
fi
if [ -n "$INFIX_DOC" ]; then
echo "DOCUMENTATION_URL=\"$INFIX_DOC\""
fi
if [ -n "$INFIX_SUPPORT" ]; then
echo "SUPPORT_URL=\"$INFIX_SUPPORT\""
fi
if [ -n "$INFIX_DESC" ]; then
echo "INFIX_DESC=\"$INFIX_DESC\""
fi
} > "$TARGET_DIR/etc/os-release"
echo "Infix by KernelKit $GIT_VERSION -- $(date +"%b %e %H:%M %Z %Y")" > "$TARGET_DIR/etc/version"
echo "$INFIX_TAGLINE $VERSION -- $(date +"%b %e %H:%M %Z %Y")" > "$TARGET_DIR/etc/version"
# Allow pdmenu (setup) and bash to be login shells, bash is added
# automatically when selected in menuyconfig, but not when BusyBox
@@ -46,13 +80,3 @@ grep -qsE '^/bin/true$$' "$TARGET_DIR/etc/shells" \
|| echo "/bin/true" >> "$TARGET_DIR/etc/shells"
grep -qsE '^/bin/false$$' "$TARGET_DIR/etc/shells" \
|| echo "/bin/false" >> "$TARGET_DIR/etc/shells"
# Menuconfig support for modifying Qemu args in release tarballs
cp "$BR2_EXTERNAL_INFIX_PATH/board/common/qemu/qemu.sh" "$BINARIES_DIR/"
sed "s/default QEMU_aarch64/default QEMU_$BR2_ARCH/" \
< "$BR2_EXTERNAL_INFIX_PATH/board/common/qemu/Config.in" \
> "$BINARIES_DIR/Config.in"
rm -f "$BINARIES_DIR/qemu.cfg"
CONFIG_="CONFIG_" BR2_CONFIG="$BINARIES_DIR/qemu.cfg" \
"$O/build/buildroot-config/conf" --olddefconfig "$BINARIES_DIR/Config.in"
rm -f "$BINARIES_DIR/qemu.cfg.old" "$BINARIES_DIR/.config.old"
+29 -12
View File
@@ -1,12 +1,23 @@
#!/bin/sh
common=$(dirname "$(readlink -f "$0")")
. $common/lib.sh
# shellcheck disable=SC2086
common=$(dirname "$(readlink -f "$0")")
. "$common/lib.sh"
# shellcheck disable=SC1091
. "$TARGET_DIR/etc/os-release"
load_cfg INFIX_ID
load_cfg BR2_ARCH
load_cfg BR2_DEFCONFIG
load_cfg BR2_EXTERNAL_INFIX_PATH
load_cfg BR2_TARGET_ROOTFS
NAME=infix-$(basename "$BR2_DEFCONFIG" _defconfig | tr _ - | sed 's/x86-64/x86_64/')
if [ -n "$IMAGE_ID" ]; then
NAME="$IMAGE_ID"
else
NAME="$INFIX_ID"-$(echo "$BR2_ARCH" | tr _ - | sed 's/x86-64/x86_64/')
fi
diskimg=disk.img
ver()
{
@@ -31,7 +42,7 @@ fi
load_cfg DISK_IMAGE
if [ "$DISK_IMAGE" = "y" ]; then
ixmsg "Creating Disk Image"
diskimg="${NAME}-disk.img"
bootcfg=
if [ "$DISK_IMAGE_BOOT_DATA" ]; then
bootcfg="-b $DISK_IMAGE_BOOT_DATA -B $DISK_IMAGE_BOOT_OFFSET"
@@ -44,16 +55,15 @@ if [ "$DISK_IMAGE" = "y" ]; then
[ -f "$archive" ] || wget -O"$archive" "$DISK_IMAGE_RELEASE_URL"
tar -xa --strip-components=1 -C "$BINARIES_DIR" -f "$archive"
fi
$common/mkrauc-status.sh "$BINARIES_DIR/${NAME}.pkg" >"$BINARIES_DIR/rauc.status"
$common/mkdisk.sh -a $BR2_ARCH -s $DISK_IMAGE_SIZE $bootcfg
$common/mkdisk.sh -a $BR2_ARCH -n $diskimg -s $DISK_IMAGE_SIZE $bootcfg
fi
load_cfg GNS3_APPLIANCE
if [ "$GNS3_APPLIANCE" = "y" ]; then
load_cfg GNS3_APPLIANCE_RAM
load_cfg GNS3_APPLIANCE_IFNUM
ixmsg "Creating GNS3 Appliance, $GNS3_APPLIANCE_RAM MiB with $GNS3_APPLIANCE_IFNUM ports"
$common/mkgns3a.sh $NAME $GNS3_APPLIANCE_RAM $GNS3_APPLIANCE_IFNUM
$common/mkgns3a.sh $BR2_ARCH $NAME $diskimg $GNS3_APPLIANCE_RAM $GNS3_APPLIANCE_IFNUM
fi
load_cfg FIT_IMAGE
@@ -63,13 +73,20 @@ if [ "$FIT_IMAGE" = "y" ]; then
fi
if [ "$BR2_TARGET_ROOTFS_SQUASHFS" = "y" ]; then
if [ -z "${NAME##*minimal*}" ]; then
NAME=$(echo "$NAME" | sed 's/-minimal//')
fi
rel=$(ver)
ln -sf rootfs.squashfs "$BINARIES_DIR/${NAME}${rel}.img"
if [ -n "$rel" ]; then
ln -sf "$BINARIES_DIR/${NAME}${rel}.img" "$BINARIES_DIR/${NAME}.img"
fi
fi
# Menuconfig support for modifying Qemu args in release tarballs
cp "$BR2_EXTERNAL_INFIX_PATH/board/common/qemu/qemu.sh" "$BINARIES_DIR/"
sed -e "s/@ARCH@/QEMU_$BR2_ARCH/" \
-e "s/@DISK_IMG@/$diskimg/" \
< "$BR2_EXTERNAL_INFIX_PATH/board/common/qemu/Config.in.in" \
> "$BINARIES_DIR/Config.in"
rm -f "$BINARIES_DIR/qemu.cfg"
CONFIG_="CONFIG_" BR2_CONFIG="$BINARIES_DIR/qemu.cfg" \
"$O/build/buildroot-config/conf" --olddefconfig "$BINARIES_DIR/Config.in"
rm -f "$BINARIES_DIR/qemu.cfg.old" "$BINARIES_DIR/.config.old"
@@ -2,7 +2,7 @@ mainmenu "QEMU Virtualization"
choice
prompt "Target Architecture"
default QEMU_aarch64
default @ARCH@
config QEMU_x86_64
bool "x86_64"
@@ -64,7 +64,7 @@ endchoice
config QEMU_MACHINE
string
default "qemu-system-aarch64 -M virt -cpu cortex-a72 -m 256M" if QEMU_aarch64
default "qemu-system-x86_64 -M q35,accel=kvm -cpu host -m 512M" if QEMU_x86_64
default "qemu-system-x86_64 -M q35,accel=kvm -cpu host -m 256M" if QEMU_x86_64
config QEMU_KERNEL
string
@@ -80,7 +80,7 @@ config QEMU_BIOS
config QEMU_ROOTFS
string
default "disk.img" if !QEMU_ROOTFS_INITRD
default "@DISK_IMG@" if !QEMU_ROOTFS_INITRD
default "rootfs.squashfs" if QEMU_ROOTFS_INITRD
config QEMU_DTB_EXTEND
@@ -137,6 +137,10 @@ endchoice
config QEMU_NET_MODEL
string "Interface model"
default "virtio-net-pci"
help
The default, virtio-net-pci, NIC works for most use-cases, but
if you want to play with low-level stuff like ethtool, you
might want to test the Intel 82545EM driver, e1000.
config QEMU_NET_BRIDGE_DEV
string "Bridge device"
+12
View File
@@ -0,0 +1,12 @@
#!/bin/sh
Q=$@
echo "$Q, are you sure? (y/N)"
read -n1 yorn
if [ x$yorn != "xy" ]; then
echo "Ok, aborting"
exit 1
fi
exit 0
@@ -1,141 +0,0 @@
_cond()
{
initctl -pt cond dump | awk '{print $4}' | sed 's/<\(.*\)>/\1/'
}
_ident()
{
if [ -n "$1" ]; then
initctl ident | grep -q $1
else
initctl ident
fi
}
_svc()
{
initctl ls -pt | grep $1 | sed "s/.*\/\(.*\)/\1/g" | sort -u
}
_enabled()
{
echo "$(_svc enabled)"
}
_available()
{
all=$(mktemp)
ena=$(mktemp)
echo "$(_svc available)" >$all
echo "$(_svc enabled)" >$ena
grep -v -f $ena $all
rm $all $ena
}
# Determine first non-option word. Usually the command
_firstword() {
local firstword i
firstword=
for ((i = 1; i < ${#COMP_WORDS[@]}; ++i)); do
if [[ ${COMP_WORDS[i]} != -* ]]; then
firstword=${COMP_WORDS[i]}
break
fi
done
echo $firstword
}
# Determine last non-option word. Uusally a sub-command
_lastword() {
local lastword i
lastword=
for ((i = 1; i < ${#COMP_WORDS[@]}; ++i)); do
if [[ ${COMP_WORDS[i]} != -* ]] && [[ -n ${COMP_WORDS[i]} ]] && [[ ${COMP_WORDS[i]} != $cur ]]; then
lastword=${COMP_WORDS[i]}
fi
done
echo $lastword
}
_initctl()
{
local cur command
cur=${COMP_WORDS[COMP_CWORD]}
prev="${COMP_WORDS[COMP_CWORD-1]}"
firstword=$(_firstword)
lastword=$(_lastword)
commands="status cond debug help kill ls log version list enable \
disable touch show cat edit create delete reload start \
stop restart signal cgroup ps top plugins runlevel reboot \
halt poweroff suspend utmp"
cond_cmds="set get clear status dump"
cond_types="hook net pid service task usr"
signals="int term hup stop tstp cont usr1 usr2 pwr"
options="-b --batch \
-c --create \
-d --debug \
-f --force \
-h --help \
-j --json \
-n --noerr \
-1 --once \
-p --plain \
-q --quiet \
-t --no-heading \
-v --verbose \
-V --version"
case "${firstword}" in
enable)
COMPREPLY=($(compgen -W "$(_available)" -- $cur))
;;
disable|touch)
COMPREPLY=($(compgen -W "$(_enabled)" -- $cur))
;;
show|cat|edit|delete)
COMPREPLY=($(compgen -W "$(_svc .)" -- $cur))
;;
start|stop|restart|log|status)
COMPREPLY=($(compgen -W "$(_ident)" -- $cur))
;;
signal|kill)
if $(_ident "${prev}"); then
COMPREPLY=($(compgen -W "$signals" -- $cur))
else
COMPREPLY=($(compgen -W "$(_ident)" -- $cur))
fi
;;
cond)
case "${lastword}" in
set|clear)
compopt -o nospace
COMPREPLY=($(compgen -W "usr/" -- $cur))
;;
get)
COMPREPLY=($(compgen -W "$(_cond)" -- $cur))
;;
dump)
COMPREPLY=($(compgen -W "$cond_types" -- $cur))
;;
*)
COMPREPLY=($(compgen -W "$cond_cmds" -- $cur))
;;
esac
;;
*)
COMPREPLY=($(compgen -W "$commands" -- $cur))
;;
esac
if [[ $cur == -* ]]; then
COMPREPLY=($(compgen -W "$options" -- $cur))
fi
}
complete -F _initctl initctl
@@ -1,2 +1,3 @@
run [S] /lib/infix/sysctl-sync-ip-conf --
run [S] /lib/infix/nameif -- Probing network interfaces
run [S] /lib/infix/probe -- Probing system information
run [S] <pid/syslogd> /lib/infix/sysctl-sync-ip-conf --
run [S] <pid/syslogd> /lib/infix/nameif -- Probing network interfaces
@@ -1,2 +0,0 @@
task [S] /lib/infix/ssh-hostkeys --
service [2345789] <usr/ssh-hostkeys> /usr/sbin/sshd -D -- OpenSSH daemon
@@ -0,0 +1,5 @@
# Override Finit plugin
service cgroup.system name:dbus pid:!/run/messagebus.pid <pid/syslogd> \
[S123456789] /usr/bin/dbus-daemon --nofork --system --syslog-only \
-- D-Bus message bus daemon
@@ -11,6 +11,7 @@ alias view='vi -R'
alias emacs='mg'
alias sensible-editor=edit
alias sensible-pager=pager
alias hd="hexdump -C"
alias ip='ip --color=auto'
alias ipb='ip -br'
@@ -18,4 +19,6 @@ alias ipaddr='ip addr'
alias iplink='ip link'
alias bridge='bridge --color=auto'
alias llping='ping -L ff02::1 -I'
alias docker=podman
+3 -1
View File
@@ -30,7 +30,9 @@ for netif in /sys/class/net/*; do
done
# Find and mark all switch ports
ports=$(devlink port 2>/dev/null | awk '/flavour physical/{print $5}')
ports=$(devlink -j port | jq -r '.port[]
| select(.flavour == "physical")
| .netdev')
for iface in $ports; do
ip link set "$iface" group port
done
+6
View File
@@ -0,0 +1,6 @@
#!/bin/sh
# Probe for various types of harware features
if dmesg |grep -q QEMU || test -d /sys/module/qemu_fw_cfg; then
initctl cond set qemu
fi
@@ -1,9 +0,0 @@
#!/bin/sh
for type in ecdsa ed25519 rsa; do
[ -f /var/lib/ssh/ssh_host_${type}_key ] \
|| ssh-keygen -N "" -t $type -f /var/lib/ssh/ssh_host_${type}_key \
|| exit 1
done
initctl cond set ssh-hostkeys
+5 -1
View File
@@ -8,9 +8,13 @@
&env {
vendor = "infix";
bootdelay = "-2";
bootcmd = "run ixboot";
bootcmd = "run ixbtn";
boot_targets = "virtio mmc";
ixbtn = /incbin/("scripts/ixbtn.sh");
ixdevmode = /incbin/("scripts/ixdevmode.sh");
ixfactory = /incbin/("scripts/ixfactory.sh");
ixbtn = /incbin/("scripts/ixbtn.sh");
ixboot = /incbin/("scripts/ixboot.sh");
ixbootmedia = /incbin/("scripts/ixbootmedia.sh");
ixbootslot = /incbin/("scripts/ixbootslot.sh");
+11 -1
View File
@@ -1,3 +1,5 @@
setenv valid_media no
for tgt in "${boot_targets}"; do
if test "${tgt}" = "mmc0"; then
setenv devtype "mmc"
@@ -17,7 +19,7 @@ for tgt in "${boot_targets}"; do
env import -b ${loadaddr} ${filesize} BOOT_ORDER DEBUG
fi
test -n "${BOOT_ORDER}" || setenv BOOT_ORDER "primary secondary dhcp"
test -n "${BOOT_ORDER}" || setenv BOOT_ORDER "primary secondary net"
if test -n "${DEBUG}"; then
setenv bootargs_log "debug"
@@ -25,8 +27,16 @@ for tgt in "${boot_targets}"; do
setenv bootargs_log "loglevel=4"
fi
setenv valid_media yes
run ixbootmedia
fi
done
if test "${valid_media}" = "no"; then
echo "NO BOOTABLE MEDIA FOUND, falling back to netboot"
setenv BOOT_ORDER "net"
setenv bootargs_log "debug"
run ixbootmedia
fi
reset
+7 -1
View File
@@ -14,7 +14,13 @@ if test "${prepared}" = "ok"; then
if iminfo ${ramdisk_addr_r}; then
echo "${slot}: Booting..."
setenv bootargs_rauc "rauc.slot=${slot}"
setenv bootargs_user "rauc.slot=${slot}"
if test "${factory_reset}" = "yes"; then
setenv bootargs_user "${bootargs_user} finit.cond=factory-reset"
fi
if test "${dev_mode}" = "yes"; then
setenv bootargs_user "${bootargs_user} finit.cond=dev-mode"
fi
blkmap create boot
blkmap get boot dev blkmapnum
+13
View File
@@ -0,0 +1,13 @@
setenv dev_mode no
setenv factory_reset no
echo -n "dev-mode: "
run ixdevmode
echo -n "factory-reset: "
run ixfactory
if test "${dev_mode}" = "yes"; then
sleep 1 && run ixboot
else
run ixboot
fi
+3
View File
@@ -0,0 +1,3 @@
if button dev-mode; then
setenv dev_mode yes
fi
+7
View File
@@ -0,0 +1,7 @@
if button factory-reset; then
echo "Keep button pressed for 10 seconds to engage reset"
if sleep 10 && button factory-reset; then
setenv factory_reset yes
echo "FACTORY RESET ENGAGED"
fi
fi
@@ -1,35 +0,0 @@
#!/bin/sh
set -e
PATH=/lib/infix/factory:$PATH
[ "$FACTORY_D" ] || FACTORY_D=/etc/auto-factory.d
[ "$CFG_D" ] || CFG_D=/cfg
[ "$GENCFG_D" ] || GENCFG_D=/cfg/factory.d
mkdir -p $GENCFG_D
gen-hostname >$FACTORY_D/20-auto-hostname.json
gen-interfaces >$FACTORY_D/20-auto-interfaces.json
[ -s $GENCFG_D/20-auto-hostkey.json ] || gen-hostkeys >$GENCFG_D/20-auto-hostkey.json
# Allow regenerating default factory-config, but keep it read-ony
# to prevent it from being overwritten by mistake by users.
rm -f $CFG_D/auto-factory-config.cfg
# shellcheck disable=SC2046
jq -s 'reduce .[] as $item ({}; . * $item)' \
$(find $FACTORY_D -name '*.json') \
$(find $GENCFG_D -name '*.json') \
>$CFG_D/auto-factory-config.cfg
chmod 444 $CFG_D/auto-factory-config.cfg
# TODO: Look for statically defined factory-config, based on the
# system's product ID.
# If we haven't found a better one, settle for auto-factory-config as
# the system's factory-config.
[ -h $CFG_D/factory-config.cfg ] || \
ln -sf auto-factory-config.cfg $CFG_D/factory-config.cfg
# Bootstrap sysrepo db with all modules required by confd
/usr/libexec/confd/confd-bootstrap.sh $CFG_D/factory-config.cfg $CFG_D/startup-config.cfg
+43 -13
View File
@@ -32,6 +32,16 @@ class Decore():
return Decore.decorate("32", txt, "39")
class Iface:
def get_json_data(self, default, *args):
data = self.data
for arg in args:
if data.get(arg):
data = data.get(arg)
else:
return default
return data
def __init__(self, data):
self.data = data
self.name = data.get('name', '')
@@ -46,8 +56,6 @@ class Iface:
self.in_octets = ''
self.out_octets = ''
self.parent = data.get('ietf-if-extensions:parent-interface', None)
if self.data.get('ietf-ip:ipv4'):
self.mtu = self.data.get('ietf-ip:ipv4').get('mtu', '')
self.ipv4_addr = self.data.get('ietf-ip:ipv4').get('address', '')
@@ -65,6 +73,11 @@ class Iface:
else:
self.bridge = ''
if self.data.get('infix-interfaces:vlan'):
self.lower_if = self.data.get('infix-interfaces:vlan', None).get('lower-layer-if',None)
else:
self.lower_if = ''
def is_vlan(self):
return self.data['type'] == "infix-if-type:vlan"
@@ -95,8 +108,8 @@ class Iface:
def pr_proto_eth(self):
row = f"{'ethernet':<{Pad.proto}}"
dec = Decore.green if self.data['oper-status'] == "up" else Decore.red
row += dec(f"{self.data['oper-status'].upper():<{Pad.state}}")
dec = Decore.green if self.oper_status == "up" else Decore.red
row += dec(f"{self.oper_status.upper():<{Pad.state}}")
row += f"{self.data['phys-address']:<{Pad.data}}"
print(row)
@@ -126,7 +139,7 @@ class Iface:
self.pr_name(pipe="")
self.pr_proto_eth()
if self.parent:
if self.lower_if:
self.pr_proto_ipv4(pipe='│')
self.pr_proto_ipv6(pipe='│')
else:
@@ -134,7 +147,7 @@ class Iface:
self.pr_proto_ipv6()
return
parent = find_iface(_ifaces, self.parent)
parent = find_iface(_ifaces, self.lower_if)
if not parent:
print(f"Error, didn't find parent interface for vlan {self.name}")
sys.exit(1)
@@ -181,6 +194,13 @@ class Iface:
print(f"{'in-octets':<{20}}: {self.in_octets}")
print(f"{'out-octets':<{20}}: {self.out_octets}")
frame = self.get_json_data([], 'ieee802-ethernet-interface:ethernet',
'statistics', 'frame')
if frame:
print(f"")
for key, val in frame.items():
print(f"eth-{key:<{25}}: {val}")
def find_iface(_ifaces, name):
for _iface in [Iface(data) for data in _ifaces]:
@@ -210,7 +230,7 @@ def pr_interface_list(json):
continue
# These interfaces are printed by there parent, such as bridge
if iface.parent:
if iface.lower_if:
continue
if iface.bridge:
continue
@@ -234,11 +254,21 @@ def ietf_interfaces(json, name):
sys.exit(1)
return iface.pr_iface()
def main():
try:
json_data = json.load(sys.stdin)
except json.JSONDecodeError:
print("Error, invalid JSON input")
sys.exit(1)
except Exception as e:
print("Error, unexpected error parsing JSON")
sys.exit(1)
json = json.load(sys.stdin)
if args.module == "ietf-interfaces":
sys.exit(ietf_interfaces(json_data, args.name))
else:
print(f"Error, unknown module {args.module}")
sys.exit(1)
if args.module == "ietf-interfaces":
sys.exit(ietf_interfaces(json, args.name))
else:
print(f"Error, unknown module {args.module}")
sys.exit(1)
if __name__ == "__main__":
main()
@@ -1,43 +0,0 @@
#!/bin/sh
set -e
gen_interface()
{
cat <<EOF
,{
"name": "$1",
"type": "infix-if-type:ethernet",
"ietf-ip:ipv6": {
"enabled": true
}
}
EOF
}
phys_ifaces=$(ip -d -j link show | jq -r '
.[] |
select(.link_type == "ether") |
select(.group != "internal") |
select(has("parentbus")) |
.ifname')
cat <<EOF
{
"ietf-interfaces:interfaces": {
"interface": [
{
"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 }]
}
}
$(for iface in $phys_ifaces; do gen_interface $iface; done)
]
}
}
EOF
+12 -3
View File
@@ -21,14 +21,19 @@ BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNA
BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh ${BR2_EXTERNAL_INFIX_PATH}/board/classic/post-build.sh"
BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image.sh"
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.5.6"
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/linux_defconfig"
BR2_LINUX_KERNEL_DTS_SUPPORT=y
BR2_LINUX_KERNEL_INTREE_DTS_NAME="marvell/armada-3720-espressobin marvell/armada-3720-espressobin-emmc marvell/armada-3720-espressobin-v7 marvell/armada-3720-espressobin-v7-emmc marvell/armada-3720-espressobin-ultra marvell/cn9130-crb-A marvell/cn9130-crb-B sparx5_pcb135_emmc_no_psci"
BR2_LINUX_KERNEL_CUSTOM_DTS_PATH="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/dts/microchip/sparx5_pcb135_emmc_no_psci.dts"
BR2_LINUX_KERNEL_INTREE_DTS_NAME="alder/alder marvell/armada-3720-espressobin marvell/armada-3720-espressobin-emmc marvell/armada-3720-espressobin-v7 marvell/armada-3720-espressobin-v7-emmc marvell/armada-3720-espressobin-ultra marvell/cn9130-crb-A marvell/cn9130-crb-B microchip/sparx5_pcb135_emmc_no_psci"
BR2_LINUX_KERNEL_CUSTOM_DTS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/dts"
BR2_LINUX_KERNEL_DTB_KEEP_DIRNAME=y
BR2_LINUX_KERNEL_INSTALL_TARGET=y
BR2_PACKAGE_BUSYBOX_CONFIG="${BR2_EXTERNAL_INFIX_PATH}/board/common/busybox_defconfig"
BR2_PACKAGE_BUSYBOX_SHOW_OTHERS=y
BR2_PACKAGE_STRACE=y
BR2_PACKAGE_STRESS_NG=y
BR2_PACKAGE_JQ=y
BR2_PACKAGE_MDIO_TOOLS=y
BR2_PACKAGE_RNG_TOOLS=y
@@ -44,6 +49,7 @@ BR2_PACKAGE_AVAHI=y
# BR2_PACKAGE_AVAHI_AUTOIPD is not set
BR2_PACKAGE_AVAHI_DAEMON=y
BR2_PACKAGE_AVAHI_DEFAULT_SERVICES=y
BR2_PACKAGE_CHRONY=y
BR2_PACKAGE_DHCPCD=y
BR2_PACKAGE_DNSMASQ=y
BR2_PACKAGE_DROPBEAR=y
@@ -67,7 +73,6 @@ BR2_PACKAGE_NMAP_NMAP=y
BR2_PACKAGE_NMAP_NPING=y
BR2_PACKAGE_OPENRESOLV=y
BR2_PACKAGE_SOCAT=y
BR2_PACKAGE_SSDP_RESPONDER=y
BR2_PACKAGE_TCPDUMP=y
BR2_PACKAGE_TRACEROUTE=y
BR2_PACKAGE_DIALOG=y
@@ -94,6 +99,10 @@ BR2_PACKAGE_HOST_RAUC=y
BR2_PACKAGE_HOST_UBOOT_TOOLS=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
INFIX_VENDOR_HOME="https://github.com/kernelkit"
INFIX_DESC="Infix is a Network Operating System based on Linux. It can be set up both as a switch, with offloading using switchdev, and a router with firewalling."
INFIX_HOME="https://github.com/kernelkit/infix/"
INFIX_DOC="https://github.com/kernelkit/infix/tree/main/doc"
INFIX_VARIANT_CLASSIC=y
BR2_PACKAGE_FACTORY=y
BR2_PACKAGE_FINIT_SULOGIN=y
+13 -9
View File
@@ -13,7 +13,6 @@ BR2_TARGET_GENERIC_ISSUE="Infix by KernelKit"
BR2_INIT_FINIT=y
BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV=y
BR2_ROOTFS_DEVICE_TABLE="system/device_table.txt ${BR2_EXTERNAL_INFIX_PATH}/board/common/xattrs ${BR2_EXTERNAL_INFIX_PATH}/board/netconf/xattrs"
BR2_SYSTEM_BIN_SH_BASH=y
BR2_TARGET_GENERIC_GETTY_TERM="xterm"
BR2_SYSTEM_DHCP="eth0"
BR2_ENABLE_LOCALE_WHITELIST="C en_US en_CA"
@@ -23,11 +22,13 @@ BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNA
BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh ${BR2_EXTERNAL_INFIX_PATH}/board/netconf/post-build.sh"
BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image.sh"
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.5.6"
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/linux_defconfig"
BR2_LINUX_KERNEL_DTS_SUPPORT=y
BR2_LINUX_KERNEL_INTREE_DTS_NAME="marvell/armada-3720-espressobin marvell/armada-3720-espressobin-emmc marvell/armada-3720-espressobin-v7 marvell/armada-3720-espressobin-v7-emmc marvell/armada-3720-espressobin-ultra marvell/cn9130-crb-A marvell/cn9130-crb-B sparx5_pcb135_emmc_no_psci"
BR2_LINUX_KERNEL_CUSTOM_DTS_PATH="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/dts/microchip/sparx5_pcb135_emmc_no_psci.dts"
BR2_LINUX_KERNEL_INTREE_DTS_NAME="alder/alder marvell/armada-3720-espressobin marvell/armada-3720-espressobin-emmc marvell/armada-3720-espressobin-v7 marvell/armada-3720-espressobin-v7-emmc marvell/armada-3720-espressobin-ultra marvell/cn9130-crb-A marvell/cn9130-crb-B microchip/sparx5_pcb135_emmc_no_psci"
BR2_LINUX_KERNEL_CUSTOM_DTS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/dts"
BR2_LINUX_KERNEL_DTB_KEEP_DIRNAME=y
BR2_LINUX_KERNEL_INSTALL_TARGET=y
BR2_PACKAGE_BUSYBOX_CONFIG="${BR2_EXTERNAL_INFIX_PATH}/board/common/busybox_defconfig"
@@ -35,17 +36,18 @@ BR2_PACKAGE_BUSYBOX_SHOW_OTHERS=y
BR2_PACKAGE_STRACE=y
BR2_PACKAGE_STRESS_NG=y
BR2_PACKAGE_JQ=y
BR2_PACKAGE_MDIO_TOOLS=y
BR2_PACKAGE_DBUS_CXX=y
BR2_PACKAGE_DBUS_GLIB=y
BR2_PACKAGE_DBUS_TRIGGERD=y
BR2_PACKAGE_EUDEV_RULES_GEN=y
# BR2_PACKAGE_EUDEV_ENABLE_HWDB is not set
BR2_PACKAGE_MDIO_TOOLS=y
BR2_PACKAGE_RNG_TOOLS=y
BR2_PACKAGE_UBOOT_TOOLS=y
BR2_PACKAGE_UBOOT_TOOLS_FIT_SUPPORT=y
BR2_PACKAGE_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
BR2_PACKAGE_UBOOT_TOOLS_FIT_CHECK_SIGN=y
BR2_PACKAGE_PYTHON3=y
BR2_PACKAGE_CA_CERTIFICATES=y
BR2_PACKAGE_LIBOPENSSL_BIN=y
BR2_PACKAGE_LIBCURL_CURL=y
@@ -76,10 +78,10 @@ BR2_PACKAGE_NMAP_NPING=y
BR2_PACKAGE_OPENRESOLV=y
BR2_PACKAGE_OPENSSH=y
BR2_PACKAGE_SOCAT=y
BR2_PACKAGE_SSDP_RESPONDER=y
BR2_PACKAGE_TCPDUMP=y
BR2_PACKAGE_TRACEROUTE=y
BR2_PACKAGE_ULOGD=y
BR2_PACKAGE_BASH=y
BR2_PACKAGE_BASH_COMPLETION=y
BR2_PACKAGE_IRQBALANCE=y
BR2_PACKAGE_KMOD_TOOLS=y
@@ -104,23 +106,25 @@ BR2_PACKAGE_HOST_RAUC=y
BR2_PACKAGE_HOST_UBOOT_TOOLS=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
INFIX_VENDOR_HOME="https://github.com/kernelkit"
INFIX_DESC="Infix is a Network Operating System based on Linux. It can be set up both as a switch, with offloading using switchdev, and a router with firewalling."
INFIX_HOME="https://github.com/kernelkit/infix"
INFIX_DOC="https://github.com/kernelkit/infix/tree/main/doc"
INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
BR2_PACKAGE_CONFD=y
BR2_PACKAGE_STATD=y
BR2_PACKAGE_FACTORY=y
BR2_PACKAGE_FINIT_SULOGIN=y
BR2_PACKAGE_FINIT_PLUGIN_HOTPLUG=y
BR2_PACKAGE_FINIT_PLUGIN_HOOK_SCRIPTS=y
BR2_PACKAGE_FINIT_PLUGIN_MODULES_LOAD=y
BR2_PACKAGE_FINIT_PLUGIN_MODPROBE=y
BR2_PACKAGE_FINIT_PLUGIN_RTC=y
BR2_PACKAGE_FINIT_PLUGIN_TTY=y
BR2_PACKAGE_FINIT_PLUGIN_URANDOM=y
BR2_PACKAGE_KLISH_PLUGIN_INFIX=y
BR2_PACKAGE_LOWDOWN=y
BR2_PACKAGE_NET=y
BR2_PACKAGE_PYTHON3=y
BR2_PACKAGE_PYTHON3_PYC_ONLY=y
BR2_PACKAGE_TETRIS=y
BR2_PACKAGE_QUERIERD=y
DISK_IMAGE_BOOT_BIN=y
GNS3_APPLIANCE_RAM=512
GNS3_APPLIANCE_IFNUM=10
+7 -1
View File
@@ -20,6 +20,8 @@ BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNA
BR2_ROOTFS_POST_BUILD_SCRIPT="board/qemu/x86_64/post-build.sh ${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh ${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh ${BR2_EXTERNAL_INFIX_PATH}/board/classic/post-build.sh"
BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image.sh"
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.5.6"
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/x86_64/linux_defconfig"
BR2_LINUX_KERNEL_INSTALL_TARGET=y
@@ -63,7 +65,6 @@ BR2_PACKAGE_NMAP_NMAP=y
BR2_PACKAGE_NMAP_NPING=y
BR2_PACKAGE_OPENRESOLV=y
BR2_PACKAGE_SOCAT=y
BR2_PACKAGE_SSDP_RESPONDER=y
BR2_PACKAGE_TCPDUMP=y
BR2_PACKAGE_TRACEROUTE=y
BR2_PACKAGE_DIALOG=y
@@ -98,6 +99,10 @@ BR2_PACKAGE_HOST_RAUC=y
BR2_PACKAGE_HOST_UBOOT_TOOLS=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
INFIX_VENDOR_HOME="https://github.com/kernelkit"
INFIX_DESC="Infix is a Network Operating System based on Linux. It can be set up both as a switch, with offloading using switchdev, and a router with firewalling."
INFIX_HOME="https://github.com/kernelkit/infix/"
INFIX_DOC="https://github.com/kernelkit/infix/tree/main/doc"
INFIX_VARIANT_CLASSIC=y
BR2_PACKAGE_FACTORY=y
BR2_PACKAGE_FINIT_SULOGIN=y
@@ -110,3 +115,4 @@ BR2_PACKAGE_FINIT_PLUGIN_TTY=y
BR2_PACKAGE_FINIT_PLUGIN_URANDOM=y
BR2_PACKAGE_IFUPDOWN_NG=y
BR2_PACKAGE_TETRIS=y
DISK_IMAGE_BOOT_BIN=y
+9 -6
View File
@@ -12,7 +12,6 @@ BR2_TARGET_GENERIC_ISSUE="Infix by KernelKit"
BR2_INIT_FINIT=y
BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV=y
BR2_ROOTFS_DEVICE_TABLE="system/device_table.txt ${BR2_EXTERNAL_INFIX_PATH}/board/common/xattrs ${BR2_EXTERNAL_INFIX_PATH}/board/netconf/xattrs"
BR2_SYSTEM_BIN_SH_BASH=y
BR2_TARGET_GENERIC_GETTY_TERM="xterm"
BR2_SYSTEM_DHCP="eth0"
BR2_ENABLE_LOCALE_WHITELIST="C en_US en_CA"
@@ -22,6 +21,8 @@ BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNA
BR2_ROOTFS_POST_BUILD_SCRIPT="board/qemu/x86_64/post-build.sh ${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh ${BR2_EXTERNAL_INFIX_PATH}/board/netconf/post-build.sh"
BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image.sh"
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.5.6"
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/x86_64/linux_defconfig"
BR2_LINUX_KERNEL_INSTALL_TARGET=y
@@ -42,6 +43,7 @@ BR2_PACKAGE_UBOOT_TOOLS=y
BR2_PACKAGE_UBOOT_TOOLS_FIT_SUPPORT=y
BR2_PACKAGE_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
BR2_PACKAGE_UBOOT_TOOLS_FIT_CHECK_SIGN=y
BR2_PACKAGE_PYTHON3=y
BR2_PACKAGE_CA_CERTIFICATES=y
BR2_PACKAGE_LIBOPENSSL_BIN=y
BR2_PACKAGE_LIBCURL_CURL=y
@@ -72,10 +74,10 @@ BR2_PACKAGE_NMAP_NPING=y
BR2_PACKAGE_OPENRESOLV=y
BR2_PACKAGE_OPENSSH=y
BR2_PACKAGE_SOCAT=y
BR2_PACKAGE_SSDP_RESPONDER=y
BR2_PACKAGE_TCPDUMP=y
BR2_PACKAGE_TRACEROUTE=y
BR2_PACKAGE_ULOGD=y
BR2_PACKAGE_BASH=y
BR2_PACKAGE_BASH_COMPLETION=y
BR2_PACKAGE_IRQBALANCE=y
BR2_PACKAGE_KMOD_TOOLS=y
@@ -108,22 +110,23 @@ BR2_PACKAGE_HOST_RAUC=y
BR2_PACKAGE_HOST_UBOOT_TOOLS=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
INFIX_VENDOR_HOME="https://github.com/kernelkit"
INFIX_DESC="Infix is a Network Operating System based on Linux. It can be set up both as a switch, with offloading using switchdev, and a router with firewalling."
INFIX_HOME="https://github.com/kernelkit/infix/"
INFIX_DOC="https://github.com/kernelkit/infix/tree/main/doc"
INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
BR2_PACKAGE_CONFD=y
BR2_PACKAGE_STATD=y
BR2_PACKAGE_FACTORY=y
BR2_PACKAGE_FINIT_SULOGIN=y
BR2_PACKAGE_FINIT_PLUGIN_HOTPLUG=y
BR2_PACKAGE_FINIT_PLUGIN_HOOK_SCRIPTS=y
BR2_PACKAGE_FINIT_PLUGIN_MODULES_LOAD=y
BR2_PACKAGE_FINIT_PLUGIN_MODPROBE=y
BR2_PACKAGE_FINIT_PLUGIN_RTC=y
BR2_PACKAGE_FINIT_PLUGIN_TTY=y
BR2_PACKAGE_FINIT_PLUGIN_URANDOM=y
BR2_PACKAGE_KLISH_PLUGIN_INFIX=y
BR2_PACKAGE_LOWDOWN=y
BR2_PACKAGE_NET=y
BR2_PACKAGE_PYTHON3=y
BR2_PACKAGE_PYTHON3_PYC_ONLY=y
BR2_PACKAGE_TETRIS=y
BR2_PACKAGE_QUERIERD=y
GNS3_APPLIANCE_RAM=512
-73
View File
@@ -1,73 +0,0 @@
BR2_x86_64=y
BR2_x86_corei7=y
BR2_TOOLCHAIN_EXTERNAL=y
BR2_TOOLCHAIN_EXTERNAL_GDB_SERVER_COPY=y
BR2_DL_DIR="${BR2_EXTERNAL_INFIX_PATH}/dl"
BR2_CCACHE=y
BR2_CCACHE_DIR="${BR2_EXTERNAL_INFIX_PATH}/.ccache"
BR2_ENABLE_DEBUG=y
BR2_GLOBAL_PATCH_DIR="${BR2_EXTERNAL_INFIX_PATH}/patches"
BR2_TARGET_GENERIC_HOSTNAME="infix"
BR2_TARGET_GENERIC_ISSUE="Minfix by KernelKit"
BR2_INIT_FINIT=y
BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV=y
BR2_ROOTFS_DEVICE_TABLE="system/device_table.txt ${BR2_EXTERNAL_INFIX_PATH}/board/common/xattrs ${BR2_EXTERNAL_INFIX_PATH}/board/netconf/xattrs"
BR2_SYSTEM_BIN_SH_BASH=y
BR2_TARGET_GENERIC_GETTY_TERM="xterm"
BR2_SYSTEM_DHCP="eth0"
BR2_ENABLE_LOCALE_WHITELIST="C en_US en_CA"
BR2_GENERATE_LOCALE="en_US en_CA"
BR2_TARGET_TZ_INFO=y
BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNAL_INFIX_PATH}/board/x86_64/rootfs ${BR2_EXTERNAL_INFIX_PATH}/board/netconf/rootfs"
BR2_ROOTFS_POST_BUILD_SCRIPT="board/qemu/x86_64/post-build.sh ${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh ${BR2_EXTERNAL_INFIX_PATH}/board/netconf/post-build.sh"
BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image.sh"
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/x86_64/linux_defconfig"
BR2_LINUX_KERNEL_INSTALL_TARGET=y
BR2_LINUX_KERNEL_NEEDS_HOST_LIBELF=y
BR2_PACKAGE_BUSYBOX_CONFIG="${BR2_EXTERNAL_INFIX_PATH}/board/common/busybox_defconfig"
BR2_PACKAGE_BUSYBOX_SHOW_OTHERS=y
BR2_PACKAGE_JQ=y
BR2_PACKAGE_DBUS_CXX=y
BR2_PACKAGE_DBUS_GLIB=y
BR2_PACKAGE_DBUS_TRIGGERD=y
BR2_PACKAGE_EUDEV_RULES_GEN=y
# BR2_PACKAGE_EUDEV_ENABLE_HWDB is not set
BR2_PACKAGE_RNG_TOOLS=y
BR2_PACKAGE_LIBOPENSSL_BIN=y
BR2_PACKAGE_NETOPEER2_CLI=y
BR2_PACKAGE_NSS_MDNS=y
BR2_PACKAGE_ONIGURUMA=y
BR2_PACKAGE_AVAHI=y
BR2_PACKAGE_AVAHI_DAEMON=y
BR2_PACKAGE_AVAHI_DEFAULT_SERVICES=y
BR2_PACKAGE_CHRONY=y
BR2_PACKAGE_DNSMASQ=y
BR2_PACKAGE_ETHTOOL=y
# BR2_PACKAGE_IFUPDOWN_SCRIPTS is not set
BR2_PACKAGE_LLDPD=y
BR2_PACKAGE_OPENRESOLV=y
BR2_PACKAGE_OPENSSH=y
BR2_PACKAGE_SSDP_RESPONDER=y
BR2_PACKAGE_TCPDUMP=y
BR2_PACKAGE_KMOD_TOOLS=y
BR2_PACKAGE_SYSKLOGD=y
BR2_PACKAGE_SYSKLOGD_LOGGER=y
BR2_TARGET_ROOTFS_SQUASHFS=y
# BR2_TARGET_ROOTFS_TAR is not set
BR2_PACKAGE_CONFD=y
BR2_PACKAGE_STATD=y
BR2_PACKAGE_FACTORY=y
BR2_PACKAGE_FINIT_SULOGIN=y
BR2_PACKAGE_FINIT_PLUGIN_HOTPLUG=y
BR2_PACKAGE_FINIT_PLUGIN_HOOK_SCRIPTS=y
BR2_PACKAGE_FINIT_PLUGIN_MODULES_LOAD=y
BR2_PACKAGE_FINIT_PLUGIN_MODPROBE=y
BR2_PACKAGE_FINIT_PLUGIN_RTC=y
BR2_PACKAGE_FINIT_PLUGIN_TTY=y
BR2_PACKAGE_FINIT_PLUGIN_URANDOM=y
BR2_PACKAGE_KLISH_PLUGIN_INFIX=y
BR2_PACKAGE_NET=y
# SIGN_ENABLED is not set
# GNS3_APPLIANCE is not set
+125 -1
View File
@@ -4,6 +4,129 @@ Change Log
All notable changes to the project are documented in this file.
[v23.10.0][] - 2023-10-31
-------------------------
> **Note:** upcoming releases will lock the `root` user for system-only
> services. Instead an `admin` user will be the only default user with
> the CLI as its login shell. This user is already available, so please
> consider updating any guidelines or documentation you may have.
### YANG Status
- [ietf-system][]:
- [infix-system][]: MotD (Message of the Day) augment
- [infix-system][]: user login shell augment, default: `/bin/false`
- [infix-system-software][]: system-state/software augment for
remotely querying firmware version information
- [infix-system-software][]: firmware upgrade with `install-bundle` RPC
- [infix-system][]: timezone-name deviation, using with IANA timezones,
deviation for UTC offset, only support per-hour offsets with [tzdata][].
Also, username deviation, clarifying Linux restrictions.
- [infix-system][]: deviations for unsupported features, e.g. RADIUS
- [ietf-interfaces][]:
- [infix-interfaces][]: deviation for `if:phys-address` to allow read-write
- [ietf-ip][]: augmented with IPv4LL similar to standardized IPv6LL
- [infix-ip][]: deviations (`not-supported`) added for IPv4 and IPv6:
- `/if:interfaces/if:interface/ip:ipv4/ip:address/ip:subnet/ip:netmask`
- `/if:interfaces/if:interface/ip:ipv6/ip:address/ip:status`
- `/if:interfaces/if:interface/ip:ipv4/ip:mtu`
- `/if:interfaces/if:interface/ip:ipv6/ip:mtu`
- `/if:interfaces/if:interface/ip:ipv4/ip:neighbor`
- `/if:interfaces/if:interface/ip:ipv6/ip:neighbor`
- ~~[ietf-if-vlan-encapsulation][]:~~ Removed in favor of a native model.
- [infix-if-bridge][]: Linux bridge interfaces with native VLAN support
- [infix-if-type][]: deviation for interface types, limiting number
to supported types only. New identities are derived from default
IANA interface types, ensuring compatibility with other standard
models, e.g., `ieee802-ethernet-interface.yang`
- [infix-if-veth][]: Linux VETH pairs
- [infix-if-vlan][]: Linux VLAN interfaces, e.g. `eth0.10` (New model!)
- Configurable services:
- [ieee802-dot1ab-lldp][]: stripped down to an `enabled` setting
- [infix-services][]: support for enabling mDNS service/device discovery
[tzdata]: https://www.iana.org/time-zones
[ieee802-dot1ab-lldp]: https://github.com/kernelkit/infix/tree/50a550b/src/confd/yang/ieee802-dot1ab-lldp%402022-03-15.yang
[ietf-system]: https://www.rfc-editor.org/rfc/rfc7317.html
[ietf-interfaces]: https://www.rfc-editor.org/rfc/rfc7223.html
[ietf-ip]: https://www.rfc-editor.org/rfc/rfc8344.html
[ietf-if-vlan-encapsulation]: https://www.ietf.org/id/draft-ietf-netmod-sub-intf-vlan-model-08.html
[infix-if-bridge]: https://github.com/kernelkit/infix/blob/fc5310b/src/confd/yang/infix-if-bridge%402023-08-21.yang
[infix-if-type]: https://github.com/kernelkit/infix/tree/fc5310b/src/confd/yang/infix-if-type%402023-08-21.yang
[infix-if-veth]: https://github.com/kernelkit/infix/tree/fc5310b/src/confd/yang/infix-if-veth%402023-06-05.yang
[infix-if-vlan]: https://github.com/kernelkit/infix/blob/fc5310b/src/confd/yang/infix-if-vlan%402023-10-25.yang
[infix-interfaces]: https://github.com/kernelkit/infix/tree/fc5310b/src/confd/yang/infix-interfaces%402023-09-19.yang
[infix-ip]: https://github.com/kernelkit/infix/tree/fc5310b/src/confd/yang/infix-ip%402023-09-14.yang
[infix-services]: https://github.com/kernelkit/infix/blob/fc5310b/src/confd/yang/infix-services%402023-10-16.yang
[infix-system]: https://github.com/kernelkit/infix/blob/fc5310b/src/confd/yang/infix-system%402023-10-19.yang
[infix-system-software]: https://github.com/kernelkit/infix/tree/fc5310b/src/confd/yang/infix-system-software%402023-06-27.yang
### Changes
- Add support for setting/querying IPv4/IPv6 MTU, see #152 for details.
- Add support for *Fail Secure Mode*: if loading `startup-config` fails,
e.g. YANG model validation failure after upgrade, the system now falls back
to load `failure-config` instead of just crashing. This config, along with
`factory-config`, is generated on every boot to match the active image's
YANG models. In case neither config can be loaded, or even bootstrapping
YANG models fail, the system will go into an RMA state -- Return to
Manufacturer, clearly signaled on the console and, on devices that support
it, angry LED signaling. See #154 for more.
- Add support for generating GNS3 appliance file for NETCONF Aarch64.
- Add support for UTC offset (+/- HH:00) in `ietf-system`, PR #174
- Add support for `ietf-factory-default` RPC, PR #175
- Add support for performing factory reset (using #175 RPC) from CLI
- Replace `ietf-if-vlan-encapsulation` YANG model with the native
`infix-if-vlan` model. This fits better with Linux VLAN interfaces and
simplifies the syntax greatly. For details, see PR #179
admin@example:/config/interfaces/interface/eth0.10/> set vlan id 10 lower-layer-if eth0
- The following new NETCONF interface operational counters have been added:
| **YANG** | **Linux / Ethtool** |
|-----------------------------|-----------------------------------|
| `out-frames` | `FramesTransmittedOK` |
| `out-multicast-frames` | `MulticastFramesXmittedOK` |
| `out-broadcast-frames` | `BroadcastFramesXmittedOK` |
| `in-total-frames` | `FramesReceivedOK` |
| | + `FrameCheckSequenceErrors` |
| | + `FramesLostDueToIntMACRcvError` |
| | + `AlignmentErrors` |
| | + `etherStatsOversizePkts` |
| | + `etherStatsJabbers` |
| `in-frames` | `FramesReceivedOK` |
| `in-multicast-frames` | `MulticastFramesReceivedOK` |
| `in-broadcast-frames` | `BroadcastFramesReceivedOK` |
| `in-error-undersize-frames` | `undersize_pkts` |
| `in-error-fcs-frames` | `FrameCheckSequenceErrors` |
- Greatly improved branding support using `make menuconfig`. All the
identifying strings, including firmware image, is in `/etc/os-release`, will
be used in CLI `show system-information`, the WebUI About dialog, and any
prominent areas when booting up (on console), logging in to CLI and WebUI.
- IGMP/MLD snooping is now disabled by default on new bridges. Support
for multicast filtering bridges expected no later than v24.01.
- The SSDP responder, device discovery in Windows, has been removed in favor
of Windows 10 (build 1709) native support for mDNS-SD. Details in #166
- A GreenPAK programmer has been added, not enabled by default. This is a
popular programmable little chip from Renesas. Worth a look!
- The `confd` script `gen-interfaces` can now generate bridges and stand-alone
interfaces with IPv6 (SLAAC) for `factory-config` et al.
- Drop `x86_64_minimal_defconfig`, previously used for regression tests only
- Documentation updates of how IPv4/IPv6 addresses are shown in NETCONF
operational data, as well as the built-in CLI, see #163 for details.
### Fixes
- Fix #106: confd: drop deviation `ietf-system:timezone-utc-offset`
- Fix #151: Operational status broken in v23.09
- Fix #159: Hacky generation of `/etc/resolv.conf` at boot
- Fix #162: VLAN interface without encapsulation is accepted by YANG model
[v23.09.0][] - 2023-10-02
-------------------------
@@ -216,7 +339,8 @@ Supported YANG models in addition to those used by sysrepo and netopeer:
- N/A
[buildroot]: https://buildroot.org/
[UNRELEASED]: https://github.com/kernelkit/infix/compare/v23.08.0...HEAD
[UNRELEASED]: https://github.com/kernelkit/infix/compare/v23.10.0...HEAD
[v23.10.0]: https://github.com/kernelkit/infix/compare/v23.09.0...v23.10.0
[v23.09.0]: https://github.com/kernelkit/infix/compare/v23.08.0...v23.09.0
[v23.08.0]: https://github.com/kernelkit/infix/compare/v23.06.0...v23.08.0
[v23.06.0]: https://github.com/kernelkit/infix/compare/BASE...v23.06.0
+1 -1
View File
@@ -1,7 +1,7 @@
* TODO doc: User Guide
- Feature set and scope, e.g.
- Device discovery: SSDP, LLDP, mDNS-SD how do they work, interfacing with Windows/macOS/Linux
- Device discovery: LLDP, mDNS-SD how do they work, interfacing with Windows/macOS/Linux
- Network redundancy protocols: STP/RSTP, MRP
- Configuring the system; using ifupdown2, enabling/disabling services
- Diagnosing the system; using rmon, port mirroring, debugging services, searching logs
+149
View File
@@ -0,0 +1,149 @@
Branding & Releases
===================
This document is for projects using Infix as a br2-external, i.e., OEMs.
Branding
--------
Branding is done in menuconfig, there are several settings affecting
it, most are in the Infix external subsection called "Branding", but
there is also `BR2_TARGET_GENERIC_HOSTNAME`, which deserves a
special mention.
The hostname is used for the system default `/etc/hostname`, which
is the base name for the "unique:ified" hostname + the last three
octets of the base MAC[^1] address, e.g., `infix-c0-ff-ee`. This in
turn is the hostname that is set at first boot and also advertised
by device discovery protocols like mDNS-SD and LLDP.
See the help texts for the *Infix Branding* settings to understand
which ones are mandatory and which are optional, menuconfig does not
check this for you and you may end up with odd results.
Verify the result after a build by inspecting:
- `output/images/*`: names, missing prefix, etc.
- `output/target/etc/os-release`: this file is sourced by
other build scripts, e.g., `mkgns3a.sh`. For reference, see
https://www.freedesktop.org/software/systemd/man/os-release.html
> **Note:** to get proper GIT revision (hash) from your composed OS,
> remember in menuconfig to set `INFIX_OEM_PATH`. When unset the
> Infix `post-build.sh` script defaults to the Infix base path. The
> revision is stored in the file `/etc/os-release` as BUILD_ID and
> is also in the file `/etc/version`. See below for more info.
[^1]: The base MAC address is defined in the device's Vital Product
Data (VPD) EEPROM, or similar, which is used by the kernel to
create the system interfaces. This MAC address is usually also
printed on a label on the device.
Integration
-----------
When integrating your software stack with Infix there may be protocols
that want to change system settings like hostname and dynamically set
IP address and default gateway, e.g. PROFINET. This section detail a
few recommendations for maintaining co-existence in this scenario of
the multiple producers problem.
First, there's a clear difference between "singleton" like hostsname
and an interface IP address. Consider the case of a static IP and a
DHCP assigned IP, these can co-exist because of the `proto NUM` field
available in iproute2. This is used in Infix so that static addresses
can be flushed independently of DHCP addresses. The same can be done
by other "address providers", e.g., PROFINET.
Changing properties like hostname should be done by injecting a change
into Infix, by for example calling `sysrepocfg -Ediff.xml`. Here is an
example of how to get the current hostname and apply an XML diff:
```
root@infix-00-00-00:~# sysrepocfg -X -x "/system/hostname" > hostnm.xml
root@infix-00-00-00:~# cat hostnm.xml
<system xmlns="urn:ietf:params:xml:ns:yang:ietf-system">
<hostname>infix-00-00-00</hostname>
</system>
root@infix-00-00-00:~# edit hostnm.xml
root@infix-00-00-00:~# sysrepocfg -Ehostnm.xml
root@example:~#
```
Second, perform all changes on `running-config`, the running datastore.
That way you have a clear state to return to if your application needs
to do a factory reset. E.g., in PROFINET a type 1/2 factory reset will
reset only the PROFINET specific settings. That way you can actually
have your system `startup-config` disable all physical ports and the
PROFINET application enables only ports that are not deactivated. (On
factory reset it will not know of any ports to deactivate so it will
activate all.)
You can consider the system composed of two entities:
- NETCONF starts up the system using `startup-config`, then
- Hands over control to your application at runtime
Infix is prepared for this by already having two "runlevels" for these
two states. The `startup-config` is applied in runlevel S (bootstrap)
and the system then enters runlevel 2 for normal operation.
This allow you to keep a set of functionality that is provided by the
underlying system, and another managed by your application. You can
of course in your br2-external provide a sysrepo plugin that block
operations on certain datastores when your application is enabled.
E.g., to prevent changes to startup after initial deployment. In
that case a proper factory reset would be needed to get back to a
"pre-deployment" state where you can reconfigure your baseline.
Releases
--------
A release build requires the global variable `INFIX_RELEASE` to be set.
It can be derived from GIT, if the source tree is kept in GIT VCS. First,
let us talk about versioning in general.
### Versioning
Two popular scheme for versioning a product derived from Infix:
1. Track Infix major.minor, e.g. *Foobar v23.08.z*, where `z` is
your patch level. I.e., Foobar v23.08.0 could be based on Infix
v23.08.0, or v23.08.12, it is up to you. Maybe you based it on
v23.08.12 and then back ported changes from v23.10.0, but it was
the first release you made to your customer(s).
2. Start from v1.0.0 and step the major number every time you sync
with a new Infix release, or every time Infix bumps to the next
Buildroot LTS.
The important thing is to be consistent, not only for your own sake,
but also for your end customers. The *major.minor.patch* style is
the most common and often recommended style, which usually maps well
to other systems, e.g. PROFINET GSDML files require this (*VX.Y.Z*).
But you can of course use only two numbers, *major.minor*, as well.
> What could be confusing, however, is if you use the name *Infix*
> with your own versioning scheme.
### `INFIX_RELEASE`
This global variable **must be** a lower-case string (no spaces or
other characters outside of 09, az, '.', '_' and '-') identifying
the operating system version, excluding any OS name information or
release code name, and suitable for processing by scripts or usage
in generated filenames.
Used for `VERSION` and `VERSION_ID` in `/etc/os-release` and
generated file names like disk images, etc.
**Default:** generated using `git describe --always --dirty --tags`,
with an additional `-C $infix_path`. This variable defaults to the
Infix tree and can be changed by setting the menuconfig branding
variable `INFIX_OEM_PATH` to that of the br2-external. It is also
possible to set the `GIT_VERSION` variable in your `post-build.sh`
script to change how the VCS version is extracted.
+3 -28
View File
@@ -41,8 +41,9 @@ admin@infix-00-00-00:~$
## Discovery mechanisms available in Infix
Infix advertises its presence via the [mDNS](#mdns) and [SSDP](#ssdp) discovery
protocols in addition to [LLDP](#lldp).
Infix advertises its presence via the [mDNS](#mdns) and [LLDP](#lldp)
discovery protocols.
### LLDP
@@ -173,29 +174,3 @@ linux-pc:#
[^2]: [mdns-scan](http://0pointer.de/lennart/projects/mdns-scan/): a
tool for scanning for mDNS/DNS-SD published services on the local
network
### SSDP
For Windows clients, Infix advertises itself via the SSDP
protocol. The Infix unit will appear as a *Network Infrastructure*
equipment icon in the *Network* tab of Windows Explorer.
In Linux, the *ssdp-scan*[^3] tool can be used to find Infix units via
SSDP.
```
linux-pc:# ssdp-scan tap0
+ infix-00-00-00 http://10.0.1.1
linux-pc:#
```
> Note 1: Infix presents itself with a HTTP URL, however, currently no
> Web server is running. Still, the IP address 10.0.1.1 is discovered
> and can be used for SSH access, etc.
> Note 2: SSDP is limited to IPv4. Thus, it is only valid as discovery
> mechanism when Infix as well as the client PC has an IPv4 address
> assigned.
[^3]: [SSDP Responder for
Linux/UNIX](https://github.com/troglobit/ssdp-responder)
+31
View File
@@ -0,0 +1,31 @@
# YANG to Ethtool Mapping
This column contains the mapping between YANG and Linux / Ethtool counters.
```
┌─────────────────────────────────┬──────────────────────────────────┐
│ YANG │ Linux / Ethtool │
├─────────────────────────────────┼──────────────────────────────────┤
│ out-frames │ FramesTransmittedOK │
├─────────────────────────────────┼──────────────────────────────────┤
│ out-multicast-frames │ MulticastFramesXmittedOK │
├─────────────────────────────────┼──────────────────────────────────┤
│ out-broadcast-frames │ BroadcastFramesXmittedOK │
├─────────────────────────────────┼──────────────────────────────────┤
│ in-total-frames │ FramesReceivedOK, │
│ │ FrameCheckSequenceErrors │
│ │ FramesLostDueToIntMACRcvError │
│ │ AlignmentErrors │
│ │ etherStatsOversizePkts │
│ │ etherStatsJabbers │
├─────────────────────────────────┼──────────────────────────────────┤
│ in-frames │ FramesReceivedOK │
├─────────────────────────────────┼──────────────────────────────────┤
│ in-multicast-frames │ MulticastFramesReceivedOK │
├─────────────────────────────────┼──────────────────────────────────┤
│ in-broadcast-frames │ BroadcastFramesReceivedOK │
├─────────────────────────────────┼──────────────────────────────────┤
│ in-error-undersize-frames │ undersize_pkts │
├─────────────────────────────────┼──────────────────────────────────┤
│ in-error-fcs-frames │ FrameCheckSequenceErrors │
└─────────────────────────────────┴──────────────────────────────────┘
```
+54 -60
View File
@@ -118,14 +118,14 @@ identifier.
![Switch example (eth0 and lo)](img/ip-address-example-switch.svg)
root@infix-00-00-00:/> show interfaces
admin@example:/> show interfaces
INTERFACE PROTOCOL STATE DATA
eth0 ethernet UP 02:00:00:00:00:00
ipv6 fe80::ff:fe00:0/64 (link-layer)
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
root@infix-00-00-00:/>
admin@example:/>
To illustrate IP address configuration, the examples below uses a
switch with a single Ethernet interface (eth0) and a loopback
@@ -137,11 +137,11 @@ default.
![Setting static IPv4 (and link-local IPv4)](img/ip-address-example-ipv4-static.svg)
root@example:/> configure
root@example:/config/> edit interfaces interface eth0 ipv4
root@example:/config/interfaces/interface/eth0/ipv4/> set address 10.0.1.1 prefix-length 24
root@example:/config/interfaces/interface/eth0/ipv4/> set autoconf enabled true
root@infix-example:/config/interfaces/interface/eth0/ipv4/> diff
admin@example:/> configure
admin@example:/config/> edit interfaces interface eth0 ipv4
admin@example:/config/interfaces/interface/eth0/ipv4/> set address 10.0.1.1 prefix-length 24
admin@example:/config/interfaces/interface/eth0/ipv4/> set autoconf enabled true
admin@example:/config/interfaces/interface/eth0/ipv4/> diff
+interfaces {
+ interface eth0 {
+ ipv4 {
@@ -154,16 +154,8 @@ default.
+ }
+ }
+}
root@infix-example:/config/interfaces/interface/eth0/ipv4/> leave
root@infix-example:/> show interfaces
INTERFACE PROTOCOL STATE DATA
eth0 ethernet UP 02:00:00:00:00:00
ipv4 10.0.1.1/24 (static)
ipv6 fe80::ff:fe00:0/64 (link-layer)
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
root@infix-example:/> show interfaces
admin@example:/config/interfaces/interface/eth0/ipv4/> leave
admin@example:/> show interfaces
INTERFACE PROTOCOL STATE DATA
eth0 ethernet UP 02:00:00:00:00:00
ipv4 169.254.1.3/16 (random)
@@ -172,7 +164,7 @@ default.
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
root@infix-example:/>
admin@example:/>
As shown, the link-local IPv4 address is configured with `set autconf
enabled true`. The resulting address (169.254.1.3/16) is of type
@@ -182,12 +174,12 @@ enabled true`. The resulting address (169.254.1.3/16) is of type
![Using DHCP for IPv4 address assignment](img/ip-address-example-ipv4-dhcp.svg)
root@example:/> configure
root@example:/config/> edit dhcp-client
root@example:/config/dhcp-client/> set client-if eth0
root@example:/config/dhcp-client/> set enabled true
root@example:/config/dhcp-client/> leave
root@example:/> show interfaces
admin@example:/> configure
admin@example:/config/> edit dhcp-client
admin@example:/config/dhcp-client/> set client-if eth0
admin@example:/config/dhcp-client/> set enabled true
admin@example:/config/dhcp-client/> leave
admin@example:/> show interfaces
INTERFACE PROTOCOL STATE DATA
eth0 ethernet UP 02:00:00:00:00:00
ipv4 10.1.2.100/24 (dhcp)
@@ -195,8 +187,7 @@ enabled true`. The resulting address (169.254.1.3/16) is of type
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
root@example:/>
admin@example:/>
The resulting address (10.1.2.100/24) is of type *dhcp*.
@@ -206,28 +197,28 @@ The resulting address (10.1.2.100/24) is of type *dhcp*.
The (only) way to disable IPv6 link-local addresses is by disabling IPv6 on the interface.
```(disabling
root@example:/> configure
root@example:/config/> edit interfaces interface eth0 ipv6
root@example:/config/interfaces/interface/eth0/ipv6/> set enabled false
root@example:/config/interfaces/interface/eth0/ipv6/> leave
root@example:/> show interfaces
admin@example:/> configure
admin@example:/config/> edit interfaces interface eth0 ipv6
admin@example:/config/interfaces/interface/eth0/ipv6/> set enabled false
admin@example:/config/interfaces/interface/eth0/ipv6/> leave
admin@example:/> show interfaces
INTERFACE PROTOCOL STATE DATA
eth0 ethernet UP 02:00:00:00:00:00
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
root@example:/>
admin@example:/>
```
#### Static IPv6 address
![Setting static IPv6](img/ip-address-example-ipv6-static.svg)
root@example:/> configure
root@example:/config/> edit interfaces interface eth0 ipv6
root@example:/config/interfaces/interface/eth0/ipv6/> set address 2001:db8::1 prefix-length 64
root@example:/config/interfaces/interface/eth0/ipv6/> leave
root@example:/> show interfaces
admin@example:/> configure
admin@example:/config/> edit interfaces interface eth0 ipv6
admin@example:/config/interfaces/interface/eth0/ipv6/> set address 2001:db8::1 prefix-length 64
admin@example:/config/interfaces/interface/eth0/ipv6/> leave
admin@example:/> show interfaces
INTERFACE PROTOCOL STATE DATA
eth0 ethernet UP 02:00:00:00:00:00
ipv6 2001:db8::1/64 (static)
@@ -235,7 +226,7 @@ root@example:/>
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
root@example:/>
admin@example:/>
#### Stateless Auto-configuration of Global IPv6 Address
@@ -244,33 +235,35 @@ root@example:/>
Stateless address auto-configuration of global addresses is enabled by
default. The address is formed by concatenating the network prefix
advertised by the router (here 2001:db8:0:1::0/64) and the interface
identifier. The resulting address is of type *other*.
identifier. The resulting address is of type *link-layer*, as it
is formed based on the interface identifier ([IETF
ip-yang][ietf-ip-yang]).
root@infix-example:/> show interfaces
admin@example:/> show interfaces
INTERFACE PROTOCOL STATE DATA
eth0 ethernet UP 02:00:00:00:00:00
ipv6 2001:db8:0:1:0:ff:fe00:0/64 (other)
ipv6 2001:db8:0:1:0:ff:fe00:0/64 (link-layer)
ipv6 fe80::ff:fe00:0/64 (link-layer)
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
root@infix-example:/>
admin@example:/>
Disabling auto-configuration of global IPv6 addresses can be done as shown
below.
root@infix-00-00-00:/> configure
root@infix-00-00-00:/config/> edit interfaces interface eth0 ipv6
root@infix-00-00-00:/config/interfaces/interface/eth0/ipv6/> set autoconf create-global-addresses false
root@infix-00-00-00:/config/interfaces/interface/eth0/ipv6/> leave
root@infix-00-00-00:/> show interfaces
admin@example:/> configure
admin@example:/config/> edit interfaces interface eth0 ipv6
admin@example:/config/interfaces/interface/eth0/ipv6/> set autoconf create-global-addresses false
admin@example:/config/interfaces/interface/eth0/ipv6/> leave
admin@example:/> show interfaces
INTERFACE PROTOCOL STATE DATA
eth0 ethernet UP 02:00:00:00:00:00
ipv6 fe80::ff:fe00:0/64 (link-layer)
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
root@infix-00-00-00:/>
admin@example:/>
#### Random Link Identifiers for IPv6 Stateless Autoconfiguration
@@ -279,34 +272,35 @@ below.
By default, the auto-configured link-local and global IPv6 addresses
are formed from a link-identifier based on the MAC address.
root@infix-example:/> show interfaces
admin@example:/> show interfaces
INTERFACE PROTOCOL STATE DATA
eth0 ethernet UP 02:00:00:00:00:00
ipv6 2001:db8:0:1:0:ff:fe00:0/64 (other)
ipv6 2001:db8:0:1:0:ff:fe00:0/64 (link-layer)
ipv6 fe80::ff:fe00:0/64 (link-layer)
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
root@infix-example:/>
admin@example:/>
To avoid revealing identity information in the IPv6 address, it is
possible to specify use of a random identifier ([ietf-ip][ietf-ip-yang] YANG and [RFC8981][ietf-ipv6-privacy]).
root@infix-example:/> configure
root@infix-example:/config/> edit interfaces interface eth0 ipv6
root@infix-example:/config/interfaces/interface/eth0/ipv6/> set autoconf create-temporary-addresses true
root@infix-example:/config/interfaces/interface/eth0/ipv6/> leave
root@infix-example:/> show interfaces
admin@example:/> configure
admin@example:/config/> edit interfaces interface eth0 ipv6
admin@example:/config/interfaces/interface/eth0/ipv6/> set autoconf create-temporary-addresses true
admin@example:/config/interfaces/interface/eth0/ipv6/> leave
admin@example:/> show interfaces
INTERFACE PROTOCOL STATE DATA
eth0 ethernet UP 02:00:00:00:00:00
ipv6 2001:db8:0:1:fba2:f413:dd22:13ad/64 (other)
ipv6 fe80::b886:6849:18dc:19ef/64 (random)
ipv6 2001:db8:0:1:b705:8374:638e:74a8/64 (random)
ipv6 fe80::ad3d:b274:885a:9ffb/64 (random)
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
root@infix-example:/>
admin@example:/>
The link-local address has changed type to *random*.
Both the link-local address (fe80::) and the global address (2001:)
have changed type to *random*.
[ietf-ip-yang]: https://www.rfc-editor.org/rfc/rfc8344.html
[ietf-ipv6-privacy]: https://www.rfc-editor.org/rfc/rfc8981.html
+1
View File
@@ -16,3 +16,4 @@ source "$BR2_EXTERNAL_INFIX_PATH/package/podman/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/skeleton-init-finit/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/tetris/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/querierd/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/greenpak-programmer/Config.in"
+32
View File
@@ -0,0 +1,32 @@
#set DEBUG=1
run name:bootstrap log:prio:user.notice norestart <pid/syslogd> \
[S] /usr/libexec/confd/bootstrap \
-- Bootstrapping YANG datastore
run name:error :1 log:console norestart if:<run/bootstrap/failure> \
[S] /usr/libexec/confd/error --
service name:confd log <run/bootstrap/success> \
[S12345789] sysrepo-plugind -f -p /run/confd.pid -n -v3 -- Configuration daemon
# Bootstrap system with startup-config
run name:startup log:prio:user.notice norestart \
[S] <pid/confd> /usr/libexec/confd/load -b startup-config \
-- Loading startup-config
# Run if loading startup-config fails for some reason
run name:failure log:prio:user.critical norestart if:<run/startup/failure> \
[S] <pid/confd> /usr/libexec/confd/load failure-config \
-- Loading failure-config
run name:error :2 log:console norestart if:<run/failure/failure> \
[S] /usr/libexec/confd/error --
service name:netopeer log \
[12345789] <pid/confd> netopeer2-server -F -t 60 \
-- NETCONF server
# Create initial /etc/resolv.conf after successful bootstrap
task name:resolv :conf norestart if:<run/startup/success> \
[S] <pid/dnsmasq> resolvconf -u -- Update DNS configuration
+2 -2
View File
@@ -14,8 +14,8 @@ CONFD_DEPENDENCIES = augeas jansson libite sysrepo libsrx
CONFD_AUTORECONF = YES
define CONFD_INSTALL_EXTRA
cp $(CONFD_PKGDIR)/sysrepo.conf $(FINIT_D)/available/
ln -sf ../available/sysrepo.conf $(FINIT_D)/enabled/sysrepo.conf
cp $(CONFD_PKGDIR)/confd.conf $(FINIT_D)/available/
ln -sf ../available/confd.conf $(FINIT_D)/enabled/confd.conf
cp $(CONFD_PKGDIR)/tmpfiles.conf $(TARGET_DIR)/etc/tmpfiles.d/confd.conf
endef
CONFD_POST_INSTALL_TARGET_HOOKS += CONFD_INSTALL_EXTRA
-13
View File
@@ -1,13 +0,0 @@
run name:bootstrap log:prio:user.notice \
[S] /lib/infix/cfg-bootstrap -- Bootstrapping YANG models
service name:sysrepo log \
[S12345789] sysrepo-plugind -f -p /run/sysrepo.pid -n -- Configuration daemon
run name:startup log:prio:user.notice \
[S] <pid/sysrepo> sysrepocfg -I/cfg/startup-config.cfg -f json \
-- Loading startup-config
service name:netopeer log \
[12345789] <pid/sysrepo> netopeer2-server -F -t 60 \
-- NETCONF server
# XXX: This is a hack, talk to Joachim
task [12345789] resolvconf -u -- Update DNS configuration
+2 -1
View File
@@ -1,2 +1,3 @@
d /run/confd/factory.d - - -
d /run/confd/failure.d - - -
d /run/resolvconf/interfaces - - -
+1 -1
View File
@@ -1,5 +1,5 @@
# From https://github.com/troglobit/finit/releases/
sha256 af89d4048415a8be7d49e397bc45f838fe72f93e1087d7bc6bc0db085c7c2621 finit-4.4.tar.gz
sha256 ef73d9ba01aefef1a2171483f26339c7aefdf92dd25d7b322f15efa48e78d655 finit-4.5.tar.gz
# Locally calculated
sha256 3a2b964c1772d03ab17b73a389ecce9151e0b190a9247817a2c009b16d356422 LICENSE
+8 -1
View File
@@ -4,7 +4,7 @@
#
################################################################################
FINIT_VERSION = 4.4
FINIT_VERSION = 4.5
FINIT_SITE = https://github.com/troglobit/finit/releases/download/$(FINIT_VERSION)
FINIT_LICENSE = MIT
FINIT_LICENSE_FILES = LICENSE
@@ -30,6 +30,7 @@ FINIT_CONF_OPTS = \
--exec-prefix= \
--disable-doc \
--disable-contrib \
--disable-rescue \
--disable-silent-rules \
--with-group=$(BR2_PACKAGE_FINIT_INITCTL_GROUP)
@@ -118,6 +119,12 @@ else
FINIT_CONF_OPTS += --disable-alsa-utils-plugin
endif
ifeq ($(BR2_PACKAGE_BASH_COMPLETION),y)
FINIT_CONF_OPTS += --with-bash-completiond-dir
else
FINIT_CONF_OPTS += --without-bash-completiond-dir
endif
ifeq ($(BR2_PACKAGE_DBUS),y)
FINIT_CONF_OPTS += --enable-dbus-plugin
else
+7
View File
@@ -0,0 +1,7 @@
config BR2_PACKAGE_GREENPAK_PROGRAMMER
bool "greenpak-programmer"
select BR2_PACKAGE_I2C_TOOLS
help
Tool for programming GreenPAK chips in-circuit using I2C
https://github.com/addiva-elektronik/greenpak-programmer/
@@ -0,0 +1,5 @@
# From https://github.com/addiva-elektronik/greenpak-programmer/releases/download/v1.1/greenpak-programmer-1.1.tar.gz.sha256
sha256 960521714312e3b519a238b6c527826c3aacf6af93252f9ceb2fa2a22e341449 greenpak-programmer-1.1.tar.gz
# Locally generated
sha256 c1673b6eecedfe5f461ee719291ff81b57d31f64f36cad3d00fb97b14dffc025 LICENSE.txt
@@ -0,0 +1,22 @@
################################################################################
#
# greenpak-programmer
#
################################################################################
GREENPAK_PROGRAMMER_VERSION = 1.1
GREENPAK_PROGRAMMER_SITE = https://github.com/addiva-elektronik/greenpak-programmer/releases/download/v$(GREENPAK_PROGRAMMER_VERSION)
GREENPAK_PROGRAMMER_LICENSE = MIT
GREENPAK_PROGRAMMER_LICENSE_FILES = LICENSE.txt
GREENPAK_PROGRAMMER_INSTALL_STAGING = YES
GREENPAK_PROGRAMMER_DEPENDENCIES = i2c-tools
define GREENPAK_PROGRAMMER_BUILD_CMDS
$(TARGET_CONFIGURE_OPTS) $(MAKE) -C $(@D) all
endef
define GREENPAK_PROGRAMMER_INSTALL_TARGET_CMDS
$(INSTALL) -D -m 0755 $(@D)/greenpak-programmer $(TARGET_DIR)/usr/bin/greenpak-programmer
endef
$(eval $(generic-package))
@@ -1 +1 @@
service [S12345789] dnsmasq -k -u root -- DHCP/DNS proxy
service [S12345789] <pid/syslogd> dnsmasq -k -u root -- DHCP/DNS proxy
@@ -1,2 +1,4 @@
task [S] /usr/bin/ssh-genhostkeys --
service [2345789] <usr/ssh-hostkeys> env:-/etc/default/sshd /usr/sbin/sshd -D $SSHD_OPTS -- OpenSSH daemon
task <pid/syslogd> \
[S] /usr/bin/ssh-hostkeys -- Verifying SSH host keys
service <task/ssh-hostkeys/success> env:-/etc/default/sshd \
[2345789] /usr/sbin/sshd -D $SSHD_OPTS -- OpenSSH daemon
@@ -1 +1,2 @@
service name:sysklogd [S0123456789] env:-/etc/default/sysklogd syslogd -F $SYSLOGD_ARGS -- System log daemon
service name:syslogd env:-/etc/default/sysklogd <run/udevadm:5/success> \
[S0123456789] syslogd -F $SYSLOGD_ARGS -- System log daemon
@@ -1,15 +0,0 @@
#!/bin/sh
if sshd -t; then
initctl cond set ssh-hostkeys
exit 0
fi
if sshd -t 2>&1 |grep hostkeys; then
ssh-keygen -A
initctl cond set ssh-hostkeys
else
logger -t sshd "invadlid sshd_config, check with: sshd -t"
fi
exit 0
+49
View File
@@ -0,0 +1,49 @@
#!/bin/sh
tmp=$(mktemp)
dir=$(dirname "$(grep -r '^HostKey' /etc/ssh/* |tail -1 | awk '{print $2}')")
log()
{
prio=notice
if [ "$1" = "-p" ]; then
prio=$2
shift 2
fi
logger -sik -p "security.$prio" -t sshd "$@"
}
check()
{
if sshd -t >"$tmp" 2>&1; then
log "SSH hostkeys OK, setting ssh-hostkeys condition"
return 0
fi
return 1
}
rc=0
if ! check; then
files=$(awk '/invalid format/{print $6}' "$tmp" | sed 's/.*"\(.*\)".*/\1/')
for file in $files; do
log -p warn "Removing $file: invalid format!"
invalid=yes
rm "$file"
done
if [ -n "$invalid" ]; then
log "Invalid hostkeys detected, regenerating all SSH hostkeys ..."
else
log "Generating SSH hostkeys ..."
fi
if ssh-keygen -A; then
mv /etc/ssh/ssh_host_* "$dir/"
fi
if ! check; then
log -p err "Failed generating SSH hostkeys!"
rc=1
fi
fi
rm "$tmp"
exit $rc
+1 -1
View File
@@ -1 +1 @@
service name:statd log [S12345789] <pid/sysrepo> statd -f -p /run/statd.pid -n -- Status daemon
service name:statd log [S12345789] <pid/confd> statd -f -p /run/statd.pid -n -- Status daemon
@@ -0,0 +1,40 @@
From 4f0e44e9b494485dc63de3264aa99dad5def5f55 Mon Sep 17 00:00:00 2001
From: Henrik Nordstrom <henrik.nordstrom@addiva.se>
Date: Wed, 13 Sep 2023 22:45:00 +0200
Subject: [PATCH 1/2] cn9130: Default DDR4 4GByte 16-bit/die ECC
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
plat/marvell/octeontx/otx2/t91/t9130/board/dram_port.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/plat/marvell/octeontx/otx2/t91/t9130/board/dram_port.c b/plat/marvell/octeontx/otx2/t91/t9130/board/dram_port.c
index 82ce07b09..07753ea97 100644
--- a/plat/marvell/octeontx/otx2/t91/t9130/board/dram_port.c
+++ b/plat/marvell/octeontx/otx2/t91/t9130/board/dram_port.c
@@ -45,18 +45,18 @@ struct mv_ddr_iface dram_iface_ap0 = {
{0x1, 0x0, 0, 0},
{0x1, 0x0, 0, 0},
{0x1, 0x0, 0, 0} },
- SPEED_BIN_DDR_2400T, /* speed_bin */
- MV_DDR_DEV_WIDTH_8BIT, /* sdram device width */
+ SPEED_BIN_DDR_2400R, /* speed_bin */
+ MV_DDR_DEV_WIDTH_16BIT, /* sdram device width */
MV_DDR_DIE_CAP_8GBIT, /* die capacity */
MV_DDR_FREQ_SAR, /* frequency */
0, 0, /* cas_l, cas_wl */
- MV_DDR_TEMP_LOW} }, /* temperature */
+ MV_DDR_TEMP_HIGH} }, /* temperature */
#if DDR32
MV_DDR_32BIT_ECC_PUP8_BUS_MASK, /* subphys mask */
#else
MV_DDR_64BIT_ECC_PUP8_BUS_MASK, /* subphys mask */
#endif
- MV_DDR_CFG_SPD, /* ddr configuration data src */
+ MV_DDR_CFG_DEFAULT, /* ddr configuration data src */
NOT_COMBINED, /* ddr twin-die combined*/
{ {0} }, /* raw spd data */
{0}, /* timing parameters */
--
2.34.1
@@ -0,0 +1,29 @@
From da31240645cdf7ae424727ac330fdb6f6b118691 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Mon, 16 Oct 2023 10:52:19 +0200
Subject: [PATCH 2/2] marvell: Allow mv-ddr-marvell to be built from tarball
Build system relies on the mv-ddr-marvell being a valid GIT working
directory, which is not the case when building from a tarball.
Therefore, reduce this requirement from a hard error to a warning.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
plat/marvell/armada/a8k/common/ble/ble.mk | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/plat/marvell/armada/a8k/common/ble/ble.mk b/plat/marvell/armada/a8k/common/ble/ble.mk
index 752ab419d..db817e996 100644
--- a/plat/marvell/armada/a8k/common/ble/ble.mk
+++ b/plat/marvell/armada/a8k/common/ble/ble.mk
@@ -31,5 +31,5 @@ $(MV_DDR_LIB): FORCE
# Do not remove! Following checks are required to ensure correct TF-A builds, removing these checks leads to broken TF-A builds
$(if $(value MV_DDR_PATH),,$(error "Platform '$(PLAT)' for BLE requires MV_DDR_PATH. Please set MV_DDR_PATH to point to the right directory"))
$(if $(wildcard $(value MV_DDR_PATH)/*),,$(error "'MV_DDR_PATH=$(value MV_DDR_PATH)' was specified, but '$(value MV_DDR_PATH)' directory does not exist"))
- $(if $(shell git -C $(value MV_DDR_PATH) rev-parse --show-cdup 2>&1),$(error "'MV_DDR_PATH=$(value MV_DDR_PATH)' was specified, but '$(value MV_DDR_PATH)' does not contain valid mv-ddr-marvell git repository"))
+ $(if $(shell git -C $(value MV_DDR_PATH) rev-parse --show-cdup 2>&1),$(warning "'MV_DDR_PATH=$(value MV_DDR_PATH)' was specified, but '$(value MV_DDR_PATH)' does not contain valid mv-ddr-marvell git repository"))
@+make -C $(MV_DDR_PATH) --no-print-directory PLAT_INCLUDES="$(MV_DDR_INCLUDES)" PLATFORM=$(PLAT) ARCH=AARCH64 OBJ_DIR=$(BUILD_PLAT)/ble
--
2.34.1
@@ -0,0 +1,40 @@
From 99e3fc4a7c6d31f5d0fdc7bb5c409c776c19012c Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 5 Oct 2023 16:09:25 +0200
Subject: [PATCH 1/9] eth: fwnode: Fall back to NVMEM provided MAC address from
OF
In the cases where the fwnode is an OF node, make use of any NVMEM
source of the interface's MAC address that might have been specified
in the device tree.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
net/ethernet/eth.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index 2edc8b796a4e..04900a41fab3 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -609,11 +609,17 @@ static int fwnode_get_mac_addr(struct fwnode_handle *fwnode,
*/
int fwnode_get_mac_address(struct fwnode_handle *fwnode, char *addr)
{
+ struct device_node *np;
+
if (!fwnode_get_mac_addr(fwnode, "mac-address", addr) ||
!fwnode_get_mac_addr(fwnode, "local-mac-address", addr) ||
!fwnode_get_mac_addr(fwnode, "address", addr))
return 0;
+ np = to_of_node(fwnode);
+ if (np)
+ return of_get_mac_address_nvmem(np, addr);
+
return -ENOENT;
}
EXPORT_SYMBOL(fwnode_get_mac_address);
--
2.34.1
@@ -0,0 +1,472 @@
From 5ddc784a4c8803aff2c3fa3c6595e9d32933d4aa Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 5 Sep 2023 13:08:29 +0200
Subject: [PATCH 2/9] net: dsa: mv88e6xxx: Create API to read a single stat
counter
This change contains no functional change. We simply push the hardware
specific stats logic to a function reading a single counter, rather
than the whole set.
This is a preparatory change for the upcoming standard ethtool
statistics support (i.e. "eth-mac", "eth-ctrl" etc.).
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 160 ++++++++++++++++++-------------
drivers/net/dsa/mv88e6xxx/chip.h | 27 +++---
2 files changed, 105 insertions(+), 82 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 7af2f08a62f1..1e944cf08233 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -1082,7 +1082,7 @@ static struct mv88e6xxx_hw_stat mv88e6xxx_hw_stats[] = {
};
static uint64_t _mv88e6xxx_get_ethtool_stat(struct mv88e6xxx_chip *chip,
- struct mv88e6xxx_hw_stat *s,
+ const struct mv88e6xxx_hw_stat *s,
int port, u16 bank1_select,
u16 histogram)
{
@@ -1265,59 +1265,82 @@ static int mv88e6xxx_get_sset_count(struct dsa_switch *ds, int port, int sset)
return count;
}
-static int mv88e6xxx_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
- uint64_t *data, int types,
- u16 bank1_select, u16 histogram)
+static int mv88e6095_stats_get_stat(struct mv88e6xxx_chip *chip, int port,
+ const struct mv88e6xxx_hw_stat *stat,
+ uint64_t *data)
{
- struct mv88e6xxx_hw_stat *stat;
- int i, j;
+ if (!(stat->type & (STATS_TYPE_BANK0 | STATS_TYPE_PORT)))
+ return 0;
- for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
- stat = &mv88e6xxx_hw_stats[i];
- if (stat->type & types) {
- mv88e6xxx_reg_lock(chip);
- data[j] = _mv88e6xxx_get_ethtool_stat(chip, stat, port,
- bank1_select,
- histogram);
- mv88e6xxx_reg_unlock(chip);
+ *data = _mv88e6xxx_get_ethtool_stat(chip, stat, port, 0,
+ MV88E6XXX_G1_STATS_OP_HIST_RX_TX);
+ return 1;
+}
- j++;
- }
- }
- return j;
+static int mv88e6250_stats_get_stat(struct mv88e6xxx_chip *chip, int port,
+ const struct mv88e6xxx_hw_stat *stat,
+ uint64_t *data)
+{
+ if (!(stat->type & STATS_TYPE_BANK0))
+ return 0;
+
+ *data = _mv88e6xxx_get_ethtool_stat(chip, stat, port, 0,
+ MV88E6XXX_G1_STATS_OP_HIST_RX_TX);
+ return 1;
}
-static int mv88e6095_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
- uint64_t *data)
+static int mv88e6320_stats_get_stat(struct mv88e6xxx_chip *chip, int port,
+ const struct mv88e6xxx_hw_stat *stat,
+ uint64_t *data)
{
- return mv88e6xxx_stats_get_stats(chip, port, data,
- STATS_TYPE_BANK0 | STATS_TYPE_PORT,
- 0, MV88E6XXX_G1_STATS_OP_HIST_RX_TX);
+ if (!(stat->type & (STATS_TYPE_BANK0 | STATS_TYPE_BANK1)))
+ return 0;
+
+ *data = _mv88e6xxx_get_ethtool_stat(chip, stat, port,
+ MV88E6XXX_G1_STATS_OP_BANK_1_BIT_9,
+ MV88E6XXX_G1_STATS_OP_HIST_RX_TX);
+ return 1;
}
-static int mv88e6250_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
- uint64_t *data)
+static int mv88e6390_stats_get_stat(struct mv88e6xxx_chip *chip, int port,
+ const struct mv88e6xxx_hw_stat *stat,
+ uint64_t *data)
{
- return mv88e6xxx_stats_get_stats(chip, port, data, STATS_TYPE_BANK0,
- 0, MV88E6XXX_G1_STATS_OP_HIST_RX_TX);
+ if (!(stat->type & (STATS_TYPE_BANK0 | STATS_TYPE_BANK1)))
+ return 0;
+
+ *data = _mv88e6xxx_get_ethtool_stat(chip, stat, port,
+ MV88E6XXX_G1_STATS_OP_BANK_1_BIT_10,
+ 0);
+ return 1;
}
-static int mv88e6320_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
- uint64_t *data)
+static int mv88e6xxx_stats_get_stat(struct mv88e6xxx_chip *chip, int port,
+ const struct mv88e6xxx_hw_stat *stat,
+ uint64_t *data)
{
- return mv88e6xxx_stats_get_stats(chip, port, data,
- STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
- MV88E6XXX_G1_STATS_OP_BANK_1_BIT_9,
- MV88E6XXX_G1_STATS_OP_HIST_RX_TX);
+ int ret = 0;
+
+ if (chip->info->ops->stats_get_stat) {
+ mv88e6xxx_reg_lock(chip);
+ ret = chip->info->ops->stats_get_stat(chip, port, stat, data);
+ mv88e6xxx_reg_unlock(chip);
+ }
+
+ return ret;
}
-static int mv88e6390_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
+static int mv88e6xxx_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
uint64_t *data)
{
- return mv88e6xxx_stats_get_stats(chip, port, data,
- STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
- MV88E6XXX_G1_STATS_OP_BANK_1_BIT_10,
- 0);
+ struct mv88e6xxx_hw_stat *stat;
+ int i, j;
+
+ for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
+ stat = &mv88e6xxx_hw_stats[i];
+ j += mv88e6xxx_stats_get_stat(chip, port, stat, &data[j]);
+ }
+ return j;
}
static void mv88e6xxx_atu_vtu_get_stats(struct mv88e6xxx_chip *chip, int port,
@@ -1333,10 +1356,9 @@ static void mv88e6xxx_atu_vtu_get_stats(struct mv88e6xxx_chip *chip, int port,
static void mv88e6xxx_get_stats(struct mv88e6xxx_chip *chip, int port,
uint64_t *data)
{
- int count = 0;
+ int count;
- if (chip->info->ops->stats_get_stats)
- count = chip->info->ops->stats_get_stats(chip, port, data);
+ count = mv88e6xxx_stats_get_stats(chip, port, data);
mv88e6xxx_reg_lock(chip);
if (chip->info->ops->serdes_get_stats) {
@@ -4196,7 +4218,7 @@ static const struct mv88e6xxx_ops mv88e6085_ops = {
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
- .stats_get_stats = mv88e6095_stats_get_stats,
+ .stats_get_stat = mv88e6095_stats_get_stat,
.set_cpu_port = mv88e6095_g1_set_cpu_port,
.set_egress_port = mv88e6095_g1_set_egress_port,
.watchdog_ops = &mv88e6097_watchdog_ops,
@@ -4234,7 +4256,7 @@ static const struct mv88e6xxx_ops mv88e6095_ops = {
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
- .stats_get_stats = mv88e6095_stats_get_stats,
+ .stats_get_stat = mv88e6095_stats_get_stat,
.mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu,
.serdes_power = mv88e6185_serdes_power,
.serdes_get_lane = mv88e6185_serdes_get_lane,
@@ -4277,7 +4299,7 @@ static const struct mv88e6xxx_ops mv88e6097_ops = {
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
- .stats_get_stats = mv88e6095_stats_get_stats,
+ .stats_get_stat = mv88e6095_stats_get_stat,
.set_cpu_port = mv88e6095_g1_set_cpu_port,
.set_egress_port = mv88e6095_g1_set_egress_port,
.watchdog_ops = &mv88e6097_watchdog_ops,
@@ -4323,7 +4345,7 @@ static const struct mv88e6xxx_ops mv88e6123_ops = {
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
- .stats_get_stats = mv88e6095_stats_get_stats,
+ .stats_get_stat = mv88e6095_stats_get_stat,
.set_cpu_port = mv88e6095_g1_set_cpu_port,
.set_egress_port = mv88e6095_g1_set_egress_port,
.watchdog_ops = &mv88e6097_watchdog_ops,
@@ -4366,7 +4388,7 @@ static const struct mv88e6xxx_ops mv88e6131_ops = {
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
- .stats_get_stats = mv88e6095_stats_get_stats,
+ .stats_get_stat = mv88e6095_stats_get_stat,
.set_cpu_port = mv88e6095_g1_set_cpu_port,
.set_egress_port = mv88e6095_g1_set_egress_port,
.watchdog_ops = &mv88e6097_watchdog_ops,
@@ -4415,7 +4437,7 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
- .stats_get_stats = mv88e6390_stats_get_stats,
+ .stats_get_stat = mv88e6390_stats_get_stat,
.set_cpu_port = mv88e6390_g1_set_cpu_port,
.set_egress_port = mv88e6390_g1_set_egress_port,
.watchdog_ops = &mv88e6390_watchdog_ops,
@@ -4477,7 +4499,7 @@ static const struct mv88e6xxx_ops mv88e6161_ops = {
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
- .stats_get_stats = mv88e6095_stats_get_stats,
+ .stats_get_stat = mv88e6095_stats_get_stat,
.set_cpu_port = mv88e6095_g1_set_cpu_port,
.set_egress_port = mv88e6095_g1_set_egress_port,
.watchdog_ops = &mv88e6097_watchdog_ops,
@@ -4515,7 +4537,7 @@ static const struct mv88e6xxx_ops mv88e6165_ops = {
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
- .stats_get_stats = mv88e6095_stats_get_stats,
+ .stats_get_stat = mv88e6095_stats_get_stat,
.set_cpu_port = mv88e6095_g1_set_cpu_port,
.set_egress_port = mv88e6095_g1_set_egress_port,
.watchdog_ops = &mv88e6097_watchdog_ops,
@@ -4563,7 +4585,7 @@ static const struct mv88e6xxx_ops mv88e6171_ops = {
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
- .stats_get_stats = mv88e6095_stats_get_stats,
+ .stats_get_stat = mv88e6095_stats_get_stat,
.set_cpu_port = mv88e6095_g1_set_cpu_port,
.set_egress_port = mv88e6095_g1_set_egress_port,
.watchdog_ops = &mv88e6097_watchdog_ops,
@@ -4612,7 +4634,7 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
- .stats_get_stats = mv88e6095_stats_get_stats,
+ .stats_get_stat = mv88e6095_stats_get_stat,
.set_cpu_port = mv88e6095_g1_set_cpu_port,
.set_egress_port = mv88e6095_g1_set_egress_port,
.watchdog_ops = &mv88e6097_watchdog_ops,
@@ -4668,7 +4690,7 @@ static const struct mv88e6xxx_ops mv88e6175_ops = {
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
- .stats_get_stats = mv88e6095_stats_get_stats,
+ .stats_get_stat = mv88e6095_stats_get_stat,
.set_cpu_port = mv88e6095_g1_set_cpu_port,
.set_egress_port = mv88e6095_g1_set_egress_port,
.watchdog_ops = &mv88e6097_watchdog_ops,
@@ -4717,7 +4739,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
- .stats_get_stats = mv88e6095_stats_get_stats,
+ .stats_get_stat = mv88e6095_stats_get_stat,
.set_cpu_port = mv88e6095_g1_set_cpu_port,
.set_egress_port = mv88e6095_g1_set_egress_port,
.watchdog_ops = &mv88e6097_watchdog_ops,
@@ -4769,7 +4791,7 @@ static const struct mv88e6xxx_ops mv88e6185_ops = {
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
- .stats_get_stats = mv88e6095_stats_get_stats,
+ .stats_get_stat = mv88e6095_stats_get_stat,
.set_cpu_port = mv88e6095_g1_set_cpu_port,
.set_egress_port = mv88e6095_g1_set_egress_port,
.watchdog_ops = &mv88e6097_watchdog_ops,
@@ -4820,7 +4842,7 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
- .stats_get_stats = mv88e6390_stats_get_stats,
+ .stats_get_stat = mv88e6390_stats_get_stat,
.set_cpu_port = mv88e6390_g1_set_cpu_port,
.set_egress_port = mv88e6390_g1_set_egress_port,
.watchdog_ops = &mv88e6390_watchdog_ops,
@@ -4885,7 +4907,7 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
- .stats_get_stats = mv88e6390_stats_get_stats,
+ .stats_get_stat = mv88e6390_stats_get_stat,
.set_cpu_port = mv88e6390_g1_set_cpu_port,
.set_egress_port = mv88e6390_g1_set_egress_port,
.watchdog_ops = &mv88e6390_watchdog_ops,
@@ -4948,7 +4970,7 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
- .stats_get_stats = mv88e6390_stats_get_stats,
+ .stats_get_stat = mv88e6390_stats_get_stat,
.set_cpu_port = mv88e6390_g1_set_cpu_port,
.set_egress_port = mv88e6390_g1_set_egress_port,
.watchdog_ops = &mv88e6390_watchdog_ops,
@@ -5014,7 +5036,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
- .stats_get_stats = mv88e6095_stats_get_stats,
+ .stats_get_stat = mv88e6095_stats_get_stat,
.set_cpu_port = mv88e6095_g1_set_cpu_port,
.set_egress_port = mv88e6095_g1_set_egress_port,
.watchdog_ops = &mv88e6097_watchdog_ops,
@@ -5074,7 +5096,7 @@ static const struct mv88e6xxx_ops mv88e6250_ops = {
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6250_stats_get_sset_count,
.stats_get_strings = mv88e6250_stats_get_strings,
- .stats_get_stats = mv88e6250_stats_get_stats,
+ .stats_get_stat = mv88e6250_stats_get_stat,
.set_cpu_port = mv88e6095_g1_set_cpu_port,
.set_egress_port = mv88e6095_g1_set_egress_port,
.watchdog_ops = &mv88e6250_watchdog_ops,
@@ -5121,7 +5143,7 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
- .stats_get_stats = mv88e6390_stats_get_stats,
+ .stats_get_stat = mv88e6390_stats_get_stat,
.set_cpu_port = mv88e6390_g1_set_cpu_port,
.set_egress_port = mv88e6390_g1_set_egress_port,
.watchdog_ops = &mv88e6390_watchdog_ops,
@@ -5187,7 +5209,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
- .stats_get_stats = mv88e6320_stats_get_stats,
+ .stats_get_stat = mv88e6320_stats_get_stat,
.set_cpu_port = mv88e6095_g1_set_cpu_port,
.set_egress_port = mv88e6095_g1_set_egress_port,
.watchdog_ops = &mv88e6390_watchdog_ops,
@@ -5234,7 +5256,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
- .stats_get_stats = mv88e6320_stats_get_stats,
+ .stats_get_stat = mv88e6320_stats_get_stat,
.set_cpu_port = mv88e6095_g1_set_cpu_port,
.set_egress_port = mv88e6095_g1_set_egress_port,
.watchdog_ops = &mv88e6390_watchdog_ops,
@@ -5283,7 +5305,7 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
- .stats_get_stats = mv88e6390_stats_get_stats,
+ .stats_get_stat = mv88e6390_stats_get_stat,
.set_cpu_port = mv88e6390_g1_set_cpu_port,
.set_egress_port = mv88e6390_g1_set_egress_port,
.watchdog_ops = &mv88e6390_watchdog_ops,
@@ -5348,7 +5370,7 @@ static const struct mv88e6xxx_ops mv88e6350_ops = {
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
- .stats_get_stats = mv88e6095_stats_get_stats,
+ .stats_get_stat = mv88e6095_stats_get_stat,
.set_cpu_port = mv88e6095_g1_set_cpu_port,
.set_egress_port = mv88e6095_g1_set_egress_port,
.watchdog_ops = &mv88e6097_watchdog_ops,
@@ -5394,7 +5416,7 @@ static const struct mv88e6xxx_ops mv88e6351_ops = {
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
- .stats_get_stats = mv88e6095_stats_get_stats,
+ .stats_get_stat = mv88e6095_stats_get_stat,
.set_cpu_port = mv88e6095_g1_set_cpu_port,
.set_egress_port = mv88e6095_g1_set_egress_port,
.watchdog_ops = &mv88e6097_watchdog_ops,
@@ -5445,7 +5467,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
- .stats_get_stats = mv88e6095_stats_get_stats,
+ .stats_get_stat = mv88e6095_stats_get_stat,
.set_cpu_port = mv88e6095_g1_set_cpu_port,
.set_egress_port = mv88e6095_g1_set_egress_port,
.watchdog_ops = &mv88e6097_watchdog_ops,
@@ -5514,7 +5536,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
- .stats_get_stats = mv88e6390_stats_get_stats,
+ .stats_get_stat = mv88e6390_stats_get_stat,
.set_cpu_port = mv88e6390_g1_set_cpu_port,
.set_egress_port = mv88e6390_g1_set_egress_port,
.watchdog_ops = &mv88e6390_watchdog_ops,
@@ -5583,7 +5605,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
- .stats_get_stats = mv88e6390_stats_get_stats,
+ .stats_get_stat = mv88e6390_stats_get_stat,
.set_cpu_port = mv88e6390_g1_set_cpu_port,
.set_egress_port = mv88e6390_g1_set_egress_port,
.watchdog_ops = &mv88e6390_watchdog_ops,
@@ -5652,7 +5674,7 @@ static const struct mv88e6xxx_ops mv88e6393x_ops = {
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
- .stats_get_stats = mv88e6390_stats_get_stats,
+ .stats_get_stat = mv88e6390_stats_get_stat,
/* .set_cpu_port is missing because this family does not support a global
* CPU port, only per port CPU port which is set via
* .port_set_upstream_port method.
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index 0ad34b2d8913..268c97cde8d8 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -318,6 +318,17 @@ struct mv88e6xxx_mst {
struct mv88e6xxx_stu_entry stu;
};
+#define STATS_TYPE_PORT BIT(0)
+#define STATS_TYPE_BANK0 BIT(1)
+#define STATS_TYPE_BANK1 BIT(2)
+
+struct mv88e6xxx_hw_stat {
+ char string[ETH_GSTRING_LEN];
+ size_t size;
+ int reg;
+ int type;
+};
+
struct mv88e6xxx_chip {
const struct mv88e6xxx_info *info;
@@ -574,8 +585,9 @@ struct mv88e6xxx_ops {
/* Return the number of strings describing statistics */
int (*stats_get_sset_count)(struct mv88e6xxx_chip *chip);
int (*stats_get_strings)(struct mv88e6xxx_chip *chip, uint8_t *data);
- int (*stats_get_stats)(struct mv88e6xxx_chip *chip, int port,
- uint64_t *data);
+ int (*stats_get_stat)(struct mv88e6xxx_chip *chip, int port,
+ const struct mv88e6xxx_hw_stat *stat,
+ uint64_t *data);
int (*set_cpu_port)(struct mv88e6xxx_chip *chip, int port);
int (*set_egress_port)(struct mv88e6xxx_chip *chip,
enum mv88e6xxx_egress_direction direction,
@@ -736,17 +748,6 @@ struct mv88e6xxx_ptp_ops {
u32 cc_mult_dem;
};
-#define STATS_TYPE_PORT BIT(0)
-#define STATS_TYPE_BANK0 BIT(1)
-#define STATS_TYPE_BANK1 BIT(2)
-
-struct mv88e6xxx_hw_stat {
- char string[ETH_GSTRING_LEN];
- size_t size;
- int reg;
- int type;
-};
-
static inline bool mv88e6xxx_has_stu(struct mv88e6xxx_chip *chip)
{
return chip->info->max_sid > 0 &&
--
2.34.1
@@ -0,0 +1,196 @@
From 63c14938bdaa1891386989aa46bee4571c1c0777 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 5 Sep 2023 21:10:15 +0200
Subject: [PATCH 3/9] net: dsa: mv88e6xxx: Give each hw stat an ID
With the upcoming standard counter group support, we are no longer
reading out the whole set of counters, but rather mapping a subset to
the requested group.
Therefore, create an enum with an ID for each stat, such that
mv88e6xxx_hw_stats[] can be subscripted with a human-readable ID
corresponding to the counters name.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 141 +++++++++++++++++--------------
1 file changed, 78 insertions(+), 63 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 1e944cf08233..ea4fb0d3e628 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -1019,68 +1019,83 @@ static int mv88e6xxx_stats_snapshot(struct mv88e6xxx_chip *chip, int port)
return chip->info->ops->stats_snapshot(chip, port);
}
-static struct mv88e6xxx_hw_stat mv88e6xxx_hw_stats[] = {
- { "in_good_octets", 8, 0x00, STATS_TYPE_BANK0, },
- { "in_bad_octets", 4, 0x02, STATS_TYPE_BANK0, },
- { "in_unicast", 4, 0x04, STATS_TYPE_BANK0, },
- { "in_broadcasts", 4, 0x06, STATS_TYPE_BANK0, },
- { "in_multicasts", 4, 0x07, STATS_TYPE_BANK0, },
- { "in_pause", 4, 0x16, STATS_TYPE_BANK0, },
- { "in_undersize", 4, 0x18, STATS_TYPE_BANK0, },
- { "in_fragments", 4, 0x19, STATS_TYPE_BANK0, },
- { "in_oversize", 4, 0x1a, STATS_TYPE_BANK0, },
- { "in_jabber", 4, 0x1b, STATS_TYPE_BANK0, },
- { "in_rx_error", 4, 0x1c, STATS_TYPE_BANK0, },
- { "in_fcs_error", 4, 0x1d, STATS_TYPE_BANK0, },
- { "out_octets", 8, 0x0e, STATS_TYPE_BANK0, },
- { "out_unicast", 4, 0x10, STATS_TYPE_BANK0, },
- { "out_broadcasts", 4, 0x13, STATS_TYPE_BANK0, },
- { "out_multicasts", 4, 0x12, STATS_TYPE_BANK0, },
- { "out_pause", 4, 0x15, STATS_TYPE_BANK0, },
- { "excessive", 4, 0x11, STATS_TYPE_BANK0, },
- { "collisions", 4, 0x1e, STATS_TYPE_BANK0, },
- { "deferred", 4, 0x05, STATS_TYPE_BANK0, },
- { "single", 4, 0x14, STATS_TYPE_BANK0, },
- { "multiple", 4, 0x17, STATS_TYPE_BANK0, },
- { "out_fcs_error", 4, 0x03, STATS_TYPE_BANK0, },
- { "late", 4, 0x1f, STATS_TYPE_BANK0, },
- { "hist_64bytes", 4, 0x08, STATS_TYPE_BANK0, },
- { "hist_65_127bytes", 4, 0x09, STATS_TYPE_BANK0, },
- { "hist_128_255bytes", 4, 0x0a, STATS_TYPE_BANK0, },
- { "hist_256_511bytes", 4, 0x0b, STATS_TYPE_BANK0, },
- { "hist_512_1023bytes", 4, 0x0c, STATS_TYPE_BANK0, },
- { "hist_1024_max_bytes", 4, 0x0d, STATS_TYPE_BANK0, },
- { "sw_in_discards", 4, 0x10, STATS_TYPE_PORT, },
- { "sw_in_filtered", 2, 0x12, STATS_TYPE_PORT, },
- { "sw_out_filtered", 2, 0x13, STATS_TYPE_PORT, },
- { "in_discards", 4, 0x00, STATS_TYPE_BANK1, },
- { "in_filtered", 4, 0x01, STATS_TYPE_BANK1, },
- { "in_accepted", 4, 0x02, STATS_TYPE_BANK1, },
- { "in_bad_accepted", 4, 0x03, STATS_TYPE_BANK1, },
- { "in_good_avb_class_a", 4, 0x04, STATS_TYPE_BANK1, },
- { "in_good_avb_class_b", 4, 0x05, STATS_TYPE_BANK1, },
- { "in_bad_avb_class_a", 4, 0x06, STATS_TYPE_BANK1, },
- { "in_bad_avb_class_b", 4, 0x07, STATS_TYPE_BANK1, },
- { "tcam_counter_0", 4, 0x08, STATS_TYPE_BANK1, },
- { "tcam_counter_1", 4, 0x09, STATS_TYPE_BANK1, },
- { "tcam_counter_2", 4, 0x0a, STATS_TYPE_BANK1, },
- { "tcam_counter_3", 4, 0x0b, STATS_TYPE_BANK1, },
- { "in_da_unknown", 4, 0x0e, STATS_TYPE_BANK1, },
- { "in_management", 4, 0x0f, STATS_TYPE_BANK1, },
- { "out_queue_0", 4, 0x10, STATS_TYPE_BANK1, },
- { "out_queue_1", 4, 0x11, STATS_TYPE_BANK1, },
- { "out_queue_2", 4, 0x12, STATS_TYPE_BANK1, },
- { "out_queue_3", 4, 0x13, STATS_TYPE_BANK1, },
- { "out_queue_4", 4, 0x14, STATS_TYPE_BANK1, },
- { "out_queue_5", 4, 0x15, STATS_TYPE_BANK1, },
- { "out_queue_6", 4, 0x16, STATS_TYPE_BANK1, },
- { "out_queue_7", 4, 0x17, STATS_TYPE_BANK1, },
- { "out_cut_through", 4, 0x18, STATS_TYPE_BANK1, },
- { "out_octets_a", 4, 0x1a, STATS_TYPE_BANK1, },
- { "out_octets_b", 4, 0x1b, STATS_TYPE_BANK1, },
- { "out_management", 4, 0x1f, STATS_TYPE_BANK1, },
+#define MV88E6XXX_HW_STAT_MAPPER(_fn) \
+ _fn(in_good_octets, 8, 0x00, STATS_TYPE_BANK0) \
+ _fn(in_bad_octets, 4, 0x02, STATS_TYPE_BANK0) \
+ _fn(in_unicast, 4, 0x04, STATS_TYPE_BANK0) \
+ _fn(in_broadcasts, 4, 0x06, STATS_TYPE_BANK0) \
+ _fn(in_multicasts, 4, 0x07, STATS_TYPE_BANK0) \
+ _fn(in_pause, 4, 0x16, STATS_TYPE_BANK0) \
+ _fn(in_undersize, 4, 0x18, STATS_TYPE_BANK0) \
+ _fn(in_fragments, 4, 0x19, STATS_TYPE_BANK0) \
+ _fn(in_oversize, 4, 0x1a, STATS_TYPE_BANK0) \
+ _fn(in_jabber, 4, 0x1b, STATS_TYPE_BANK0) \
+ _fn(in_rx_error, 4, 0x1c, STATS_TYPE_BANK0) \
+ _fn(in_fcs_error, 4, 0x1d, STATS_TYPE_BANK0) \
+ _fn(out_octets, 8, 0x0e, STATS_TYPE_BANK0) \
+ _fn(out_unicast, 4, 0x10, STATS_TYPE_BANK0) \
+ _fn(out_broadcasts, 4, 0x13, STATS_TYPE_BANK0) \
+ _fn(out_multicasts, 4, 0x12, STATS_TYPE_BANK0) \
+ _fn(out_pause, 4, 0x15, STATS_TYPE_BANK0) \
+ _fn(excessive, 4, 0x11, STATS_TYPE_BANK0) \
+ _fn(collisions, 4, 0x1e, STATS_TYPE_BANK0) \
+ _fn(deferred, 4, 0x05, STATS_TYPE_BANK0) \
+ _fn(single, 4, 0x14, STATS_TYPE_BANK0) \
+ _fn(multiple, 4, 0x17, STATS_TYPE_BANK0) \
+ _fn(out_fcs_error, 4, 0x03, STATS_TYPE_BANK0) \
+ _fn(late, 4, 0x1f, STATS_TYPE_BANK0) \
+ _fn(hist_64bytes, 4, 0x08, STATS_TYPE_BANK0) \
+ _fn(hist_65_127bytes, 4, 0x09, STATS_TYPE_BANK0) \
+ _fn(hist_128_255bytes, 4, 0x0a, STATS_TYPE_BANK0) \
+ _fn(hist_256_511bytes, 4, 0x0b, STATS_TYPE_BANK0) \
+ _fn(hist_512_1023bytes, 4, 0x0c, STATS_TYPE_BANK0) \
+ _fn(hist_1024_max_bytes, 4, 0x0d, STATS_TYPE_BANK0) \
+ _fn(sw_in_discards, 4, 0x10, STATS_TYPE_PORT) \
+ _fn(sw_in_filtered, 2, 0x12, STATS_TYPE_PORT) \
+ _fn(sw_out_filtered, 2, 0x13, STATS_TYPE_PORT) \
+ _fn(in_discards, 4, 0x00, STATS_TYPE_BANK1) \
+ _fn(in_filtered, 4, 0x01, STATS_TYPE_BANK1) \
+ _fn(in_accepted, 4, 0x02, STATS_TYPE_BANK1) \
+ _fn(in_bad_accepted, 4, 0x03, STATS_TYPE_BANK1) \
+ _fn(in_good_avb_class_a, 4, 0x04, STATS_TYPE_BANK1) \
+ _fn(in_good_avb_class_b, 4, 0x05, STATS_TYPE_BANK1) \
+ _fn(in_bad_avb_class_a, 4, 0x06, STATS_TYPE_BANK1) \
+ _fn(in_bad_avb_class_b, 4, 0x07, STATS_TYPE_BANK1) \
+ _fn(tcam_counter_0, 4, 0x08, STATS_TYPE_BANK1) \
+ _fn(tcam_counter_1, 4, 0x09, STATS_TYPE_BANK1) \
+ _fn(tcam_counter_2, 4, 0x0a, STATS_TYPE_BANK1) \
+ _fn(tcam_counter_3, 4, 0x0b, STATS_TYPE_BANK1) \
+ _fn(in_da_unknown, 4, 0x0e, STATS_TYPE_BANK1) \
+ _fn(in_management, 4, 0x0f, STATS_TYPE_BANK1) \
+ _fn(out_queue_0, 4, 0x10, STATS_TYPE_BANK1) \
+ _fn(out_queue_1, 4, 0x11, STATS_TYPE_BANK1) \
+ _fn(out_queue_2, 4, 0x12, STATS_TYPE_BANK1) \
+ _fn(out_queue_3, 4, 0x13, STATS_TYPE_BANK1) \
+ _fn(out_queue_4, 4, 0x14, STATS_TYPE_BANK1) \
+ _fn(out_queue_5, 4, 0x15, STATS_TYPE_BANK1) \
+ _fn(out_queue_6, 4, 0x16, STATS_TYPE_BANK1) \
+ _fn(out_queue_7, 4, 0x17, STATS_TYPE_BANK1) \
+ _fn(out_cut_through, 4, 0x18, STATS_TYPE_BANK1) \
+ _fn(out_octets_a, 4, 0x1a, STATS_TYPE_BANK1) \
+ _fn(out_octets_b, 4, 0x1b, STATS_TYPE_BANK1) \
+ _fn(out_management, 4, 0x1f, STATS_TYPE_BANK1) \
+ /* */
+
+#define MV88E6XXX_HW_STAT_ENTRY(_string, _size, _reg, _type) \
+ { #_string, _size, _reg, _type },
+static const struct mv88e6xxx_hw_stat mv88e6xxx_hw_stats[] = {
+ MV88E6XXX_HW_STAT_MAPPER(MV88E6XXX_HW_STAT_ENTRY)
};
+#define MV88E6XXX_HW_STAT_ENUM(_string, _size, _reg, _type) \
+ MV88E6XXX_HW_STAT_ID_ ## _string,
+enum mv88e6xxx_hw_stat_id {
+ MV88E6XXX_HW_STAT_MAPPER(MV88E6XXX_HW_STAT_ENUM)
+
+ MV88E6XXX_HW_STAT_ID_MAX
+};
+
+
static uint64_t _mv88e6xxx_get_ethtool_stat(struct mv88e6xxx_chip *chip,
const struct mv88e6xxx_hw_stat *s,
int port, u16 bank1_select,
@@ -1125,7 +1140,7 @@ static uint64_t _mv88e6xxx_get_ethtool_stat(struct mv88e6xxx_chip *chip,
static int mv88e6xxx_stats_get_strings(struct mv88e6xxx_chip *chip,
uint8_t *data, int types)
{
- struct mv88e6xxx_hw_stat *stat;
+ const struct mv88e6xxx_hw_stat *stat;
int i, j;
for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
@@ -1206,7 +1221,7 @@ static void mv88e6xxx_get_strings(struct dsa_switch *ds, int port,
static int mv88e6xxx_stats_get_sset_count(struct mv88e6xxx_chip *chip,
int types)
{
- struct mv88e6xxx_hw_stat *stat;
+ const struct mv88e6xxx_hw_stat *stat;
int i, j;
for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
@@ -1333,7 +1348,7 @@ static int mv88e6xxx_stats_get_stat(struct mv88e6xxx_chip *chip, int port,
static int mv88e6xxx_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
uint64_t *data)
{
- struct mv88e6xxx_hw_stat *stat;
+ const struct mv88e6xxx_hw_stat *stat;
int i, j;
for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
--
2.34.1
@@ -0,0 +1,86 @@
From ffd5442fcbadcbd8733b9ac870d83d7561cca9fc Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 5 Sep 2023 21:15:52 +0200
Subject: [PATCH 4/9] net: dsa: mv88e6xxx: Add "eth-mac" counter group support
After this change, mv88e6xxx ports can report the applicable subset of
their counters using ethtool's standardized "eth-mac" counter group.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 52 ++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index ea4fb0d3e628..ec3a4717bc44 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -1403,6 +1403,57 @@ static void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
}
+static void mv88e6xxx_get_eth_mac_stats(struct dsa_switch *ds, int port,
+ struct ethtool_eth_mac_stats *mac_stats)
+{
+#define MV88E6XXX_ETH_MAC_STAT_MAPPING(_id, _member) \
+ [MV88E6XXX_HW_STAT_ID_ ## _id] = \
+ offsetof(struct ethtool_eth_mac_stats, stats._member) \
+
+ static const size_t stat_map[MV88E6XXX_HW_STAT_ID_MAX] = {
+ MV88E6XXX_ETH_MAC_STAT_MAPPING(out_unicast, FramesTransmittedOK),
+ MV88E6XXX_ETH_MAC_STAT_MAPPING(single, SingleCollisionFrames),
+ MV88E6XXX_ETH_MAC_STAT_MAPPING(multiple, MultipleCollisionFrames),
+ MV88E6XXX_ETH_MAC_STAT_MAPPING(in_unicast, FramesReceivedOK),
+ MV88E6XXX_ETH_MAC_STAT_MAPPING(in_fcs_error, FrameCheckSequenceErrors),
+ MV88E6XXX_ETH_MAC_STAT_MAPPING(out_octets, OctetsTransmittedOK),
+ MV88E6XXX_ETH_MAC_STAT_MAPPING(deferred, FramesWithDeferredXmissions),
+ MV88E6XXX_ETH_MAC_STAT_MAPPING(late, LateCollisions),
+ MV88E6XXX_ETH_MAC_STAT_MAPPING(in_good_octets, OctetsReceivedOK),
+ MV88E6XXX_ETH_MAC_STAT_MAPPING(out_multicasts, MulticastFramesXmittedOK),
+ MV88E6XXX_ETH_MAC_STAT_MAPPING(out_broadcasts, BroadcastFramesXmittedOK),
+ MV88E6XXX_ETH_MAC_STAT_MAPPING(excessive, FramesWithExcessiveDeferral),
+ MV88E6XXX_ETH_MAC_STAT_MAPPING(in_multicasts, MulticastFramesReceivedOK),
+ MV88E6XXX_ETH_MAC_STAT_MAPPING(in_broadcasts, BroadcastFramesReceivedOK),
+ };
+ struct mv88e6xxx_chip *chip = ds->priv;
+ const struct mv88e6xxx_hw_stat *stat;
+ enum mv88e6xxx_hw_stat_id id;
+ u64 *member;
+ int ret;
+
+ mv88e6xxx_reg_lock(chip);
+ ret = mv88e6xxx_stats_snapshot(chip, port);
+ mv88e6xxx_reg_unlock(chip);
+
+ if (ret < 0)
+ return;
+
+ stat = mv88e6xxx_hw_stats;
+ for (id = 0; id < MV88E6XXX_HW_STAT_ID_MAX; id++, stat++) {
+ if (!stat_map[id])
+ continue;
+
+ member = (u64 *)(((char *)mac_stats) + stat_map[id]);
+ mv88e6xxx_stats_get_stat(chip, port, stat, member);
+ }
+
+ mac_stats->stats.FramesTransmittedOK += mac_stats->stats.MulticastFramesXmittedOK;
+ mac_stats->stats.FramesTransmittedOK += mac_stats->stats.BroadcastFramesXmittedOK;
+ mac_stats->stats.FramesReceivedOK += mac_stats->stats.MulticastFramesReceivedOK;
+ mac_stats->stats.FramesReceivedOK += mac_stats->stats.BroadcastFramesReceivedOK;
+}
+
static int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port)
{
struct mv88e6xxx_chip *chip = ds->priv;
@@ -7160,6 +7211,7 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
.phylink_mac_link_up = mv88e6xxx_mac_link_up,
.get_strings = mv88e6xxx_get_strings,
.get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
+ .get_eth_mac_stats = mv88e6xxx_get_eth_mac_stats,
.get_sset_count = mv88e6xxx_get_sset_count,
.port_enable = mv88e6xxx_port_enable,
.port_disable = mv88e6xxx_port_disable,
--
2.34.1
@@ -0,0 +1,90 @@
From 2cfafa598282efc980baf00b312a61032b9f5aa9 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Wed, 6 Sep 2023 10:55:53 +0200
Subject: [PATCH 5/9] net: dsa: mv88e6xxx: Add "rmon" counter group support
After this change, mv88e6xxx ports can report the applicable subset of
their counters using ethtool's standardized "rmon" counter group.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 56 ++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index ec3a4717bc44..eb5990cfc7d4 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -1454,6 +1454,61 @@ static void mv88e6xxx_get_eth_mac_stats(struct dsa_switch *ds, int port,
mac_stats->stats.FramesReceivedOK += mac_stats->stats.BroadcastFramesReceivedOK;
}
+static void mv88e6xxx_get_rmon_stats(struct dsa_switch *ds, int port,
+ struct ethtool_rmon_stats *rmon_stats,
+ const struct ethtool_rmon_hist_range **ranges)
+{
+#define MV88E6XXX_RMON_STAT_MAPPING(_id, _member) \
+ [MV88E6XXX_HW_STAT_ID_ ## _id] = \
+ offsetof(struct ethtool_rmon_stats, stats._member) \
+
+ static const size_t stat_map[MV88E6XXX_HW_STAT_ID_MAX] = {
+ MV88E6XXX_RMON_STAT_MAPPING(in_undersize, undersize_pkts),
+ MV88E6XXX_RMON_STAT_MAPPING(in_oversize, oversize_pkts),
+ MV88E6XXX_RMON_STAT_MAPPING(in_fragments, fragments),
+ MV88E6XXX_RMON_STAT_MAPPING(in_jabber, jabbers),
+ MV88E6XXX_RMON_STAT_MAPPING(hist_64bytes, hist[0]),
+ MV88E6XXX_RMON_STAT_MAPPING(hist_65_127bytes, hist[1]),
+ MV88E6XXX_RMON_STAT_MAPPING(hist_128_255bytes, hist[2]),
+ MV88E6XXX_RMON_STAT_MAPPING(hist_256_511bytes, hist[3]),
+ MV88E6XXX_RMON_STAT_MAPPING(hist_512_1023bytes, hist[4]),
+ MV88E6XXX_RMON_STAT_MAPPING(hist_1024_max_bytes, hist[5]),
+ };
+ static const struct ethtool_rmon_hist_range rmon_ranges[] = {
+ { 64, 64 },
+ { 65, 127 },
+ { 128, 255 },
+ { 256, 511 },
+ { 512, 1023 },
+ { 1024, 65535 },
+ {}
+ };
+ struct mv88e6xxx_chip *chip = ds->priv;
+ const struct mv88e6xxx_hw_stat *stat;
+ enum mv88e6xxx_hw_stat_id id;
+ u64 *member;
+ int ret;
+
+ mv88e6xxx_reg_lock(chip);
+ ret = mv88e6xxx_stats_snapshot(chip, port);
+ mv88e6xxx_reg_unlock(chip);
+
+ if (ret < 0)
+ return;
+
+ stat = mv88e6xxx_hw_stats;
+ for (id = 0; id < MV88E6XXX_HW_STAT_ID_MAX; id++, stat++) {
+ if (!stat_map[id])
+ continue;
+
+ member = (u64 *)(((char *)rmon_stats) + stat_map[id]);
+ mv88e6xxx_stats_get_stat(chip, port, stat, member);
+ }
+
+ *ranges = rmon_ranges;
+}
+
+
static int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port)
{
struct mv88e6xxx_chip *chip = ds->priv;
@@ -7212,6 +7267,7 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
.get_strings = mv88e6xxx_get_strings,
.get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
.get_eth_mac_stats = mv88e6xxx_get_eth_mac_stats,
+ .get_rmon_stats = mv88e6xxx_get_rmon_stats,
.get_sset_count = mv88e6xxx_get_sset_count,
.port_enable = mv88e6xxx_port_enable,
.port_disable = mv88e6xxx_port_disable,
--
2.34.1
@@ -0,0 +1,39 @@
From 7abdce276172fe74e24fd30d204a75e388bbab6c Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 21 Sep 2023 11:10:26 +0200
Subject: [PATCH 6/9] arm64: dts: marvell: cp11x: Provide clock names for MDIO
controllers
This will let the driver figure out the rate of the core clk, such
that custom MDC frequencies can be supported.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
arch/arm64/boot/dts/marvell/armada-cp11x.dtsi | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi b/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi
index 4ec1aae0a3a9..f268017498a9 100644
--- a/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi
@@ -180,6 +180,8 @@ CP11X_LABEL(mdio): mdio@12a200 {
reg = <0x12a200 0x10>;
clocks = <&CP11X_LABEL(clk) 1 9>, <&CP11X_LABEL(clk) 1 5>,
<&CP11X_LABEL(clk) 1 6>, <&CP11X_LABEL(clk) 1 18>;
+ clock-names = "gop_clk", "mg_clk",
+ "mg_core_clk", "axi_clk";
status = "disabled";
};
@@ -190,6 +192,8 @@ CP11X_LABEL(xmdio): mdio@12a600 {
reg = <0x12a600 0x10>;
clocks = <&CP11X_LABEL(clk) 1 5>,
<&CP11X_LABEL(clk) 1 6>, <&CP11X_LABEL(clk) 1 18>;
+ clock-names = "mg_clk",
+ "mg_core_clk", "axi_clk";
status = "disabled";
};
--
2.34.1
@@ -0,0 +1,119 @@
From 8dc464b6506fbc038ccdae0a88936989fdf32117 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 19 Sep 2023 18:19:40 +0200
Subject: [PATCH 7/9] net: mvmdio: Avoid excessive sleeps in polled mode
Before this change, when operating in polled mode, i.e. no IRQ is
available, every individual C45 access would be hit with a 150us sleep
after the bus access.
For example, on a board with a CN9130 SoC connected to an MV88X3310
PHY, a single C45 read would take around 165us:
root@infix:~$ mdio f212a600.mdio-mii mmd 4:1 bench 0xc003
Performed 1000 reads in 165ms
By replacing the long sleep with a tighter poll loop, we observe a 10x
increase in bus throughput:
root@infix:~$ mdio f212a600.mdio-mii mmd 4:1 bench 0xc003
Performed 1000 reads in 15ms
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
drivers/net/ethernet/marvell/mvmdio.c | 41 +++++++++++----------------
1 file changed, 16 insertions(+), 25 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvmdio.c b/drivers/net/ethernet/marvell/mvmdio.c
index 8662543ca5c8..37e20c2702b5 100644
--- a/drivers/net/ethernet/marvell/mvmdio.c
+++ b/drivers/net/ethernet/marvell/mvmdio.c
@@ -23,6 +23,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/io.h>
+#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_device.h>
@@ -58,11 +59,6 @@
* - Armada 370 (Globalscale Mirabox): 41us to 43us (Polled)
*/
#define MVMDIO_SMI_TIMEOUT 1000 /* 1000us = 1ms */
-#define MVMDIO_SMI_POLL_INTERVAL_MIN 45
-#define MVMDIO_SMI_POLL_INTERVAL_MAX 55
-
-#define MVMDIO_XSMI_POLL_INTERVAL_MIN 150
-#define MVMDIO_XSMI_POLL_INTERVAL_MAX 160
struct orion_mdio_dev {
void __iomem *regs;
@@ -84,8 +80,6 @@ enum orion_mdio_bus_type {
struct orion_mdio_ops {
int (*is_done)(struct orion_mdio_dev *);
- unsigned int poll_interval_min;
- unsigned int poll_interval_max;
};
/* Wait for the SMI unit to be ready for another operation
@@ -94,23 +88,24 @@ static int orion_mdio_wait_ready(const struct orion_mdio_ops *ops,
struct mii_bus *bus)
{
struct orion_mdio_dev *dev = bus->priv;
- unsigned long timeout = usecs_to_jiffies(MVMDIO_SMI_TIMEOUT);
- unsigned long end = jiffies + timeout;
- int timedout = 0;
+ unsigned long end, timeout;
+ int done, timedout;
- while (1) {
- if (ops->is_done(dev))
+ if (dev->err_interrupt <= 0) {
+ if (!read_poll_timeout_atomic(ops->is_done, done, done, 2,
+ MVMDIO_SMI_TIMEOUT, false, dev))
return 0;
- else if (timedout)
- break;
-
- if (dev->err_interrupt <= 0) {
- usleep_range(ops->poll_interval_min,
- ops->poll_interval_max);
+ } else {
+ timeout = usecs_to_jiffies(MVMDIO_SMI_TIMEOUT);
+ end = jiffies + timeout;
+ timedout = 0;
+
+ while (1) {
+ if (ops->is_done(dev))
+ return 0;
+ else if (timedout)
+ break;
- if (time_is_before_jiffies(end))
- ++timedout;
- } else {
/* wait_event_timeout does not guarantee a delay of at
* least one whole jiffie, so timeout must be no less
* than two.
@@ -135,8 +130,6 @@ static int orion_mdio_smi_is_done(struct orion_mdio_dev *dev)
static const struct orion_mdio_ops orion_mdio_smi_ops = {
.is_done = orion_mdio_smi_is_done,
- .poll_interval_min = MVMDIO_SMI_POLL_INTERVAL_MIN,
- .poll_interval_max = MVMDIO_SMI_POLL_INTERVAL_MAX,
};
static int orion_mdio_smi_read(struct mii_bus *bus, int mii_id,
@@ -194,8 +187,6 @@ static int orion_mdio_xsmi_is_done(struct orion_mdio_dev *dev)
static const struct orion_mdio_ops orion_mdio_xsmi_ops = {
.is_done = orion_mdio_xsmi_is_done,
- .poll_interval_min = MVMDIO_XSMI_POLL_INTERVAL_MIN,
- .poll_interval_max = MVMDIO_XSMI_POLL_INTERVAL_MAX,
};
static int orion_mdio_xsmi_read_c45(struct mii_bus *bus, int mii_id,
--
2.34.1
@@ -0,0 +1,88 @@
From 1956176490d4eec3a889a38626326b375782a55a Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 21 Sep 2023 11:12:55 +0200
Subject: [PATCH 8/9] net: mvmdio: Support setting the MDC frequency on XSMI
controllers
Support the standard "clock-frequency" attribute to set the generated
MDC frequency. If not specified, the driver will leave the divisor
untouched.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
drivers/net/ethernet/marvell/mvmdio.c | 45 +++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/drivers/net/ethernet/marvell/mvmdio.c b/drivers/net/ethernet/marvell/mvmdio.c
index 37e20c2702b5..a33f63b7f773 100644
--- a/drivers/net/ethernet/marvell/mvmdio.c
+++ b/drivers/net/ethernet/marvell/mvmdio.c
@@ -53,6 +53,13 @@
#define MVMDIO_XSMI_BUSY BIT(30)
#define MVMDIO_XSMI_ADDR_REG 0x8
+#define MVMDIO_XSMI_CFG_REG 0xc
+#define MVMDIO_XSMI_CLKDIV_MASK 0x3
+#define MVMDIO_XSMI_CLKDIV_256 0x0
+#define MVMDIO_XSMI_CLKDIV_64 0x1
+#define MVMDIO_XSMI_CLKDIV_32 0x2
+#define MVMDIO_XSMI_CLKDIV_8 0x3
+
/*
* SMI Timeout measurements:
* - Kirkwood 88F6281 (Globalscale Dreamplug): 45us to 95us (Interrupt)
@@ -237,6 +244,41 @@ static int orion_mdio_xsmi_write_c45(struct mii_bus *bus, int mii_id,
return 0;
}
+static void orion_mdio_xsmi_set_mdc_freq(struct mii_bus *bus)
+{
+ struct orion_mdio_dev *dev = bus->priv;
+ struct clk *mg_core;
+ u32 div, freq, cfg;
+
+ if (device_property_read_u32(bus->parent, "clock-frequency", &freq))
+ return;
+
+ mg_core = of_clk_get_by_name(bus->parent->of_node, "mg_core_clk");
+ if (IS_ERR(mg_core)) {
+ dev_err(bus->parent,
+ "MG core clock unknown, not changing MDC frequency");
+ return;
+ }
+
+ div = clk_get_rate(mg_core) / (freq + 1) + 1;
+ clk_put(mg_core);
+
+ if (div <= 8)
+ div = MVMDIO_XSMI_CLKDIV_8;
+ else if (div <= 32)
+ div = MVMDIO_XSMI_CLKDIV_32;
+ else if (div <= 64)
+ div = MVMDIO_XSMI_CLKDIV_64;
+ else
+ div = MVMDIO_XSMI_CLKDIV_256;
+
+ cfg = readl(dev->regs + MVMDIO_XSMI_CFG_REG);
+ cfg &= ~MVMDIO_XSMI_CLKDIV_MASK;
+ cfg |= div;
+ writel(cfg, dev->regs + MVMDIO_XSMI_CFG_REG);
+}
+
+
static irqreturn_t orion_mdio_err_irq(int irq, void *dev_id)
{
struct orion_mdio_dev *dev = dev_id;
@@ -315,6 +357,9 @@ static int orion_mdio_probe(struct platform_device *pdev)
dev_warn(&pdev->dev,
"unsupported number of clocks, limiting to the first "
__stringify(ARRAY_SIZE(dev->clk)) "\n");
+
+ if (type == BUS_TYPE_XSMI)
+ orion_mdio_xsmi_set_mdc_freq(bus);
} else {
dev->clk[0] = clk_get(&pdev->dev, NULL);
if (PTR_ERR(dev->clk[0]) == -EPROBE_DEFER) {
--
2.34.1
@@ -0,0 +1,198 @@
From 0de9c5dfc6395eb2e3066488638ac86de58b8068 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 19 Sep 2023 18:38:10 +0200
Subject: [PATCH 9/9] net: phy: marvell10g: Support firmware loading on 88X3310
If a device is found waiting for firmware to be loaded into its RAM,
ask userspace for the binary and load it over XMDIO.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
drivers/net/phy/marvell10g.c | 143 +++++++++++++++++++++++++++++++++++
1 file changed, 143 insertions(+)
diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c
index d4bb90d76881..155f439d9c1c 100644
--- a/drivers/net/phy/marvell10g.c
+++ b/drivers/net/phy/marvell10g.c
@@ -25,6 +25,7 @@
#include <linux/bitfield.h>
#include <linux/ctype.h>
#include <linux/delay.h>
+#include <linux/firmware.h>
#include <linux/hwmon.h>
#include <linux/marvell_phy.h>
#include <linux/phy.h>
@@ -50,6 +51,13 @@ enum {
MV_PMA_21X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH = 0x6,
MV_PMA_BOOT = 0xc050,
MV_PMA_BOOT_FATAL = BIT(0),
+ MV_PMA_BOOT_PRGS_MASK = 0x0006,
+ MV_PMA_BOOT_PRGS_INIT = 0x0000,
+ MV_PMA_BOOT_PRGS_WAIT = 0x0002,
+ MV_PMA_BOOT_PRGS_CSUM = 0x0004,
+ MV_PMA_BOOT_PRGS_JRAM = 0x0006,
+ MV_PMA_BOOT_APP_STARTED = BIT(4),
+ MV_PMA_BOOT_APP_LOADED = BIT(6),
MV_PCS_BASE_T = 0x0000,
MV_PCS_BASE_R = 0x1000,
@@ -96,6 +104,12 @@ enum {
MV_PCS_PORT_INFO_NPORTS_MASK = 0x0380,
MV_PCS_PORT_INFO_NPORTS_SHIFT = 7,
+ /* Firmware downloading */
+ MV_PCS_FW_ADDR_LOW = 0xd0f0,
+ MV_PCS_FW_ADDR_HIGH = 0xd0f1,
+ MV_PCS_FW_DATA = 0xd0f2,
+ MV_PCS_FW_CSUM = 0xd0f3,
+
/* SerDes reinitialization 88E21X0 */
MV_AN_21X0_SERDES_CTRL2 = 0x800f,
MV_AN_21X0_SERDES_CTRL2_AUTO_INIT_DIS = BIT(13),
@@ -499,6 +513,129 @@ static const struct sfp_upstream_ops mv3310_sfp_ops = {
.module_insert = mv3310_sfp_insert,
};
+struct mv3310_fw_hdr {
+ struct {
+ u32 size;
+ u32 addr;
+ u16 csum;
+ } __packed data;
+
+ u8 flags;
+#define MV3310_FW_HDR_DATA_ONLY BIT(6)
+
+ u8 port_skip;
+ u32 next_hdr;
+ u16 csum;
+
+ u8 pad[14];
+} __packed;
+
+static int mv3310_load_fw_sect(struct phy_device *phydev,
+ const struct mv3310_fw_hdr *hdr, const u8 *data)
+{
+ int err = 0;
+ size_t i;
+ u16 csum;
+
+ dev_dbg(&phydev->mdio.dev, "Loading %u byte %s section at 0x%08x\n",
+ hdr->data.size,
+ (hdr->flags & MV3310_FW_HDR_DATA_ONLY) ? "data" : "executable",
+ hdr->data.addr);
+
+ for (i = 0, csum = 0; i < hdr->data.size; i++)
+ csum += data[i];
+
+ if ((u16)~csum != hdr->data.csum) {
+ dev_err(&phydev->mdio.dev, "Corrupt section data\n");
+ return -EINVAL;
+ }
+
+ phy_lock_mdio_bus(phydev);
+
+ /* Any existing checksum is cleared by a read */
+ __phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_FW_CSUM);
+
+ __phy_write_mmd(phydev, MDIO_MMD_PCS, MV_PCS_FW_ADDR_LOW, hdr->data.addr & 0xffff);
+ __phy_write_mmd(phydev, MDIO_MMD_PCS, MV_PCS_FW_ADDR_HIGH, hdr->data.addr >> 16);
+
+ for (i = 0; i < hdr->data.size; i += 2) {
+ __phy_write_mmd(phydev, MDIO_MMD_PCS, MV_PCS_FW_DATA,
+ (data[i + 1] << 8) | data[i]);
+ }
+
+ csum = __phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_FW_CSUM);
+ if ((u16)~csum != hdr->data.csum) {
+ dev_err(&phydev->mdio.dev, "Download failed\n");
+ err = -EIO;
+ goto unlock;
+ }
+
+ if (hdr->flags & MV3310_FW_HDR_DATA_ONLY)
+ goto unlock;
+
+ __phy_modify_mmd(phydev, MDIO_MMD_PMAPMD, MV_PMA_BOOT, 0, MV_PMA_BOOT_APP_LOADED);
+ mdelay(200);
+ if (!(__phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MV_PMA_BOOT) & MV_PMA_BOOT_APP_STARTED)) {
+ dev_err(&phydev->mdio.dev, "Application did not startup\n");
+ err = -ENOSYS;
+ }
+
+unlock:
+ phy_unlock_mdio_bus(phydev);
+ return err;
+}
+
+static int mv3310_load_fw(struct phy_device *phydev)
+{
+ const struct firmware *fw;
+ struct mv3310_fw_hdr hdr;
+ const u8 *sect;
+ size_t i;
+ u16 csum;
+ int err;
+
+ /* dev_info(&phydev->mdio.dev, "Requ */
+ err = request_firmware(&fw, "x33x0fw.hdr", &phydev->mdio.dev);
+ if (err)
+ return err;
+
+ if (fw->size & 1) {
+ err = -EINVAL;
+ goto release;
+ }
+
+ for (sect = fw->data; (sect + sizeof(hdr)) < (fw->data + fw->size);) {
+ memcpy(&hdr, sect, sizeof(hdr));
+ hdr.data.size = cpu_to_le32(hdr.data.size);
+ hdr.data.addr = cpu_to_le32(hdr.data.addr);
+ hdr.data.csum = cpu_to_le16(hdr.data.csum);
+ hdr.next_hdr = cpu_to_le32(hdr.next_hdr);
+ hdr.csum = cpu_to_le16(hdr.csum);
+
+ for (i = 0, csum = 0; i < offsetof(struct mv3310_fw_hdr, csum); i++)
+ csum += sect[i];
+
+ if ((u16)~csum != hdr.csum) {
+ dev_err(&phydev->mdio.dev, "Corrupt section header\n");
+ err = -EINVAL;
+ break;
+ }
+
+ err = mv3310_load_fw_sect(phydev, &hdr, sect + sizeof(hdr));
+ if (err)
+ break;
+
+ if (!hdr.next_hdr)
+ break;
+
+ sect = fw->data + hdr.next_hdr;
+ }
+
+release:
+ release_firmware(fw);
+ return err;
+}
+
static int mv3310_probe(struct phy_device *phydev)
{
const struct mv3310_chip *chip = to_mv3310_chip(phydev);
@@ -520,6 +657,12 @@ static int mv3310_probe(struct phy_device *phydev)
return -ENODEV;
}
+ if ((ret & MV_PMA_BOOT_PRGS_MASK) == MV_PMA_BOOT_PRGS_WAIT) {
+ ret = mv3310_load_fw(phydev);
+ if (ret)
+ return ret;
+ }
+
priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
--
2.34.1
@@ -1,16 +0,0 @@
Index: linux-6.1.32/arch/arm64/boot/dts/marvell/cn9130-crb.dtsi
===================================================================
--- linux-6.1.32.orig/arch/arm64/boot/dts/marvell/cn9130-crb.dtsi
+++ linux-6.1.32/arch/arm64/boot/dts/marvell/cn9130-crb.dtsi
@@ -284,6 +284,11 @@
reg = <10>;
label = "cpu";
ethernet = <&cp0_eth0>;
+ phy-mode = "10gbase-r";
+ fixed-link {
+ speed = <10000>;
+ full-duplex;
+ };
};
};
@@ -0,0 +1,156 @@
From 4348261902b60f93c217f07069a2b5613a933c17 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 17 Oct 2023 13:15:58 +0200
Subject: [PATCH 1/5] net: mv88e6xxx: Add reset-gpios support
If the switch's RESETn signal is under the CPUs control, release it
before starting the probe.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
drivers/net/mv88e6xxx.c | 68 ++++++++++++++++++++++++++++++++++++-----
1 file changed, 61 insertions(+), 7 deletions(-)
diff --git a/drivers/net/mv88e6xxx.c b/drivers/net/mv88e6xxx.c
index 64e860e324..1bf7cfd6a6 100644
--- a/drivers/net/mv88e6xxx.c
+++ b/drivers/net/mv88e6xxx.c
@@ -33,6 +33,8 @@
#include <miiphy.h>
#include <net/dsa.h>
+#include <asm-generic/gpio.h>
+
/* Device addresses */
#define DEVADDR_PHY(p) (p)
#define DEVADDR_SERDES 0x0F
@@ -146,6 +148,8 @@ struct mv88e6xxx_priv {
int port_reg_base; /* Base of the switch port registers */
u8 global1; /* Offset of Switch Global 1 registers */
u8 global2; /* Offset of Switch Global 2 registers */
+
+ struct gpio_desc reset;
};
/* Wait for the current SMI indirect command to complete */
@@ -675,6 +679,37 @@ static int mv88e6xxx_probe_mdio(struct udevice *dev)
return ret;
}
+static int mv88e6xxx_probe_reset(struct udevice *dev)
+{
+ struct mv88e6xxx_priv *priv = dev_get_priv(dev);
+ int err;
+
+ if (!CONFIG_IS_ENABLED(DM_GPIO))
+ return 0;
+
+ err = gpio_request_by_name(dev, "reset-gpios", 0,
+ &priv->reset, GPIOD_IS_OUT);
+ if (err && (err != -ENOENT))
+ return err;
+
+ if (dm_gpio_is_valid(&priv->reset)) {
+ dm_gpio_set_value(&priv->reset, 0);
+ mdelay(10);
+ }
+
+ return 0;
+}
+
+static void mv88e6xxx_remove_reset(struct udevice *dev)
+{
+ struct mv88e6xxx_priv *priv = dev_get_priv(dev);
+
+ if (CONFIG_IS_ENABLED(DM_GPIO) && dm_gpio_is_valid(&priv->reset)) {
+ dm_gpio_set_value(&priv->reset, 1);
+ dm_gpio_free(dev, &priv->reset);
+ }
+}
+
static int mv88e6xxx_probe(struct udevice *dev)
{
struct dsa_pdata *dsa_pdata = dev_get_uclass_plat(dev);
@@ -684,17 +719,22 @@ static int mv88e6xxx_probe(struct udevice *dev)
if (ofnode_valid(dev_ofnode(dev)) &&
!ofnode_is_enabled(dev_ofnode(dev))) {
dev_dbg(dev, "switch disabled\n");
- return -ENODEV;
+ ret = -ENODEV;
+ goto err;
}
+ ret = mv88e6xxx_probe_reset(dev);
+ if (ret)
+ goto err;
+
/* probe internal mdio bus */
ret = mv88e6xxx_probe_mdio(dev);
if (ret)
- return ret;
+ goto err_remove_reset;
ret = mv88e6xxx_priv_reg_offs_pre_init(dev);
if (ret)
- return ret;
+ goto err_remove_reset;
dev_dbg(dev, "ID=0x%x PORT_BASE=0x%02x GLOBAL1=0x%02x GLOBAL2=0x%02x\n",
priv->id, priv->port_reg_base, priv->global1, priv->global2);
@@ -716,28 +756,40 @@ static int mv88e6xxx_probe(struct udevice *dev)
priv->port_count = 7;
break;
default:
- return -ENODEV;
+ ret = -ENODEV;
+ goto err_remove_reset;
}
ret = mv88e6xxx_switch_reset(dev);
if (ret < 0)
- return ret;
+ goto err_remove_reset;
if (mv88e6xxx_6352_family(dev)) {
val = mv88e6xxx_get_cmode(dev, dsa_pdata->cpu_port);
if (val < 0)
- return val;
+ goto err_remove_reset;
/* initialize serdes */
if (val == PORT_REG_STATUS_CMODE_100BASE_X ||
val == PORT_REG_STATUS_CMODE_1000BASE_X ||
val == PORT_REG_STATUS_CMODE_SGMII) {
ret = mv88e6xxx_serdes_init(dev);
if (ret < 0)
- return ret;
+ goto err_remove_reset;
}
}
return 0;
+
+err_remove_reset:
+ mv88e6xxx_remove_reset(dev);
+err:
+ return ret;
+}
+
+static int mv88e6xxx_remove(struct udevice *dev)
+{
+ mv88e6xxx_remove_reset(dev);
+ return 0;
}
static const struct udevice_id mv88e6xxx_ids[] = {
@@ -750,6 +802,8 @@ U_BOOT_DRIVER(mv88e6xxx) = {
.id = UCLASS_DSA,
.of_match = mv88e6xxx_ids,
.probe = mv88e6xxx_probe,
+ .remove = mv88e6xxx_remove,
.ops = &mv88e6xxx_dsa_ops,
.priv_auto = sizeof(struct mv88e6xxx_priv),
+ .flags = DM_FLAG_OS_PREPARE,
};
--
2.34.1
@@ -0,0 +1,181 @@
From d87aea2f0d0acfa0d54adb20a980256c0ba95023 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 17 Oct 2023 13:20:19 +0200
Subject: [PATCH 2/5] net: mv88e6xxx: Support clause 45 addressing on internal
MDIO bus
This is needed to access SERDES registers on newer chips, like the
6393X.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
drivers/net/mv88e6xxx.c | 113 +++++++++++++++++++++++++++++++++++++---
1 file changed, 106 insertions(+), 7 deletions(-)
diff --git a/drivers/net/mv88e6xxx.c b/drivers/net/mv88e6xxx.c
index 1bf7cfd6a6..eddac332e0 100644
--- a/drivers/net/mv88e6xxx.c
+++ b/drivers/net/mv88e6xxx.c
@@ -114,6 +114,9 @@
#define SMI_CMD_CLAUSE_22 BIT(12)
#define SMI_CMD_CLAUSE_22_OP_READ (2 << 10)
#define SMI_CMD_CLAUSE_22_OP_WRITE (1 << 10)
+#define SMI_CMD_CLAUSE_45_OP_WADDR (0 << 10)
+#define SMI_CMD_CLAUSE_45_OP_WDATA (1 << 10)
+#define SMI_CMD_CLAUSE_45_OP_RDATA (3 << 10)
#define SMI_CMD_ADDR_SHIFT 5
#define SMI_CMD_ADDR_MASK 0x1f
#define SMI_CMD_REG_SHIFT 0
@@ -126,6 +129,18 @@
(SMI_BUSY | SMI_CMD_CLAUSE_22 | SMI_CMD_CLAUSE_22_OP_WRITE) | \
(((addr) & SMI_CMD_ADDR_MASK) << SMI_CMD_ADDR_SHIFT) | \
(((reg) & SMI_CMD_REG_MASK) << SMI_CMD_REG_SHIFT)
+#define XSMI_CMD_WADDR(port, dev) \
+ (SMI_BUSY | SMI_CMD_CLAUSE_45_OP_WADDR) | \
+ (((port) & SMI_CMD_ADDR_MASK) << SMI_CMD_ADDR_SHIFT) | \
+ (((dev) & SMI_CMD_REG_MASK) << SMI_CMD_REG_SHIFT)
+#define XSMI_CMD_WDATA(port, dev) \
+ (SMI_BUSY | SMI_CMD_CLAUSE_45_OP_WDATA) | \
+ (((port) & SMI_CMD_ADDR_MASK) << SMI_CMD_ADDR_SHIFT) | \
+ (((dev) & SMI_CMD_REG_MASK) << SMI_CMD_REG_SHIFT)
+#define XSMI_CMD_RDATA(port, dev) \
+ (SMI_BUSY | SMI_CMD_CLAUSE_45_OP_RDATA) | \
+ (((port) & SMI_CMD_ADDR_MASK) << SMI_CMD_ADDR_SHIFT) | \
+ (((dev) & SMI_CMD_REG_MASK) << SMI_CMD_REG_SHIFT)
/* ID register values for different switch models */
#define PORT_SWITCH_ID_6020 0x0200
@@ -273,7 +288,41 @@ static int mv88e6xxx_phy_wait(struct udevice *dev)
return -ETIMEDOUT;
}
-static int mv88e6xxx_phy_read_indirect(struct udevice *dev, int phyad, int devad, int reg)
+static int mv88e6xxx_phy_read_indirect_c45(struct udevice *dev, int phyad, int devad, int reg)
+{
+ struct mv88e6xxx_priv *priv = dev_get_priv(dev);
+ int res;
+
+ res = mv88e6xxx_reg_write(dev, priv->global2,
+ GLOBAL2_REG_PHY_DATA, reg);
+ if (res < 0)
+ return res;
+
+ res = mv88e6xxx_reg_write(dev, priv->global2,
+ GLOBAL2_REG_PHY_CMD,
+ XSMI_CMD_WADDR(phyad, devad));
+ if (res < 0)
+ return res;
+
+ res = mv88e6xxx_phy_wait(dev);
+ if (res < 0)
+ return res;
+
+ res = mv88e6xxx_reg_write(dev, priv->global2,
+ GLOBAL2_REG_PHY_CMD,
+ XSMI_CMD_RDATA(phyad, devad));
+ if (res < 0)
+ return res;
+
+ res = mv88e6xxx_phy_wait(dev);
+ if (res < 0)
+ return res;
+
+ return mv88e6xxx_reg_read(dev, priv->global2,
+ GLOBAL2_REG_PHY_DATA);
+}
+
+static int mv88e6xxx_phy_read_indirect_c22(struct udevice *dev, int phyad, int reg)
{
struct mv88e6xxx_priv *priv = dev_get_priv(dev);
int res;
@@ -293,8 +342,16 @@ static int mv88e6xxx_phy_read_indirect(struct udevice *dev, int phyad, int devad
GLOBAL2_REG_PHY_DATA);
}
-static int mv88e6xxx_phy_write_indirect(struct udevice *dev, int phyad,
- int devad, int reg, u16 data)
+static int mv88e6xxx_phy_read_indirect(struct udevice *dev, int phyad, int devad, int reg)
+{
+ if (devad == MDIO_DEVAD_NONE)
+ return mv88e6xxx_phy_read_indirect_c22(dev, phyad, reg);
+
+ return mv88e6xxx_phy_read_indirect_c45(dev, phyad, devad, reg);
+}
+
+static int mv88e6xxx_phy_write_indirect_c22(struct udevice *dev, int phyad,
+ int reg, u16 data)
{
struct mv88e6xxx_priv *priv = dev_get_priv(dev);
int res;
@@ -315,6 +372,50 @@ static int mv88e6xxx_phy_write_indirect(struct udevice *dev, int phyad,
return mv88e6xxx_phy_wait(dev);
}
+static int mv88e6xxx_phy_write_indirect_c45(struct udevice *dev, int phyad,
+ int devad, int reg, u16 data)
+{
+ struct mv88e6xxx_priv *priv = dev_get_priv(dev);
+ int res;
+
+ res = mv88e6xxx_reg_write(dev, priv->global2,
+ GLOBAL2_REG_PHY_DATA, reg);
+ if (res < 0)
+ return res;
+
+ res = mv88e6xxx_reg_write(dev, priv->global2,
+ GLOBAL2_REG_PHY_CMD,
+ XSMI_CMD_WADDR(phyad, devad));
+ if (res < 0)
+ return res;
+
+ res = mv88e6xxx_phy_wait(dev);
+ if (res < 0)
+ return res;
+
+ res = mv88e6xxx_reg_write(dev, priv->global2,
+ GLOBAL2_REG_PHY_DATA, data);
+ if (res < 0)
+ return res;
+
+ res = mv88e6xxx_reg_write(dev, priv->global2,
+ GLOBAL2_REG_PHY_CMD,
+ XSMI_CMD_WDATA(phyad, devad));
+ if (res < 0)
+ return res;
+
+ return mv88e6xxx_phy_wait(dev);
+}
+
+static int mv88e6xxx_phy_write_indirect(struct udevice *dev, int phyad,
+ int devad, int reg, u16 data)
+{
+ if (devad == MDIO_DEVAD_NONE)
+ return mv88e6xxx_phy_write_indirect_c22(dev, phyad, reg, data);
+
+ return mv88e6xxx_phy_write_indirect_c45(dev, phyad, devad, reg, data);
+}
+
/* Wrapper function to make calls to phy_read_indirect simpler */
static int mv88e6xxx_phy_read(struct udevice *dev, int phy, int reg)
{
@@ -493,15 +594,13 @@ static int mv88e6xxx_priv_reg_offs_pre_init(struct udevice *dev)
static int mv88e6xxx_mdio_read(struct udevice *dev, int addr, int devad, int reg)
{
- return mv88e6xxx_phy_read_indirect(dev->parent, DEVADDR_PHY(addr),
- MDIO_DEVAD_NONE, reg);
+ return mv88e6xxx_phy_read_indirect(dev->parent, DEVADDR_PHY(addr), devad, reg);
}
static int mv88e6xxx_mdio_write(struct udevice *dev, int addr, int devad,
int reg, u16 val)
{
- return mv88e6xxx_phy_write_indirect(dev->parent, DEVADDR_PHY(addr),
- MDIO_DEVAD_NONE, reg, val);
+ return mv88e6xxx_phy_write_indirect(dev->parent, DEVADDR_PHY(addr), devad, reg, val);
}
static const struct mdio_ops mv88e6xxx_mdio_ops = {
--
2.34.1
@@ -0,0 +1,216 @@
From c801299f06f0e5c95bd597fe0ce4ad6c3df9a444 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 17 Oct 2023 13:22:00 +0200
Subject: [PATCH 3/5] net: mv88e6xxx: Add support for 6393X
Only built-in copper PHYs are supported as access ports. Support
10GBASE-R SERDES connection to CPU.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
drivers/net/mv88e6xxx.c | 134 ++++++++++++++++++++++++++++++++++++++--
1 file changed, 130 insertions(+), 4 deletions(-)
diff --git a/drivers/net/mv88e6xxx.c b/drivers/net/mv88e6xxx.c
index eddac332e0..4a4a3ae0b1 100644
--- a/drivers/net/mv88e6xxx.c
+++ b/drivers/net/mv88e6xxx.c
@@ -74,6 +74,7 @@
#define PORT_REG_STATUS_SPEED_1000 2
#define PORT_REG_STATUS_CMODE_MASK 0xF
+#define PORT_REG_STATUS_CMODE_10GBASE_R 0xd
#define PORT_REG_STATUS_CMODE_SGMII 0xa
#define PORT_REG_STATUS_CMODE_1000BASE_X 0x9
#define PORT_REG_STATUS_CMODE_100BASE_X 0x8
@@ -155,6 +156,7 @@
#define PORT_SWITCH_ID_6250 0x2500
#define PORT_SWITCH_ID_6320 0x1150
#define PORT_SWITCH_ID_6352 0x3520
+#define PORT_SWITCH_ID_6393 0x3930
struct mv88e6xxx_priv {
int smi_addr;
@@ -475,6 +477,17 @@ static bool mv88e6xxx_6352_family(struct udevice *dev)
return false;
}
+static bool mv88e6xxx_6393_family(struct udevice *dev)
+{
+ struct mv88e6xxx_priv *priv = dev_get_priv(dev);
+
+ switch (priv->id) {
+ case PORT_SWITCH_ID_6393:
+ return true;
+ }
+ return false;
+}
+
static int mv88e6xxx_get_cmode(struct udevice *dev, u8 port)
{
int res;
@@ -529,7 +542,7 @@ static int mv88e6xxx_switch_reset(struct udevice *dev)
return 0;
}
-static int mv88e6xxx_serdes_init(struct udevice *dev)
+static int mv88e6352_serdes_init(struct udevice *dev)
{
int val;
@@ -549,6 +562,107 @@ static int mv88e6xxx_serdes_init(struct udevice *dev)
return 0;
}
+static int mv88e6393_serdes_erratum_4_6(struct udevice *dev, int port)
+{
+ int val;
+
+ /* mv88e6393x family errata 4.6:
+ * Cannot clear PwrDn bit on SERDES if device is configured CPU_MGD
+ * mode or P0_mode is configured for [x]MII.
+ * Workaround: Set SERDES register 4.F002 bit 5=0 and bit 15=1.
+ *
+ * It seems that after this workaround the SERDES is automatically
+ * powered up (the bit is cleared), so power it down.
+ */
+ val = mv88e6xxx_phy_read_indirect(dev, port, MDIO_MMD_PHYXS, 0xf002);
+ if (val < 0)
+ return val;
+
+ val &= ~BIT(5);
+ val |= MDIO_CTRL1_RESET;
+ return mv88e6xxx_phy_write_indirect(dev, port, MDIO_MMD_PHYXS, 0xf002, val);
+}
+
+static int mv88e6393_serdes_erratum_5_2(struct udevice *dev, int port, int cmode)
+{
+ static const struct {
+ u16 dev, reg, val, mask;
+ } fixes[] = {
+ { MDIO_MMD_VEND1, 0x8093, 0xcb5a, 0xffff },
+ { MDIO_MMD_VEND1, 0x8171, 0x7088, 0xffff },
+ { MDIO_MMD_VEND1, 0x80c9, 0x311a, 0xffff },
+ { MDIO_MMD_VEND1, 0x80a2, 0x8000, 0xff7f },
+ { MDIO_MMD_VEND1, 0x80a9, 0x0000, 0xfff0 },
+ { MDIO_MMD_VEND1, 0x80a3, 0x0000, 0xf8ff },
+ { MDIO_MMD_PHYXS, 0xf002, 0x8000, 0x8000 }
+ };
+ int val, i;
+
+ /* mv88e6393x family errata 5.2:
+ * For optimal signal integrity the following sequence should be applied
+ * to SERDES operating in 10G mode. These registers only apply to 10G
+ * operation and have no effect on other speeds.
+ */
+ if (cmode != PORT_REG_STATUS_CMODE_10GBASE_R)
+ return 0;
+
+ for (i = 0; i < ARRAY_SIZE(fixes); ++i) {
+ val = mv88e6xxx_phy_read_indirect(dev, port, fixes[i].dev, fixes[i].reg);
+ if (val < 0)
+ return val;
+
+ val &= ~fixes[i].mask;
+ val |= fixes[i].val;
+
+ val = mv88e6xxx_phy_write_indirect(dev, port, fixes[i].dev, fixes[i].reg, val);
+ if (val < 0)
+ return val;
+ }
+
+ return 0;
+}
+
+static int mv88e6393_serdes_init(struct udevice *dev, int port, int cmode)
+{
+ u16 base;
+ int val;
+
+ val = mv88e6393_serdes_erratum_4_6(dev, port);
+ if (val < 0)
+ return val;
+
+ val = mv88e6393_serdes_erratum_5_2(dev, port, cmode);
+ if (val < 0)
+ return val;
+
+ switch (cmode) {
+ case PORT_REG_STATUS_CMODE_10GBASE_R:
+ base = 0x1000;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ val = mv88e6xxx_phy_read_indirect(dev, port, MDIO_MMD_PHYXS, base);
+ if (val < 0)
+ return val;
+
+ val &= ~MDIO_CTRL1_LPOWER;
+ val |= MDIO_CTRL1_RESET;
+
+ return mv88e6xxx_phy_write_indirect(dev, port, MDIO_MMD_PHYXS, base, val);
+}
+
+static int mv88e6xxx_serdes_init(struct udevice *dev, int cpu_port, int cmode)
+{
+ if (mv88e6xxx_6352_family(dev))
+ return mv88e6352_serdes_init(dev);
+ else if (mv88e6xxx_6393_family(dev))
+ return mv88e6393_serdes_init(dev, cpu_port, cmode);
+
+ return -EOPNOTSUPP;
+}
+
/*
* This function is used to pre-configure the required register
* offsets, so that the indirect register access to the PHY registers
@@ -569,6 +683,15 @@ static int mv88e6xxx_priv_reg_offs_pre_init(struct udevice *dev)
*/
priv->port_reg_base = 0x10;
priv->id = mv88e6xxx_get_switch_id(dev);
+ if (priv->id == 0xfff0) {
+ /*
+ * Look for a newer device in which ports start at
+ * offset 0 (6390/6393 and compatible switches).
+ */
+ priv->port_reg_base = 0;
+ priv->id = mv88e6xxx_get_switch_id(dev);
+ }
+
if (priv->id != 0xfff0) {
priv->global1 = 0x1B;
priv->global2 = 0x1C;
@@ -844,6 +967,7 @@ static int mv88e6xxx_probe(struct udevice *dev)
case PORT_SWITCH_ID_6176:
case PORT_SWITCH_ID_6240:
case PORT_SWITCH_ID_6352:
+ case PORT_SWITCH_ID_6393:
priv->port_count = 11;
break;
case PORT_SWITCH_ID_6020:
@@ -863,15 +987,17 @@ static int mv88e6xxx_probe(struct udevice *dev)
if (ret < 0)
goto err_remove_reset;
- if (mv88e6xxx_6352_family(dev)) {
+ if (mv88e6xxx_6352_family(dev) ||
+ mv88e6xxx_6393_family(dev)) {
val = mv88e6xxx_get_cmode(dev, dsa_pdata->cpu_port);
if (val < 0)
goto err_remove_reset;
/* initialize serdes */
if (val == PORT_REG_STATUS_CMODE_100BASE_X ||
val == PORT_REG_STATUS_CMODE_1000BASE_X ||
- val == PORT_REG_STATUS_CMODE_SGMII) {
- ret = mv88e6xxx_serdes_init(dev);
+ val == PORT_REG_STATUS_CMODE_SGMII ||
+ val == PORT_REG_STATUS_CMODE_10GBASE_R) {
+ ret = mv88e6xxx_serdes_init(dev, dsa_pdata->cpu_port, val);
if (ret < 0)
goto err_remove_reset;
}
--
2.34.1
@@ -0,0 +1,54 @@
From 5013dadfd3ba92eba930f8ea0f88c0f34b8c55a5 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Fri, 20 Oct 2023 13:19:41 +0200
Subject: [PATCH 4/5] i2c: pcf8575: Properly address chip
These devices hold a simple shift register that is accessed without
any "register" setup.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
drivers/gpio/pcf8575_gpio.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/gpio/pcf8575_gpio.c b/drivers/gpio/pcf8575_gpio.c
index d5930d941f..bc0275b901 100644
--- a/drivers/gpio/pcf8575_gpio.c
+++ b/drivers/gpio/pcf8575_gpio.c
@@ -49,9 +49,15 @@ static int pcf8575_i2c_write(struct udevice *dev, unsigned int word)
{
struct dm_i2c_chip *chip = dev_get_parent_plat(dev);
u8 buf[2] = { word & 0xff, word >> 8, };
+ struct i2c_msg wmsg = {
+ .addr = chip->chip_addr,
+ .flags = 0,
+ .buf = buf,
+ .len = dev_get_driver_data(dev),
+ };
int ret;
- ret = dm_i2c_write(dev, 0, buf, dev_get_driver_data(dev));
+ ret = dm_i2c_xfer(dev, &wmsg, 1);
if (ret)
printf("%s i2c write failed to addr %x\n", __func__,
chip->chip_addr);
@@ -63,9 +69,15 @@ static int pcf8575_i2c_read(struct udevice *dev)
{
struct dm_i2c_chip *chip = dev_get_parent_plat(dev);
u8 buf[2] = {0x00, 0x00};
+ struct i2c_msg rmsg = {
+ .addr = chip->chip_addr,
+ .flags = I2C_M_RD,
+ .buf = buf,
+ .len = dev_get_driver_data(dev),
+ };
int ret;
- ret = dm_i2c_read(dev, 0, buf, dev_get_driver_data(dev));
+ ret = dm_i2c_xfer(dev, &rmsg, 1);
if (ret) {
printf("%s i2c read failed from addr %x\n", __func__,
chip->chip_addr);
--
2.34.1
@@ -0,0 +1,576 @@
From c0495a607652aef38a4d4480ebdb6dd45e3dd9b9 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 24 Oct 2023 22:23:44 +0200
Subject: [PATCH 5/5] arm64: mvebu: a8k: Add eFuse support
Add support for reading and burning LD and HD fuses. Use a specialized
commandline implementation over the standard "fuse" command because:
- We want to reference fuses by the die and module they belong to,
rather than a plain integer bank ID.
- Our lines are wider than 32 bits, meaning that we would have to use
similar tactics as arch/arm/mach-mvebu/efuse.c in order to support
fuse programming, which is cumbersome.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
arch/arm/mach-mvebu/Kconfig | 7 +
arch/arm/mach-mvebu/armada8k/Makefile | 2 +
arch/arm/mach-mvebu/armada8k/efuse.c | 516 ++++++++++++++++++++++++++
3 files changed, 525 insertions(+)
create mode 100644 arch/arm/mach-mvebu/armada8k/efuse.c
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index ac484c73f6..45584b4282 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -421,6 +421,13 @@ config MVEBU_EFUSE_VHV_GPIO_ACTIVE_LOW
bool "VHV_Enable GPIO is Active Low"
depends on MVEBU_EFUSE_VHV_GPIO != ""
+config MVEBU_8K_EFUSE
+ bool "Enable eFuse support"
+ depends on ARMADA_8K
+ select HEX_DUMP
+ help
+ Enable support for reading and writing eFuses on mvebu SoCs.
+
config SECURED_MODE_IMAGE
bool "Build image for trusted boot"
default false
diff --git a/arch/arm/mach-mvebu/armada8k/Makefile b/arch/arm/mach-mvebu/armada8k/Makefile
index 0a4756717a..c1be059b85 100644
--- a/arch/arm/mach-mvebu/armada8k/Makefile
+++ b/arch/arm/mach-mvebu/armada8k/Makefile
@@ -3,3 +3,5 @@
# Copyright (C) 2016 Stefan Roese <sr@denx.de>
obj-y = cpu.o cache_llc.o dram.o
+
+obj-$(CONFIG_MVEBU_8K_EFUSE) += efuse.o
diff --git a/arch/arm/mach-mvebu/armada8k/efuse.c b/arch/arm/mach-mvebu/armada8k/efuse.c
new file mode 100644
index 0000000000..5438d4466d
--- /dev/null
+++ b/arch/arm/mach-mvebu/armada8k/efuse.c
@@ -0,0 +1,516 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2015-2016 Reinhard Pfau <reinhard.pfau@gdsys.cc>
+ */
+
+#include <command.h>
+#include <common.h>
+#include <errno.h>
+#include <hexdump.h>
+
+#include <asm/io.h>
+
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+
+enum mvebu_efuse_mod {
+ MVEBU_EFUSE_MOD_LD0,
+ MVEBU_EFUSE_MOD_LD1,
+ MVEBU_EFUSE_MOD_HD,
+};
+
+struct mvebu_efuse_ld {
+ u32 array[256 / 32];
+#define MVEBU_EFUSE_LD_PARITY_BIT BIT(31)
+ u32 burn;
+};
+
+struct mvebu_efuse_hd_line {
+ u32 array[2];
+#define MVEBU_EFUSE_HD_ECC_MASK 0xfe000000
+ u32 lock;
+ u32 pad;
+};
+
+struct mvebu_efuse_hd {
+#define MVEBU_EFUSE_HD_LINES 64
+ struct mvebu_efuse_hd_line line[MVEBU_EFUSE_HD_LINES];
+};
+
+struct mvebu_efuse_die {
+ union {
+ struct {
+ u32 resvd0;
+ u32 resvd1;
+ u32 ctrl;
+ };
+
+ u8 pad_ctrl[0xf00];
+ };
+
+ union {
+ struct mvebu_efuse_ld ld;
+ u8 pad_ld[0x100];
+ };
+
+ union {
+ struct mvebu_efuse_hd hd;
+ };
+};
+
+static const struct mvebu_efuse_die __iomem *mvebu_efuse_dies[] = {
+ (void __iomem *)0xf06f8000,
+ (void __iomem *)0xf2400000,
+};
+
+static void mvebu_efuse_program_set(const struct mvebu_efuse_die __iomem *die,
+ bool enable)
+{
+ if (enable)
+ setbits_le32(&die->ctrl, BIT(31));
+ else
+ clrbits_le32(&die->ctrl, BIT(31));
+}
+
+static void mvebu_efuse_secure_set(const struct mvebu_efuse_die __iomem *die,
+ bool enable)
+{
+ if (enable)
+ setbits_le32(&die->ctrl, BIT(7));
+ else
+ clrbits_le32(&die->ctrl, BIT(7));
+}
+
+static void mvebu_efuse_ld_select(const struct mvebu_efuse_die __iomem *die,
+ bool ld1)
+{
+ if (ld1)
+ setbits_le32(&die->ctrl, BIT(6));
+ else
+ clrbits_le32(&die->ctrl, BIT(6));
+}
+
+static void mvebu_efuse_ld_read(const struct mvebu_efuse_die __iomem *die,
+ bool ld1, struct mvebu_efuse_ld *ld)
+{
+ size_t i;
+
+ mvebu_efuse_ld_select(die, ld1);
+
+ for (i = 0; i < ARRAY_SIZE(ld->array); i++) {
+ ld->array[i] = readl(&die->ld.array[i]);
+ if (i & 1)
+ ld->array[i] &= ~MVEBU_EFUSE_LD_PARITY_BIT;
+ }
+}
+
+static int mvebu_efuse_ld_write(const struct mvebu_efuse_die __iomem *die,
+ bool ld1, bool secure, const struct mvebu_efuse_ld *ld)
+{
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(ld->array); i++)
+ if ((i & 1) && (ld->array[i] & MVEBU_EFUSE_LD_PARITY_BIT))
+ return -EINVAL;
+
+ mvebu_efuse_ld_select(die, ld1);
+ mvebu_efuse_program_set(die, true);
+ mvebu_efuse_secure_set(die, secure);
+
+ for (i = 0; i < ARRAY_SIZE(ld->array); i++)
+ writel(ld->array[i], &die->ld.array[i]);
+
+ writel(0, &die->ld.burn);
+ mdelay(1);
+
+ mvebu_efuse_program_set(die, false);
+ return 0;
+}
+
+static int mvebu_efuse_hd_read_line(const struct mvebu_efuse_die __iomem *die,
+ u8 line, struct mvebu_efuse_hd_line *hdl)
+{
+ if (line >= ARRAY_SIZE(die->hd.line))
+ return -ERANGE;
+
+ hdl->array[0] = readl(&die->hd.line[line].array[0]);
+ hdl->array[1] = readl(&die->hd.line[line].array[1]);
+ hdl->array[1] &= ~MVEBU_EFUSE_HD_ECC_MASK;
+ hdl->lock = readl(&die->hd.line[line].lock);
+ return 0;
+}
+
+static int mvebu_efuse_hd_write_line(const struct mvebu_efuse_die __iomem *die,
+ u8 line, const struct mvebu_efuse_hd_line *hdl)
+{
+ if (line >= ARRAY_SIZE(die->hd.line))
+ return -ERANGE;
+
+ if (hdl->array[1] & MVEBU_EFUSE_HD_ECC_MASK)
+ return -EINVAL;
+
+ mvebu_efuse_program_set(die, true);
+
+ writel(hdl->array[0], &die->hd.line[line].array[0]);
+ writel(hdl->array[1], &die->hd.line[line].array[1]);
+ writel(0, &die->hd.line[line].lock);
+ mdelay(1);
+
+ mvebu_efuse_program_set(die, false);
+ return 0;
+}
+
+
+/*
+ * Commandline interface
+ */
+
+static int mvefuse_die(const char *diestr,
+ const struct mvebu_efuse_die __iomem **diep)
+{
+ if (!strcmp(diestr, "ap")) {
+ *diep = mvebu_efuse_dies[0];
+ } else if (!strcmp(diestr, "cp0")) {
+ *diep = mvebu_efuse_dies[1];
+ } else {
+ printf("\"%s\" is not a valid die\n", diestr);
+ return CMD_RET_USAGE;
+ }
+
+ return 0;
+}
+
+static int mvefuse_mod(const char *fuse, enum mvebu_efuse_mod *modp)
+{
+ if (!strcmp(fuse, "ld0")) {
+ *modp = MVEBU_EFUSE_MOD_LD0;
+ } else if (!strcmp(fuse, "ld1")) {
+ *modp = MVEBU_EFUSE_MOD_LD1;
+ } else if (!strncmp(fuse, "hd", 2)) {
+ *modp = MVEBU_EFUSE_MOD_HD;
+ } else {
+ printf("\"%s\" is not a valid fuse\n", fuse);
+ return CMD_RET_USAGE;
+ }
+
+ return 0;
+}
+
+#define MVEFUSE_LINE_ALL 0xff
+
+static int mvefuse_line(const char *fuse, u8 *linep)
+{
+ unsigned long line;
+
+ if (!strcmp(fuse, "hd")) {
+ *linep = MVEFUSE_LINE_ALL;
+ return 0;
+ }
+
+ line = simple_strtoul(&fuse[2], NULL, 0);
+ if (line >= MVEBU_EFUSE_HD_LINES) {
+ printf("\"%s\" is not valid HD fuse\n", fuse);
+ return CMD_RET_USAGE;
+ }
+
+ *linep = line;
+ return 0;
+}
+
+static int mvefuse_parse(char * const *argv,
+ const struct mvebu_efuse_die __iomem **diep,
+ enum mvebu_efuse_mod *modp,
+ u8 *linep)
+{
+ int err;
+
+ err = mvefuse_die(argv[0], diep);
+ if (err)
+ return err;
+
+ err = mvefuse_mod(argv[1], modp);
+ if (err)
+ return err;
+
+ if (*modp != MVEBU_EFUSE_MOD_HD)
+ return 0;
+
+ return mvefuse_line(argv[1], linep);
+}
+
+static int do_mvefuse_md_ld(const struct mvebu_efuse_die __iomem *die,
+ bool ld1)
+{
+ struct mvebu_efuse_ld ld;
+
+ mvebu_efuse_ld_read(die, ld1, &ld);
+
+ print_hex_dump("", DUMP_PREFIX_OFFSET, 16, 4,
+ ld.array, sizeof(ld.array), false);
+ return 0;
+}
+
+static int do_mvefuse_md_hd_line(const struct mvebu_efuse_die __iomem *die,
+ u8 line)
+{
+ struct mvebu_efuse_hd_line hdl;
+ int err;
+
+ err = mvebu_efuse_hd_read_line(die, line, &hdl);
+ if (err) {
+ printf("Unable to read HD line %u: %d\n", line, err);
+ return CMD_RET_FAILURE;
+ }
+
+ printf("%08x %08x %s\n", hdl.array[0], hdl.array[1],
+ hdl.lock ? "[LOCKED]" : "");
+ return 0;
+}
+
+static int do_mvefuse_md_hd_all(const struct mvebu_efuse_die __iomem *die)
+{
+ u8 line;
+ int err;
+
+ for (line = 0; line < MVEBU_EFUSE_HD_LINES; line++) {
+ printf("Line %02u: ", line);
+ err = do_mvefuse_md_hd_line(die, line);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+static int do_mvefuse_md(struct cmd_tbl *cmdtp, int flag,
+ int argc, char *const *argv)
+{
+ const struct mvebu_efuse_die __iomem *die;
+ enum mvebu_efuse_mod mod;
+ u8 line;
+ int err;
+
+ if (argc < 3)
+ return CMD_RET_USAGE;
+
+ err = mvefuse_parse(&argv[1], &die, &mod, &line);
+ if (err)
+ return err;
+
+ switch (mod) {
+ case MVEBU_EFUSE_MOD_LD0:
+ return do_mvefuse_md_ld(die, false);
+ case MVEBU_EFUSE_MOD_LD1:
+ return do_mvefuse_md_ld(die, true);
+ case MVEBU_EFUSE_MOD_HD:
+ if (line == MVEFUSE_LINE_ALL)
+ return do_mvefuse_md_hd_all(die);
+ else
+ return do_mvefuse_md_hd_line(die, line);
+ }
+
+ return CMD_RET_FAILURE;
+}
+
+static int do_mvefuse_mw_ld(const struct mvebu_efuse_die __iomem *die,
+ bool ld1, int argc, char *const *argv,
+ bool interactive)
+{
+ struct mvebu_efuse_ld ld;
+ bool secure = false;
+ size_t i;
+ int err;
+
+ mvebu_efuse_ld_read(die, ld1, &ld);
+
+ switch (argc) {
+ case 9:
+ if (!strcmp(argv[8], "lock"))
+ secure = true;
+ else
+ return CMD_RET_USAGE;
+
+ /* fallthrough */
+ case 8:
+ for (i = 0; i < ARRAY_SIZE(ld.array); i++)
+ ld.array[i] |= hextoul(argv[i], NULL);
+
+ break;
+
+ default:
+ return CMD_RET_USAGE;
+ }
+
+ if (interactive) {
+ printf("The following values will be written%s into %s:\n",
+ secure ? ", and PERMANENTLY LOCKED," : "",
+ ld1 ? "LD1" : "LD0");
+
+ print_hex_dump("", DUMP_PREFIX_OFFSET, 16, 4,
+ ld.array, sizeof(ld.array), false);
+
+ puts("WARNING: This operation is irreversible\n"
+ "Are you sure you want to continue? (y/N)\n");
+
+ if (!confirm_yesno()) {
+ puts("Programming aborted\n");
+ return CMD_RET_FAILURE;
+ }
+ }
+
+ err = mvebu_efuse_ld_write(die, ld1, secure, &ld);
+ if (err) {
+ printf("Failed to program %s: %d\n", ld1 ? "LD1" : "LD0", err);
+ return CMD_RET_FAILURE;
+ }
+
+ return 0;
+}
+
+static int do_mvefuse_mw_hd_line(const struct mvebu_efuse_die __iomem *die,
+ u8 line, int argc, char *const *argv,
+ bool interactive)
+{
+ struct mvebu_efuse_hd_line hdl;
+ int err;
+
+ mvebu_efuse_hd_read_line(die, line, &hdl);
+ if (hdl.lock) {
+ printf("Unable to program LOCKED line HD%u\n", line);
+ return CMD_RET_FAILURE;
+ }
+
+ switch (argc) {
+ case 3:
+ /* In contrast to the LD fuse array, HD fuse lines are
+ * always locked when programmed, make sure the user
+ * is aware of this by requiring the "lock" keyword to
+ * be specified. */
+ if (strcmp(argv[2], "lock"))
+ return CMD_RET_USAGE;
+
+ hdl.array[0] |= hextoul(argv[0], NULL);
+ hdl.array[1] |= hextoul(argv[1], NULL);
+ break;
+
+ default:
+ return CMD_RET_USAGE;
+ }
+
+ if (interactive) {
+ printf("The following values will be PERMANENTLY written into HD%u:\n",
+ line);
+
+ printf("%08x %08x\n", hdl.array[0], hdl.array[1]);
+
+ puts("WARNING: This operation is irreversible\n"
+ "Are you sure you want to continue? (y/N)\n");
+
+ if (!confirm_yesno()) {
+ puts("Programming aborted\n");
+ return CMD_RET_FAILURE;
+ }
+ }
+
+ err = mvebu_efuse_hd_write_line(die, line, &hdl);
+ if (err) {
+ printf("Failed to program HD%u: %d\n", line, err);
+ return CMD_RET_FAILURE;
+ }
+
+ return 0;
+}
+
+static int do_mvefuse_mw(struct cmd_tbl *cmdtp, int flag,
+ int argc, char *const *argv)
+{
+ const struct mvebu_efuse_die __iomem *die;
+ enum mvebu_efuse_mod mod;
+ bool interactive = true;
+ u8 line;
+ int err;
+
+ /* Pop off "md" */
+ argv++, argc--;
+
+ if (argc && (!strcmp("-y", argv[0]))) {
+ interactive = false;
+ argv++, argc--;
+ }
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ err = mvefuse_parse(argv, &die, &mod, &line);
+ if (err)
+ return err;
+
+ /* Pop off <die> and <fuse> */
+ argv++, argc--;
+ argv++, argc--;
+
+ switch (mod) {
+ case MVEBU_EFUSE_MOD_LD0:
+ return do_mvefuse_mw_ld(die, false, argc, argv, interactive);
+ case MVEBU_EFUSE_MOD_LD1:
+ return do_mvefuse_mw_ld(die, true, argc, argv, interactive);
+ case MVEBU_EFUSE_MOD_HD:
+ if (line == MVEFUSE_LINE_ALL)
+ return CMD_RET_USAGE;
+ else
+ return do_mvefuse_mw_hd_line(die, line, argc, argv, interactive);
+ }
+
+ return CMD_RET_FAILURE;
+}
+
+static int do_mvefuse_unlocked(struct cmd_tbl *cmdtp, int flag,
+ int argc, char *const argv[])
+{
+ const struct mvebu_efuse_die __iomem *die;
+ struct mvebu_efuse_hd_line hdl;
+ enum mvebu_efuse_mod mod;
+ u8 line;
+ int err;
+
+ if (argc != 3)
+ return CMD_RET_USAGE;
+
+ err = mvefuse_parse(&argv[1], &die, &mod, &line);
+ if (err)
+ return err;
+
+ if (mod != MVEBU_EFUSE_MOD_HD) {
+ printf("Only HD fuse lines have individual lock bits\n");
+ return CMD_RET_FAILURE;
+ }
+
+ if (line == MVEFUSE_LINE_ALL) {
+ printf("Only an individual fuse line can be tested\n");
+ return CMD_RET_FAILURE;
+ }
+
+ err = mvebu_efuse_hd_read_line(die, line, &hdl);
+ if (err) {
+ printf("Unable to read HD%u: %d\n", line, err);
+ return CMD_RET_FAILURE;
+ }
+
+ return !!hdl.lock;
+}
+
+U_BOOT_CMD_WITH_SUBCMDS(
+ mvefuse, "Marvell eFuse Access",
+ "md <die> <fuse> - Dump the contents of <fuse> from <die>\n"
+ "mvefuse mw [-y] <die> <fuse> <words...> [lock] - Program <words..> into\n"
+ " <fuse> in <die>, optionally permanently locking it\n"
+ "mvefuse unlocked <die> hd<0-63> - Test if an HD fuse line on <die> is \n"
+ " unlocked\n"
+ "\n"
+ "<die>: ap|cp0\n"
+ "<fuse>: ld0|ld1|hd<0-63>\n",
+
+ U_BOOT_SUBCMD_MKENT(md, 3, 1, do_mvefuse_md),
+ U_BOOT_SUBCMD_MKENT(mw, 12, 1, do_mvefuse_mw),
+ U_BOOT_SUBCMD_MKENT(unlocked, 3, 1, do_mvefuse_unlocked));
--
2.34.1
-13
View File
@@ -1,13 +0,0 @@
Index: uboot-2023.07.02/arch/arm/dts/cn9130-crb.dtsi
===================================================================
--- uboot-2023.07.02.orig/arch/arm/dts/cn9130-crb.dtsi
+++ uboot-2023.07.02/arch/arm/dts/cn9130-crb.dtsi
@@ -239,7 +239,7 @@
&cp0_eth0 {
status = "okay";
- phy-mode = "sfi";
+ phy-mode = "10gbase-r";
};
&cp0_eth1 {
+2 -2
View File
@@ -1,5 +1,5 @@
SUBDIRS = src yang
SUBDIRS = bin share src yang
dist_doc_DATA = README.md LICENSE
pkglibexec_SCRIPTS = confd-bootstrap.sh
dist_sysconf_DATA = confdrc
DISTCLEANFILES = *~ *.d
ACLOCAL_AMFLAGS = -I m4
+37
View File
@@ -0,0 +1,37 @@
# Defaults for testing bootstrap script -*-conf-*-
#set -x
TESTING=true
PATH=.:$PATH
INIT_DATA=/etc/sysrepo/factory-default.json
SEARCH=/usr/share/yang/modules/confd:/usr/share/yang/modules/libnetconf2:/usr/share/yang/modules/libyang:/usr/share/yang/modules/netopeer2:/usr/share/yang/modules/sysrepo
CFG_PATH_=/tmp/confd/cfg
RUN_PATH_=/tmp/confd/run
FACTORY_DEFAULTS_D=../share/factory.d
FAILURE_DEFAULTS_D=../share/failure.d
FACTORY_D=$RUN_PATH_/factory.d
FAILURE_D=$RUN_PATH_/failure.d
FACTORY_GEN=$RUN_PATH_/factory-config.gen
FAILURE_GEN=$RUN_PATH_/failure-config.gen
FACTORY_CFG=$RUN_PATH_/factory-config.cfg
FAILURE_CFG=$RUN_PATH_/failure-config.cfg
STARTUP_CFG=$CFG_PATH_/startup-config.cfg
# Uncomment this line in to create a bridge (br0) with all (classified
# 'group port') interfaces as bridge ports. The br0 interface will get
# an IPv6 EUI64 SLAAC address as well as an IPv4 ZeroConf address, and a
# DHCPv4 address if the device is attached to a LAN with a DHCP server.
#GEN_IFACE_OPTS="-b -4 -d"
# Default hostname in Fail Secure mode, plus last three octets in the base
# MAC address, e.g. "failed-c0-ff-ee".
FAIL_HOSTNAME="failed"
# Only needed for testing
mkdir -p "$CFG_PATH_" "$RUN_PATH_" "$FACTORY_D" "$FAILURE_D"
+2
View File
@@ -0,0 +1,2 @@
pkglibexec_SCRIPTS = bootstrap error load \
gen-hostkeys gen-hostname gen-interfaces
+193
View File
@@ -0,0 +1,193 @@
#!/bin/sh
# Bootstrap system factory-config, failure-config and sysrepo db.
#
# The system factory-config and failure-config are derived from default
# settings snippets, from /usr/share/confd/factory.d, and some generated
# snippets, e.g., device unique password, hostname (based on base MAC
# address), and number of interfaces.
#
# The resulting factory-config is used to create the syrepo db (below)
# {factory} datastore. Hence, the factory-config file must match the
# the YANG models of the active image.
#
# /etc/confdrc controls the behavior or most of the gen-scripts,
# customize in an overlay when using Infix as an br2-external.
RC=/etc/confdrc
if [ "$1" = "-f" ] && [ -f "$2" ]; then
RC=$2
fi
if [ ! -f "$RC" ]; then
logger -sik -p user.error -t bootstrap "Missing rc file $RC" 2>/dev/null \
|| echo "Missing rc file $RC"
exit 99
fi
# shellcheck disable=SC1090
. "$RC"
# shellcheck disable=SC2046,SC2086
collate()
{
gen=$1; shift
cfg=$1; shift
dir=$*
rm -f "$gen"
jq -s 'reduce .[] as $item ({}; . * $item)' $(find $dir -name '*.json' | sort) >"$gen"
chmod 444 "$gen"
if [ ! -f "$cfg" ]; then
cp "$gen" "$cfg"
fi
}
# TODO: Look for statically defined factory-config, based on the
# system's product ID, or just custom site-specific factory.
#
# If we haven't found a more specific, better match, settle for
# factory-config.gen as the system's factory-config.
factory()
{
gen=$1
# Create an overlay for /etc/hostname to change the default in an br2-external
gen-hostname >"$FACTORY_D/20-hostname.json"
# shellcheck disable=SC2086
gen-interfaces $GEN_IFACE_OPTS >"$FACTORY_D/20-interfaces.json"
[ -s "$FACTORY_D/20-hostkey.json" ] || gen-hostkeys >"$FACTORY_D/20-hostkey.json"
# Optional commands (from an overlay) to run for br2-externals
[ -x "$(command -v gen-ifs-custom)" ] && gen-ifs-custom >"$FACTORY_D/20-interfaces.json"
[ -x "$(command -v gen-cfg-custom)" ] && gen-cfg-custom >"$FACTORY_D/30-config.json"
rm -f "$FACTORY_GEN"
# shellcheck disable=SC2046
jq -s 'reduce .[] as $item ({}; . * $item)' \
$(find "$FACTORY_DEFAULTS_D" "$FACTORY_D" -name '*.json' | sort) \
>"$FACTORY_GEN"
chmod 444 "$FACTORY_GEN"
collate "$FACTORY_GEN" "$FACTORY_CFG" "$FACTORY_DEFAULTS_D" "$FACTORY_D"
}
failure()
{
gen=$1
gen-hostname "$FAIL_HOSTNAME" >"$FAILURE_D/20-hostname.json"
gen-interfaces >"$FAILURE_D/20-interfaces.json"
[ -s "$FAILURE_D/20-hostkey.json" ] || gen-hostkeys >"$FAILURE_D/20-hostkey.json"
# Optional failure/error config to generate (or override) for br2-externals
[ -x "$(command -v gen-err-custom)" ] && gen-err-custom >"$FAILURE_D/30-error.json"
collate "$FAILURE_GEN" "$FAILURE_CFG" "$FAILURE_DEFAULTS_D" "$FAILURE_D"
}
factory "$FACTORY_GEN"
failure "$FAILURE_GEN"
if [ -n "$TESTING" ]; then
echo "Done."
exit 0
fi
# Drop all pre-initialized data from netopeer2 install, then re-create
# with required netopeer2 models, sysrepo implicitly installs its own,
# and then we initialize it all with our factory defaults.
rm -rf /etc/sysrepo/* /dev/shm/sr_*
mkdir -p /etc/sysrepo/
cp "$FACTORY_CFG" "$INIT_DATA"
sysrepoctl -s $SEARCH \
-i ietf-system@2014-08-06.yang -g wheel -p 0660 \
-e authentication \
-e local-users \
-e ntp \
-e ntp-udp-port \
-e timezone-name \
-i iana-timezones@2013-11-19.yang -g wheel -p 0660 \
-i nc-notifications@2008-07-14.yang -g wheel -p 0660 \
-i notifications@2008-07-14.yang -g wheel -p 0660 \
-i ietf-keystore@2019-07-02.yang -g wheel -p 0660 \
-e keystore-supported \
-e local-definitions-supported \
-e key-generation \
-i ietf-truststore@2019-07-02.yang -g wheel -p 0660 \
-e truststore-supported \
-e x509-certificates \
-i ietf-tcp-common@2019-07-02.yang -g wheel -p 0660 \
-e keepalives-supported \
-i ietf-ssh-server@2019-07-02.yang -g wheel -p 0660 \
-e local-client-auth-supported \
-i ietf-tls-server@2019-07-02.yang -g wheel -p 0660 \
-e local-client-auth-supported \
-i ietf-netconf-server@2019-07-02.yang -g wheel -p 0660 \
-e ssh-listen \
-e tls-listen \
-e ssh-call-home \
-e tls-call-home \
-i ietf-interfaces@2018-02-20.yang -g wheel -p 0660 \
-e if-mib \
-i ietf-ip@2018-02-22.yang -g wheel -p 0660 \
-e ipv6-privacy-autoconf \
-i ietf-network-instance@2019-01-21.yang -g wheel -p 0660 \
-i ietf-netconf-monitoring@2010-10-04.yang -g wheel -p 0660 \
-i ietf-netconf-nmda@2019-01-07.yang -g wheel -p 0660 \
-e origin \
-e with-defaults \
-i ietf-subscribed-notifications@2019-09-09.yang \
-g wheel -p 0660 \
-e encode-xml \
-e replay \
-e subtree \
-e xpath \
-i ietf-yang-push@2019-09-09.yang -g wheel -p 0660 \
-e on-change \
-i iana-if-type@2023-01-26.yang -g wheel -p 0660 \
-i ieee802-dot1q-types@2022-10-29.yang -g wheel -p 0660 \
-i infix-ip@2023-09-14.yang -g wheel -p 0660 \
-i infix-if-type@2023-08-21.yang -g wheel -p 0660 \
-i infix-interfaces@2023-09-19.yang -g wheel -p 0660 \
-e vlan-filtering \
-i ieee802-dot1ab-lldp@2022-03-15.yang -g wheel -p 0660 \
-i infix-lldp@2023-08-23.yang -g wheel -p 0660 \
-i infix-dhcp-client@2023-05-22.yang -g wheel -p 0660 \
-i infix-shell-type@2023-08-21.yang -g wheel -p 0660 \
-i infix-system@2023-10-19.yang -g wheel -p 0660 \
-i infix-services@2023-10-16.yang -g wheel -p 0660 \
-i ieee802-ethernet-interface@2019-06-21.yang -g wheel -p 0660 \
-I "${INIT_DATA}"
rc=$?
# Unlike `sysrepoctl -i` the `-c` command requires separate invocations.
# NOTE: we ignore any errors from these at bootstrap since sysrepo may
# already enable some of these feature, resulting in error here.
# Enable features required by netopeer2
sysrepoctl -c ietf-netconf -g wheel -p 0660 \
-e writable-running \
-e candidate \
-e rollback-on-error \
-e validate \
-e startup \
-e url \
-e xpath \
-e confirmed-commit
# Allow wheel group users (admin) to modify NACM
sysrepoctl -c ietf-netconf-acm -g wheel -p 0660
# On first boot, install factory-config as startup-config. Due to a
# limitation in sysrepo we cannot initialize ietf-netconf-acm, so we
# cheat, see sysrepo#3079
if [ ! -f "$STARTUP_CFG" ]; then
sysrepocfg -f json -X"$STARTUP_CFG"
fi
# Clear running-config so we can load startup in the next step
echo "{}" > "$INIT_DATA"
sysrepocfg -f json -I"$INIT_DATA" -d running
exit $rc
+5
View File
@@ -0,0 +1,5 @@
#!/bin/sh
# Override using an overlay in your br2-external to change the behavior
logger -sik -p user.error "The device has reached an unrecoverable error, please RMA."
exec sleep infinity
+161
View File
@@ -0,0 +1,161 @@
#!/bin/sh
# Generates ietf-intefaces + ietf-ip settings for all detected interfaces
# Interfaces must be of type Ethernet (copper/sfp), not be "internal" DSA
# ports, and must have a "parentbus", i.e., be physical ports.
#
# Usage: gen-interfaces [-4bd]
#
# -b brN Bridged mode, set all interfaces as ports in brN
# -4 Generic option for both modes, enables ZeroConf IPv4
# -d Generic option for both modes, enables DHCPv4 client
#
# By default this script generates plain interfaces with IPv6 autoconfig
# (EUI64) enabled. Useful both in a plain router and a Fail Secure mode
# where any switchcore-backed ports should be prevented from switching.
#
# The default mode currently does not support the '-4' or '-d' options
# for IPv4 ZeroConf or DHCPv4 address, beacause they require source
# routing, or similar, to work. IPv6 does not require that and is
# therefore the recommended access method. A separate (and optional)
# 'gen-cfg-custom' script is checked for in the bootstrap script which
# can be used to enable IPv4 and DHCP on a single service interface if
# needed.
#
# The '-b brname' option triggers the bridge mode, creating a 'brname'
# bridge interface using all interfaces classified in 'group port' by
# the nameif script. In the bridge mode port interfaces do not have any
# IP address, the IPv6 autoconfig address is instead set on 'brN'. If
# the '-4' option is set, ZeroConfig (169.254.x.y) is anabled on 'brN'.
# If the '-d' option is set, a DHCPv4 client is enabled on 'brN'.
#
# A "mixed mode" is also supported, where the system may have multiple
# ports in a switchcore, but some Ethernet interfaces directly connected
# to the SoC. In this case, if '-b brname' is given, all 'group port'
# interfaces will be placed in the bridge 'brname' and all other
# interfaces will be brought up and given an IPv6 address (like above).
#
set -e
bridge=
ipv4=false
dhcp=
gen_interface()
{
cat <<EOF
,{
"name": "$1",
"type": "infix-if-type:ethernet",
"ietf-ip:ipv6": {
"enabled": $2
EOF
if [ -n "$3" ]; then
cat <<EOF
},
"infix-interfaces:bridge-port": {
"bridge": "$3"
EOF
fi
cat <<EOF
}
}
EOF
}
while [ "$1" != "" ]; do
case $1 in
-4)
ipv4=true
;;
-b)
bridge="$2"
shift
;;
-d)
dhcp=true
;;
*)
break
esac
shift
done
phys_ifaces=$(ip -d -j link show | jq -r '
.[] |
select(.link_type == "ether") |
select(.group != "internal") |
select(has("parentbus")) |
.ifname' | sort -V)
ports=$(ip -d -j link show group port | jq -r '
.[] |
select(.link_type == "ether") |
select(.group != "internal") |
select(has("parentbus")) |
.ifname' | sort -V)
ifaces=""
for phy in $phys_ifaces; do
found=""
for port in $ports; do
if [ $port = $phy ]; then
found=true
break
fi
done
if [ -z "$found" ]; then
ifaces="$ifaces $phy"
fi
done
cat <<EOF
{
"ietf-interfaces:interfaces": {
"interface": [
{
"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 }]
}
EOF
if [ -n "$bridge" ]; then
cat <<EOF
},
{
"name": "$bridge",
"type": "infix-if-type:bridge",
"ietf-ip:ipv4": {
"infix-ip:autoconf": {
"enabled": $ipv4
}
},
"ietf-ip:ipv6": {
"enabled": true
}
EOF
fi
cat <<EOF
}
$(for iface in $ifaces; do gen_interface $iface true; done)
$(for iface in $ports; do gen_interface $iface false $bridge; done)
]
EOF
if [ "$dhcp" = "true" ] && [ -n "$bridge" ]; then
cat <<EOF
},
"infix-dhcp-client:dhcp-client": {
"enabled": true,
"client-if": [
{
"if-name": "$bridge"
}
]
EOF
fi
cat <<EOF
}
}
EOF
+44
View File
@@ -0,0 +1,44 @@
#!/bin/sh
# load [-b] <startup-config | failure-config>
#
# Import a configuration to the sysrepo datastore using `sysrepocfg -Ifile`
#
# If the '-b' option is used we set the Finit <usr/bootstrap> condition if
# sysrepocfg returns OK. This to be able to detect and trigger the Infix
# Fail Secure Mode at boot.
#
set -e
if [ "$1" = "-b" ]; then
bootstrap=true
shift
else
bootstrap=false
fi
config=$1
if [ -f "$config" ]; then
fn="$config"
else
if [ -f "/cfg/${config}.cfg" ]; then
fn="/cfg/${config}.cfg"
else
fn="/run/confd/${config}.cfg"
fi
fi
if [ ! -f "$fn" ]; then
logger -sik -p user.error "No such file, $fn, aborting!"
exit 1
fi
if ! sysrepocfg -v3 -I"$fn" -f json; then
if eval $bootstrap; then
logger -sik -p user.error "Failed bootstrapping system, reverting to Fail Secure mode!"
initctl -nbq runlevel 9
else
logger -sik -p user.error "Failed loading $fn, aborting!"
fi
exit 1
fi
logger -sik -p user.notice "Loaded $fn successfully."
-122
View File
@@ -1,122 +0,0 @@
#!/bin/sh
# 1. Load all yang models with /cfg/factory-config
# 2. [ if /cfg/startup-config is missing :: copy {factory} -> /cfg/startup-config ]
# 3. Import /cfg/startup -> {startup} ]
# 4. Clear running-config :: import NULL -> {running}
# 5. Start sysrepo-plugind
# 6. Activate startup-config by :: copy {startup} -> {running}
#
# It's all really simple ... this script takes care of 1-4
#
FACTORY=$1
STARTUP=$2
INIT_DATA=/etc/sysrepo/factory-default.json
SEARCH=/usr/share/yang/modules/confd:/usr/share/yang/modules/libnetconf2:/usr/share/yang/modules/libyang:/usr/share/yang/modules/netopeer2:/usr/share/yang/modules/sysrepo
if [ -z "$FACTORY" -o -z "$STARTUP" ]; then
echo "Missing argument to sysrepo-bootstrap.sh $FACTORY $STARTUP"
exit 1
fi
# Drop all pre-initialized data from netopeer2 install, then re-create
# with required netopeer2 models, sysrepo implicitly installs its own,
# and then we initialize it all with our factory defaults.
rm -rf /etc/sysrepo/* /dev/shm/sr_*
mkdir -p /etc/sysrepo/
cp "$FACTORY" "$INIT_DATA"
sysrepoctl -s $SEARCH \
-i ietf-system@2014-08-06.yang -g wheel -p 0660 \
-e authentication \
-e local-users \
-e ntp \
-e ntp-udp-port \
-e timezone-name \
-i iana-timezones@2013-11-19.yang -g wheel -p 0660 \
-i nc-notifications@2008-07-14.yang -g wheel -p 0660 \
-i notifications@2008-07-14.yang -g wheel -p 0660 \
-i ietf-keystore@2019-07-02.yang -g wheel -p 0660 \
-e keystore-supported \
-e local-definitions-supported \
-e key-generation \
-i ietf-truststore@2019-07-02.yang -g wheel -p 0660 \
-e truststore-supported \
-e x509-certificates \
-i ietf-tcp-common@2019-07-02.yang -g wheel -p 0660 \
-e keepalives-supported \
-i ietf-ssh-server@2019-07-02.yang -g wheel -p 0660 \
-e local-client-auth-supported \
-i ietf-tls-server@2019-07-02.yang -g wheel -p 0660 \
-e local-client-auth-supported \
-i ietf-netconf-server@2019-07-02.yang -g wheel -p 0660 \
-e ssh-listen \
-e tls-listen \
-e ssh-call-home \
-e tls-call-home \
-i ietf-interfaces@2018-02-20.yang -g wheel -p 0660 \
-e if-mib \
-i ietf-ip@2018-02-22.yang -g wheel -p 0660 \
-e ipv6-privacy-autoconf \
-i ietf-network-instance@2019-01-21.yang -g wheel -p 0660 \
-i ietf-netconf-monitoring@2010-10-04.yang -g wheel -p 0660 \
-i ietf-netconf-nmda@2019-01-07.yang -g wheel -p 0660 \
-e origin \
-e with-defaults \
-i ietf-subscribed-notifications@2019-09-09.yang \
-g wheel -p 0660 \
-e encode-xml \
-e replay \
-e subtree \
-e xpath \
-i ietf-yang-push@2019-09-09.yang -g wheel -p 0660 \
-e on-change \
-i iana-if-type@2023-01-26.yang -g wheel -p 0660 \
-i ietf-if-extensions@2023-01-26.yang -g wheel -p 0660 \
-e sub-interfaces \
-i ieee802-dot1q-types@2022-10-29.yang -g wheel -p 0660 \
-i ietf-if-vlan-encapsulation@2023-01-26.yang \
-g wheel -p 0660 \
-i infix-ip@2023-09-14.yang -g wheel -p 0660 \
-i infix-if-type@2023-08-21.yang -g wheel -p 0660 \
-i infix-interfaces@2023-09-19.yang -g wheel -p 0660 \
-e vlan-filtering \
-i ieee802-dot1ab-lldp@2022-03-15.yang -g wheel -p 0660 \
-i infix-lldp@2023-08-23.yang -g wheel -p 0660 \
-i infix-dhcp-client@2023-05-22.yang -g wheel -p 0660 \
-i infix-shell-type@2023-08-21.yang -g wheel -p 0660 \
-i infix-system@2023-08-15.yang -g wheel -p 0660 \
-i infix-services@2023-08-22.yang -g wheel -p 0660 \
-I "${INIT_DATA}"
rc=$?
# Unlike `sysrepoctl -i` the `-c` command requires separate invocations.
# NOTE: we ignore any errors from these at bootstrap since sysrepo may
# already enable some of these feature, resulting in error here.
# Enable features required by netopeer2
sysrepoctl -c ietf-netconf -g wheel -p 0660 \
-e writable-running \
-e candidate \
-e rollback-on-error \
-e validate \
-e startup \
-e url \
-e xpath \
-e confirmed-commit
# Allow wheel group users (admin) to modify NACM
sysrepoctl -c ietf-netconf-acm -g wheel -p 0660
# On first boot, install factory-config as startup-config
# Otherwise, load startup-config to {startup}. Due to a
# limitation in sysrepo we cannot initialize factory for
# ietf-netconf-acm, so we cheat, see sysrepo#3079
if [ -f "$STARTUP" ]; then
sysrepocfg -f json -I"$STARTUP"
else
sysrepocfg -f json -X"$STARTUP"
fi
# Clear running-config
echo "{}" > "$INIT_DATA"
sysrepocfg -f json -I"$INIT_DATA" -d running
exit $rc
+37
View File
@@ -0,0 +1,37 @@
# Defaults for /usr/libexec/confd/bootstrap -*-conf-*-
# Copy and mofify this file to your br2-external overlay
PATH=/usr/libexec/confd/:$PATH
INIT_DATA=/etc/sysrepo/factory-default.json
SEARCH=/usr/share/yang/modules/confd:/usr/share/yang/modules/libnetconf2:/usr/share/yang/modules/libyang:/usr/share/yang/modules/netopeer2:/usr/share/yang/modules/sysrepo
CFG_PATH_=/cfg
RUN_PATH_=/run/confd
# Static defaults, base Infix and any br2-external derivative.
FACTORY_DEFAULTS_D=/usr/share/confd/factory.d
FAILURE_DEFAULTS_D=/usr/share/confd/failure.d
# Generated config snippets, e.g., hostname, password, and interfaces.
FACTORY_D=$RUN_PATH_/factory.d
FAILURE_D=$RUN_PATH_/failure.d
# The default config snippets and generated snippets are collated into
# RAM-only name-config.gen , which are candidates for name-config.cfg
FACTORY_GEN=$RUN_PATH_/factory-config.gen
FAILURE_GEN=$RUN_PATH_/failure-config.gen
# The resulting .cfg files can be peristent (factory-config) or not.
FACTORY_CFG=$RUN_PATH_/factory-config.cfg
FAILURE_CFG=$RUN_PATH_/failure-config.cfg
STARTUP_CFG=$CFG_PATH_/startup-config.cfg
# Uncomment this line in to create a bridge (br0) with all (classified
# 'group port') interfaces as bridge ports. The br0 interface will get
# an IPv6 EUI64 SLAAC address as well as an IPv4 ZeroConf address, and a
# DHCPv4 address if the device is attached to a LAN with a DHCP server.
#GEN_IFACE_OPTS="-b br0 -4 -d"
# Default hostname in Fail Secure mode, plus last three octets in the base
# MAC address, e.g. "failed-c0-ff-ee".
FAIL_HOSTNAME="failed"

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