Board Configuration
The board configuration is the most important part of the board-tailoring, and it works as a data structure containing all the tailoring data which can be supplied by the customers of Microchip (here customer is the one designing a board - not the end user).
The board configuration itself is guarded by a YANG schema file which describes all the fields which can be configured and encoded as CBOR as defined by RFC9254.
The board.yang is different from all the other YANG modules in the system as it is not exposed over CORECONF, and completely invisible to the end-user. The board-yang data belong to the firmware image and are signed along with that image, and therefore being considered as part of the firmware. |
CBOR is a compact and machine-friendly encoding, but not very human-friendly, and for this reason, the actual board configurations are written in YAML format, and then converted to CBOR. The build system takes care of doing that.
When reading this material, one should have the board.tree and board.yang files open, and reference them.
The high-level structure of the board.tree looks like this:
module: board +--rw drivers <container> | ... +--rw capabilities <container> | ... +--rw factory_default_config? <anydata> | ... +--rw extmod <container> | ...
A basic and empty board configuration YAML template can look like this:
board:drivers:
board:capabilities:
board:factory_default_config:
The following section will go into detail with each of the major sections
1. Drivers
1.1. SGPIO Banks
SGPIOs (Serial GPIOs) are used for communication with devices on the board such as SFP modules and LEDs. Up to 32 SGPIO ports can be enabled, with each port consisting of 1-4 bits. This configuration results in a serial data stream comprising 'ports * bits' number of GPIOs. The definition looks like this:
module: board
+--rw drivers
+--rw sgpio_banks
+--rw sgpio_bank* [sgpio_bank]
+--rw sgpio_bank dev_sgpio_bank
+--rw bit_count uint32
+--rw port_mask uint32
+--rw clock_div? uint32
+--rw pin_ctrl
+--rw pins* uint32
+--rw pin_function pin_function
-
sgpio_bank
is used to select which physical instance in hardware to configure; typically, 1-3 instances are available. -
bit_count
is the number of GPIOs (or bits) that are enabled per SGPIO port, with 1-4 bits available. -
port_mask
defines the SGPIO ports that get enabled. Some signals (e.g., SFP LOS) are mapped directly to the chip device with the same number as the SGPIO port in this mask. -
clock_div
maps directly into the hardware where the SGPIO frequency is set. The resulting frequency is the system clock divided by this value. -
pin_ctrl
is used to assign physical pins on the SoC to this function. Check the datasheet for an overview of which pins can be used.
Example with SGPIO ports 0,1,24,25,26,27 enabled, with 4 bits per port:
sgpio_banks:
sgpio_bank:
- sgpio_bank: DEV_SGPIO_BANK_0
bit_count: 4
port_mask: 0x0F000003
clock_div: 65
pin_ctrl:
pins: [5, 6, 7, 8]
pin_function: alt1
1.2. FlexCom
FlexCOM is a SoC HW component capable of providing a UART, I2C, or SPI interface. The definition of the FlexCOM in the board.tree looks like this:
+--rw drivers
+--rw flexcoms
+--rw flexcom* [hw_instance]
+--rw hw_instance uint32
+--rw uart? dev_uart
+--rw i2c? dev_i2c
+--rw spi? dev_spi
+--rw pin_ctrl
+--rw pins* uint32
+--rw pin_function pin_function
Here:
-
hw_instance
is used to select which physical instance in HW to configure. Typically a SoC supports 2-5 instances, and each instance can only be configured to work with a fixed pool of pins. It is therefore important to configure the correct instance (according to the schematic). -
uart
,i2c
, andspi
are used to select the personality of the FlexCOM instance. Any givenflexcom
entry must include one and only one of them. TheDEV_xxx
value assigned to eitheruart
,i2c
, orspi
is an internal handle, used further down in the file to reference the FlexCOM instance. -
pin_ctrl
is used to assign physical pins on the SoC to this function. Check the datasheet for an overview of what pins can be used.
Following is an example where FlexCom-0 is configured as UART, and FlexCOM-3 is configured as an I2C controller:
board:drivers:
flexcoms:
flexcom:
- hw_instance: 0
uart: DEV_UART_0
pin_ctrl:
pins: [3, 4]
pin_function: alt1
- hw_instance: 3
i2c: DEV_I2C_0
pin_ctrl:
pins: [55, 56]
pin_function: alt2
1.3. Pin Group
Pin group is used to configure and manage the multiplexing of pins to allow multiple devices to share the same physical pins. The pins can be either GPIOs or SGPIOs. The typical usage is to control a mux to I2C devices. The definition looks like this:
module: board
+--rw drivers
+--rw pin_groups
+--rw pin_group* [pin_group]
+--rw pin_group dev_pin_group
+--rw sleep uint32
+--ro mux_pins* []
+--ro (ref)
| +--:(sgpio)
| | +--ro sgpio
| | +--ro ref_sgpio_bank dev_sgpio_bank
| | +--ro port uint8
| | +--ro bit uint8
| +--:(gpio)
| +--ro gpio? uint32
+--ro direction gpio_direction
+--ro active_state? active
-
pin_group
is the internal handle for others to reference when choosing a pin group. -
sleep
is the time it takes to change the mux, i.e., the driver waits this number of ms before returning and the mux is formed. -
sgpio
defines a reference to an SGPIO bank and which port/bit are used to form the group. -
gpio
has the same purpose assgpio
, just for GPIOs.
Example of a pin group formed by 3 SGPIO pins, wich can contol mux with up to 8 outputs:
pin_groups:
pin_group:
- pin_group: DEV_PIN_GROUP_0
sleep: 10
mux_pins:
- sgpio:
ref_sgpio_bank: DEV_SGPIO_BANK_0
port: 0
bit: 1
direction: GPIO_DIR_OUT
- sgpio:
ref_sgpio_bank: DEV_SGPIO_BANK_0
port: 0
bit: 2
direction: GPIO_DIR_OUT
- sgpio:
ref_sgpio_bank: DEV_SGPIO_BANK_0
port: 0
bit: 3
direction: GPIO_DIR_OUT
1.4. I2C Mux
I2C Mux is used to control a number of I2C devices (which share the same I2C bus) by enabling only one of them at a time and keeping the others disabled. Users will reference the MUX based on how it should be configured with 'DEV_MUX_x'. The definition looks like this:
module: board
+--rw drivers
+--rw i2c_muxs
+--rw i2c_mux* [i2c_mux]
+--rw i2c_mux dev_i2c_mux
+--rw ref_parent dev_i2c
+--rw ref_pin_group dev_pin_group
+--rw gpio_mask uint32
-
i2c_mux
is the internal handle for others to reference when choosing an I2C mux with a specific mux configuration. -
ref_parent
is a reference to an already defined HW I2C instance. -
ref_pin_group
is a reference to an already defined pin controller. -
gpio_mask
defines how this instance will configure the mux.
Example of an I2C MUX which uses the pin group and the I2C instance above and sets the MUX to positions 0-3.
i2c_muxs:
i2c_mux:
- i2c_mux: DEV_MUX_0
ref_parent: DEV_I2C_0
ref_pin_group: DEV_PIN_GROUP_0
gpio_mask: 0
- i2c_mux: DEV_MUX_1
ref_parent: DEV_I2C_0
ref_pin_group: DEV_PIN_GROUP_0
gpio_mask: 1
- i2c_mux: DEV_MUX_2
ref_parent: DEV_I2C_0
ref_pin_group: DEV_PIN_GROUP_0
gpio_mask: 2
- i2c_mux: DEV_MUX_3
ref_parent: DEV_I2C_0
ref_pin_group: DEV_PIN_GROUP_0
gpio_mask: 3
1.5. SFP
The SFP signals that are defined consist of the following: LOS (input), TX_FAULT (input), PRESENT (input), and TX_ENABLE (output). When inserted, 'PRESENT' goes high and the ROM is read via I2C to determine the type and thereby how to configure the switch port to match its capabilities. The definition looks like this:
module: board
+--rw drivers
+--rw sfps
+--rw sfp* [portno]
+--rw los
| +--rw (ref)
| | +--:(sgpio)
| | | +--rw sgpio
| | | +--rw ref_sgpio_bank dev_sgpio_bank
| | | +--rw port uint8
| | | +--rw bit uint8
| | +--:(gpio)
| | +--rw gpio? uint32
| +--rw direction gpio_direction
| +--rw active_state? active
+--rw tx_fault
| +--rw (ref)
| | +--:(sgpio)
| | | +--rw sgpio
| | | +--rw ref_sgpio_bank dev_sgpio_bank
| | | +--rw port uint8
| | | +--rw bit uint8
| | +--:(gpio)
| | +--rw gpio? uint32
| +--rw direction gpio_direction
| +--rw active_state? active
+--rw present
| +--rw (ref)
| | +--:(sgpio)
| | | +--rw sgpio
| | | +--rw ref_sgpio_bank dev_sgpio_bank
| | | +--rw port uint8
| | | +--rw bit uint8
| | +--:(gpio)
| | +--rw gpio? uint32
| +--rw direction gpio_direction
| +--rw active_state? active
+--rw tx_enable
| +--rw (ref)
| | +--:(sgpio)
| | | +--rw sgpio
| | | +--rw ref_sgpio_bank dev_sgpio_bank
| | | +--rw port uint8
| | | +--rw bit uint8
| | +--:(gpio)
| | +--rw gpio? uint32
| +--rw direction gpio_direction
| +--rw active_state? active
+--rw portno uint32
+--rw ref_i2c_mux? dev_i2c_mux
-
portno
defines to which switch front port (zero-based) this SFP belongs. -
los
indicates a loss of the received optical signal. -
present
indicates that a module is present. -
tx_enable
signal is used to enable the transmitter output. -
tx_fault
indicates faults in the Tx direction. -
direction
can be either input or output (output fortx_enable
, input for others). -
active_state
defines the signal’s active state. This is usually documented in schematics. -
sgpio/gpio
section defines how the signals are mapped to either SGPIO port/bit or GPIO ID. -
ref_i2c_mux
is a reference to an already defined I2C mux, which enables this SFP I2C.
Example of a single SFP implementation:
sfps:
sfp:
- portno: 24
ref_i2c_mux: DEV_MUX_0
los:
sgpio:
ref_sgpio_bank: DEV_SGPIO_BANK_0
port: 24
bit: 0
direction: GPIO_DIR_IN
active_state: high
tx_fault:
sgpio:
ref_sgpio_bank: DEV_SGPIO_BANK_0
port: 24
bit: 2
direction: GPIO_DIR_IN
active_state: high
present:
sgpio:
ref_sgpio_bank: DEV_SGPIO_BANK_0
port: 24
bit: 1
direction: GPIO_DIR_IN
active_state: low
tx_enable:
sgpio:
ref_sgpio_bank: DEV_SGPIO_BANK_0
port: 24
bit: 2
direction: GPIO_DIR_OUT
active_state: low
1.6. MDIO
The MDIO (Management Data Input/Output) is a serial bus protocol used for PHY access. There are usually 1-3 buses available on the SoC, and each PHY will reference which bus they belong to.
module: board
+--rw drivers
+--rw mdios
+--rw mdio* [miim_bus]
+--rw miim_bus miim_bus
+--rw pin_ctrl
| +--rw pins* uint32
| +--rw pin_function pin_function
+--rw frequency? uint32
-
miim_bus
is the bus ID, used for reference. -
pin_ctrl
is used to assign physical pins on the SoC to this function. Check the datasheet for an overview of what pins can be used. -
frequency
is the MIIM bus frequency in Hz. Leave out for default SoC frequency.
Example of an MDIO:
mdios:
mdio:
- miim_bus: MIIM_BUS_0
frequency: 2500000
pin_ctrl:
pins: [9, 10]
pin_function: alt1
1.7. MUP1
MUP1 is a UART protocol facilitating configuring and inspecting the status of the Switch using the UART.
MUP1 is a SW function, but it needs to know which UART device it shall use. This is done by setting a handle, which ties it to the HW instance of the same handle (typically a FlexCom).
The definition of the MUP1 in the board.tree looks like this:
module: board
+--rw drivers
+--rw mup1
+--rw ref_uart? dev_uart
Following is an example connecting the MUP1 function to the HW instance using
DEV_UART_0
.
board:drivers:
mup1:
ref_uart: DEV_UART_0
See also: FlexCom
1.8. GPIO-Restart
The GPIO for Board restart is defined here. A board restart can e.g. be performed from management. The definition looks like this:
module: board
+--rw drivers
+--rw gpio_restart
+--rw (ref)
| +--:(sgpio)
| | +--rw sgpio
| | +--rw ref_sgpio_bank dev_sgpio_bank
| | +--rw port uint8
| | +--rw bit uint8
| +--:(gpio)
| +--rw gpio? uint32
+--rw direction gpio_direction
+--rw active_state? active
-
sgpio/gpio
section defines how the signals are mapped to either SGPIO port/bit or GPIO ID. -
direction
is output. -
active_state
defines the signal’s active state. This is usually documented in schematics.
Example:
gpio_restart:
gpio: 60
direction: GPIO_DIR_OUT
active_state: low
1.9. GPIO-Reset
This reset is an input signal (activated by pressing a button) that indicates a reset-to-default should be performed. The SoC will immediately reset and read this signal during startup (state of the reset button). If active, the configuration is restored to default. The definition looks like this:
module: board
+--rw drivers
+--rw gpio_reset
+--rw (ref)
| +--:(sgpio)
| | +--rw sgpio
| | +--rw ref_sgpio_bank dev_sgpio_bank
| | +--rw port uint8
| | +--rw bit uint8
| +--:(gpio)
| +--rw gpio? uint32
+--rw direction gpio_direction
+--rw active_state? active
-
sgpio/gpio
section defines how the signals are mapped to either SGPIO port/bit or GPIO ID. -
direction
is input. -
active_state
defines the signal’s active state. This is usually documented in schematics.
Example:
gpio_reset:
gpio: 2
direction: GPIO_DIR_IN
1.10. Status Led
Initially, the status LED is turned off, and after the initial configuration is applied, it turns green (or blinks) to indicate normal operation.
module: board
+--rw drivers
+--rw status_led
+--rw (ref)
| +--:(sgpio)
| | +--rw sgpio
| | +--rw ref_sgpio_bank dev_sgpio_bank
| | +--rw port uint8
| | +--rw bit uint8
| +--:(gpio)
| +--rw gpio? uint32
+--rw direction gpio_direction
+--rw active_state? active
-
sgpio/gpio
section defines how the signals are mapped to either SGPIO port/bit or GPIO ID. -
direction
is output. -
active_state
defines the signal’s active state. This is usually documented in schematics.
Example:
status_led:
gpio: 61
direction: GPIO_DIR_OUT
active_state: low
1.11. PHY Reset
The PHY’s reset state is controlled through the pin defined here.
module: board
+--rw drivers
+--rw phy_reset
+--rw (ref)
| +--:(sgpio)
| | +--rw sgpio
| | +--rw ref_sgpio_bank dev_sgpio_bank
| | +--rw port uint8
| | +--rw bit uint8
| +--:(gpio)
| +--rw gpio? uint32
+--rw direction gpio_direction
+--rw active_state? active
-
sgpio/gpio
section defines how the signals are mapped to either SGPIO port/bit or GPIO ID. -
direction
is output. -
active_state
defines the signal’s active state. This is usually documented in schematics.
Example:
phy_reset:
gpio: 62
direction: GPIO_DIR_OUT
active_state: low
1.12. WatchDog
The watchdog is a hardware timer and helps to ensure the system can recover from unforeseen failures. It reboots the system if its timer has not been updated by the CPU within a period that is set here. If left out, then the watchdog is disabled.
module: board
+--rw drivers
+--rw watchdog
+--rw timeout? enumeration
Example, when timeout is set to 2 seconds:
watchdog:
timeout: timeout_2000ms
1.13. Port Leds
This section defines how the front port LEDs should be accessed, typically SFP-based LEDs. Each switch port typically has two LEDs: green for 'high' speed and a second one (red/yellow/orange, etc.) for 'low' speed. Note that the PHYs usually control the LEDs directly through their own GPIOs and do not require any board configuration setup.
module: board
+--rw drivers
+--rw port_leds
+--rw port_led* [portno]
+--rw portno uint32
+--rw led_green
| +--rw (ref)
| | +--:(sgpio)
| | | +--rw sgpio
| | | +--rw ref_sgpio_bank dev_sgpio_bank
| | | +--rw port uint8
| | | +--rw bit uint8
| | +--:(gpio)
| | +--rw gpio? uint32
| +--rw direction gpio_direction
| +--rw active_state? active
+--rw led_second
+--rw (ref)
| +--:(sgpio)
| | +--rw sgpio
| | +--rw ref_sgpio_bank dev_sgpio_bank
| | +--rw port uint8
| | +--rw bit uint8
| +--:(gpio)
| +--rw gpio? uint32
+--rw direction gpio_direction
+--rw active_state? active
-
portno
defines to which switch front port (zero-based) these LEDs belong. -
led_green
defines how the green LED is accessed through SGPIOs or GPIOs. -
led_second
defines how the second LED is accessed through SGPIOs or GPIOs. -
sgpio/gpio
section defines how the signals are mapped to either SGPIO port/bit or GPIO ID. Example:
port_leds: port_led: - portno: 24 led_green: sgpio: ref_sgpio_bank: DEV_SGPIO_BANK_0 port: 24 bit: 0 direction: GPIO_DIR_OUT active_state: low led_second: sgpio: ref_sgpio_bank: DEV_SGPIO_BANK_0 port: 24 bit: 1 direction: GPIO_DIR_OUT active_state: low
1.14. Bridge
The Ethernet bridge interconnects multiple ports to form a LAN. This section defines the switch chip and the properties of each of the attached ports and phys.
module: board
+--rw drivers
+--rw bridge
+--rw mux_mode? port_mux_mode
+--rw target_chip target_chip_type
+--rw eth_ports
+--rw eth_port* [port_dev]
+--rw port_dev uint32
+--rw phy_mode phy_mode
+--rw phy_chip? int32
+--rw in_band_aneg? boolean
+--rw bandwidth? uint32
+--rw phy
+--rw ref_miim_bus miim_bus
+--rw miim_addr uint32
+--rw dummy? boolean
+--rw base_port? uint32
+--rw fixed_link
| +--rw speed? uint32
| +--rw role? phy_role
+--rw led* [id]
+--rw id phy_led_id
+--rw mode phy_led_mode
-
mux_mode
defines which devices and serdeses are used. Used on some SoCs. -
phy_mode
defines the PHY to MAC interface. -
target_chip
The physical chip sometimes supports different skews.target_chip
defines which one. -
port_dev
defines the chip port device to be used. -
phy_chip
defines the physical PHY chip this port is associated with, for hardware monitoring. -
bandwidth
defines the internal switch core bandwidth this port requires. -
in_band_aneg
means that the PHY status is fetched via the device PCS as opposed to via MDIO access. Supported for some interfaces. -
ref_miim_bus
defines the PHY MIIM bus ID. -
miim_addr
defines the PHY address on the bus. -
dummy
means that this is a software PHY and PHY access is disabled. Typically used where PHY access is not possible. -
base_port
is used for quad PHYs for determining which port ID should be used for access of shared resources. -
fixed_link
means that the speed is forced as opposed to 'aneg', and is left out when aneg is enabled. -
speed
defines the speed of the fixed_link. -
role
defines the role (master/slave) of the PHY, and is left out when aneg is enabled. -
led
defines the LED settings for the PHY. Supported for some PHYs.
The following example is a bridge with one PHY-based port and one SFP-based port:
target_chip: lan9696tsn
eth_ports:
eth_port:
- port_dev: 0
phy_mode: qsgmii
phy_chip: 1
bandwidth: 1000
phy:
ref_miim_bus: MIIM_BUS_0
miim_addr: 4
base_port: 0
led:
- id: led0
mode: link1000_activity
- id: led1
mode: link10_100_activity
- port_dev: 24
phy_mode: 10gbase-r
bandwidth: 10000
1.15. PTP
Pin configuration of PTP functions. This section defines the GPIO to PTP mapping.
module: board
+--rw drivers
+--rw ptp
+--ro pins* []
+--ro pin_ctrl
+--ro pins* uint32
+--ro pin_function pin_function
-
pin_ctrl
is used to assign physical pins on the SoC to this function. Check the datasheet for an overview of what pins can be used. -
pins
defines the GPIO(s) ID. -
pin_function
defines the mode to configure the pin(s).
The following example maps 3 GPIOs to the 1PPS PTP function ALT4:
ptp:
pins:
- pin_ctrl:
pins: [57, 58, 59]
pin_function: alt4
2. Allocating of resources (capabilities)
The capabilities
section is used to provide selected configurations for the application.
All capability configurations are parsed at boot-time, and if this configuration
requires memory to be allocated, then this allocation is done before the MUP1
announce packet is emitted.
If too many resources are assigned, it will result in a fatal boot error, and the board-tailor needs to lower the counts.
Here is what the capability section looks like in the board.tree:
module: board
+--rw capabilities
+--rw manufacturer string
+--rw model string
+--rw l3_count? uint32
+--rw ltc_count? uint32
+--rw ltc_pin_count? uint8
+--rw phy_timestamping? boolean
+--rw stream_count? uint32
+--rw coap_session_count? uint32
+--rw arp_count? uint32
+--rw ipv4_route_count? uint32
Where:
-
manufacturer
: is a string returned by the IETF-HW YANG manufacturer leaf. -
model
: is the model returned in the IETF-System YANG. -
l3_count?
: Is the number of L3 interfaces. This shall be set to 1 on SW variants without routing support, and can be up to 32 on SW variants with routing support. -
ltc_count?
: Is the number of PTP instances (each instance is tied to a PTP domain). Set this to 3, as this is the number of domains supported in HW. -
ltc_pin_count?
: Number of PTP Pins which can be used for 1PPS in/out. -
phy_timestamping?
: Select if PHY time-stamping shall be used (requires PHYs with time-stamping support). -
stream_count?
: Number of PSFP Streams. -
coap_session_count?
: Number of CoAP sessions to support. -
arp_count?
: Number of ARP entries to support. -
ipv4_route_count?
: Number of IPv4 static routes. This shall be set to zero on SW variants without routing, and above 1 on systems with SW routing.
Here is an example of the capabilities:
board:capabilities:
manufacturer: "Microchip Technology Inc."
model: "LAN9698RED - EV89P81A (UNG8422)"
l3_count: 1
ltc_count: 3
ltc_pin_count: 8
phy_timestamping: false
stream_count: 64
coap_session_count: 4
arp_count: 64
ipv4_route_count: 0
3. Factory defaults
The factory defaults can contain the full CORECONF data-store, and is applied at boot time if no user-configuration is stored in flash.
An example of a factory defaults which includes port 1 and port 2 in VLAN 1 is shown below:
board:factory_default_config:
ieee802-dot1q-bridge:bridges:
bridge:
- name: b0
component:
- name: c0
filtering-database:
vlan-registration-entry:
- database-id: 0
vids: '1'
entry-type: static
port-map:
- port-ref: 1
static-vlan-registration-entries:
vlan-transmitted: untagged
- port-ref: 2
static-vlan-registration-entries:
vlan-transmitted: untagged