From 6eb2531bd7ec4eb1fe25ed18990547da5e2fe8bf Mon Sep 17 00:00:00 2001 From: duanchunming Date: Tue, 4 Aug 2026 14:18:20 +0800 Subject: [PATCH] Broadcom Bailly CPO oe/rlm/mcu firmware upgrade. Signed-off-by: duanchunming --- .../CPO-Firmware-Upgrade-CMD.md | 384 ++++++++++++++++++ .../CPO-Firmware-Upgrade-CMIS-Bailly-API.md | 279 +++++++++++++ 2 files changed, 663 insertions(+) create mode 100644 doc/layer1/CPO Firmware Upgrade/CPO-Firmware-Upgrade-CMD.md create mode 100644 doc/layer1/CPO Firmware Upgrade/CPO-Firmware-Upgrade-CMIS-Bailly-API.md diff --git a/doc/layer1/CPO Firmware Upgrade/CPO-Firmware-Upgrade-CMD.md b/doc/layer1/CPO Firmware Upgrade/CPO-Firmware-Upgrade-CMD.md new file mode 100644 index 00000000000..4287521611f --- /dev/null +++ b/doc/layer1/CPO Firmware Upgrade/CPO-Firmware-Upgrade-CMD.md @@ -0,0 +1,384 @@ +# CPO Firmware Upgrade Command + +## Table of Contents + +- [CPO Firmware Upgrade Command](#cpo-firmware-upgrade-command) + - [Table of Contents](#table-of-contents) + - [1. Revision](#1-revision) + - [2. Scope](#2-scope) + - [3. Definitions/Abbreviations](#3-definitionsabbreviations) + - [4. Background](#4-background) + - [4.1 Traditional Transceiver Default Pattern](#41-traditional-transceiver-default-pattern) + - [4.2 CPO Architecture Speciality](#42-cpo-architecture-speciality) + - [5. Proposed CLI](#5-proposed-cli) + - [5.1 Unified Command Syntax](#51-unified-command-syntax) + - [5.2 Port-based Operations](#52-port-based-operations) + - [5.2.1 unlock (support --password)](#521-unlock-support---password) + - [5.2.2 download](#522-download) + - [5.2.3 run](#523-run) + - [5.2.4 commit](#524-commit) + - [5.2.5 upgrade (one-step full flow, support --password)](#525-upgrade-one-step-full-flow-support---password) + - [5.3 Global Bulk Upgrade with -a Flag](#53-global-bulk-upgrade-with--a-flag) + - [5.4 show firmware vesion](#54-show-firmware-vesion) + - [6. High-Level Design](#6-high-level-design) + - [7. Target Resolution](#7-target-resolution) + - [8. Firmware Upgrade Execution Sequence Constraint](#8-firmware-upgrade-execution-sequence-constraint) + - [9. Locking \& Concurrency](#9-locking--concurrency) + - [10. Status \& Version Display](#10-status--version-display) + - [11. Command to CPO CMIS API Mapping](#11-command-to-cpo-cmis-api-mapping) + - [12. Test Plan](#12-test-plan) + +## 1. Revision + +| Rev | Date | Author | Change Description | +| --- | ---------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 0.1 | 2026-08-02 | KroosMicas | Initial version | +| 0.2 | 2026-08-07 | KroosMicas | Rework CLI: port-based as default;
add -a for all ports bulk upgrade;
Add full command ↔ CPO CMIS API mapping chapter, API implementation reference HLD: CPO Firmware Upgrade CMIS Bailly API | + +## 2. Scope + +This HLD defines SONiC support for **CPO firmware upgrade** via `cpoutil firmware` command model. + +Key design points: + +1. Port-based operations are the default user interface, consistent with traditional `sfputil` transceiver operation habit. +2. Add single optional `-a` flag to perform bulk upgrade for all CPO ports on platform; +3. Mandatory mcu/oe/els subcommand is added before port target: + Actions without firmware file (unlock/run/commit) cannot parse package to auto-detect component type, must explicitly specify target component. + Download/upgrade with firmware file also unify the same CLI format for consistent syntax. +4. CPO architecture has multiple ports sharing one MCU/OE/ELS partition; CLI automatically maps input port to corresponding backend hardware instance. + +Firmware-bearing entities inside CPO vModule: + +* MCU / CMIS controller +* OE (Optical Engine / PRISM) +* ELS (External Laser Source / RLM) + +## 3. Definitions/Abbreviations + +| **Term** | **Definition/Abbreviations** | +| -------------- | ----------------------------------------- | +| CDB | Command Data Block | +| CMIS | Common Management Interface Specification | +| optoe | Optical Transceiver Open EEPROM driver | +| EPL | Extended Payload | +| CPO | Co-packaged optics | +| OE | Optical Engine / PRISM | +| ELS/RLM | External Laser Sources | +| MCU | Microprogrammed Control Unit | + +## 4. Background + +### 4.1 Traditional Transceiver Default Pattern + +Traditional sfputil firmware operations are port-based: + +``` +sfputil firmware unlock Ethernet0 +sfputil firmware download Ethernet0 +sfputil firmware run Ethernet0 +sfputil firmware commit Ethernet +sfputil firmware upgrade Ethernet0 +``` + +### 4.2 CPO Architecture Speciality + +CPO breaks one-port-one-module mapping: multiple front panel Ethernet ports share a single MCU/OE/ELS hardware partition. + +* Port-based input remains default for daily operation. +* `-a` flag provides one-click full-platform bulk upgrade for production deployment. +* For actions without firmware binary input (`unlock / run / commit`), there is no package header to parse and auto-judge target component type. Thus, `mcu/oe/els` subcommand must be explicitly specified in all firmware commands to clarify which partition the operation acts on. + +## 5. Proposed CLI + +### 5.1 Unified Command Syntax + +``` +cpoutil firmware {EthernetX | -a} [fw_package] [--password ] +Usage: + : unlock / download / run / commit / upgrade + : mandatory mcu / oe / els + Target selector: either single port EthernetX (default) or -a (all CPO ports bulk) + [fw_package]: optional, only required for download / upgrade + [--password ]: optional parameter only valid for unlock / upgrade actions +``` + + + + + +### 5.2 Port-based Operations + +Behavior: + +* Explicit component subcommand defines target partition; +* Resolve all ports sharing the same target component instance, print affected port list and prompt user confirmation `[N/Y]`. + +#### 5.2.1 unlock (support --password) + +``` +cpoutil firmware unlock mcu Ethernet0 --password 123456 +cpoutil firmware unlock oe Ethernet0 +cpoutil firmware unlock els Ethernet0 --password abcdef +``` + +#### 5.2.2 download + +``` +cpoutil firmware download mcu Ethernet0 mcu.bin +cpoutil firmware download oe Ethernet0 oe.bin +cpoutil firmware download els Ethernet0 rlm.bin +``` + +#### 5.2.3 run + +``` +cpoutil firmware run mcu Ethernet0 +cpoutil firmware run oe Ethernet0 +cpoutil firmware run els Ethernet0 +``` + +#### 5.2.4 commit + +``` +cpoutil firmware commit mcu Ethernet0 +cpoutil firmware commit oe Ethernet0 +cpoutil firmware commit els Ethernet0 +``` + +#### 5.2.5 upgrade (one-step full flow, support --password) + +``` +cpoutil firmware upgrade mcu Ethernet0 mcu.bin --password 123456 +cpoutil firmware upgrade oe Ethernet0 oe.bin +cpoutil firmware upgrade els Ethernet0 rlm.bin --password abcdef +``` + +### 5.3 Global Bulk Upgrade with -a Flag + +Append -a flag to command to trigger upgrade for all CPO ports on platform; no port argument needed. + +``` +# unlock bulk +cpoutil firmware unlock mcu -a --password 123456 +cpoutil firmware unlock oe -a +# download bulk +cpoutil firmware download oe -a oe.bin +# run bulk +cpoutil firmware run els -a +# commit bulk +cpoutil firmware commit mcu -a +# upgrade bulk +cpoutil firmware upgrade els -a rlm.bin --password abcdef +``` + +Bulk upgrade behavior: + +1. Enumerate all valid CPO ports from cpo.json config automatically. +2. Execute component-specific workflow sequentially for every port. +3. Print full port list affected before workflow start, require user confirmation. +4. Acquire global chassis lock to block other CPO firmware operations during bulk upgrade. +5. Restriction: Cannot mix Ethernet port argument and -a flag in one command, parser throws syntax error. + +### 5.4 show firmware vesion + +Consistent component + port / -a syntax: + +``` +# Single port component version +cpoutil show fwversion mcu Ethernet0 +cpoutil show fwversion oe Ethernet0 +cpoutil show fwversion els Ethernet0 + +# Dump target component version of all CPO ports +cpoutil show fwversion mcu -a +cpoutil show fwversion oe -a +cpoutil show fwversion els -a +``` + +## 6. High-Level Design + +``` +cpoutil firmware {EthernetX | -a} [fw_package] + ↓ +CPO target resolver + ├─ If EthernetX: map port to bound mcu/oe/els component instance + └─ If -a: expand to all CPO ports for specified component + ↓ +CPO firmware upgrade manager (locking + user confirmation prompt) + ↓ +CpoCmisApi CDB upgrade handler + ↓ +CdbFw / XcvrEeprom + ↓ +optoe / CMIS CDB access + ↓ +I2C MCU / OE / ELS hardware +``` + +**Component Roles** + +| Component | Responsibility | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| cpoutil | CLI parser; enforce mandatory mcu/oe/els subcommand; distinguish port target vs`-a` bulk flag; reject mixed port + `-a` input | +| CPO target resolver | 1. Map Ethernet port to bound MCU/OE/ELS entity
2. Expand`-a`flag to full list of all CPO ports
3. Collect all dependent ports for confirmation prompt | +| CPO firmware upgrade manager | Manage instance/chassis lock; list affected ports/hardware and wait user confirmation before running CDB workflow | +| CpoCmisApi CDB upgrade handler | Execute standard CDB command sequence (0x0100/0101/0102/0104/0107/0109/010A) | +| CdbFw | CMIS/CDB XcvrEeprom read-write API | +| optoe driver | CMIS EEPROM low-level access | + +## 7. Target Resolution + +**Case 1 Single Port Operation** + +``` +cpoutil firmware upgrade oe Ethernet0 oe_fw.bin + ↓ +Resolver map Ethernet0 to bound OE instance + ↓ +Prompt all shared affected ports, wait Y confirmation,defaut is N(Not upgrade). +eg:This will affect Ethernet0 Ethernet8 Ethernet16 Ethernet24 Ethernet32 Ethernet40 Ethernet48 Ethernet56, Are you sure you want to continue? [N/Y] + ↓ +Execute full OE upgrade CDB sequence +``` + +**Case 2 Bulk -a All Ports Operation +** + +``` +cpoutil firmware run mcu -a + ↓ +Enumerate all CPO ports on chassis bound to MCU + ↓ +Print full port list, request user confirmation +eg:This will affect all Ports, Are you sure you want to continue? [N/Y] + ↓ +Acquire chassis global lock, sequentially run MCU run operation for all ports +``` + +## 8. Firmware Upgrade Execution Sequence Constraint + +Hardware cross-partition dependency rule enforced by upgrade manager: + +1. If user intends to upgrade multiple partition types (OE -> MCU/ELS): + + The full OE workflow `unlock → download → run → commit` must finish completely before triggering any MCU or ELS upgrade command. +2. System check before every MCU/ELS upgrade entry: + + CPO manager query OE firmware running & committed status via CDB 0x0100 status API. + + If OE upgrade incomplete / uncommitted, reject MCU/ELS upgrade and output error prompt: + + `Error: OE firmware upgrade flow unfinished, complete OE unlock/download/run/commit first before MCU/ELS operation` +3. MCU and ELS upgrade have same sequential restriction with OE + +## 9. Locking & Concurrency + +| Target Mode | Lock Scope | Restriction Rules | +| ---------------------- | --------------------------------------- | ------------------------------------------------------------- | +| mcu/oe/els + EthernetX | Only hardware entity bound to this port | Block concurrent operations targeting same MCU/OE/ELS | +| mcu/oe/els + -a | Entire chassis all CPO hardware | Block all other cpoutil firmware commands during bulk upgrade | + +General rules: + +* Block overlapping upgrades sharing same underlying MCU/OE/ELS resource +* Disable all firmware operations during warm / fast reboot +* `-a` bulk upgrade holds exclusive highest priority chassis lock + +## 10. Status & Version Display + +Single port query output + +``` +cpoutil show fwversion mcu Ethernet0 +``` + +Example output: + +``` +MCU (CMIS): + Active: 1.2.0 + Inactive: 1.3.0 +``` + +Full platform dump with -a + +``` +cpoutil show fwversion oe -a +``` + +Iterate every CPO port and print corresponding MCU/OE/ELS version info one by one. + +## 11. Command ↔ Standard CDB Handler API Mapping + +All underlying API implementation logic refers to independent design document: **HLD: CPO Firmware Upgrade CMIS Bailly API** + +**Common Rule** + +1. Unified community standard `CdbFwHandler` methods reused for all partitions; no custom function names. +2. Partition differentiation via dedicated handle instances: + * MCU partition: `api.cdb_mcu_fw_hdlr` + * OE partition: `api.cdb_oe_fw_hdlr` + * ELS partition: `api.cdb_els_fw_hdlr` +3. Composite `upgrade` command internally invokes full sequence: `enter_password → start_fw_download → write block loop → complete_fw_download → run_fw_image → commit_fw_image` +4. All CDB opcode mapping aligns with base CdbFwHandler definition: + +| Handler Method | CDB Opcode | Function Description | +| ------------------------------ | ---------- | ------------------------------------------------ | +| enter_password(password) | 0x0001 | CDB authentication unlock | +| get_fw_status() | 0x0100 | Query firmware bank status & last command result | +| start_fw_download(imgpath) | 0x0101 | Initialize firmware download session | +| abort_fw_download() | 0x0102 | Terminate incomplete download session | +| write_lpl_block(address, data) | 0x0103 | Write LPL payload chunk | +| write_epl_block(address, data) | 0x0104 | Write EPL payload chunk | +| complete_fw_download() | 0x0107 | Finish download & trigger MCU image validation | +| run_fw_image(mode) | 0x0109 | Switch active firmware bank & soft reset | +| commit_fw_image() | 0x010A | Persist running image to non-volatile boot bank | + +**Full Mapping Table** + +| CLI Command Segment | Target Partition Handler Call Logic | +| ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| cpoutil firmware unlock mcu {port/-a} [--password pwd] | `api.cdb_mcu_fw_hdlr.enter_password(password)` | +| cpoutil firmware unlock oe {port/-a} [--password pwd] | `api.cdb_oe_fw_hdlr.enter_password(password)` | +| cpoutil firmware unlock els {port/-a} [--password pwd] | `api.cdb_els_fw_hdlr.enter_password(password)` | +| cpoutil show fwversion mcu {port/-a} | `api.cdb_mcu_fw_hdlr.get_fw_status()`(0x0100) | +| cpoutil show fwversion oe {port/-a} | `api.cdb_oe_fw_hdlr.get_fw_status()`(0x0100) | +| cpoutil show fwversion els {port/-a} | `api.cdb_els_fw_hdlr.get_fw_status()`(0x0100) | +| cpoutil firmware download mcu {port/-a} img | 1.`api.cdb_mcu_fw_hdlr.start_fw_download(imgpath)`(0x0101)
2. Loop`write_lpl_block`/`write_epl_block`(0x0103/0x0104)
3.`api.cdb_mcu_fw_hdlr.complete_fw_download()`(0x0107) | +| cpoutil firmware download oe {port/-a} img | 1.`api.cdb_oe_fw_hdlr.start_fw_download(imgpath)`(0x0101)
2. Loop`write_lpl_block`/`write_epl_block`(0x0103/0x0104,)
3.`api.cdb_oe_fw_hdlr.complete_fw_download()`(0x0107) | +| cpoutil firmware download els {port/-a} img | 1.`api.cdb_els_fw_hdlr.start_fw_download(imgpath)`(0x0101)
2. Loop`write_lpl_block`/`write_epl_block`(0x0103/0x0104)
3.`api.cdb_els_fw_hdlr.complete_fw_download()`(0x0107) | +| cpoutil firmware run mcu {port/-a} | `api.cdb_mcu_fw_hdlr.run_fw_image(mode=0x01)`(0x0109) | +| cpoutil firmware run oe {port/-a} | `api.cdb_oe_fw_hdlr.run_fw_image(mode=0x01)`(0x0109) | +| cpoutil firmware run els {port/-a} | `api.cdb_els_fw_hdlr.run_fw_image(mode=0x01)`(0x0109) | +| cpoutil firmware commit mcu {port/-a} | `api.cdb_mcu_fw_hdlr.commit_fw_image()`(0x010A) | +| cpoutil firmware commit oe {port/-a} | `api.cdb_oe_fw_hdlr.commit_fw_image()`(0x010A) | +| cpoutil firmware commit els {port/-a} | `api.cdb_els_fw_hdlr.commit_fw_image()`(0x010A) | +| cpoutil firmware upgrade mcu {port/-a} img [--password pwd] | Composite sequential calls:
1.`cdb_mcu_fw_hdlr.enter_password(password)`
2. Full download sequence (start + block write + complete)
3.`cdb_mcu_fw_hdlr.run_fw_image()`
4.`cdb_mcu_fw_hdlr.commit_fw_image()` | +| cpoutil firmware upgrade oe {port/-a} img [--password pwd] | Composite sequential calls:
1.`cdb_oe_fw_hdlr.enter_password(password)`
2. Full download sequence (start + block write + complete)
3.`cdb_oe_fw_hdlr.run_fw_image()`
4.`cdb_oe_fw_hdlr.commit_fw_image()` | +| cpoutil firmware upgrade els {port/-a} img [--password pwd] | Composite sequential calls:
1.`cdb_els_fw_hdlr.enter_password(password)`
2. Full download sequence (start + block write + complete)
3.`cdb_els_fw_hdlr.run_fw_image()`
4.`cdb_els_fw_hdlr.commit_fw_image()` | + +## 12. Test Plan + +**Unit Tests** + +* CLI parser validation: port as default target, support `-a` flag, reject port + `-a` mixed input +* CLI parser verify mcu/oe/els is mandatory subcommand, reject commands missing component. +* `-a` flag enumerates all CPO ports defined in cpo.json +* Port-to-component mapping lookup correctness. + +**Integration Tests** + +* Single port full workflow: unlock → download → run → commit and upgrade for mcu/oe/els respectively. +* `-a` bulk upgrade all CPO ports end-to-end +* Confirm user prompt lists all affected ports for single port and `-a` mode +* Post-upgrade version verification via `show fwversion` single port / `-a` + +**Negative Tests** + +* Mix Ethernet port and `-a` flag in one command (syntax error rejected) +* Missing mcu/oe/els subcommand (CLI syntax error rejected). +* Invalid port name or unsupported component keyword. +* Concurrent firmware operation on same hardware entity (blocked by lock) +* Execute firmware commands during warm/fast reboot (rejected) +* Interrupted upgrade recovery for single port and `-a` bulk upgrade mode diff --git a/doc/layer1/CPO Firmware Upgrade/CPO-Firmware-Upgrade-CMIS-Bailly-API.md b/doc/layer1/CPO Firmware Upgrade/CPO-Firmware-Upgrade-CMIS-Bailly-API.md new file mode 100644 index 00000000000..218c37934a1 --- /dev/null +++ b/doc/layer1/CPO Firmware Upgrade/CPO-Firmware-Upgrade-CMIS-Bailly-API.md @@ -0,0 +1,279 @@ +`class BaillyApi(CmisApi):class BaillyApi(CmisApi):` + +# HLD: CPO Firmware Upgrade CMIS Bailly API + +## Table of Contents + +- [HLD: CPO Firmware Upgrade CMIS Bailly API](#hld-cpo-firmware-upgrade-cmis-bailly-api) + - [Table of Contents](#table-of-contents) + - [1. Revision](#1-revision) + - [2. Scope](#2-scope) + - [3. Background \& Class Hierarchy](#3-background--class-hierarchy) + - [3.1 Original Community Class Structure](#31-original-community-class-structure) + - [3.2 CPO Extension Architecture Adjustment](#32-cpo-extension-architecture-adjustment) + - [3.3. Class Inheritance Design](#33-class-inheritance-design) + - [4. CDB Opcode Reuse \& Override Rule](#4-cdb-opcode-reuse--override-rule) + - [4.1 Default Reuse Rule](#41-default-reuse-rule) + - [4.2 Example Implementation of BaillyCdbFwHandler](#42-example-implementation-of-baillycdbfwhandler) + - [5. Full CDB Command Call Flow (Unchanged Upper Layer)](#5-full-cdb-command-call-flow-unchanged-upper-layer) + - [6. Core Design Benefits](#6-core-design-benefits) + - [7. Open Items](#7-open-items) + - [8. Summary](#8-summary) + +## 1. Revision + +| Rev | Date | Author | Change Description | +| --- | ------------ | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 0.1 | 2026-08-02 | KroosMicas | Initial version: Focus on extending base`CdbFwHandler` via inheritance for CPO; reuse standard 0x0100/0101/0102/0104/0107/0109/010A CDB commands, override only differentiated logic | +| 0.2 | 2026‑08‑08 | KroosMicas | Split three independent handler`McuCdbFwHandler` / `OeCdbFwHandler` / `ElsCdbFwHandler` for MCU / OE / ELS partitions; | + +## 2. Scope + +This HLD only covers the CDB firmware handler extension design inside CPO firmware upgrade stack, **excludes CLI layer**. +Core design principle: + +1. Reuse community base `CdbFwHandler` as parent class for all standard CDB firmware opcodes (0x0100,0x0101,0x0102,0x0104,0x0107,0x0109,0x010A). +2. Create three vendor‑specific sub‑classes inherited from CdbFwHandler: + 1. `McuCdbFwHandler: for MCU / CMIS controller partition` + 2. `OeCdbFwHandler: for OE / PRISM partition` + 3. `ElsCdbFwHandler: for ELS‑RLM partition` +3. Inheritance chain: `CmisCdbFw` → `CmisApi(CmisCdbFw, XcvrApi)` → `BaillyApi(CmisApi)`. +4. `BaillyApi` adds **three new properties** : `cdb_mcu_fw_hdlr`, `cdb_oe_fw_hdlr`, `cdb_els_fw_hdlr`. Each property lazy‑instantiates its corresponding partition handler instance. +5. All upper-layer firmware flow logic inside `CmisCdbFw` remains unchanged, transparent to caller. + +> Note: The original single overridden `cdb_fw_hdlr` property from parent `CmisCdbFw` is **not used** for CPO multi‑partition scenario. CPO uses three newly‑added partition‑specific handler properties instead. + +## 3. Background & Class Hierarchy + +### 3.1 Original Community Class Structure + +```python +# Base CDB firmware handler with all 7 standard CDB firmware opcodes +class CdbFwHandler: + def get_fw_status(self): # 0x0100 + def start_fw_download(self): # 0x0101 + def abort_fw_download(self): # 0x0102 + def write_lpl_block(self): # 0x0103 LPL + def write_epl_block(self): # 0x0104 EPL + def complete_fw_download(self):# 0x0107 + def run_fw_image(self): # 0x0109 + def commit_fw_image(self): # 0x010A + +# CDB firmware capability wrapper, provides high-level upgrade APIs +class CmisCdbFw: + @property + def cdb_fw_hdlr(self): + if self._cdb_fw_hdlr is None: + self._cdb_fw_hdlr = self._create_cdb_fw_handler() + return self._cdb_fw_hdlr + + def _create_cdb_fw_handler(self): + # Default: create standard base handler + return CdbFwHandler(self.xcvr_eeprom.reader, self.xcvr_eeprom.writer, self._cdb_mem_map) + +# Unified CMIS transceiver API, inherits CmisCdbFw to get all CDB firmware methods +class CmisApi(CmisCdbFw, XcvrApi): + pass +``` + +- `CmisCdbFw` is the upper API layer, all firmware operations forward to `self._cdb_fw_hdlr`; +- Base `CdbFwHandler` implements standard CMIS CDB firmware command logic for common pluggable modules; +- Bailly‑CPO hardware contains three independent firmware partitions (MCU, OE, ELS‑RLM). Each partition needs its own isolated handler instance.CPO hardware (MCU/OE/ELS partitioned firmware) has customized CDB processing logic for partial opcodes, so inheritance extension is introduce. + +### 3.2 CPO Extension Architecture Adjustment + +Step 1: Vendor partition‑specific handler sub‑classes, inherit community CdbFwHandler + +```Python +class McuCdbFwHandler(CdbFwHandler): + """Handler dedicated for MCU / CMIS controller partition""" + def __init__(self, reader, writer, cdb_map): + super().__init__(reader, writer, cdb_map) + # Re‑use parent method by default; override only MCU‑specific opcode logic if needed + +class OeCdbFwHandler(CdbFwHandler): + """Handler dedicated for OE / PRISM partition""" + def __init__(self, reader, writer, cdb_map): + super().__init__(reader, writer, cdb_map) + # Example: OE needs strip 4‑byte start‑address header during EPL write + def write_epl_block(self, address, data): + stripped_data = data[4:] + return super().write_epl_block(address, stripped_data) + +class ElsCdbFwHandler(CdbFwHandler): + """Handler dedicated for ELS‑RLM partition""" + def __init__(self, reader, writer, cdb_map): + super().__init__(reader, writer, cdb_map) + # Re‑use parent method by default; override only ELS‑RLM‑specific opcode logic if needed +``` + +Step 2: BaillyApi(CmisApi) adds three lazy‑load handler properties + +```Python +class BaillyApi(CmisApi): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._cdb_mcu_fw_hdlr = None + self._cdb_oe_fw_hdlr = None + self._cdb_els_fw_hdlr = None + + @property + def cdb_mcu_fw_hdlr(self): + """Lazy‑load handler for MCU partition""" + if not self._init_cdb_fw_handler: + return None + if self._cdb_mcu_fw_hdlr is None: + self._cdb_mcu_fw_hdlr = McuCdbFwHandler( + self.xcvr_eeprom.reader, + self.xcvr_eeprom.writer, + self._cdb_mem_map, + ) + return self._cdb_mcu_fw_hdlr + + @property + def cdb_oe_fw_hdlr(self): + """Lazy‑load handler for OE partition""" + if not self._init_cdb_fw_handler: + return None + if self._cdb_oe_fw_hdlr is None: + self._cdb_oe_fw_hdlr = OeCdbFwHandler( + self.xcvr_eeprom.reader, + self.xcvr_eeprom.writer, + self._cdb_mem_map, + ) + return self._cdb_oe_fw_hdlr + + @property + def cdb_els_fw_hdlr(self): + """Lazy‑load handler for ELS‑RLM partition""" + if not self._init_cdb_fw_handler: + return None + if self._cdb_els_fw_hdlr is None: + self._cdb_els_fw_hdlr = ElsCdbFwHandler( + self.xcvr_eeprom.reader, + self.xcvr_eeprom.writer, + self._cdb_mem_map, + ) + return self._cdb_els_fw_hdlr +``` + +note: + +`BaillyApi` **does NOT modify / override parent `cdb_fw_hdlr` property** inherited from `CmisCdbFw`. + +The original `cdb_fw_hdlr` remains available for traditional single‑partition CMIS module compatibility, but **is not used by CPO firmware upgrade workflow** . + +CPO business layer explicitly selects `cdb_mcu_fw_hdlr` / `cdb_oe_fw_hdlr` / `cdb_els_fw_hdlr` according to target component. + +### 3.3. Class Inheritance Design + +``` +Community Base Handler + └── CdbFwHandler + ├─ McuCdbFwHandler (CPO‑MCU vendor subclass) + ├─ OeCdbFwHandler (CPO‑OE vendor subclass) + └─ ElsCdbFwHandler (CPO‑ELS‑RLM vendor subclass) + +Community API hierarchy +CmisCdbFw + ↓ +CmisApi(CmisCdbFw, XcvrApi) + ↓ +BaillyApi(CmisApi) + ├─ @property cdb_mcu_fw_hdlr → returns McuCdbFwHandler instance + ├─ @property cdb_oe_fw_hdlr → returns OeCdbFwHandler instance + └─ @property cdb_els_fw_hdlr → returns ElsCdbFwHandler instance +``` + +* `CmisApi` inherits `CmisCdbFw`, so it owns the original `cdb_fw_hdlr` property and all high-level firmware APIs (`module_fw_download`, `module_fw_run`, etc.). +* `BaillyApi` inherits `CmisApi`, and overrides the `cdb_fw_hdlr` property. +* When any firmware API inside `CmisCdbFw` accesses `self.cdb_fw_hdlr`, it will resolve to the overridden property in `BaillyApi`, returning `BaillyCdbFwHandler` instance. +* No changes required to `CmisCdbFw`, `CmisApi`, or any upper calling logic; vendor differentiation is fully encapsulated in `BaillyApi` + `BaillyCdbFwHandler`. + +## 4. CDB Opcode Reuse & Override Rule + +### 4.1 Default Reuse Rule + +Each partition handler (`McuCdbFwHandler` / `OeCdbFwHandler` / `ElsCdbFwHandler`) inherits all methods from base `CdbFwHandler`: + +1. If partition processing logic conforms to standard CMIS CDB specification: **do NOT override** , directly call parent class implementation. +2. If partition requires special register offset, payload pre‑processing, partition‑specific handshake sequence: override corresponding method inside that partition’s handler class only. + +Mapping between CDB opcode and base handler method: + +| CDB Opcode | Base`CdbFwHandler`Method | Reuse Policy | +| ---------- | -------------------------- | ---------------------------------------------------------------------------------------- | +| 0x0001 | enter_password(password) | Default reuse parent; override if partition has special auth flow | +| 0x0100 | get_fw_status() | Default reuse parent; override only when partition status register layout differs | +| 0x0101 | start_fw_download() | Default reuse parent; override if partition needs special initialization before download | +| 0x0102 | abort_fw_download() | Default reuse parent; override only for partition‑specific cleanup | +| 0x0103 | write_lpl_block() | Default reuse parent | +| 0x0104 | write_epl_block() | Default reuse parent; e.g. OE overrides for header‑stripping | +| 0x0107 | complete_fw_download() | Default reuse parent; override if partition adds extra CRC / metadata check | +| 0x0109 | run_fw_image() | Default reuse parent; override for partition‑specific reset mode | +| 0x010A | commit_fw_image() | Default reuse parent; override for partition non‑volatile persist logic | + +### 4.2 Handler Sub‑class Example Implementation + +```python +class OeCdbFwHandler(CdbFwHandler): + def __init__(self, reader, writer, cdb_map): + super().__init__(reader, writer, cdb_map) + + # No override → transparently use parent: get_fw_status(), start_fw_download(), abort_fw_download() + + def write_epl_block(self, address, data): + """OE partition special: strip leading 4‑byte hardware start‑address header from payload""" + stripped_data = data[4:] + return super().write_epl_block(address, stripped_data) + + # Other methods reuse base‑class implementation without modification +``` + +## 5. Full CDB Command Call Flow (Unchanged Upper Layer) + +Upper business layer (CPO firmware upgrade manager from cpoutil HLD) selects corresponding handler property according to target component(mcu / oe / els): + +``` +BaillyApi instance + ├─ When target component = mcu → self.cdb_mcu_fw_hdlr (McuCdbFwHandler) + ├─ When target component = oe → self.cdb_oe_fw_hdlr (OeCdbFwHandler) + └─ When target component = els → self.cdb_els_fw_hdlr (ElsCdbFwHandler) + +Example for OE download flow: +api.cdb_oe_fw_hdlr.enter_password(password) #0x0001 +api.cdb_oe_fw_hdlr.start_fw_download(imgpath) #0x0101 +loop: api.cdb_oe_fw_hdlr.write_epl_block(address,data) #0x0104 (OE overridden version) +api.cdb_oe_fw_hdlr.complete_fw_download() #0x0107 +api.cdb_oe_fw_hdlr.run_fw_image(mode=0x01) #0x0109 +api.cdb_oe_fw_hdlr.commit_fw_image() #0x010A + +Status / recovery example: +api.cdb_oe_fw_hdlr.get_fw_status() #0x0100 +api.cdb_oe_fw_hdlr.abort_fw_download() #0x0102 +``` + +* All low‑level opcode logic is encapsulated inside each partition handler instance. +* Upper layer business code only selects which handler property to invoke; does not modify any opcode implementation. +* Upstream community classes `CmisCdbFw`, `CmisApi`, `CdbFwHandler` remain untouched. + +## 6. Core Design Benefits + +* **Zero intrusion to community upstream code** : All vendor‑specific logic is isolated inside three sub‑classes (`McuCdbFwHandler` / `OeCdbFwHandler` / `ElsCdbFwHandler`) and `BaillyApi` extended properties. No patches to `CmisCdbFw` / `CmisApi` / `CdbFwHandler`. +* **Partition isolation** : MCU / OE / ELS each owns independent handler instance; state (download session, error status) is isolated per partition, no cross‑partition state pollution. +* **Fine‑grained override capability** : Only override the exact method that differs for a given partition; maximum reuse of standard CMIS‑CDB base‑class logic. +* **Consistent method signature** : Reuse community `CdbFwHandler` function signatures, no custom‑named vendor‑only APIs. Upper‑layer code uses uniform method interface across all three partitions. +* **Lazy‑instantiation** : Handler objects are created on first access; avoid unnecessary resource consumption for unused partitions. +* **Compliant with SONiC XcvrApi extension pattern** : Vendor‑specific `BaillyApi` inherits standard `CmisApi`. + +## 7. Open Items + +If any + +## 8. Summary + +* Inheritance tree: `CdbFwHandler` (community base) → three partition‑specific sub‑classes: `McuCdbFwHandler`, `OeCdbFwHandler`, `ElsCdbFwHandler`. +* `BaillyApi(CmisApi)` adds three new lazy‑load read‑only properties: `cdb_mcu_fw_hdlr`, `cdb_oe_fw_hdlr`, `cdb_els_fw_hdlr`. Each property instantiates its corresponding partition‑handler instance. +* Original parent‑class `cdb_fw_hdlr` property from `CmisCdbFw` is preserved for compatibility but **not used by CPO multi‑partition upgrade workflow** . +* Each partition handler reuses base `CdbFwHandler` opcode‑methods by default; override only when hardware partition requires special processing. +* Upper‑level upgrade manager selects correct handler property by target component(mcu / oe / els), then invoke standard handler methods; community upstream source files are unchanged.