This post builds on the EthTrcv series and picks up directly where the previous post on migration left off. That post covered what changes at the protocol and configuration level when moving from 100BASE-TX to 100BASE-T1. This one takes a step further toward the hardware — but deliberately only as far as a software developer needs to go to understand what actually happens on the other side of an EthTrcv_Init call.

If you’re after the full electrical depth — line-level signals, PCB timing, EMC, power sequencing down to the pin — that’s covered in the concluding Hardware Deep Dive post of this series. Think of this post as the bridge to that one: conceptual, functional, no oscilloscope required.

This post answers "what does the PHY chip functionally do?" — not "what does the signal on the cable look like electrically?". For the latter, see the hardware deep dive at the end of the series.

PHY Architecture at a Glance

An Ethernet PHY isn’t a monolithic chip that somehow turns bits into signals. Internally it’s organized into three functional blocks that IEEE 802.3 keeps cleanly separated: PCS, PMA, and MDI.

                         PHY Chip
   ┌───────────────────────────────────────────────────┐
   │                                                     │
   │   MAC side               Inside the PHY            │
   │  ┌─────────┐    ┌─────────────┐    ┌─────────┐     │
   │  │  MII/    │    │             │    │         │     │
   │  │  RMII/   │───►│     PCS     │───►│   PMA   │───┐ │
   │  │  RGMII   │◄───│ (coding &   │◄───│(line    │◄──┤ │
   │  │ interface│    │  framing)   │    │coupling)│  │ │
   │  └─────────┘    └─────────────┘    └─────────┘  │ │
   │       ▲                 ▲                        │ │
   │       │            ┌─────────┐                   ▼ │
   │       │            │Register │              ┌─────────┐
   │       │            │  bank   │              │   MDI   │──► Cable
   │       │            │  (via   │              └─────────┘
   │       │            │  MDIO)  │
   │       │            └─────────┘
   │       │                 ▲
   └───────┼─────────────────┼─────────────────────────┘
           │                 │
      Data path         Management path
      (frames)          (MDC/MDIO — control & status)

The three blocks, briefly:

BlockJob

PCS (Physical Coding Sublayer)

Translates between the digital frame bits coming from the MAC and the line code the transmission technology requires. Handles scrambling, bit encoding, and framing of transmission blocks.

PMA (Physical Medium Attachment)

Converts the PCS’s encoded bits into physical symbols (e.g. voltage levels) and back. On 100BASE-T1, this is also where the echo-cancellation logic lives that makes bidirectional operation on a single wire pair possible.

MDI (Medium Dependent Interface)

The actual physical connection point to the cable. Everything that’s medium-specific — impedance, coupling, filtering — conceptually sits here.

This three-way split isn’t just layering theory. When a PHY datasheet separates "PCS status" registers from "PMA/PMD status" registers (typical for Clause 45 PHYs), that’s this architecture showing through directly. Knowing which block is responsible for what helps you find the right register for a given symptom much faster.

On top of that sits the register bank — a set of control and status registers readable, and partly writable, over the MDIO bus. It isn’t a signal path of its own; it’s the interface through which software (ultimately EthTrcv) configures the PHY and reads back its state.

What Actually Happens During EthTrcv_Init?

From the software side, EthTrcv_Init is a single function call with a configuration pointer. From the PHY’s side, that call kicks off a multi-stage sequence that takes considerably longer than the function call itself — a good part of it keeps running asynchronously after EthTrcv_Init has already returned.

EthTrcv_Init(config)
   │
   ├─► 1. Trigger hardware reset
   │      Pull RST_N low for a defined time (or set a soft-reset bit via MDIO)
   │      → PHY discards internal state, all registers back to power-on defaults
   │
   ├─► 2. Wait for PHY boot
   │      Internal power-on self-test, PLL settling time, internal calibration
   │      of analog blocks (reference voltages, termination resistors)
   │      → typically < 1 ms up to a few ms, vendor-dependent
   │
   ├─► 3. Verify PHY identification
   │      Read the PHY ID register over MDIO, compare against the ID expected
   │      from configuration (see part 2 of the series)
   │
   ├─► 4. Program static configuration
   │      Interface mode (RGMII/RMII/...), auto-negotiation advertisement,
   │      master/slave role for 100BASE-T1, vendor-specific strap registers
   │
   ├─► 5. State: UNINIT → INIT
   │      EthTrcv_Init() returns — but the PHY is not "linked up" yet
   │
   ── from here it continues asynchronously, only after SetTransceiverMode(ACTIVE) ──
   │
   ├─► 6. Internal calibration of the line driver
   │      The analog front-end amplifier calibrates itself to the actual line
   │      impedance — on 100BASE-T1 a prerequisite for working echo cancellation
   │
   └─► 7. Link training begins
          (covered in its own section below)

Step 2 — the boot and calibration time — is why some implementations insert a short, defined delay after EthTrcv_Init before the first MDIO access. Access the PHY too early and it either doesn’t respond at all, or returns values from a register that isn’t fully initialized yet — a classic, hard-to-reproduce bringup bug.

The key thing for your mental model: EthTrcv_Init configures the PHY, it does not create a link. The link only comes into existence through link training, which only begins once the transceiver has been activated via EthTrcv_SetTransceiverMode(ACTIVE) — and even then, depending on the technology, it can take a noticeable amount of time before the link is actually up (more on that shortly).

The MDIO Bus — the Short Version

Every step above — reading a register, writing a register, checking the PHY ID — runs over the MDIO bus. Conceptually, this much is enough for now:

SoC ── MDC (clock) ─────────────► PHY
    ── MDIO (data, bidirectional) ─► PHY

MDIO is a simple, serial two-wire bus that software uses to address, read, and write registers inside the PHY — similar in principle to I2C, but with its own frame format. There are two frame variants (Clause 22 for simpler PHYs, Clause 45 for PHYs needing more register space, including all 1000BASE-T1 PHYs), and multiple PHYs can share the same bus via distinct PHY addresses.

Register layout, the Clause 22 vs. 45 differences, electrical specifics (pull-up resistors, timing, clock frequency), and typical diagnostic registers are covered in a dedicated post: MDIO post. If you already know that EthTrcv_Init "talks to the PHY over MDIO somehow" and just want to understand what those register accesses actually accomplish functionally, this post gives you enough.

Signal Processing Inside the PHY

Between "bits from the MAC" and "signal on the cable" sits an entire chain of signal-processing steps that happens entirely inside the PHY chip and stays invisible to software — but understanding this chain explains why PHY chips are as complex as they are, and why certain failure patterns can occur at all.

Frame bits (from the MAC)
     │
     ▼
┌───────────┐   prevents long runs of identical bits
│ Scrambling│   (DC balance, spectral shaping)
└─────┬─────┘
      ▼
┌───────────┐   maps bit groups onto transmission symbols
│  Encoding │   (e.g. PAM3 on 100BASE-T1)
└─────┬─────┘
      ▼
┌───────────┐   adds redundancy so receive errors can be
│  Forward   │   corrected without retransmission
│  Error     │
│Correction  │
└─────┬─────┘
      ▼
┌───────────┐   for single-pair operation: subtract the PHY's
│   Echo     │   own transmit signal from the receive signal
│Cancellation│
└─────┬─────┘
      ▼
   Signal on the line

Scrambling ensures the line never carries long runs of identical bits — a cable held permanently high or low creates unfavorable DC content and makes clock recovery harder for the receiver. Scrambling is reversible and changes only the representation on the wire, never the actual data.

Encoding maps bit groups onto transmission symbols. 100BASE-T1 uses PAM3 — instead of just two voltage levels (classically 0/1), three levels are used, so each symbol carries more information. The result: a higher data rate at a lower symbol rate on the cable, which in turn eases the demands on the cable and on EMC.

Forward error correction (FEC) adds controlled redundancy so the receiver can correct a certain proportion of bit errors on its own, without requiring retransmission. This matters particularly in automotive environments, where electromagnetic interference on the line can never be entirely ruled out.

For software developers, the exact mechanics of this chain are rarely actionable — it runs entirely inside the PHY and isn’t exposed through the API. What is worth knowing is that it exists: if a PHY status register reports a rising error-correction rate, that’s an early warning sign of degrading line quality — often well before the link fails outright.

One point that regularly causes confusion in practice: after EthTrcv_Init and EthTrcv_SetTransceiverMode(ACTIVE), the link is not up immediately. On 100BASE-T1, the first link establishment can noticeably take longer than users familiar with classic Ethernet would expect — and that’s not a bug, it’s how the technology works.

SetTransceiverMode(ACTIVE)
   │
   ├─► Master/slave role is already configured
   │   (unlike TX, 100BASE-T1 has no auto-negotiation race —
   │    the role is fixed statically via configuration)
   │
   ├─► Silence detection
   │      Both sides initially "listen" on the line
   │
   ├─► Signal detection
   │      Master starts transmitting, slave detects a present signal
   │
   ├─► Link training phase
   │      Adaptive filters inside the PMA converge to the actual line
   │      characteristics: echo-cancellation coefficients, equalizer
   │      filters, timing recovery
   │      → this step takes time, because the filters converge iteratively
   │
   ├─► Descrambler synchronization
   │      Transmitter and receiver sync up their scrambler states
   │
   └─► Link up
          EthTrcv_GetLinkState() returns ETHTRCV_LINK_STATE_ACTIVE

Rough order of magnitude: where classic 100BASE-TX often establishes a link in well under a second, the first link establishment on 100BASE-T1 — depending on PHY chip, cable length, and environmental conditions — can take anywhere from several hundred milliseconds up to a few seconds. The cause is the iterative filter adaptation during link training, which can need several attempts on a new or noisy connection.

For the application layer this means: setting a timeout of a few hundred milliseconds on EthTrcv_GetLinkState right after SetTransceiverMode(ACTIVE) risks reporting false-negative link failures during bringup — even though the PHY is working correctly and simply still training.

Repeated but ultimately successful link training (several training attempts before the link comes up) is not, by itself, a hardware fault on 100BASE-T1. It only becomes a signal of an actual problem if the link consistently fails to come up, or repeatedly drops and retrains during normal operation — pointing to the cable, connector, an EMC interference source, or a misconfigured master/slave role.

Once the first training cycle succeeds, the resulting filter coefficients are typically retained as long as the link isn’t fully lost — so a re-link after a brief signal interruption is often faster than the initial bringup.

The MAC-PHY Interface — MII, RMII, RGMII at a Glance

On the MAC side you regularly run into abbreviations like MII, RMII, or RGMII in ARXML configurations — which variant is actually populated is implicit in the hardware and driver integration rather than an explicit, separately selectable ARXML parameter. For a conceptual understanding, this much is enough:

InterfaceShort characterizationTypical use in the vehicle

MII

The original, wide parallel interface (many lines). Rarely found in new automotive designs today.

Older / simple ECUs, legacy designs

RMII

Reduced variant with fewer lines, shared reference clock between MAC and PHY.

Smaller ECUs with limited GPIO resources

RGMII

Reduced interface for gigabit-capable links, uses both clock edges to transfer data.

Application SoCs, gateways, ADAS domains running 1000BASE-T1

The full electrical description of these interfaces — exact signal timing, detailed line counts, the RGMII delay problem, and how this choice shows up in the PCB layout — is covered in the Hardware Deep Dive post. For day-to-day EthTrcv configuration work, it’s usually enough to know: choosing the interface is a hardware decision that gets reflected in a configuration parameter — not the other way around.

Interrupt vs. Polling — How the PHY Informs the Stack

The PHY always knows its own link state — the question is how that information reaches software. Two mechanisms are common in practice, and many production projects combine both.

Approach 1: Polling
────────────────────
   Task (10-100ms cycle)
      │
      └─► EthTrcv_GetLinkState() ── reads the link status register via MDIO
             │
             └─► Change only visible at the next poll cycle


Approach 2: Interrupt-driven
─────────────────────────────
   PHY detects a link change internally
      │
      └─► asserts a dedicated IRQ pin
             │
             └─► ISR on the SoC ── sets a flag / triggers an event
                    │
                    └─► Task context calls EthTrcv_GetLinkState()
                        close in time to the actual change
ApproachAdvantageDrawback

Polling

Simple, no extra pin required, deterministic timing

Detection latency = poll interval; MDIO bus is loaded even when nothing changed

Interrupt

Low latency on link loss, MDIO bus load only when needed

Extra hardware pin, ISR handling, not every PHY/board supports it

Even with the interrupt approach, software still reads the actual link state via EthTrcv_GetLinkState (i.e. over MDIO) — the interrupt only tells you that something changed, not what changed. The IRQ pin doesn’t replace the MDIO access; it just moves up the point in time at which it happens.

A common pattern in production projects: interrupt-driven handling for fast reaction to safety-relevant link loss (e.g. backbone links to central ECUs), plus low-frequency polling as a fallback in case the interrupt path misses an event for some reason — for instance a brief interrupt-controller overload.

Power States — from PHY Chip to AUTOSAR Modes

A modern automotive PHY knows more internal power states than just "on" and "off." These PHY-internal power states are the hardware foundation for what shows up at the AUTOSAR level as Eth_ModeType (the mode type also used by EthTrcv_SetTransceiverMode) and sleep handling.

PHY-internal power states            AUTOSAR view (simplified)
──────────────────────────           ──────────────────────────
┌───────────────┐
│    Normal      │  link active,     ┌─────────────────────┐
│  (full power)  │  transmission runs│ ETH_MODE_ACTIVE      │
└───────┬────────┘                   └─────────────────────┘
        │ no traffic,
        │ link stays up
        ▼
┌───────────────┐                    ┌─────────────────────┐
│  Standby /     │  link held,       │ ETH_MODE_ACTIVE      │
│  low-power idle│  reduced power    │ (with reduced        │
│                │  consumption      │  internal activity)  │
└───────┬────────┘                   └─────────────────────┘
        │ sleep request
        │ (EcuM sleep sequence)
        ▼
┌───────────────┐                    ┌─────────────────────┐
│    Sleep       │  link inactive,   │ ETH_MODE_DOWN /      │
│                │  PHY waits for a  │ sleep state via      │
│                │  wakeup event     │ vendor-specific API  │
└───────┬────────┘                   └─────────────────────┘
        │ wakeup pulse on the line
        ▼
┌───────────────┐                    ┌─────────────────────┐
│  Wake-up /     │  PHY powers up,   │ EthTrcv_CheckWakeup()│
│  boot          │  register access  │ → EcuM wakeup chain  │
│                │  possible again   │                      │
└────────────────┘                   └─────────────────────┘
PHY stateMeaning

Normal (full power)

All analog and digital blocks active, PHY transmits and receives at full power consumption. Corresponds to ETH_MODE_ACTIVE with the link up.

Standby / low-power idle

The link stays physically up, but the transmit/receive circuitry reduces its activity while no traffic is pending. From software’s perspective the link still looks active — the power saving happens transparently inside the PHY.

Sleep

The PHY drastically reduces power consumption, the link is no longer active. The PHY keeps monitoring the line for a defined wakeup signal. On the AUTOSAR side this typically corresponds to a transition into ETH_MODE_DOWN combined with a vendor-specific sleep request issued over MDIO registers.

Wake-up / boot

Transitional state in which the PHY powers back up after detecting a wakeup event. On the software side, this transition feeds into the EcuM wakeup handling via EthTrcv_CheckWakeup.

The mapping between these PHY-internal power states and AUTOSAR modes is not specified 1:1 — it’s implemented via vendor-specific MDIO registers. The SWS defines Eth_ModeType with the values ETH_MODE_DOWN, ETH_MODE_ACTIVE, and ETH_MODE_ACTIVE_WITH_WAKEUP_REQUEST — but what genuine low-power sleep with wakeup capability looks like at the PHY register level, in many implementations, runs through additional, non-standardized functions of the PHY driver, or directly through register sequences configured in ARXML.

Wakeup detection itself — which signal pattern on the line counts as a valid wakeup, and how the PHY signals that to the SoC via the INH pin — is again a topic that sits at the boundary to electronics, and is covered in detail in the hardware deep dive post.

Summary

TopicKey takeaway for software developers

PHY architecture

PCS (coding), PMA (signal conversion), and MDI (physical connection) are three separate functional blocks — often mirrored directly in the datasheet’s register layout

EthTrcv_Init

Triggers a multi-stage sequence (reset, boot, ID check, configuration) that partly runs asynchronously — the call itself doesn’t yet produce a link

MDIO

Control bus to the PHY; register-level detail is covered in a dedicated MDIO post

Signal processing

Scrambling, encoding (e.g. PAM3), error correction, and echo cancellation run entirely inside the PHY — visible to software only indirectly via status registers

Link training (100BASE-T1)

Iterative filter adaptation can make the first link establishment take several hundred milliseconds up to seconds — that’s normal, not a fault

MAC-PHY interface

MII/RMII/RGMII are hardware decisions reflected in configuration parameters; full electrical detail lives in the hardware deep dive

Interrupt vs. polling

Both approaches ultimately read link state over MDIO; interrupts only move up the timing of that read

Power states

PHY-internal states (normal, standby, sleep) map only partially 1:1 onto Eth_ModeType — sleep/wakeup often runs through vendor-specific mechanisms