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_bankis used to select which physical instance in hardware to configure; typically, 1-3 instances are available. -
bit_countis the number of GPIOs (or bits) that are enabled per SGPIO port, with 1-4 bits available. -
port_maskdefines 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_divmaps directly into the hardware where the SGPIO frequency is set. The resulting frequency is the system clock divided by this value. -
pin_ctrlis 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_instanceis 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, andspiare used to select the personality of the FlexCOM instance. Any givenflexcomentry must include one and only one of them. TheDEV_xxxvalue assigned to eitheruart,i2c, orspiis an internal handle, used further down in the file to reference the FlexCOM instance. -
pin_ctrlis 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. UART
UART peripheral within a SoC. The definition of the uart in the board.tree looks like this:
+--rw drivers
+--rw uarts
+--rw uart* [hw_instance]
+--rw hw_instance uint32
+--rw logical_id? dev_uart
Here:
-
hw_instanceis used to select which physical instance in HW to configure. On PIC64-HPSC/HX, instance 0 is the SysC UART and instance 1-4 are for AppC UART 0-3. -
logical_idis the logical handle (DEV_UART_xvalue) for this UART. This is used when referencing the UART in other places, such as in the "mup1" section.
1.4. I2C
I2C bus controller within a SoC. The definition of the i2c in the board.tree looks like this:
+--rw drivers
+--rw i2cs
+--rw i2c* [hw_instance]
+--rw hw_instance uint32
+--rw logical_id? dev_i2c
Here:
-
hw_instanceis used to select which physical instance in HW to configure. On PIC64-HPSC/HX, instance 0 is the SysC I2C and instance 1-4 are for AppC I2C 0-3. -
logical_idis the logical handle (DEV_I2C_xvalue) for this I2C. This is used when referencing the I2C bus in other places, such as when specifying the parent bus of an I2C multiplexer.
1.5. 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_groupis the internal handle for others to reference when choosing a pin group. -
sleepis the time it takes to change the mux, i.e., the driver waits this number of ms before returning and the mux is formed. -
sgpiodefines a reference to an SGPIO bank and which port/bit are used to form the group. -
gpiohas 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.6. 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'.
Two types of I2C muxes are supported. The first type uses GPIOs to select between different I2C channels. The second type are PCA954x type devices which accepts writes to one I2C address to switch between the different I2C channels.
I2C muxes must mux an I2C root bus. An I2C root bus is a bus controller declared in FlexCom or I2C. It is not allowed to place a mux on the output of a mux.
Only one type of mux must be used on a given I2C root bus. i.e., it is not allowed to mix GPIOs type muxes with PCA954x type muxes on a given I2C root bus.
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
+--rw i2c_mux_pca954x
+--rw i2c_mux* [i2c_mux]
+--rw i2c_mux dev_i2c_mux
+--rw ref_parent dev_i2c
+--rw i2c_address uint8
+--rw i2c_val uint8
-
i2c_muxis the internal handle for others to reference when choosing an I2C mux with a specific mux configuration. -
ref_parentis a reference to an already defined HW I2C instance. -
ref_pin_groupis a reference to an already defined pin group for GPIO controlled I2C mux. -
gpio_maskdefines the pin mask for GPIO controlled I2C mux. -
i2c_addressdefines the I2C address to write to for PCA954x I2C mux. -
i2c_valdefines the I2C value written toi2c_addressfor PCA954x I2C mux.
Example of a GPIO controlled I2C MUX with a reference for channel 0 to 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
Example of a PCA954x I2C MUX at address 0x70 with a reference for channel 0 and 1:
i2c_mux_pca954x:
i2c_mux:
- i2c_mux: DEV_MUX_0
ref_parent: DEV_I2C_0
i2c_address: 0x70
i2c_val: 0x01
- i2c_mux: DEV_MUX_1
ref_parent: DEV_I2C_0
i2c_address: 0x70
i2c_val: 0x02
1.7. MCP230xx I2C GPIO expander
module: board
+--rw gpio_mcp230xx
+--rw mcp230xx* [handle]
+--rw handle dev_sgpio_bank
+--rw (i2c_parent)
+--:(i2c_bus)
| +--rw i2c_bus? dev_i2c
+--:(i2c_mux)
+--rw i2c_mux? dev_i2c_mux
+--rw i2c_address uint8
+--rw gpio_count uint32
-
handleis the internal handle for others to reference this mcp230xx instance. -
i2c_busis the I2C bus of this mcp230xx instance if it is placed on a root I2C bus. See FlexCom or I2C. -
i2c_muxis the I2C bus of this mcp230xx instance if it is placed on an I2C multiplexer. See I2C Mux. -
i2c_addressis the I2C address of this mcp230xx instance. -
gpio_countis the total number of gpio of this mcp230xx instance. Must be 8 or 16.
Example of three MCP230xx at address 0x21, 0x22 and 0x23 on I2C bus DEV_MUX_0, each providing 16 GPIOs:
gpio_mcp230xx:
mcp230xx:
- handle: DEV_SGPIO_BANK_0
i2c_mux: DEV_MUX_0
i2c_address: 0x21
gpio_count: 16
- handle: DEV_SGPIO_BANK_1
i2c_mux: DEV_MUX_0
i2c_address: 0x22
gpio_count: 16
- handle: DEV_SGPIO_BANK_2
i2c_mux: DEV_MUX_0
i2c_address: 0x23
gpio_count: 16
1.8. 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
-
portnodefines to which switch front port (zero-based) this SFP belongs. -
losindicates a loss of the received optical signal. -
presentindicates that a module is present. -
tx_enablesignal is used to enable the transmitter output. -
tx_faultindicates faults in the Tx direction. -
directioncan be either input or output (output fortx_enable, input for others). -
active_statedefines the signal’s active state. This is usually documented in schematics. -
sgpio/gpiosection defines how the signals are mapped to either SGPIO port/bit or GPIO ID. -
ref_i2c_muxis 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.9. 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_busis the bus ID, used for reference. -
pin_ctrlis used to assign physical pins on the SoC to this function. Check the datasheet for an overview of what pins can be used. -
frequencyis 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.10. 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.11. Flash
The SPI-NOR (QSPI) flash holds the bootloader, the firmware images and the file system. How fast and how wide it can be driven depends on the board — trace lengths, layout and the flash part fitted — so it is a board setting rather than a property of the software.
LAN969x and LAN966x based designs require a flash part that can erase
down to 4 KiB pages. The driver issues the 4 KiB sector-erase opcode (0x20)
and nothing else, so a part whose smallest erasable unit is larger — a 64 KiB
block-erase-only device, for instance — cannot be used, regardless of the
mode and speed selected here.
|
The definition in the board.tree looks like this:
module: board
+--rw drivers
+--rw flash_static
+--rw mode? enumeration
+--rw speed? uint32
The container is called flash_static because every value is stated by the
board, rather than discovered from the flash part itself.
mode names the read protocol by its command-address-data bus widths:
| Value | Meaning |
|---|---|
|
One line throughout, using the low-frequency read opcode ( |
|
Quad I/O ( |
speed is an upper bound in MHz, not an exact frequency. The achievable
frequencies are the SoC clock divided by an integer, so the driver picks the
highest one that does not exceed the bound — usually landing below it. A bound
below the slowest the divider can express is clamped to that slowest rate.
The value is taken as given: it is not checked against what the platform or the flash part can sustain. Consult the datasheet for the platform and the part fitted before raising it — what is safe varies by board layout, trace length and the part itself.
Both settings are applied when the flash is brought up and are fixed for the lifetime of the device; there is no runtime reconfiguration and no management node reporting them.
Omitting the container gives single_1_1_1 / 25 MHz, which is what the driver
used before these settings existed, so a board that says nothing behaves exactly
as it did. Raising either value is opt-in per board. Note the bootloader runs the
same flash at 100 MHz quad, so a part sustaining more than the default is the
normal case rather than the exception — but it wants measuring on the board
before it is declared here.
board:drivers:
flash_static:
mode: single_1_1_1
speed: 25
|
This configures the application’s flash access only. The bootloader reads its own device tree and has its own clock and bus width, so a board that cannot sustain the defaults needs both lowered — changing one leaves the other running as before. See the bootloader tailoring section in SW Tailoring. |
Raise these values only after measuring on the board in question. A setting the
board cannot sustain shows up as corrupted reads, which can look like almost any
other fault. The safe order when bringing up a new board is to start at
single_1_1_1 / 25 MHz, confirm the device is stable, and widen or speed up one step
at a time.
1.12. 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/gpiosection defines how the signals are mapped to either SGPIO port/bit or GPIO ID. -
directionis output. -
active_statedefines the signal’s active state. This is usually documented in schematics.
Example:
gpio_restart:
gpio: 60
direction: GPIO_DIR_OUT
active_state: low
1.13. 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/gpiosection defines how the signals are mapped to either SGPIO port/bit or GPIO ID. -
directionis input. -
active_statedefines the signal’s active state. This is usually documented in schematics.
Example:
gpio_reset:
gpio: 2
direction: GPIO_DIR_IN
1.14. Status Leds
A board can define up to four status GPIOs. Each one has a drive state for the boot phase and another for normal operation, so the same mechanism covers both a blinking LED that shows the system is alive and a steady signal an external host can sample to detect that the system has restarted.
Defining more than four is a board configuration error and is reported at startup.
module: board
+--rw drivers
+--rw status_leds
+--rw status_led* [instance_id]
+--rw instance_id uint8
+--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 gpio_state_at_init? status_led_state_init
+--rw gpio_state_at_boot_complete? status_led_state
-
instance_ididentifies the instance and must be unique. A duplicate is reported at startup. -
directionmust beGPIO_DIR_OUT. -
sgpio/gpiosection defines how the signals are mapped to either SGPIO port/bit or GPIO ID. -
directionis output. -
active_statedefines the signal’s active state. This is usually documented in schematics. It defaults tohigh. -
gpio_state_at_initis the state held while the system boots. It defaults totri_state. -
gpio_state_at_boot_completeis the state taken once boot has completed. It defaults toblink.
The two state leaves take these values:
| Value | Meaning |
|---|---|
|
The pin is released and left high impedance, so an external pull resistor determines its level. Not available for a pin behind an SGPIO or an I2C expander, which is always driven. |
|
The pin is driven to the level given by |
|
The pin is driven to the opposite of |
|
The pin alternates between the active and the inactive level once per second. Only valid for |
Note that active and inactive describe the signal, not the voltage: the
pin level follows from active_state. To drive a pin high once boot has
completed, set active_state: high and gpio_state_at_boot_complete: active.
Example of a blinking status LED, wired active low:
status_leds:
status_led:
- instance_id: 0
gpio: 61
direction: GPIO_DIR_OUT
active_state: low
gpio_state_at_init: inactive
gpio_state_at_boot_complete: blink
Example of a signal for detecting that the system has restarted. The pin is pulled low on the board, so it is left released while booting and driven high afterwards. A host sampling the pin sees it go low for as long as the system is booting:
status_leds:
status_led:
- instance_id: 1
gpio: 14
direction: GPIO_DIR_OUT
active_state: high
gpio_state_at_init: tri_state
gpio_state_at_boot_complete: active
|
The two are mutually exclusive. A board configuration defining both is rejected at startup, so a migration has to be completed rather than left half done. |
1.15. 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/gpiosection defines how the signals are mapped to either SGPIO port/bit or GPIO ID. -
directionis output. -
active_statedefines the signal’s active state. This is usually documented in schematics.
Example:
phy_reset:
gpio: 62
direction: GPIO_DIR_OUT
active_state: low
1.16. 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.17. FS (File System)
This section defines the file types that are needed to be stored in the flash. The types must be defined in lm_os.h. If the type is not defined here a storage is not possible. Minimum file/block size is 4096B.
module: board
+--rw fs
+--rw files* [type]
+--rw type fs_type
+--rw offset? uint32
+--rw max_size? uint32
Example, when the startup-cfg is enabled at offset 0 and max size is set to 48KB:
fs:
files:
- type: FS_TYPE_STARTUP
offset: 0
max_size: 49152 # 48KB
1.18. TimeStamp properties
This container contains timestamping proterties. Currently it has a list of time-stamp calibration profiles, which a given port can link to.
| Index 0 in the calibrations list is reserved for interfaces which does not use/require any calibration. |
module: board
+--rw drivers
+--rw timestamp
+--rw calibrations* [idx]
+--rw idx uint32
+--rw calibration* [type]
+--rw type ts_type
+--rw rx? int32
+--rw tx? int32
timestamp:
calibrations:
- idx: 1
calibration:
- type: SPEED_10MBIT
rx: 37000
tx: 10000
- type: SPEED_100MBIT
rx: 350
tx: 350
- type: SPEED_1000MBIT
rx: 0
tx: 0
- idx: 2
calibration:
- type: SPEED_100MBIT
rx: 950
tx: 950
- type: SPEED_1000MBIT
rx: 0
tx: 0
- type: SPEED_10000MBIT
rx: 0
tx: 0
The profile will only be used by ports which points to it in the
drivers/bridge/eth_ports/eth_port/ts_calibration leaf. See Bridge.
|
1.19. 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
-
portnodefines to which switch front port (zero-based) these LEDs belong. -
led_greendefines how the green LED is accessed through SGPIOs or GPIOs. -
led_seconddefines how the second LED is accessed through SGPIOs or GPIOs. -
sgpio/gpiosection 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.20. 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 ts_calibration? uint32
+--rw phy
+--rw ref_miim_bus miim_bus
+--rw miim_addr uint32
+--rw dummy? boolean
+--rw base_port? uint32
+--rw extmod? boolean
+--rw media_interface? media_interface
+--rw phy_driver_id? uint32
+--rw phy_readback* [addr]
| +--rw addr uint32
| +--rw value? uint16
| +--rw mask? uint16
+--rw fixed_link
| +--rw speed? uint32
| +--rw role? phy_role
+--rw led* [id]
| +--rw id phy_led_id
| +--rw mode phy_led_mode
+--rw tunables* [link_id]
+--rw link_id link_id_enum
+--rw tunable* [type]
+--rw type tunable
+--rw value? uint32
-
mux_modedefines which devices and serdeses are used. Used on some SoCs. -
phy_modedefines the PHY to MAC interface. Valid values:-
rgmii— RGMII (10/100/1G), 12-pin interface using a synchronous 125 MHz clock -
rgmii_txid— RGMII with 2 ns internal TX delay -
rgmii_rxid— RGMII with 2 ns internal RX delay -
rgmii_id— RGMII with 2 ns internal RX and TX delay -
rmii— RMII (10/100) -
sgmii— SGMII (10/100/1G), 8B/10B PCS encoding, supports in-band Cisco SGMII aneg -
qsgmii— QSGMII, equivalent to 4xSGMII over a single serdes -
1000base-x— 1000BASE-X (1G, 8B/10B PCS, Clause-37 in-band aneg) -
2500base-x— 2500BASE-X (2.5G, 8B/10B PCS, no autoneg) -
10gbase-r— 10GBASE-R (10G), 64B/66B PCS encoding at 10.3125 Gbaud
-
-
target_chipThe physical chip sometimes supports different skews.target_chipdefines which one. -
port_devdefines the chip port device to be used. -
phy_chipdefines the physical PHY chip this port is associated with, for hardware monitoring. -
bandwidthdefines the internal switch core bandwidth this port requires. -
ts_calibration(optionally) points to time-stamping calibration profile defined in TimeStamp properties -
in_band_anegmeans that the PHY status is fetched via the device PCS as opposed to via MDIO access. Supported for some interfaces. -
ref_miim_busdefines the PHY MIIM bus ID. -
miim_addrdefines the PHY address on the bus. -
dummymeans that this is a software PHY and PHY access is disabled. Typically used where PHY access is not possible. Afixed_linkwith the desiredspeedmust also be configured so the dummy PHY knows what link speed to report.ref_miim_busandmiim_addrmust be present (to satisfy the YANG model) but are ignored at runtime. -
base_portis used for quad PHYs for determining which port ID should be used for access of shared resources. -
extmod(optionally) declare that this PHY shall be implemented by the EXTMOD instead of the build-in driver library. See this for additional details. -
media_interfaceconfigures which media interface the PHY is using. If the leaf is missing then the default iscu. Valid values:-
cu— copper interface -
1000base-x— use 1000BASE-X (1G, 8B/10B PCS, Clause-37 in band aneg) -
sgmii— SGMII (10/100/1G), 8B/10B PCS encoding supports in-band Cisco SGMII aneg
-
-
phy_driver_id(optionally) means that the PHY driver with this ID will be used for the device instead of what is in registers 2 and 3 of the device. This is used when you want to force loading a specific driver for a PHY device. In this way it is possible that the same binary file can support future PHY devices. -
phy_readback(optionally) means that the SW will read the registers of the PHYs and compare them with the expected value. This is used to check that the expected PHY is on the board. This list can contain 0 or up to 4 entries. -
addrthe PHY register address. The address is encoded as a single u32, where the most significant 16 bits are the page, and the least significant 16 bits are the address. -
valuethe expected value to be found at the PHY register address -
maskboth the expected value and the value read from the register will be anded with this mask before being compared. -
fixed_linkmeans that the speed is forced as opposed to 'aneg', and is left out when aneg is enabled. -
speeddefines the speed of the fixed_link. -
roledefines the role (master/slave) of the PHY, and is left out when aneg is enabled. -
leddefines the LED settings for the PHY. Supported for some PHYs. -
tunablesconfigures the tunables on the interface.-
link_iddecides which points on the interface to configure. It is possible to configure the following points-
switchwhich is the switch side -
phy_hostwhich is on the PHY towards the switch -
phy_linewhich is on the PHY towards the line side
-
-
tunablecontains a list of tunable that are configured on the interface-
typedescribes the tunable type. Currently onlytx_amplis supported -
valuethe value to be set in the register
-
-
The following example is a bridge with one PHY-based port, one SFP-based port, and one dummy PHY 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
ts_calibration: 2
- port_dev: 29
phy_mode: sgmii
bandwidth: 1000
phy:
ref_miim_bus: MIIM_BUS_0
miim_addr: 0
dummy: true
fixed_link:
speed: 1000
1.21. 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_ctrlis used to assign physical pins on the SoC to this function. Check the datasheet for an overview of what pins can be used. -
pinsdefines the GPIO(s) ID. -
pin_functiondefines 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
1.22. EXTMOD (Driver)
A EXTMOD Driver used to claim HW resources and expose the relevant HW to the EXTMOD module. The EXTMOD module will have to decide what to do with it.
Currently, only GPIOs can be assigned to EXTMOD.
module: board
+--rw drivers
+--rw extmod
+--ro gpios* []
+--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
Following is an example on how to assign GPIO 25 and 26 to the GPIO module.
When using the GPIO, the lmeo_gpio_read/write functions operate on index
in this array meaning that to access GPIO 25, one will have to use index 0.
|
extmod:
gpios:
- gpio: 25
direction: GPIO_DIR_IN
- gpio: 26
direction: GPIO_DIR_OUT
active_state: low
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 platform_id? uint16
+--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. -
platform_id?: Firmware-image compatibility identifier for this board (see Firmware image compatibility (platform_id) below). Omit it (or set 0) to disable the firmware-image platform check. -
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. -
mld_instance_count?: Number of MLD snooping instances. -
mld_group_count?: Number of MLD multicast groups (across all instances). -
mld_source_count?: Number of MLD source entries (across all groups).
Here is an example of the capabilities:
board:capabilities:
manufacturer: "Microchip Technology Inc."
model: "LAN9698RED - EV89P81A (UNG8422)"
platform_id: 0x0003
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
mld_instance_count: 8
mld_group_count: 128
mld_source_count: 512
2.1. Firmware image compatibility (platform_id)
Every firmware image is stamped with the platform_id of the board it was built
for, and the firmware-update service rejects an image whose id is not compatible
with the running board before writing flash — this stops an image for a
different platform from bricking the device.
Assign ids per compatibility group: boards that should accept each other’s images get the same value, so set it in the base board configuration and the auto / no-security / DTLS variants inherit it. The Microchip lan969x boards use one id per SoC:
SoC (target_chip) |
platform_id |
|---|---|
|
|
|
|
|
|
Rules:
-
Assignable values are
0x0001–0x7ffe. Bit 15 is reserved: the build sets it on the bootloader image so an application image cannot be written to the bootloader (and vice versa). -
0x0000(the default when omitted) disables the check on that board. -
The build reads
platform_idfrom the board configuration and stamps it into the image automatically; no per-image build flag is needed.
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