Skip to content

Latest commit

 

History

History
226 lines (160 loc) · 11.4 KB

File metadata and controls

226 lines (160 loc) · 11.4 KB

SPC-6 ASIC SerDes Precoding via media_settings.json — HLD

Table of Content


1. Revision

Rev Date Author Change Description
0.1 2026-05-12 Natanel Gerbi Initial draft.

Tracking:


2. Scope

This HLD covers ASIC/SerDes precoding configuration on SPC-6 platforms while APSU is not yet supported by firmware.

In scope:

  1. Extending media_settings.json with per-lane tx_precoding / rx_precoding fields.
  2. Extending orchagent (PortsOrch) to map the new fields to SAI_PORT_SERDES_ATTR_{TX,RX}_PRECODING.

xcvrd requires no parser change — its data path is already field-agnostic (§7.2).


3. Definitions

Term Definition
CMIS Common Management Interface Specification
iLT Initial Link Training — per-lane electrical handshake between switch SERDES and module host CDR
APSU Autonomous Path Start-Up (IEEE 802.3dj Annex 178B) — end-to-end protocol that extends iLT with in-band precoding negotiation
Precoding Gray-coding applied at Tx SERDES to prevent DFE error propagation on PAM4 links
SPC-6 Spectrum-6 ASIC family
SAI Switch Abstraction Interface

4. Background

iLT adapts equalization on the local electrical segment between switch SERDES and module CDR. APSU extends iLT so that the two link ends also negotiate precoding in-band, without manual intervention.

Until module FW supports APSU, there is no automatic precoding negotiation: switch SERDES and module each come up with their own defaults which may not match, preventing link training. SONiC must therefore configure precoding on the ASIC/SERDES side to match what the module expects.


5. Requirements

# Requirement
R1 Precoding shall be configured on the ASIC/SERDES side.
R2 The standard SONiC/SAI flow (media_settings.json → APP_DB → SAI) shall be used.
R3 The flow shall be a no-op on platforms / modules where media_settings.json does not declare precoding fields (back-compat).

Assumption. SAI_PORT_SERDES_ATTR_TX_PRECODING and SAI_PORT_SERDES_ATTR_RX_PRECODING are already supported by NV SAI.


6. Architecture Design

End-to-end flow — same path used today by every other SI parameter (pre1, main, idriver, …):

flowchart TD
    JSON[["media_settings.json<br/>+ tx_precoding<br/>+ rx_precoding"]]
    XCVRD["xcvrd<br/>(field-agnostic parser)"]
    DB[("APP_DB:PORT_TABLE")]
    ORCH["orchagent<br/>(PortsOrch)"]
    SAI["SAI_PORT_SERDES_ATTR_<br/>TX/RX_PRECODING"]

    JSON -->|"1. read"| XCVRD
    XCVRD -->|"2. HSET fields"| DB
    DB -->|"3. notify on change"| ORCH
    ORCH -->|"4. create port_serdes"| SAI

    style JSON fill:#e8f5e9,stroke:#2e7d32,color:#000
    style DB   fill:#e3f2fd,stroke:#1565c0,color:#000
    style SAI  fill:#fff8e1,stroke:#f9a825,color:#000
Loading

Steps:

  1. xcvrd reads media_settings.json — on module insert (or boot), it locates the entry that matches the inserted module's <EEPROM_VENDOR_NAME>-<EEPROM_VENDOR_PN> and active <SPEED_KEY>.
  2. xcvrd writes the matched SI fields to APP_DB:PORT_TABLE|<lport> via HSET, including the new tx_precoding / rx_precoding keys when present.
  3. orchagent is notified of the APP_DB:PORT_TABLE change and runs PortsOrch::parsePortConfig, which populates PortSerdes_t from the FV list — including the two new per-lane vectors.
  4. orchagent creates the port-serdes SAI object with the resulting PortSerdesAttrMap_t. When tx_precoding / rx_precoding are set, the map includes SAI_PORT_SERDES_ATTR_{TX,RX}_PRECODING and SAI programs the ASIC SerDes accordingly.

Key property: only media_settings.json content and orchagent's per-field mapping table change. xcvrd and the Redis schema are reused as-is.


7. High-Level Design

7.1 media_settings.json schema additions

Two new keys are added under each speed:<lane_speed_key> block, using the same per-lane shape as the existing parameters (pre1, main, etc.):

  • tx_precoding — per-lane Tx precoding (0x0 = DISABLE, 0x1 = ENABLE).
  • rx_precoding — per-lane Rx precoding

Example — one global entry that matches a specific vendor + PN pattern for ports 1–64 at speed 200GAUI-1, programming tx_precoding and rx_precoding to ENABLE on all 8 lanes alongside the existing SI parameters (pre1, main, …):

{
  "GLOBAL_MEDIA_SETTINGS": {
    "1-64": {
      "VENDOR-MODEL-XX[AB]": {
        "speed:200GAUI-1": {
          "pre1": { "lane0": "0x00000000",
                    "...": "..."
                  },
          "main": { "lane0": "0x0000003f", 
                    "...": "..."
                  },
          "tx_precoding": {
            "lane0": "0x00000001",
            "...": "...",
            "lane7": "0x00000001"
          },
          "rx_precoding": {
            "lane0": "0x00000001",
            "...": "...",
            "lane7": "0x00000001"
          }
        }
      }
    }
  }
}

Key shape:

Element Meaning
1-64 Front-panel port range the entry applies to.
VENDOR-MODEL-XX[AB] Regex matched against <EEPROM_VENDOR_NAME_UPPER>-<EEPROM_VENDOR_PN> of the inserted module.
speed:200GAUI-1 Lane-speed bucket — speed: + first whitespace-token of CMIS host_electrical_interface_id.
lane0lane<N-1> One per-lane value, (for precoding - hex; 0x1 = ENABLE, 0x0 = DISABLE).

The schema is fully back-compatible — platforms that do not need precoding simply omit the fields. Concrete per-(vendor, PN, speed) values for additional modules are platform-/vendor-specific and live in the platform's media_settings.json; they are not enumerated in this HLD.

Flow — adding a new module

When a new module family is qualified for an SPC-6 platform:

  1. SI/PHY team determines the per-lane tx_precoding and rx_precoding (if needed) values for that module at each relevant lane-speed bucket.
  2. Platform owner adds a new <VENDOR_PN_REGEX> entry under the relevant <PORT_RANGE> of the platform's media_settings.json, with the per-lane values from step 1 under each speed:<key> block (same shape as the example above).

7.2 xcvrd

No code change. media_settings_parser.to_db_value() is field-agnostic — it emits a FieldValuePair for every per-lane key in the matched JSON section. tx_precoding / rx_precoding ride the same path as pre1, main, etc.

7.3 orchagent

PortsOrch already owns the SAI port-serdes object for every port. It keeps a per-port in-memory cache with one slot per SI field (pre1, main, idriver, …); each slot stores the per-lane values and an is_set marker. The SAI attributes are CREATE_ONLY, so any change to the cache is applied by remove_port_serdes + create_port_serdes, with the cumulative set of slots currently marked as set.

Adding precoding means giving that cache two new slots — one for tx_precoding, one for rx_precoding — and wiring them into the same machinery. The flow below is the existing PortsOrch pipeline; this HLD plugs in at steps 2 and 3 only.

  1. Receive change. PortsOrch reads the FV pairs that xcvrd just HSET-ed into APP_DB:PORT_TABLE for the port.
  2. Parse into cache. PortsOrch matches each field name against its schema; for every known SI field it stores the per-lane values into the matching cache slot and marks the slot as set. This HLD adds two new field-name matches — tx_precoding and rx_precoding — each writing into its own new cache slot.
  3. Build attribute list. PortsOrch walks the cache and assembles the SAI attribute list, including only slots that are marked as set. This HLD adds two new "if marked-set → SAI attribute" entries: tx_precodingSAI_PORT_SERDES_ATTR_TX_PRECODING, rx_precodingSAI_PORT_SERDES_ATTR_RX_PRECODING.
  4. Re-create SAI object. PortsOrch removes the existing port-serdes SAI object and creates a new one with the attribute list from step 3.
  5. Program ASIC. SAI / SDK translate the attributes into per-lane SerDes register writes.

No new control flow, no new DB consumer, no new object lifecycle.

APP_DB field PortSerdes_t member SAI attribute
tx_precoding serdes.tx_precoding SAI_PORT_SERDES_ATTR_TX_PRECODING
rx_precoding serdes.rx_precoding SAI_PORT_SERDES_ATTR_RX_PRECODING

Files touched (each row maps to the step it implements):

File Step Change
orchagent/port/portschema.h 2 Two new field-name string constants (PORT_TX_PRECODING, PORT_RX_PRECODING) — the strings the parser matches against when walking the FV list.
orchagent/port/portcnt.h 2 Two new per-lane slots under PortSerdes_t (tx_precoding, rx_precoding) — the in-memory cache entries that hold parsed values + is_set.
orchagent/port/porthlpr.cpp 2 Two new else if branches in the parser dispatch that route the new field names into the slots above, plus the corresponding parsePortSerdes template instantiations.
orchagent/portsorch.cpp 3 Two new if (serdes.{tx,rx}_precoding.is_set) blocks in the SerDes attribute-map builder — each emits the matching SAI attribute (SAI_PORT_SERDES_ATTR_{TX,RX}_PRECODING) only when its slot is marked set.

8. Configuration and Management


9. Testing

# Test Validates
UT1 portsorch_ut.cpp::PortAdvancedConfig (extended) PortHelper::parsePortSerdes accepts tx_precoding / rx_precoding; the resulting SAI attribute map contains SAI_PORT_SERDES_ATTR_TX_PRECODING / RX_PRECODING with the per-lane values from APP_DB.

System-level link bring-up testing on real SPC-6 hardware is covered by the SI / system test plan and is out of scope for this HLD.


10. Open Items / Future Work