This post was revised after fact-checking it against the real SWS EthSwt (see correction issue #145): SPI access in EthSwt isn’t a plain vendor mechanism outside of AUTOSAR — it’s standardized through dedicated ARXML containers (EthSwtSpi, EthSwtSpiSequence) and generic register APIs.

When SPI instead of MII as the host interface?

Per chapter 1 of the SWS, access for switch-specific configuration or functions happens via an SPI or MII/MDIO interface — mediated through the Eth driver (MII/MDIO) or directly through the Spi driver (SPI). SPI is used in particular when the host has no dedicated Ethernet MAC port to the switch, or when configuration has to happen before an Ethernet link to the switch even exists.

The real ARXML configuration: EthSwtSpi / EthSwtSpiSequence

EthSwtConfig
 └── EthSwtSpi                     (0..1 — only present if SPI is used)
      └── EthSwtSpiSequence        (1..* — one or more SPI sequences)
           ├── EthSwtSpiAccessSynchronous  (optional, boolean)
           └── reference to a real SpiSequence
               of the Spi driver (SpiSequenceId, symbolic name)

The SWS is unusually explicit here: an EthSwtSpiSequence is exclusively reserved for EthSwt — no other driver may use the same SPI sequence at the same time. Conversely, an EthSwt driver can use a single sequence to address multiple switch chips of the same type, or use multiple sequences for a single chip — so the 1:1 assumption of "one sequence per chip" doesn’t necessarily hold.

If the switch chip has no SPI interface at all, there simply is no instance of EthSwtSpi in the configuration — the container is optional (0..1) exactly for that reason.

Generic register APIs — MII and SPI behind the same interface

The key point: EthSwt exposes one generic API for register access upstream, regardless of whether MII or SPI sits underneath:

APIDescription per the SWS

EthSwt_GetSwitchReg(SwitchIdx, page, register, *content)

"Generic API for reading the content of a switch register" — per SRS_Eth_00120 explicitly accessible via MII and/or SPI

EthSwt_SetSwitchReg(SwitchIdx, page, register, content)

The write counterpart; likewise generic over MII/SPI

EthSwt_ReadTrcvRegister / EthSwt_WriteTrcvRegister

Transceiver registers "through the MII or SPI of the indexed switch port" — for registers pertaining to a specific port

For the caller of any of these APIs, it’s transparent whether an SPI transaction over the configured EthSwtSpiSequence runs underneath, or an MII/MDIO access. That’s the core of the AUTOSAR abstraction: software calling EthSwt_GetSwitchReg doesn’t need to know which hardware variant (see this series' hardware architecture post) is actually installed.

Synchronous vs. asynchronous

The optional EthSwtSpiAccessSynchronous parameter controls whether the SPI access is blocking (synchronous) or non-blocking. For time-critical accesses during initialization (see EthSwt_BackgroundTask in Part 2 of this series), this is a relevant knob for avoiding unnecessary delays in register configuration.

Typical use cases

  • Initial configuration at boot — before an Ethernet link to the switch even exists

  • Statistics readout without extra Ethernet traffic — querying MIB counters (Part 4) over SPI without loading the actual data path

  • Diagnostics on a broken Ethernet link — if MII/MDIO is unavailable for some reason, SPI remains an independent access path

Failure pattern: register access fails

As described in this series' bring-up post, a failing register access — whether via MII or SPI — results in the extended production error ETHSWT_E_ACCESS. In SPI setups, it’s additionally worth checking CPOL/CPHA settings and the timing of the configured EthSwtSpiSequence with a logic analyzer.

Summary

AspectKey takeaway

ARXML container

EthSwtSpi (0..1) with 1..* EthSwtSpiSequence instances, exclusively reserved for EthSwt

API abstraction

EthSwt_GetSwitchReg/SetSwitchReg/ReadTrcvRegister/ WriteTrcvRegister abstract MII and SPI behind the same API

Synchronicity

Configurable via EthSwtSpiAccessSynchronous

Failure case

ETHSWT_E_ACCESS on failing register access, regardless of the bus