From 896ee4f71d437f7aa0860eb14907d4be59795e4a Mon Sep 17 00:00:00 2001 From: Longyin Huang Date: Mon, 28 Aug 2023 16:20:18 -0700 Subject: [PATCH 01/28] Add auto-fec.md --- auto-fec.md | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 auto-fec.md diff --git a/auto-fec.md b/auto-fec.md new file mode 100644 index 00000000000..769b8f3e72c --- /dev/null +++ b/auto-fec.md @@ -0,0 +1,116 @@ +```mermaid +sequenceDiagram + title Auto-FEC in the case of DPB + + participant user as User + participant dpb_cli as today's DPB CLI + participant auto_fec as auto-FEC module/API + participant plat_json as platform.json + participant config_db as CONFIG_DB + participant syncd as SYNCD + + user ->>+ dpb_cli: breakout on a port + note over dpb_cli: run today's logic + dpb_cli ->>+ dpb_cli: generate the config(speed/num_lanes/etc) for new sub ports + note over dpb_cli: run added logic + dpb_cli ->>+ auto_fec: call API determine_fec(port_speed, num_lanes, optics_type=None) + auto_fec ->>+ plat_json: read FEC matrix section + plat_json -->>- auto_fec: return + auto_fec -->>- dpb_cli: return FEC mode calculated based on FEC matrix + + dpb_cli ->>+ config_db: Add new port in PORT table with proper FEC + config_db -->>- dpb_cli: Done + + dpb_cli -->>- user: Done + config_db ->>+ syncd: notify for new port + +``` + +```mermaid +sequenceDiagram + title Auto-FEC in the case of non-DPB + + participant user as User + participant fec_correct_cli as FEC correction CLI
(just a wrapper) + participant auto_fec as auto-FEC module/API + participant plat_json as platform.json + participant state_db as STATE_DB + participant config_db as CONFIG_DB + participant syncd as SYNCD + + user ->>+ fec_correct_cli: auto-correct FEC mode for all ports + fec_correct_cli ->>+ auto_fec: call API correct_fec_for_all_ports() + + auto_fec ->>+ state_db: read optics_type from TRANSCEIVER_INFO table + state_db -->>- auto_fec: return + + auto_fec ->>+ auto_fec: call API determine_fec(port_speed, num_lanes, optics_type) + auto_fec ->>+ plat_json: read FEC matrix section + plat_json -->>- auto_fec: return + auto_fec -->>- auto_fec: calculate FEC mode based on FEC matrix + auto_fec ->>+ config_db: update FEC if needed + config_db -->>- auto_fec: Done + auto_fec -->>- fec_correct_cli: Done + fec_correct_cli -->>- user: Done + + config_db ->>+ syncd: notify for FEC update + +``` + +FEC matrix in platform.json: +``` +{ +"fec_matrix": [ + { + "port_speed": 10, + "num_lanes": 4, + "fec": ["none", "kr"] + }, + { + "port_speed": 20, + "num_lanes": 2, + "fec": ["none"] + }, + { + "port_speed": 25, + "num_lanes": 2, + "fec": ["none", "rs(kp4/kr4)"] + }, + { + "port_speed": 25, + "num_lanes": 4, + "fec": ["none", "rs(kp4/kr4)"] + }, + { + "port_speed": 25, + "num_lanes": 8, + "fec": ["rs kp4"] + }, + { + "port_speed": 50, + "num_lanes": 1, + "fec": ["rs(kp4/kr4)"] + }, + { + "port_speed": 50, + "num_lanes": 4, + "fec": ["rs(kp4)"] + }, + { + "port_speed": 50, + "num_lanes": 8, + "fec": ["rs(kp4)"] + }, + { + "port_speed": 50, + "num_lanes": 16, + "fec": ["rs(kp4)"] + }, + { + "port_speed": 50, + "num_lanes": 2, + "fec": ["rs(kp4/kr4/kp4_fi)"] + } +] +} +``` \ No newline at end of file From c19407c8b0bf5e274bffd91cd54d5304fffc7f8c Mon Sep 17 00:00:00 2001 From: Longyin Huang Date: Wed, 30 Aug 2023 12:39:36 -0700 Subject: [PATCH 02/28] Update doc and location --- auto-fec.md | 116 ------------------------------- doc/port-fec/auto-fec.md | 143 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+), 116 deletions(-) delete mode 100644 auto-fec.md create mode 100644 doc/port-fec/auto-fec.md diff --git a/auto-fec.md b/auto-fec.md deleted file mode 100644 index 769b8f3e72c..00000000000 --- a/auto-fec.md +++ /dev/null @@ -1,116 +0,0 @@ -```mermaid -sequenceDiagram - title Auto-FEC in the case of DPB - - participant user as User - participant dpb_cli as today's DPB CLI - participant auto_fec as auto-FEC module/API - participant plat_json as platform.json - participant config_db as CONFIG_DB - participant syncd as SYNCD - - user ->>+ dpb_cli: breakout on a port - note over dpb_cli: run today's logic - dpb_cli ->>+ dpb_cli: generate the config(speed/num_lanes/etc) for new sub ports - note over dpb_cli: run added logic - dpb_cli ->>+ auto_fec: call API determine_fec(port_speed, num_lanes, optics_type=None) - auto_fec ->>+ plat_json: read FEC matrix section - plat_json -->>- auto_fec: return - auto_fec -->>- dpb_cli: return FEC mode calculated based on FEC matrix - - dpb_cli ->>+ config_db: Add new port in PORT table with proper FEC - config_db -->>- dpb_cli: Done - - dpb_cli -->>- user: Done - config_db ->>+ syncd: notify for new port - -``` - -```mermaid -sequenceDiagram - title Auto-FEC in the case of non-DPB - - participant user as User - participant fec_correct_cli as FEC correction CLI
(just a wrapper) - participant auto_fec as auto-FEC module/API - participant plat_json as platform.json - participant state_db as STATE_DB - participant config_db as CONFIG_DB - participant syncd as SYNCD - - user ->>+ fec_correct_cli: auto-correct FEC mode for all ports - fec_correct_cli ->>+ auto_fec: call API correct_fec_for_all_ports() - - auto_fec ->>+ state_db: read optics_type from TRANSCEIVER_INFO table - state_db -->>- auto_fec: return - - auto_fec ->>+ auto_fec: call API determine_fec(port_speed, num_lanes, optics_type) - auto_fec ->>+ plat_json: read FEC matrix section - plat_json -->>- auto_fec: return - auto_fec -->>- auto_fec: calculate FEC mode based on FEC matrix - auto_fec ->>+ config_db: update FEC if needed - config_db -->>- auto_fec: Done - auto_fec -->>- fec_correct_cli: Done - fec_correct_cli -->>- user: Done - - config_db ->>+ syncd: notify for FEC update - -``` - -FEC matrix in platform.json: -``` -{ -"fec_matrix": [ - { - "port_speed": 10, - "num_lanes": 4, - "fec": ["none", "kr"] - }, - { - "port_speed": 20, - "num_lanes": 2, - "fec": ["none"] - }, - { - "port_speed": 25, - "num_lanes": 2, - "fec": ["none", "rs(kp4/kr4)"] - }, - { - "port_speed": 25, - "num_lanes": 4, - "fec": ["none", "rs(kp4/kr4)"] - }, - { - "port_speed": 25, - "num_lanes": 8, - "fec": ["rs kp4"] - }, - { - "port_speed": 50, - "num_lanes": 1, - "fec": ["rs(kp4/kr4)"] - }, - { - "port_speed": 50, - "num_lanes": 4, - "fec": ["rs(kp4)"] - }, - { - "port_speed": 50, - "num_lanes": 8, - "fec": ["rs(kp4)"] - }, - { - "port_speed": 50, - "num_lanes": 16, - "fec": ["rs(kp4)"] - }, - { - "port_speed": 50, - "num_lanes": 2, - "fec": ["rs(kp4/kr4/kp4_fi)"] - } -] -} -``` \ No newline at end of file diff --git a/doc/port-fec/auto-fec.md b/doc/port-fec/auto-fec.md new file mode 100644 index 00000000000..bdda4c471a3 --- /dev/null +++ b/doc/port-fec/auto-fec.md @@ -0,0 +1,143 @@ +```mermaid +sequenceDiagram + title Auto-FEC in the case of breakout + + actor user as User + participant dpb_cli as today's DPB CLI + participant auto_fec as auto-FEC module + participant config_db as CONFIG_DB + participant syncd as SYNCD + + + user ->>+ dpb_cli: do breakout on a port + note over dpb_cli: run today's logic per port: + dpb_cli ->>+ dpb_cli: generate the config(speed/lanes/etc) for each new port + + alt FEC mapping section exists in platform.json + note over dpb_cli,auto_fec: run below additional logic per port: + dpb_cli ->>+ auto_fec: call API determine_fec(lane_speed, num_lanes, optics_type=None) per port + auto_fec ->>+ auto_fec: calculate FEC mode based on FEC mapping obtained from platform.json + auto_fec -->>- dpb_cli: return FEC mode + end + + dpb_cli ->>+ config_db: Add new ports in PORT table (today's workflow),
additionally with proper FEC if determined above
instead of FEC=none as default + + par + config_db -->>- dpb_cli: Done + and + config_db ->>+ syncd: notify for new port creation + end + + dpb_cli -->>- user: Done +``` + +```mermaid +sequenceDiagram + title Auto-FEC in the case of non-breakout + + actor user as User + participant fec_correct_cli as FEC correction CLI
(just a wrapper) + participant auto_fec as auto-FEC module + participant state_db as STATE_DB + participant config_db as CONFIG_DB + participant syncd as SYNCD + + user ->>+ fec_correct_cli: auto-correct FEC mode for all ports + fec_correct_cli ->>+ auto_fec: call API correct_fec_for_all_ports() + + alt FEC mapping table exists in platform.json + loop every port + auto_fec ->>+ state_db: read optics_type from TRANSCEIVER_INFO table + state_db -->>- auto_fec: return optics_type + auto_fec ->>+ auto_fec: internally call API determine_fec(lane_speed, num_lanes, optics_type)
which calculates FEC mode based on FEC mapping obtained from platform.json + end + + auto_fec ->>+ config_db: update FEC if needed + + par + config_db -->>- auto_fec: Done + and + config_db ->>+ syncd: notify for FEC update + end + end + + auto_fec -->>- fec_correct_cli: Done + fec_correct_cli -->>- user: Done + +``` + +> [!NOTE] +> In the above usecases, user needs to save config, so that changed FEC modes can be saved to config_db.json, and persists across config/system reload. + + +FEC mapping in platform.json: +1. In fec_mapping_based_on_speed_lane, If there are both rs and none in the field of "fec", preferably choose rs +2. If a port has a matched entry in both fec_mapping_based_on_speed_lane and fec_mapping_based_on_optics_type, then prefers fec_mapping_based_on_optics_type. +``` +{ +"fec_mapping_based_on_speed_lane": [ + { + "lane_speed": 10, + "num_lanes": 4, + "fec": ["none", "kr"] + }, + { + "lane_speed": 20, + "num_lanes": 2, + "fec": ["none"] + }, + { + "lane_speed": 25, + "num_lanes": 2, + "fec": ["none", "rs(kp4/kr4)"] + }, + { + "lane_speed": 25, + "num_lanes": 4, + "fec": ["none", "rs(kp4/kr4)"] + }, + { + "lane_speed": 25, + "num_lanes": 8, + "fec": ["rs kp4"] + }, + { + "lane_speed": 50, + "num_lanes": 1, + "fec": ["rs(kp4/kr4)"] + }, + { + "lane_speed": 50, + "num_lanes": 4, + "fec": ["rs(kp4)"] + }, + { + "lane_speed": 50, + "num_lanes": 8, + "fec": ["rs(kp4)"] + }, + { + "lane_speed": 50, + "num_lanes": 16, + "fec": ["rs(kp4)"] + }, + { + "lane_speed": 50, + "num_lanes": 2, + "fec": ["rs(kp4/kr4/kp4_fi)"] + } +] + +"fec_mapping_based_on_optics_type": [ + { + "optics_type": "100G-DR", + "fec": ["none"] + }, + { + "optics_type": "100G-FR", + "fec": ["none"] + } + .... +] +} +``` From bc66360484c1a5c6f32ea142b48e34b947977dac Mon Sep 17 00:00:00 2001 From: longhuan-cisco <84595962+longhuan-cisco@users.noreply.github.com> Date: Wed, 30 Aug 2023 12:54:05 -0700 Subject: [PATCH 03/28] Update auto-fec.md --- doc/port-fec/auto-fec.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/port-fec/auto-fec.md b/doc/port-fec/auto-fec.md index bdda4c471a3..4aaa04e24c6 100644 --- a/doc/port-fec/auto-fec.md +++ b/doc/port-fec/auto-fec.md @@ -1,3 +1,5 @@ +#### Flow For Breakout And Non-Breakout Use Cases + ```mermaid sequenceDiagram title Auto-FEC in the case of breakout @@ -69,6 +71,7 @@ sequenceDiagram > [!NOTE] > In the above usecases, user needs to save config, so that changed FEC modes can be saved to config_db.json, and persists across config/system reload. +#### Platform Support FEC mapping in platform.json: 1. In fec_mapping_based_on_speed_lane, If there are both rs and none in the field of "fec", preferably choose rs From d7736caa3cdc9418f8df89494a4d31a238cafe46 Mon Sep 17 00:00:00 2001 From: longhuan-cisco <84595962+longhuan-cisco@users.noreply.github.com> Date: Wed, 30 Aug 2023 12:56:08 -0700 Subject: [PATCH 04/28] Update auto-fec.md --- doc/port-fec/auto-fec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/port-fec/auto-fec.md b/doc/port-fec/auto-fec.md index 4aaa04e24c6..fd9c5fe9bf4 100644 --- a/doc/port-fec/auto-fec.md +++ b/doc/port-fec/auto-fec.md @@ -71,7 +71,7 @@ sequenceDiagram > [!NOTE] > In the above usecases, user needs to save config, so that changed FEC modes can be saved to config_db.json, and persists across config/system reload. -#### Platform Support +#### (optional) Platform Prequisite FEC mapping in platform.json: 1. In fec_mapping_based_on_speed_lane, If there are both rs and none in the field of "fec", preferably choose rs From da0afb2d81305b157d20189a5ec816783fa11277 Mon Sep 17 00:00:00 2001 From: Longyin Huang Date: Fri, 1 Sep 2023 11:45:09 -0700 Subject: [PATCH 05/28] Update doc --- doc/port-fec/auto-fec.md | 63 ++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/doc/port-fec/auto-fec.md b/doc/port-fec/auto-fec.md index fd9c5fe9bf4..aaf5c5c7fe3 100644 --- a/doc/port-fec/auto-fec.md +++ b/doc/port-fec/auto-fec.md @@ -17,7 +17,7 @@ sequenceDiagram alt FEC mapping section exists in platform.json note over dpb_cli,auto_fec: run below additional logic per port: - dpb_cli ->>+ auto_fec: call API determine_fec(lane_speed, num_lanes, optics_type=None) per port + dpb_cli ->>+ auto_fec: call API determine_fec(lane_speed, num_lanes) per port auto_fec ->>+ auto_fec: calculate FEC mode based on FEC mapping obtained from platform.json auto_fec -->>- dpb_cli: return FEC mode end @@ -71,18 +71,55 @@ sequenceDiagram > [!NOTE] > In the above usecases, user needs to save config, so that changed FEC modes can be saved to config_db.json, and persists across config/system reload. +#### API design +``` +def determine_fec(lane_speed: int, num_lanes: int, optics_type: Optional[str] = None) -> str: + """ + Determines the appropriate Forward Error Correction (FEC) type based on lane speed, number of lanes, and optics type for a specific port. + This logic is based on FEC mapping rules defined in platform.json. + + Parameters: + - lane_speed (int): The speed of each lane in GB. + - num_lanes (int): The total number of lanes. + - optics_type (Optional[str]): The type of optics in use. Can be None if not applicable. + + Returns: + - str: The recommended FEC type based on the rules in platform.json. + If no matched entry is found in the rules or no rules are defined in platform.json, return None. + + Example: + >>> determine_fec(25, 4, "100G-SR4") + "rs" + + """ +``` + #### (optional) Platform Prequisite -FEC mapping in platform.json: -1. In fec_mapping_based_on_speed_lane, If there are both rs and none in the field of "fec", preferably choose rs -2. If a port has a matched entry in both fec_mapping_based_on_speed_lane and fec_mapping_based_on_optics_type, then prefers fec_mapping_based_on_optics_type. +FEC mapping rules are defined in platform.json: +1. For now, there are two mapping rules + - ```fec_mapping_based_on_speed_lane```: This will be looked up if lane_speed and num_lanes are provided in parameters of determine_fec API. + - ```fec_mapping_based_on_optics_type```: This will be looked up if optics_type is provided in parameters of determine_fec API. +2. In ```fec_mapping_based_on_speed_lane```, if there are multiple FEC values (e.g. ```rs``` and ```none```) in the field of ```fec```, preferably choose the first value (in this example, ```rs```). +3. If a port has matched FEC entry in both ```fec_mapping_based_on_speed_lane``` and ```fec_mapping_based_on_optics_type```, then prefers FEC entry in ```fec_mapping_based_on_optics_type```, which is the first mapping rule defined in platform.json. ``` { +"fec_mapping_based_on_optics_type": [ + { + "optics_type": "100G-DR", + "fec": ["none"] + }, + { + "optics_type": "100G-FR", + "fec": ["none"] + } + .... +], "fec_mapping_based_on_speed_lane": [ { "lane_speed": 10, "num_lanes": 4, - "fec": ["none", "kr"] + "fec": ["kr", "none"] }, { "lane_speed": 20, @@ -92,12 +129,12 @@ FEC mapping in platform.json: { "lane_speed": 25, "num_lanes": 2, - "fec": ["none", "rs(kp4/kr4)"] + "fec": ["rs(kp4/kr4)", "none"] }, { "lane_speed": 25, "num_lanes": 4, - "fec": ["none", "rs(kp4/kr4)"] + "fec": ["rs(kp4/kr4)", "none"] }, { "lane_speed": 25, @@ -130,17 +167,5 @@ FEC mapping in platform.json: "fec": ["rs(kp4/kr4/kp4_fi)"] } ] - -"fec_mapping_based_on_optics_type": [ - { - "optics_type": "100G-DR", - "fec": ["none"] - }, - { - "optics_type": "100G-FR", - "fec": ["none"] - } - .... -] } ``` From e66d75981ea50068bbd46b5f90a53556574bd611 Mon Sep 17 00:00:00 2001 From: Longyin Huang Date: Fri, 1 Sep 2023 11:52:41 -0700 Subject: [PATCH 06/28] Update doc --- doc/port-fec/auto-fec.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/doc/port-fec/auto-fec.md b/doc/port-fec/auto-fec.md index aaf5c5c7fe3..6c60bfc329e 100644 --- a/doc/port-fec/auto-fec.md +++ b/doc/port-fec/auto-fec.md @@ -94,14 +94,15 @@ def determine_fec(lane_speed: int, num_lanes: int, optics_type: Optional[str] = """ ``` -#### (optional) Platform Prequisite +#### Platform Prequisite (optional) FEC mapping rules are defined in platform.json: -1. For now, there are two mapping rules +1. FEC mapping rule is optional in platform.json. If platform/vendor doesn't define it, it's no-op in terms of FEC auto determination. +2. For now, there are two mapping rules - ```fec_mapping_based_on_speed_lane```: This will be looked up if lane_speed and num_lanes are provided in parameters of determine_fec API. - ```fec_mapping_based_on_optics_type```: This will be looked up if optics_type is provided in parameters of determine_fec API. -2. In ```fec_mapping_based_on_speed_lane```, if there are multiple FEC values (e.g. ```rs``` and ```none```) in the field of ```fec```, preferably choose the first value (in this example, ```rs```). -3. If a port has matched FEC entry in both ```fec_mapping_based_on_speed_lane``` and ```fec_mapping_based_on_optics_type```, then prefers FEC entry in ```fec_mapping_based_on_optics_type```, which is the first mapping rule defined in platform.json. +3. In ```fec_mapping_based_on_speed_lane```, if there are multiple FEC values (e.g. ```rs``` and ```none```) in the field of ```fec```, preferably choose the first value (in this example, ```rs```). +4. If a port has matched FEC entry in both ```fec_mapping_based_on_speed_lane``` and ```fec_mapping_based_on_optics_type```, then prefers FEC entry in ```fec_mapping_based_on_optics_type```, which is the first mapping rule defined in platform.json. ``` { "fec_mapping_based_on_optics_type": [ From 435f37e2e290b87d90de443f5559d7f523ec3382 Mon Sep 17 00:00:00 2001 From: Longyin Huang Date: Fri, 1 Sep 2023 11:58:18 -0700 Subject: [PATCH 07/28] Update doc --- doc/port-fec/auto-fec.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/port-fec/auto-fec.md b/doc/port-fec/auto-fec.md index 6c60bfc329e..bfa656a08f4 100644 --- a/doc/port-fec/auto-fec.md +++ b/doc/port-fec/auto-fec.md @@ -22,6 +22,7 @@ sequenceDiagram auto_fec -->>- dpb_cli: return FEC mode end + note over dpb_cli, config_db: run today's logic: dpb_cli ->>+ config_db: Add new ports in PORT table (today's workflow),
additionally with proper FEC if determined above
instead of FEC=none as default par From affcb5473676507e31c37c38aee89a8ce930a5e8 Mon Sep 17 00:00:00 2001 From: Longyin Huang Date: Fri, 1 Sep 2023 11:59:26 -0700 Subject: [PATCH 08/28] Update doc --- doc/port-fec/auto-fec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/port-fec/auto-fec.md b/doc/port-fec/auto-fec.md index bfa656a08f4..091e17501b6 100644 --- a/doc/port-fec/auto-fec.md +++ b/doc/port-fec/auto-fec.md @@ -22,7 +22,7 @@ sequenceDiagram auto_fec -->>- dpb_cli: return FEC mode end - note over dpb_cli, config_db: run today's logic: + note over dpb_cli, syncd: run today's logic: dpb_cli ->>+ config_db: Add new ports in PORT table (today's workflow),
additionally with proper FEC if determined above
instead of FEC=none as default par From c7e586d3d61ff0d000b511b39396693ca1dbdd73 Mon Sep 17 00:00:00 2001 From: Longyin Huang Date: Fri, 1 Sep 2023 14:28:54 -0700 Subject: [PATCH 09/28] Update doc --- doc/port-fec/auto-fec.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/port-fec/auto-fec.md b/doc/port-fec/auto-fec.md index 091e17501b6..25811666cbe 100644 --- a/doc/port-fec/auto-fec.md +++ b/doc/port-fec/auto-fec.md @@ -1,4 +1,4 @@ -#### Flow For Breakout And Non-Breakout Use Cases +#### Flow For Different Use Cases ```mermaid sequenceDiagram @@ -70,7 +70,8 @@ sequenceDiagram ``` > [!NOTE] -> In the above usecases, user needs to save config, so that changed FEC modes can be saved to config_db.json, and persists across config/system reload. +> 1. In the above usecases, user needs to save config, so that changed FEC modes can be saved to config_db.json, and persists across config/system reload. +> 2. For non-braekout use case, in the future, auto-fec module can be further enhanced to integrated with xcvrd, which can be triggered automatically during transceiver insertion, without human intervention. #### API design ``` @@ -99,7 +100,7 @@ def determine_fec(lane_speed: int, num_lanes: int, optics_type: Optional[str] = FEC mapping rules are defined in platform.json: 1. FEC mapping rule is optional in platform.json. If platform/vendor doesn't define it, it's no-op in terms of FEC auto determination. -2. For now, there are two mapping rules +2. For now, there are two mapping rules (More rules can be added in the future if required) - ```fec_mapping_based_on_speed_lane```: This will be looked up if lane_speed and num_lanes are provided in parameters of determine_fec API. - ```fec_mapping_based_on_optics_type```: This will be looked up if optics_type is provided in parameters of determine_fec API. 3. In ```fec_mapping_based_on_speed_lane```, if there are multiple FEC values (e.g. ```rs``` and ```none```) in the field of ```fec```, preferably choose the first value (in this example, ```rs```). From b30210088aed6f3340c4dda3fb35b6d464a8585b Mon Sep 17 00:00:00 2001 From: Longyin Huang Date: Fri, 1 Sep 2023 14:29:49 -0700 Subject: [PATCH 10/28] Update doc --- doc/port-fec/auto-fec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/port-fec/auto-fec.md b/doc/port-fec/auto-fec.md index 25811666cbe..e53997e4cbf 100644 --- a/doc/port-fec/auto-fec.md +++ b/doc/port-fec/auto-fec.md @@ -71,7 +71,7 @@ sequenceDiagram > [!NOTE] > 1. In the above usecases, user needs to save config, so that changed FEC modes can be saved to config_db.json, and persists across config/system reload. -> 2. For non-braekout use case, in the future, auto-fec module can be further enhanced to integrated with xcvrd, which can be triggered automatically during transceiver insertion, without human intervention. +> 2. For non-breakout use case, in the future, auto-fec module can be further enhanced to integrated with xcvrd, which can be triggered automatically during transceiver insertion, without human intervention. #### API design ``` From aaf9f12b1e7295c2d19b9eec2b7242e97d069a5f Mon Sep 17 00:00:00 2001 From: Longyin Huang Date: Fri, 1 Sep 2023 14:55:44 -0700 Subject: [PATCH 11/28] Update doc --- doc/port-fec/auto-fec.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/doc/port-fec/auto-fec.md b/doc/port-fec/auto-fec.md index e53997e4cbf..bf3ed1eea5b 100644 --- a/doc/port-fec/auto-fec.md +++ b/doc/port-fec/auto-fec.md @@ -115,8 +115,19 @@ FEC mapping rules are defined in platform.json: { "optics_type": "100G-FR", "fec": ["none"] - } - .... + }, + { + "optics_type": "100G-LR", + "fec": ["none"] + }, + { + "optics_type": "100G AOC", + "fec": ["none"] + }, + { + "optics_type": "ALL_OTHER", + "fec": ["rs"] + }, ], "fec_mapping_based_on_speed_lane": [ { From 68afb3f4589580fb4160a723af77da57e6fe881b Mon Sep 17 00:00:00 2001 From: Longyin Huang Date: Wed, 6 Sep 2023 13:17:51 -0700 Subject: [PATCH 12/28] Update/rename doc --- .../{auto-fec.md => determine-fec.md} | 47 ++++++++++++------- 1 file changed, 31 insertions(+), 16 deletions(-) rename doc/port-fec/{auto-fec.md => determine-fec.md} (62%) diff --git a/doc/port-fec/auto-fec.md b/doc/port-fec/determine-fec.md similarity index 62% rename from doc/port-fec/auto-fec.md rename to doc/port-fec/determine-fec.md index bf3ed1eea5b..23713982e24 100644 --- a/doc/port-fec/auto-fec.md +++ b/doc/port-fec/determine-fec.md @@ -2,11 +2,11 @@ ```mermaid sequenceDiagram - title Auto-FEC in the case of breakout + title determine-FEC in the case of breakout actor user as User participant dpb_cli as today's DPB CLI - participant auto_fec as auto-FEC module + participant determine_fec as determine-FEC module participant config_db as CONFIG_DB participant syncd as SYNCD @@ -16,10 +16,10 @@ sequenceDiagram dpb_cli ->>+ dpb_cli: generate the config(speed/lanes/etc) for each new port alt FEC mapping section exists in platform.json - note over dpb_cli,auto_fec: run below additional logic per port: - dpb_cli ->>+ auto_fec: call API determine_fec(lane_speed, num_lanes) per port - auto_fec ->>+ auto_fec: calculate FEC mode based on FEC mapping obtained from platform.json - auto_fec -->>- dpb_cli: return FEC mode + note over dpb_cli,determine_fec: run below additional logic per port: + dpb_cli ->>+ determine_fec: call API determine_fec(lane_speed, num_lanes) per port + determine_fec ->>+ determine_fec: calculate FEC mode based on FEC mapping obtained from platform.json + determine_fec -->>- dpb_cli: return FEC mode end note over dpb_cli, syncd: run today's logic: @@ -36,42 +36,42 @@ sequenceDiagram ```mermaid sequenceDiagram - title Auto-FEC in the case of non-breakout + title determine-FEC in the case of non-breakout actor user as User participant fec_correct_cli as FEC correction CLI
(just a wrapper) - participant auto_fec as auto-FEC module + participant determine_fec as determine-FEC module participant state_db as STATE_DB participant config_db as CONFIG_DB participant syncd as SYNCD user ->>+ fec_correct_cli: auto-correct FEC mode for all ports - fec_correct_cli ->>+ auto_fec: call API correct_fec_for_all_ports() + fec_correct_cli ->>+ determine_fec: call API correct_fec_for_all_ports() alt FEC mapping table exists in platform.json loop every port - auto_fec ->>+ state_db: read optics_type from TRANSCEIVER_INFO table - state_db -->>- auto_fec: return optics_type - auto_fec ->>+ auto_fec: internally call API determine_fec(lane_speed, num_lanes, optics_type)
which calculates FEC mode based on FEC mapping obtained from platform.json + determine_fec ->>+ state_db: read optics_type from TRANSCEIVER_INFO table + state_db -->>- determine_fec: return optics_type + determine_fec ->>+ determine_fec: internally call API determine_fec(lane_speed, num_lanes, optics_type)
which calculates FEC mode based on FEC mapping obtained from platform.json end - auto_fec ->>+ config_db: update FEC if needed + determine_fec ->>+ config_db: update FEC if needed par - config_db -->>- auto_fec: Done + config_db -->>- determine_fec: Done and config_db ->>+ syncd: notify for FEC update end end - auto_fec -->>- fec_correct_cli: Done + determine_fec -->>- fec_correct_cli: Done fec_correct_cli -->>- user: Done ``` > [!NOTE] > 1. In the above usecases, user needs to save config, so that changed FEC modes can be saved to config_db.json, and persists across config/system reload. -> 2. For non-breakout use case, in the future, auto-fec module can be further enhanced to integrated with xcvrd, which can be triggered automatically during transceiver insertion, without human intervention. +> 2. For non-breakout use case, in the future, determine-fec module can be further enhanced to integrated with xcvrd, which can be triggered automatically during transceiver insertion, without human intervention. #### API design ``` @@ -183,3 +183,18 @@ FEC mapping rules are defined in platform.json: ] } ``` +#### Platform Common Dependency +A new ```optics_type``` field (human-readable type for optics, such as ```100G-DR```, ```100G-FR```, etc) will be added to TRANSCEIVER_INFO table, so that determine-FEC module can read it for the non-breakout use case. +Basically, ```optics_type``` can be determined based on today's transceiver_info, and be added as part of output of API [get_transceiver_info()](https://github.com/sonic-net/sonic-platform-common/blob/1988b37c7668394f38f155c86f5462a4461fe82e/sonic_platform_base/sonic_xcvr/api/xcvr_api.py#L42-L71) in ```sonic-platform-common``` repo. + +```optics_type``` field can also provide other benefits: +1. help user to easily and quickly identify what optics are plugged onto the router (if it can be added to show CLI output later) +2. test script can easily figure out the optics type based on this single ```optics_type``` field and do test actions accordingly. + +#### Difference between other design +1. [[FEC] Design for auto-fec](https://github.com/sonic-net/SONiC/pull/1416): + - FEC mode will be decided automatically at SAI/SDK(and HW) level as part of auto-negotiation feature, if auto-neg is implemented and enabled for this platform. + - fec=```auto``` in CONFIG_DB +2. determine-FEC module (this HLD's design): + - FEC mode will be decided automatically above CONFIG_DB level based on platform provided rules, and be pushed into CONFIG_DB. (flow: CONFIG_DB->syncd->orcagent->SAI/SDK) + - fec=```none```/```rs```/```fc``` in CONFIG_DB From d950f5d0c639348d889b015a1bdea69b16692d90 Mon Sep 17 00:00:00 2001 From: Longyin Huang Date: Wed, 6 Sep 2023 13:23:14 -0700 Subject: [PATCH 13/28] Update doc --- doc/port-fec/determine-fec.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/port-fec/determine-fec.md b/doc/port-fec/determine-fec.md index 23713982e24..3a25ee564df 100644 --- a/doc/port-fec/determine-fec.md +++ b/doc/port-fec/determine-fec.md @@ -185,10 +185,11 @@ FEC mapping rules are defined in platform.json: ``` #### Platform Common Dependency A new ```optics_type``` field (human-readable type for optics, such as ```100G-DR```, ```100G-FR```, etc) will be added to TRANSCEIVER_INFO table, so that determine-FEC module can read it for the non-breakout use case. -Basically, ```optics_type``` can be determined based on today's transceiver_info, and be added as part of output of API [get_transceiver_info()](https://github.com/sonic-net/sonic-platform-common/blob/1988b37c7668394f38f155c86f5462a4461fe82e/sonic_platform_base/sonic_xcvr/api/xcvr_api.py#L42-L71) in ```sonic-platform-common``` repo. -```optics_type``` field can also provide other benefits: -1. help user to easily and quickly identify what optics are plugged onto the router (if it can be added to show CLI output later) +To implement this, ```optics_type``` can be determined based on today's transceiver_info, and be added as part of output of API [get_transceiver_info()](https://github.com/sonic-net/sonic-platform-common/blob/1988b37c7668394f38f155c86f5462a4461fe82e/sonic_platform_base/sonic_xcvr/api/xcvr_api.py#L42-L71) in ```sonic-platform-common``` repo. + +```optics_type``` field can also provide benefits in readability/service-ability/debug-ability: +1. help user/engineer to easily and quickly identify what optics are plugged onto the router (if it can be added to show CLI output later) 2. test script can easily figure out the optics type based on this single ```optics_type``` field and do test actions accordingly. #### Difference between other design From 981cc55fdd29040eb5f22641cd7be91aee950836 Mon Sep 17 00:00:00 2001 From: Longyin Huang Date: Wed, 6 Sep 2023 13:28:21 -0700 Subject: [PATCH 14/28] Update doc --- doc/port-fec/determine-fec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/port-fec/determine-fec.md b/doc/port-fec/determine-fec.md index 3a25ee564df..673c29b88d9 100644 --- a/doc/port-fec/determine-fec.md +++ b/doc/port-fec/determine-fec.md @@ -70,7 +70,7 @@ sequenceDiagram ``` > [!NOTE] -> 1. In the above usecases, user needs to save config, so that changed FEC modes can be saved to config_db.json, and persists across config/system reload. +> 1. In the above use cases, automatically determined FEC mode is saved in running config, user needs to do ```config save``` to save it permanently, irregardless of config/system reload. > 2. For non-breakout use case, in the future, determine-fec module can be further enhanced to integrated with xcvrd, which can be triggered automatically during transceiver insertion, without human intervention. #### API design From b6c47ca96f9e5b26a4ae2c1ff0f9689dc23deed8 Mon Sep 17 00:00:00 2001 From: Longyin Huang Date: Wed, 6 Sep 2023 13:41:41 -0700 Subject: [PATCH 15/28] Update doc --- doc/port-fec/determine-fec.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/doc/port-fec/determine-fec.md b/doc/port-fec/determine-fec.md index 673c29b88d9..0a696db5aba 100644 --- a/doc/port-fec/determine-fec.md +++ b/doc/port-fec/determine-fec.md @@ -1,3 +1,8 @@ + +#### Background + +If not configured in CONFIG_DB, FEC mode is default to none, which might not be the correct FEC for this port/optics, and link might not come up. + #### Flow For Different Use Cases ```mermaid @@ -70,7 +75,7 @@ sequenceDiagram ``` > [!NOTE] -> 1. In the above use cases, automatically determined FEC mode is saved in running config, user needs to do ```config save``` to save it permanently, irregardless of config/system reload. +> 1. In the above use cases, automatically determined FEC mode is saved in running config, user needs to do ```config save``` to save it permanently, which will persist across config/system reload. > 2. For non-breakout use case, in the future, determine-fec module can be further enhanced to integrated with xcvrd, which can be triggered automatically during transceiver insertion, without human intervention. #### API design From 38a0123689d2f284d13468bf54c9d4d6829546d9 Mon Sep 17 00:00:00 2001 From: Longyin Huang Date: Wed, 6 Sep 2023 14:12:14 -0700 Subject: [PATCH 16/28] Update doc --- doc/port-fec/determine-fec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/port-fec/determine-fec.md b/doc/port-fec/determine-fec.md index 0a696db5aba..60e1a3dc574 100644 --- a/doc/port-fec/determine-fec.md +++ b/doc/port-fec/determine-fec.md @@ -91,7 +91,7 @@ def determine_fec(lane_speed: int, num_lanes: int, optics_type: Optional[str] = - optics_type (Optional[str]): The type of optics in use. Can be None if not applicable. Returns: - - str: The recommended FEC type based on the rules in platform.json. + - str: The recommended FEC type based on the rules in platform.json. It can be either 'none'/'rs'/'fc'. If no matched entry is found in the rules or no rules are defined in platform.json, return None. Example: From b6e1b64dec057dbfa4e06b4bbd3985a7aad7f70d Mon Sep 17 00:00:00 2001 From: Longyin Huang Date: Thu, 7 Sep 2023 11:20:17 -0700 Subject: [PATCH 17/28] Update doc --- doc/port-fec/determine-fec.md | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/doc/port-fec/determine-fec.md b/doc/port-fec/determine-fec.md index 60e1a3dc574..37d7884a9d0 100644 --- a/doc/port-fec/determine-fec.md +++ b/doc/port-fec/determine-fec.md @@ -129,6 +129,14 @@ FEC mapping rules are defined in platform.json: "optics_type": "100G AOC", "fec": ["none"] }, + { + "optics_type": "400G", + "fec": ["rs"] + }, + { + "optics_type": "40G", + "fec": ["fc"] + }, { "optics_type": "ALL_OTHER", "fec": ["rs"] @@ -138,7 +146,7 @@ FEC mapping rules are defined in platform.json: { "lane_speed": 10, "num_lanes": 4, - "fec": ["kr", "none"] + "fec": ["fc", "none"] }, { "lane_speed": 20, @@ -148,42 +156,42 @@ FEC mapping rules are defined in platform.json: { "lane_speed": 25, "num_lanes": 2, - "fec": ["rs(kp4/kr4)", "none"] + "fec": ["rs", "none"] }, { "lane_speed": 25, "num_lanes": 4, - "fec": ["rs(kp4/kr4)", "none"] + "fec": ["rs", "none"] }, { "lane_speed": 25, "num_lanes": 8, - "fec": ["rs kp4"] + "fec": ["rs"] }, { "lane_speed": 50, "num_lanes": 1, - "fec": ["rs(kp4/kr4)"] + "fec": ["rs"] }, { "lane_speed": 50, "num_lanes": 4, - "fec": ["rs(kp4)"] + "fec": ["rs"] }, { "lane_speed": 50, "num_lanes": 8, - "fec": ["rs(kp4)"] + "fec": ["rs"] }, { "lane_speed": 50, "num_lanes": 16, - "fec": ["rs(kp4)"] + "fec": ["rs"] }, { "lane_speed": 50, "num_lanes": 2, - "fec": ["rs(kp4/kr4/kp4_fi)"] + "fec": ["rs"] } ] } From 67cbd2aac9ad91f3e4d0cfcf85907465e42d2b19 Mon Sep 17 00:00:00 2001 From: Longyin Huang Date: Thu, 7 Sep 2023 11:25:26 -0700 Subject: [PATCH 18/28] Update doc --- doc/port-fec/determine-fec.md | 164 +++++++++++++++++----------------- 1 file changed, 82 insertions(+), 82 deletions(-) diff --git a/doc/port-fec/determine-fec.md b/doc/port-fec/determine-fec.md index 37d7884a9d0..3f107601bdc 100644 --- a/doc/port-fec/determine-fec.md +++ b/doc/port-fec/determine-fec.md @@ -112,88 +112,88 @@ FEC mapping rules are defined in platform.json: 4. If a port has matched FEC entry in both ```fec_mapping_based_on_speed_lane``` and ```fec_mapping_based_on_optics_type```, then prefers FEC entry in ```fec_mapping_based_on_optics_type```, which is the first mapping rule defined in platform.json. ``` { -"fec_mapping_based_on_optics_type": [ - { - "optics_type": "100G-DR", - "fec": ["none"] - }, - { - "optics_type": "100G-FR", - "fec": ["none"] - }, - { - "optics_type": "100G-LR", - "fec": ["none"] - }, - { - "optics_type": "100G AOC", - "fec": ["none"] - }, - { - "optics_type": "400G", - "fec": ["rs"] - }, - { - "optics_type": "40G", - "fec": ["fc"] - }, - { - "optics_type": "ALL_OTHER", - "fec": ["rs"] - }, -], -"fec_mapping_based_on_speed_lane": [ - { - "lane_speed": 10, - "num_lanes": 4, - "fec": ["fc", "none"] - }, - { - "lane_speed": 20, - "num_lanes": 2, - "fec": ["none"] - }, - { - "lane_speed": 25, - "num_lanes": 2, - "fec": ["rs", "none"] - }, - { - "lane_speed": 25, - "num_lanes": 4, - "fec": ["rs", "none"] - }, - { - "lane_speed": 25, - "num_lanes": 8, - "fec": ["rs"] - }, - { - "lane_speed": 50, - "num_lanes": 1, - "fec": ["rs"] - }, - { - "lane_speed": 50, - "num_lanes": 4, - "fec": ["rs"] - }, - { - "lane_speed": 50, - "num_lanes": 8, - "fec": ["rs"] - }, - { - "lane_speed": 50, - "num_lanes": 16, - "fec": ["rs"] - }, - { - "lane_speed": 50, - "num_lanes": 2, - "fec": ["rs"] - } -] + "fec_mapping_based_on_optics_type": [ + { + "optics_type": "100G-DR", + "fec": ["none"] + }, + { + "optics_type": "100G-FR", + "fec": ["none"] + }, + { + "optics_type": "100G-LR", + "fec": ["none"] + }, + { + "optics_type": "100G AOC", + "fec": ["none"] + }, + { + "optics_type": "400G", + "fec": ["rs"] + }, + { + "optics_type": "40G", + "fec": ["fc"] + }, + { + "optics_type": "ALL_OTHER", + "fec": ["rs"] + }, + ], + "fec_mapping_based_on_speed_lane": [ + { + "lane_speed": 10, + "num_lanes": 4, + "fec": ["fc", "none"] + }, + { + "lane_speed": 20, + "num_lanes": 2, + "fec": ["none"] + }, + { + "lane_speed": 25, + "num_lanes": 2, + "fec": ["rs", "none"] + }, + { + "lane_speed": 25, + "num_lanes": 4, + "fec": ["rs", "none"] + }, + { + "lane_speed": 25, + "num_lanes": 8, + "fec": ["rs"] + }, + { + "lane_speed": 50, + "num_lanes": 1, + "fec": ["rs"] + }, + { + "lane_speed": 50, + "num_lanes": 4, + "fec": ["rs"] + }, + { + "lane_speed": 50, + "num_lanes": 8, + "fec": ["rs"] + }, + { + "lane_speed": 50, + "num_lanes": 16, + "fec": ["rs"] + }, + { + "lane_speed": 50, + "num_lanes": 2, + "fec": ["rs"] + } + ] } ``` #### Platform Common Dependency From 6a9a5e792d8930bb64c8044a6a1ddf5cf75db22f Mon Sep 17 00:00:00 2001 From: Longyin Huang Date: Fri, 8 Sep 2023 11:20:00 -0700 Subject: [PATCH 19/28] Update doc --- doc/port-fec/determine-fec.md | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/doc/port-fec/determine-fec.md b/doc/port-fec/determine-fec.md index 3f107601bdc..1ca2b0633c9 100644 --- a/doc/port-fec/determine-fec.md +++ b/doc/port-fec/determine-fec.md @@ -109,10 +109,18 @@ FEC mapping rules are defined in platform.json: - ```fec_mapping_based_on_speed_lane```: This will be looked up if lane_speed and num_lanes are provided in parameters of determine_fec API. - ```fec_mapping_based_on_optics_type```: This will be looked up if optics_type is provided in parameters of determine_fec API. 3. In ```fec_mapping_based_on_speed_lane```, if there are multiple FEC values (e.g. ```rs``` and ```none```) in the field of ```fec```, preferably choose the first value (in this example, ```rs```). -4. If a port has matched FEC entry in both ```fec_mapping_based_on_speed_lane``` and ```fec_mapping_based_on_optics_type```, then prefers FEC entry in ```fec_mapping_based_on_optics_type```, which is the first mapping rule defined in platform.json. +4. If a port has matched FEC entry in both ```fec_mapping_based_on_speed_lane``` and ```fec_mapping_based_on_optics_type```, then prefers FEC entry in ```fec_mapping_based_on_optics_type```, which is the first mapping rule defined in platform.json. (e.g. 100G-DR will have a match in both rules, the matched FEC entry in ```fec_mapping_based_on_optics_type``` will be preferably choosen, which is ```none```) + +Open questions: +1. What is FC FEC mode for 40G in [saiport.h](https://github.com/opencomputeproject/SAI/blob/4cb229c2d55cbe36c2ac10204d1fe4476f4937bd/inc/saiport.h#L191-L222)? what FEC we should put in ```fec_mapping_based_on_optics_type``` for ```optics_type=40G```? And what FEC to be put for ```lane_speed=10, num_lanes=4``` in ```fec_mapping_based_on_speed_lane```? +2. For ```100G-ER4``` ```100G-LR4``` and ```100G AOC```, shall we put FEC=rs for non-low-BER, and FEC=none for low-BER? And how do we tell if it's low-BER/non-low-BER based on optics_type? If optics_type is not enough to tell, what specific field we need to tell the BER, and shall we add another column in the mapping rule? ``` { "fec_mapping_based_on_optics_type": [ + { + "optics_type": "40G", + "fec": ["fc"] + }, { "optics_type": "100G-DR", "fec": ["none"] @@ -125,6 +133,14 @@ FEC mapping rules are defined in platform.json: "optics_type": "100G-LR", "fec": ["none"] }, + { + "optics_type": "100G-LR4", + "fec": ["none"] + }, + { + "optics_type": "100G-ER4", + "fec": ["none"] + }, { "optics_type": "100G AOC", "fec": ["none"] @@ -133,10 +149,6 @@ FEC mapping rules are defined in platform.json: "optics_type": "400G", "fec": ["rs"] }, - { - "optics_type": "40G", - "fec": ["fc"] - }, { "optics_type": "ALL_OTHER", "fec": ["rs"] @@ -175,24 +187,24 @@ FEC mapping rules are defined in platform.json: }, { "lane_speed": 50, - "num_lanes": 4, + "num_lanes": 2, "fec": ["rs"] }, { "lane_speed": 50, - "num_lanes": 8, + "num_lanes": 4, "fec": ["rs"] }, { "lane_speed": 50, - "num_lanes": 16, + "num_lanes": 8, "fec": ["rs"] }, { "lane_speed": 50, - "num_lanes": 2, + "num_lanes": 16, "fec": ["rs"] - } + }, ] } ``` From 1c0915d93383e9e9b1fc86d4cc0d9fa55bc3e76a Mon Sep 17 00:00:00 2001 From: Shyam <69485234+shyam77git@users.noreply.github.com> Date: Sun, 10 Sep 2023 15:05:37 -0700 Subject: [PATCH 20/28] Updated determine-fec.md section "Difference between other design" --- doc/port-fec/determine-fec.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/port-fec/determine-fec.md b/doc/port-fec/determine-fec.md index 1ca2b0633c9..0eb73d4d2d2 100644 --- a/doc/port-fec/determine-fec.md +++ b/doc/port-fec/determine-fec.md @@ -222,5 +222,6 @@ To implement this, ```optics_type``` can be determined based on today's transcei - FEC mode will be decided automatically at SAI/SDK(and HW) level as part of auto-negotiation feature, if auto-neg is implemented and enabled for this platform. - fec=```auto``` in CONFIG_DB 2. determine-FEC module (this HLD's design): - - FEC mode will be decided automatically above CONFIG_DB level based on platform provided rules, and be pushed into CONFIG_DB. (flow: CONFIG_DB->syncd->orcagent->SAI/SDK) + - FEC mode will be decided automatically above at system start-up at CONFIG_DB level, based on platform provided rules, and be pushed into CONFIG_DB. (flow: CONFIG_DB->syncd->orcagent->SAI/SDK) - fec=```none```/```rs```/```fc``` in CONFIG_DB + - Also, this mechanism/model helps determine right FEC for dynamic events, such as: DPB (Dynamic Port Breakout), transceivers/optics insertion (OIR) etc. From 8d743ca6ef4d3b42df16c6e614659e5e387f7373 Mon Sep 17 00:00:00 2001 From: Longyin Huang Date: Tue, 3 Oct 2023 15:21:43 -0700 Subject: [PATCH 21/28] Update doc and rename file --- doc/port-fec/determine-fec.md | 227 ------------------------- doc/port-fec/fec-auto-determination.md | 199 ++++++++++++++++++++++ 2 files changed, 199 insertions(+), 227 deletions(-) delete mode 100644 doc/port-fec/determine-fec.md create mode 100644 doc/port-fec/fec-auto-determination.md diff --git a/doc/port-fec/determine-fec.md b/doc/port-fec/determine-fec.md deleted file mode 100644 index 0eb73d4d2d2..00000000000 --- a/doc/port-fec/determine-fec.md +++ /dev/null @@ -1,227 +0,0 @@ - -#### Background - -If not configured in CONFIG_DB, FEC mode is default to none, which might not be the correct FEC for this port/optics, and link might not come up. - -#### Flow For Different Use Cases - -```mermaid -sequenceDiagram - title determine-FEC in the case of breakout - - actor user as User - participant dpb_cli as today's DPB CLI - participant determine_fec as determine-FEC module - participant config_db as CONFIG_DB - participant syncd as SYNCD - - - user ->>+ dpb_cli: do breakout on a port - note over dpb_cli: run today's logic per port: - dpb_cli ->>+ dpb_cli: generate the config(speed/lanes/etc) for each new port - - alt FEC mapping section exists in platform.json - note over dpb_cli,determine_fec: run below additional logic per port: - dpb_cli ->>+ determine_fec: call API determine_fec(lane_speed, num_lanes) per port - determine_fec ->>+ determine_fec: calculate FEC mode based on FEC mapping obtained from platform.json - determine_fec -->>- dpb_cli: return FEC mode - end - - note over dpb_cli, syncd: run today's logic: - dpb_cli ->>+ config_db: Add new ports in PORT table (today's workflow),
additionally with proper FEC if determined above
instead of FEC=none as default - - par - config_db -->>- dpb_cli: Done - and - config_db ->>+ syncd: notify for new port creation - end - - dpb_cli -->>- user: Done -``` - -```mermaid -sequenceDiagram - title determine-FEC in the case of non-breakout - - actor user as User - participant fec_correct_cli as FEC correction CLI
(just a wrapper) - participant determine_fec as determine-FEC module - participant state_db as STATE_DB - participant config_db as CONFIG_DB - participant syncd as SYNCD - - user ->>+ fec_correct_cli: auto-correct FEC mode for all ports - fec_correct_cli ->>+ determine_fec: call API correct_fec_for_all_ports() - - alt FEC mapping table exists in platform.json - loop every port - determine_fec ->>+ state_db: read optics_type from TRANSCEIVER_INFO table - state_db -->>- determine_fec: return optics_type - determine_fec ->>+ determine_fec: internally call API determine_fec(lane_speed, num_lanes, optics_type)
which calculates FEC mode based on FEC mapping obtained from platform.json - end - - determine_fec ->>+ config_db: update FEC if needed - - par - config_db -->>- determine_fec: Done - and - config_db ->>+ syncd: notify for FEC update - end - end - - determine_fec -->>- fec_correct_cli: Done - fec_correct_cli -->>- user: Done - -``` - -> [!NOTE] -> 1. In the above use cases, automatically determined FEC mode is saved in running config, user needs to do ```config save``` to save it permanently, which will persist across config/system reload. -> 2. For non-breakout use case, in the future, determine-fec module can be further enhanced to integrated with xcvrd, which can be triggered automatically during transceiver insertion, without human intervention. - -#### API design -``` -def determine_fec(lane_speed: int, num_lanes: int, optics_type: Optional[str] = None) -> str: - """ - Determines the appropriate Forward Error Correction (FEC) type based on lane speed, number of lanes, and optics type for a specific port. - This logic is based on FEC mapping rules defined in platform.json. - - Parameters: - - lane_speed (int): The speed of each lane in GB. - - num_lanes (int): The total number of lanes. - - optics_type (Optional[str]): The type of optics in use. Can be None if not applicable. - - Returns: - - str: The recommended FEC type based on the rules in platform.json. It can be either 'none'/'rs'/'fc'. - If no matched entry is found in the rules or no rules are defined in platform.json, return None. - - Example: - >>> determine_fec(25, 4, "100G-SR4") - "rs" - - """ -``` - -#### Platform Prequisite (optional) - -FEC mapping rules are defined in platform.json: -1. FEC mapping rule is optional in platform.json. If platform/vendor doesn't define it, it's no-op in terms of FEC auto determination. -2. For now, there are two mapping rules (More rules can be added in the future if required) - - ```fec_mapping_based_on_speed_lane```: This will be looked up if lane_speed and num_lanes are provided in parameters of determine_fec API. - - ```fec_mapping_based_on_optics_type```: This will be looked up if optics_type is provided in parameters of determine_fec API. -3. In ```fec_mapping_based_on_speed_lane```, if there are multiple FEC values (e.g. ```rs``` and ```none```) in the field of ```fec```, preferably choose the first value (in this example, ```rs```). -4. If a port has matched FEC entry in both ```fec_mapping_based_on_speed_lane``` and ```fec_mapping_based_on_optics_type```, then prefers FEC entry in ```fec_mapping_based_on_optics_type```, which is the first mapping rule defined in platform.json. (e.g. 100G-DR will have a match in both rules, the matched FEC entry in ```fec_mapping_based_on_optics_type``` will be preferably choosen, which is ```none```) - -Open questions: -1. What is FC FEC mode for 40G in [saiport.h](https://github.com/opencomputeproject/SAI/blob/4cb229c2d55cbe36c2ac10204d1fe4476f4937bd/inc/saiport.h#L191-L222)? what FEC we should put in ```fec_mapping_based_on_optics_type``` for ```optics_type=40G```? And what FEC to be put for ```lane_speed=10, num_lanes=4``` in ```fec_mapping_based_on_speed_lane```? -2. For ```100G-ER4``` ```100G-LR4``` and ```100G AOC```, shall we put FEC=rs for non-low-BER, and FEC=none for low-BER? And how do we tell if it's low-BER/non-low-BER based on optics_type? If optics_type is not enough to tell, what specific field we need to tell the BER, and shall we add another column in the mapping rule? -``` -{ - "fec_mapping_based_on_optics_type": [ - { - "optics_type": "40G", - "fec": ["fc"] - }, - { - "optics_type": "100G-DR", - "fec": ["none"] - }, - { - "optics_type": "100G-FR", - "fec": ["none"] - }, - { - "optics_type": "100G-LR", - "fec": ["none"] - }, - { - "optics_type": "100G-LR4", - "fec": ["none"] - }, - { - "optics_type": "100G-ER4", - "fec": ["none"] - }, - { - "optics_type": "100G AOC", - "fec": ["none"] - }, - { - "optics_type": "400G", - "fec": ["rs"] - }, - { - "optics_type": "ALL_OTHER", - "fec": ["rs"] - }, - ], - "fec_mapping_based_on_speed_lane": [ - { - "lane_speed": 10, - "num_lanes": 4, - "fec": ["fc", "none"] - }, - { - "lane_speed": 20, - "num_lanes": 2, - "fec": ["none"] - }, - { - "lane_speed": 25, - "num_lanes": 2, - "fec": ["rs", "none"] - }, - { - "lane_speed": 25, - "num_lanes": 4, - "fec": ["rs", "none"] - }, - { - "lane_speed": 25, - "num_lanes": 8, - "fec": ["rs"] - }, - { - "lane_speed": 50, - "num_lanes": 1, - "fec": ["rs"] - }, - { - "lane_speed": 50, - "num_lanes": 2, - "fec": ["rs"] - }, - { - "lane_speed": 50, - "num_lanes": 4, - "fec": ["rs"] - }, - { - "lane_speed": 50, - "num_lanes": 8, - "fec": ["rs"] - }, - { - "lane_speed": 50, - "num_lanes": 16, - "fec": ["rs"] - }, - ] -} -``` -#### Platform Common Dependency -A new ```optics_type``` field (human-readable type for optics, such as ```100G-DR```, ```100G-FR```, etc) will be added to TRANSCEIVER_INFO table, so that determine-FEC module can read it for the non-breakout use case. - -To implement this, ```optics_type``` can be determined based on today's transceiver_info, and be added as part of output of API [get_transceiver_info()](https://github.com/sonic-net/sonic-platform-common/blob/1988b37c7668394f38f155c86f5462a4461fe82e/sonic_platform_base/sonic_xcvr/api/xcvr_api.py#L42-L71) in ```sonic-platform-common``` repo. - -```optics_type``` field can also provide benefits in readability/service-ability/debug-ability: -1. help user/engineer to easily and quickly identify what optics are plugged onto the router (if it can be added to show CLI output later) -2. test script can easily figure out the optics type based on this single ```optics_type``` field and do test actions accordingly. - -#### Difference between other design -1. [[FEC] Design for auto-fec](https://github.com/sonic-net/SONiC/pull/1416): - - FEC mode will be decided automatically at SAI/SDK(and HW) level as part of auto-negotiation feature, if auto-neg is implemented and enabled for this platform. - - fec=```auto``` in CONFIG_DB -2. determine-FEC module (this HLD's design): - - FEC mode will be decided automatically above at system start-up at CONFIG_DB level, based on platform provided rules, and be pushed into CONFIG_DB. (flow: CONFIG_DB->syncd->orcagent->SAI/SDK) - - fec=```none```/```rs```/```fc``` in CONFIG_DB - - Also, this mechanism/model helps determine right FEC for dynamic events, such as: DPB (Dynamic Port Breakout), transceivers/optics insertion (OIR) etc. diff --git a/doc/port-fec/fec-auto-determination.md b/doc/port-fec/fec-auto-determination.md new file mode 100644 index 00000000000..8a6f75fa382 --- /dev/null +++ b/doc/port-fec/fec-auto-determination.md @@ -0,0 +1,199 @@ +# SONiC FEC Auto Determination Design # + +## Table of Content + +- [Revision](#revision) +- [Scope](#scope) +- [Definitions/Abbreviations](#definitions/abbreviations) +- [Overview](#overview) +- [High-Level Design](#high-level-design) +- [API design](#api-design) +- [Common Rule for FEC Determination](#common-rule-for-fec-determination) + - [Table 1: FEC Mapping Based on Optics Type](#table-1-fec-mapping-based-on-optics-type) + - [Table 2: FEC Mapping Based on Lane Speed and Number of Lanes](#table-2-fec-mapping-based-on-lane-speed-and-number-of-lanes) +- [Diagram For Different Use Cases](#diagram-for-different-use-cases) +- [Dependency](#dependency) +- [Restrictions/Limitations](#restrictions/limitations) +- [Difference compared to other design](#difference-compared-to-other-design) + +### Revision + + | Rev | Date | Author | Change Description | + |:---:|:-----------:|:-------------------:|--------------------------------------------| + | 0.1 | | Shyam Kumar, Longyin Huang | Initial version | + +### Scope +This document is the design document for FEC auto-determination feature on SONiC. + +### Definitions/Abbreviations +| **Term** | **Definition** | +| -------------- | ------------------------------------------------ | +| FEC | Forward Error Correction | +| DPB | Dynamic Port Breakout | + +### Overview + + If not configured in CONFIG_DB, FEC mode is set to default value `none` at [SAI/SDK]((https://github.com/opencomputeproject/SAI/blob/a94bbbe43242a4d9e1a4d9f70780ea9251127f5d/inc/saiport.h#L1012)) layer, which might not be the proper FEC mode for this port/optics, and link might not come up. + +Two scenarios: +1. In DPB case, today's DPB CLI doesn't generate FEC config for newly created ports, FEC mode is default to none at SAI layer. +2. In non-DPB case, + - Some platforms have no FEC configured in CONFIG_DB by default. The FEC mode can be either default to none at SAI layer or manually configured by user who might not have enough domain knowledge. + - Some platforms have default FEC defined in port_config.ini, which however might not be suitable for the specific port/optics on the system. + +The feature in this document is to address the issue in both of above scenarios in a common platform-independent way, since the rule to determine FEC for a given port/optics is common for all platforms. + +### High-Level Design + +- Add determine-fec module which can determine FEC mode based on common rule for a given port with a given optics. + - This module provides a `determine_fec` API which can be invoked by below entities. +- Enhance today's DPB CLI to automatically determine and configure FEC in CONFIG_DB for newly created ports, based on determine-fec module. +- Add a user-triggered CLI `fec-auto-correct` to automatically determine and configure FEC in CONFIG_DB for existing ports, based on determine-fec module. + +### API design +``` +def determine_fec(lane_speed: int, num_lanes: int, optics_type: Optional[str] = None) -> str: + """ + Determines the appropriate Forward Error Correction (FEC) type based on lane speed, number of lanes, and optics type for a specific port. + This logic is based on FEC mapping rules common for all platforms. + + Parameters: + - lane_speed (int): The speed of each lane in GB. + - num_lanes (int): The total number of lanes. + - optics_type (Optional[str]): The type of optics in use. Can be None if not applicable. + + Returns: + - str: The recommended FEC type based on the common rules. It can be either 'none'/'rs'/'fc'. + + Example: + >>> determine_fec(25, 4, "100G-SR4") + "rs" + + """ +``` + +### Common Rule for FEC Determination + +#### Table 1: FEC Mapping Based on Optics Type +| Optics Type | FEC | +|-------------|------| +| 40G | none | +| 100G-DR | none | +| 100G-FR | none | +| 100G-LR | none | +| 100G-LR4 | none | +| 100G-ER4 | none | +| 100G AOC | none | +| 400G | rs | +| ALL_OTHER | rs | + + +#### Table 2: FEC Mapping Based on Lane Speed and Number of Lanes +| Lane Speed | Number of Lanes | FEC | +|------------|-----------------|------| +| 10 | 4 | none | +| 20 | 2 | none | +| 25 | 2 | rs | +| 25 | 4 | rs | +| 25 | 8 | rs | +| 50 | 1 | rs | +| 50 | 2 | rs | +| 50 | 4 | rs | +| 50 | 8 | rs | +| 50 | 16 | rs | + +> [!NOTE] +> If a port has matched FEC entry in both above tables, then prefers FEC entry in first table. +> For example: A port with 100G-DR optics running in non-breakout mode (`optics_type=100G-DR, lane_speed=25, num_lane=4`) will have a match in both rules, the matched FEC entry in table 1 will be preferably choosen, which is ```none``` in this case. + +### Diagram For Different Use Cases + +```mermaid +sequenceDiagram + title determine-FEC in DPB case + + actor user as User + participant dpb_cli as today's DPB CLI + participant determine_fec as determine-FEC module + participant config_db as CONFIG_DB + participant syncd as SYNCD + + + user ->>+ dpb_cli: do breakout on a port + note over dpb_cli: run today's logic per port: + dpb_cli ->>+ dpb_cli: generate the config(speed/lanes/etc) for each new port + + note over dpb_cli,determine_fec: run below additional logic per port: + dpb_cli ->>+ determine_fec: call API determine_fec(lane_speed, num_lanes) per port + determine_fec ->>+ determine_fec: calculate FEC mode based on FEC mapping + determine_fec -->>- dpb_cli: return FEC mode + + note over dpb_cli, syncd: run today's logic: + dpb_cli ->>+ config_db: Add new ports in PORT table (today's workflow),
additionally with proper FEC if determined above
instead of FEC=none as default + + par + config_db -->>- dpb_cli: Done + and + config_db ->>+ syncd: notify for new port creation + end + + dpb_cli -->>- user: Done +``` + +```mermaid +sequenceDiagram + title determine-FEC in non-DPB case + + actor user as User + participant fec_correct_cli as fec-auto-correct CLI
(just a wrapper) + participant determine_fec as determine-FEC module + participant state_db as STATE_DB + participant config_db as CONFIG_DB + participant syncd as SYNCD + + user ->>+ fec_correct_cli: auto-correct FEC mode for all ports + fec_correct_cli ->>+ determine_fec: call API correct_fec_for_all_ports() + + loop every port + determine_fec ->>+ state_db: read optics_type from TRANSCEIVER_INFO table + state_db -->>- determine_fec: return optics_type + determine_fec ->>+ determine_fec: internally call API determine_fec(lane_speed, num_lanes, optics_type)
which calculates FEC mode based on FEC mapping + end + + determine_fec ->>+ config_db: update FEC if needed + + par + config_db -->>- determine_fec: Done + and + config_db ->>+ syncd: notify for FEC update + end + + determine_fec -->>- fec_correct_cli: Done + fec_correct_cli -->>- user: Done + +``` + +> [!NOTE] +> 1. In the above use cases, automatically determined FEC mode is saved in running config, user needs to do ```config save``` to save it permanently. +> 2. For non-DPB use case, in the future, determine-fec module can be further enhanced to integrated with xcvrd, which can be triggered automatically during transceiver insertion, without human intervention. + +### Dependency +A new ```optics_type``` field (human-readable type for optics, such as ```100G-DR```, ```100G-FR```, etc) will be added to TRANSCEIVER_INFO table, so that determine-FEC module can read it for the non-breakout use case. + +To implement this, ```optics_type``` can be determined based on today's transceiver_info, and be added as part of output of API [get_transceiver_info()](https://github.com/sonic-net/sonic-platform-common/blob/1988b37c7668394f38f155c86f5462a4461fe82e/sonic_platform_base/sonic_xcvr/api/xcvr_api.py#L42-L71) in ```sonic-platform-common``` repo. + +```optics_type``` field can also provide benefits in readability/service-ability/debug-ability: +1. help user/engineer to easily and quickly identify what optics are plugged onto the router (if it can be added to show CLI output later) +2. test script can easily figure out the optics type based on this single ```optics_type``` field and do test actions accordingly. + +### Restrictions/Limitations +N/A + +### Difference compared to other design +1. [[FEC] Design for auto-fec](https://github.com/sonic-net/SONiC/blob/master/doc/port_auto_neg/auto-fec.md#sonic-port-auto-fec-design): + - FEC mode will be decided automatically at SAI/SDK(and/or HW) level as part of auto-negotiation feature, if auto-neg is implemented and enabled for this platform. + - fec=```auto``` in CONFIG_DB +2. This HLD's design: + - FEC mode will be decided automatically at level way above SAI/SDK/HW, based on common rules, and be pushed into CONFIG_DB. (flow: CONFIG_DB->syncd->orcagent->SAI/SDK) + - fec=```none```/```rs```/```fc``` in CONFIG_DB + - Also, this mechanism/model helps determine right FEC for dynamic events, such as: DPB (Dynamic Port Breakout), transceivers/optics insertion (OIR) etc. From 810ee7f01a05de645bdea4d96770d3da37cffce8 Mon Sep 17 00:00:00 2001 From: Longyin Huang Date: Tue, 3 Oct 2023 15:28:12 -0700 Subject: [PATCH 22/28] Update doc --- doc/port-fec/fec-auto-determination.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/port-fec/fec-auto-determination.md b/doc/port-fec/fec-auto-determination.md index 8a6f75fa382..347ebf52911 100644 --- a/doc/port-fec/fec-auto-determination.md +++ b/doc/port-fec/fec-auto-determination.md @@ -33,7 +33,7 @@ This document is the design document for FEC auto-determination feature on SONiC ### Overview - If not configured in CONFIG_DB, FEC mode is set to default value `none` at [SAI/SDK]((https://github.com/opencomputeproject/SAI/blob/a94bbbe43242a4d9e1a4d9f70780ea9251127f5d/inc/saiport.h#L1012)) layer, which might not be the proper FEC mode for this port/optics, and link might not come up. + If not configured in CONFIG_DB, FEC mode is set to default value `none` at [SAI/SDK](https://github.com/opencomputeproject/SAI/blob/a94bbbe43242a4d9e1a4d9f70780ea9251127f5d/inc/saiport.h#L1012) layer, which might not be the proper FEC mode for this port/optics, and link might not come up. Two scenarios: 1. In DPB case, today's DPB CLI doesn't generate FEC config for newly created ports, FEC mode is default to none at SAI layer. From aef6a01c5cc5ec149e5abeeb6ad717150082485c Mon Sep 17 00:00:00 2001 From: Longyin Huang Date: Tue, 3 Oct 2023 15:35:59 -0700 Subject: [PATCH 23/28] Update doc --- doc/port-fec/fec-auto-determination.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/port-fec/fec-auto-determination.md b/doc/port-fec/fec-auto-determination.md index 347ebf52911..d7efaee9796 100644 --- a/doc/port-fec/fec-auto-determination.md +++ b/doc/port-fec/fec-auto-determination.md @@ -120,16 +120,16 @@ sequenceDiagram user ->>+ dpb_cli: do breakout on a port - note over dpb_cli: run today's logic per port: + note over dpb_cli: run today's flow per port: dpb_cli ->>+ dpb_cli: generate the config(speed/lanes/etc) for each new port note over dpb_cli,determine_fec: run below additional logic per port: dpb_cli ->>+ determine_fec: call API determine_fec(lane_speed, num_lanes) per port - determine_fec ->>+ determine_fec: calculate FEC mode based on FEC mapping + determine_fec ->>+ determine_fec: calculate FEC mode based on common rule determine_fec -->>- dpb_cli: return FEC mode - note over dpb_cli, syncd: run today's logic: - dpb_cli ->>+ config_db: Add new ports in PORT table (today's workflow),
additionally with proper FEC if determined above
instead of FEC=none as default + note over dpb_cli, syncd: run today's flow: + dpb_cli ->>+ config_db: Add new ports in PORT table (today's flow),
additionally with proper FEC if determined above par config_db -->>- dpb_cli: Done @@ -157,7 +157,7 @@ sequenceDiagram loop every port determine_fec ->>+ state_db: read optics_type from TRANSCEIVER_INFO table state_db -->>- determine_fec: return optics_type - determine_fec ->>+ determine_fec: internally call API determine_fec(lane_speed, num_lanes, optics_type)
which calculates FEC mode based on FEC mapping + determine_fec ->>+ determine_fec: internally call API determine_fec(lane_speed, num_lanes, optics_type)
which calculates FEC mode based on common rule end determine_fec ->>+ config_db: update FEC if needed From ddd2a283165b6305ffd1b305c063c684fc950125 Mon Sep 17 00:00:00 2001 From: Longyin Huang Date: Tue, 3 Oct 2023 15:55:45 -0700 Subject: [PATCH 24/28] Update doc --- doc/port-fec/fec-auto-determination.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/doc/port-fec/fec-auto-determination.md b/doc/port-fec/fec-auto-determination.md index d7efaee9796..d86bdd66447 100644 --- a/doc/port-fec/fec-auto-determination.md +++ b/doc/port-fec/fec-auto-determination.md @@ -45,7 +45,7 @@ The feature in this document is to address the issue in both of above scenarios ### High-Level Design -- Add determine-fec module which can determine FEC mode based on common rule for a given port with a given optics. +- Add `determine-fec` module which can determine FEC mode based on common rule for a given port with a given optics. - This module provides a `determine_fec` API which can be invoked by below entities. - Enhance today's DPB CLI to automatically determine and configure FEC in CONFIG_DB for newly created ports, based on determine-fec module. - Add a user-triggered CLI `fec-auto-correct` to automatically determine and configure FEC in CONFIG_DB for existing ports, based on determine-fec module. @@ -110,11 +110,11 @@ def determine_fec(lane_speed: int, num_lanes: int, optics_type: Optional[str] = ```mermaid sequenceDiagram - title determine-FEC in DPB case + title FEC determination in DPB case actor user as User participant dpb_cli as today's DPB CLI - participant determine_fec as determine-FEC module + participant determine_fec as determine-fec module participant config_db as CONFIG_DB participant syncd as SYNCD @@ -142,11 +142,11 @@ sequenceDiagram ```mermaid sequenceDiagram - title determine-FEC in non-DPB case + title FEC determination in non-DPB case actor user as User participant fec_correct_cli as fec-auto-correct CLI
(just a wrapper) - participant determine_fec as determine-FEC module + participant determine_fec as determine-fec module participant state_db as STATE_DB participant config_db as CONFIG_DB participant syncd as SYNCD @@ -178,7 +178,7 @@ sequenceDiagram > 2. For non-DPB use case, in the future, determine-fec module can be further enhanced to integrated with xcvrd, which can be triggered automatically during transceiver insertion, without human intervention. ### Dependency -A new ```optics_type``` field (human-readable type for optics, such as ```100G-DR```, ```100G-FR```, etc) will be added to TRANSCEIVER_INFO table, so that determine-FEC module can read it for the non-breakout use case. +A new ```optics_type``` field (human-readable type for optics, such as ```100G-DR```, ```100G-FR```, etc) will be added to TRANSCEIVER_INFO table, so that determine-fec module can read it for the non-DPB use case. To implement this, ```optics_type``` can be determined based on today's transceiver_info, and be added as part of output of API [get_transceiver_info()](https://github.com/sonic-net/sonic-platform-common/blob/1988b37c7668394f38f155c86f5462a4461fe82e/sonic_platform_base/sonic_xcvr/api/xcvr_api.py#L42-L71) in ```sonic-platform-common``` repo. @@ -193,7 +193,9 @@ N/A 1. [[FEC] Design for auto-fec](https://github.com/sonic-net/SONiC/blob/master/doc/port_auto_neg/auto-fec.md#sonic-port-auto-fec-design): - FEC mode will be decided automatically at SAI/SDK(and/or HW) level as part of auto-negotiation feature, if auto-neg is implemented and enabled for this platform. - fec=```auto``` in CONFIG_DB + - Not all platforms have auto-neg implemented and enabled. Even if a platform has auto-neg running, auto-fec might not be supported as part of auto-neg. 2. This HLD's design: - FEC mode will be decided automatically at level way above SAI/SDK/HW, based on common rules, and be pushed into CONFIG_DB. (flow: CONFIG_DB->syncd->orcagent->SAI/SDK) - fec=```none```/```rs```/```fc``` in CONFIG_DB + - This is independent from auto-neg, can work for all platforms. - Also, this mechanism/model helps determine right FEC for dynamic events, such as: DPB (Dynamic Port Breakout), transceivers/optics insertion (OIR) etc. From 9c5e3c311195b004c22936945211b0dfae5647e3 Mon Sep 17 00:00:00 2001 From: Longyin Huang Date: Tue, 3 Oct 2023 16:03:23 -0700 Subject: [PATCH 25/28] Update doc --- doc/port-fec/fec-auto-determination.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/port-fec/fec-auto-determination.md b/doc/port-fec/fec-auto-determination.md index d86bdd66447..dfbed5b0c9b 100644 --- a/doc/port-fec/fec-auto-determination.md +++ b/doc/port-fec/fec-auto-determination.md @@ -36,7 +36,7 @@ This document is the design document for FEC auto-determination feature on SONiC If not configured in CONFIG_DB, FEC mode is set to default value `none` at [SAI/SDK](https://github.com/opencomputeproject/SAI/blob/a94bbbe43242a4d9e1a4d9f70780ea9251127f5d/inc/saiport.h#L1012) layer, which might not be the proper FEC mode for this port/optics, and link might not come up. Two scenarios: -1. In DPB case, today's DPB CLI doesn't generate FEC config for newly created ports, FEC mode is default to none at SAI layer. +1. In DPB(Dynamic Port Breakout) case, today's DPB CLI doesn't generate FEC config for newly created ports, FEC mode is default to none at SAI layer. 2. In non-DPB case, - Some platforms have no FEC configured in CONFIG_DB by default. The FEC mode can be either default to none at SAI layer or manually configured by user who might not have enough domain knowledge. - Some platforms have default FEC defined in port_config.ini, which however might not be suitable for the specific port/optics on the system. From 06f2cbec162d763af909b6362c09b8b768e117df Mon Sep 17 00:00:00 2001 From: Longyin Huang Date: Tue, 3 Oct 2023 16:14:28 -0700 Subject: [PATCH 26/28] Update doc --- doc/port-fec/fec-auto-determination.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/port-fec/fec-auto-determination.md b/doc/port-fec/fec-auto-determination.md index dfbed5b0c9b..a7b2083fceb 100644 --- a/doc/port-fec/fec-auto-determination.md +++ b/doc/port-fec/fec-auto-determination.md @@ -33,13 +33,13 @@ This document is the design document for FEC auto-determination feature on SONiC ### Overview - If not configured in CONFIG_DB, FEC mode is set to default value `none` at [SAI/SDK](https://github.com/opencomputeproject/SAI/blob/a94bbbe43242a4d9e1a4d9f70780ea9251127f5d/inc/saiport.h#L1012) layer, which might not be the proper FEC mode for this port/optics, and link might not come up. +FEC mode is a critical configuration for a port, which needs to be configured properly for the port to come up. -Two scenarios: -1. In DPB(Dynamic Port Breakout) case, today's DPB CLI doesn't generate FEC config for newly created ports, FEC mode is default to none at SAI layer. +There are below scenarios that can end up with wrong FEC mode: +1. In DPB(Dynamic Port Breakout) case, today's DPB CLI doesn't generate FEC config for newly created ports, FEC mode is default to `none` at [SAI/SDK](https://github.com/opencomputeproject/SAI/blob/a94bbbe43242a4d9e1a4d9f70780ea9251127f5d/inc/saiport.h#L1012) layer. 2. In non-DPB case, - - Some platforms have no FEC configured in CONFIG_DB by default. The FEC mode can be either default to none at SAI layer or manually configured by user who might not have enough domain knowledge. - - Some platforms have default FEC defined in port_config.ini, which however might not be suitable for the specific port/optics on the system. + - Some platforms have no FEC configured in CONFIG_DB by default. The FEC mode can be either default to `none` at SAI/SDK layer or manually configured by user who might not have enough domain knowledge. + - Some platforms have default FEC defined in `port_config.ini`, which however might not be suitable for the specific port/optics on the system. The feature in this document is to address the issue in both of above scenarios in a common platform-independent way, since the rule to determine FEC for a given port/optics is common for all platforms. From 78356766b525e0119cf8dbf9095e8eea636b94b7 Mon Sep 17 00:00:00 2001 From: Longyin Huang Date: Tue, 3 Oct 2023 17:46:07 -0700 Subject: [PATCH 27/28] Remove difference-to-other section --- doc/port-fec/fec-auto-determination.md | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/doc/port-fec/fec-auto-determination.md b/doc/port-fec/fec-auto-determination.md index a7b2083fceb..ec15db3824d 100644 --- a/doc/port-fec/fec-auto-determination.md +++ b/doc/port-fec/fec-auto-determination.md @@ -13,8 +13,6 @@ - [Table 2: FEC Mapping Based on Lane Speed and Number of Lanes](#table-2-fec-mapping-based-on-lane-speed-and-number-of-lanes) - [Diagram For Different Use Cases](#diagram-for-different-use-cases) - [Dependency](#dependency) -- [Restrictions/Limitations](#restrictions/limitations) -- [Difference compared to other design](#difference-compared-to-other-design) ### Revision @@ -185,17 +183,3 @@ To implement this, ```optics_type``` can be determined based on today's transcei ```optics_type``` field can also provide benefits in readability/service-ability/debug-ability: 1. help user/engineer to easily and quickly identify what optics are plugged onto the router (if it can be added to show CLI output later) 2. test script can easily figure out the optics type based on this single ```optics_type``` field and do test actions accordingly. - -### Restrictions/Limitations -N/A - -### Difference compared to other design -1. [[FEC] Design for auto-fec](https://github.com/sonic-net/SONiC/blob/master/doc/port_auto_neg/auto-fec.md#sonic-port-auto-fec-design): - - FEC mode will be decided automatically at SAI/SDK(and/or HW) level as part of auto-negotiation feature, if auto-neg is implemented and enabled for this platform. - - fec=```auto``` in CONFIG_DB - - Not all platforms have auto-neg implemented and enabled. Even if a platform has auto-neg running, auto-fec might not be supported as part of auto-neg. -2. This HLD's design: - - FEC mode will be decided automatically at level way above SAI/SDK/HW, based on common rules, and be pushed into CONFIG_DB. (flow: CONFIG_DB->syncd->orcagent->SAI/SDK) - - fec=```none```/```rs```/```fc``` in CONFIG_DB - - This is independent from auto-neg, can work for all platforms. - - Also, this mechanism/model helps determine right FEC for dynamic events, such as: DPB (Dynamic Port Breakout), transceivers/optics insertion (OIR) etc. From d636dd239cf970ff35f53da767aede6cab12cc74 Mon Sep 17 00:00:00 2001 From: Longyin Huang Date: Wed, 4 Oct 2023 17:57:52 -0700 Subject: [PATCH 28/28] Update wording and FEC mapping --- doc/port-fec/fec-auto-determination.md | 48 ++++++++++++++------------ 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/doc/port-fec/fec-auto-determination.md b/doc/port-fec/fec-auto-determination.md index ec15db3824d..8e3b53dc846 100644 --- a/doc/port-fec/fec-auto-determination.md +++ b/doc/port-fec/fec-auto-determination.md @@ -43,16 +43,16 @@ The feature in this document is to address the issue in both of above scenarios ### High-Level Design -- Add `determine-fec` module which can determine FEC mode based on common rule for a given port with a given optics. - - This module provides a `determine_fec` API which can be invoked by below entities. -- Enhance today's DPB CLI to automatically determine and configure FEC in CONFIG_DB for newly created ports, based on determine-fec module. -- Add a user-triggered CLI `fec-auto-correct` to automatically determine and configure FEC in CONFIG_DB for existing ports, based on determine-fec module. +Add `determine-fec` module which can determine FEC mode based on common rule for a given port with a given optics. This module provides a `determine_fec` API which can be invoked in below use cases: +1. DPB use case: Enhance today's DPB CLI to automatically determine and configure FEC in CONFIG_DB for dynamically created ports, based on determine-fec module. +2. non-DPB use case: Add a user-triggered CLI `fec-auto-correct` to automatically determine and configure FEC in CONFIG_DB for existing ports, based on determine-fec module. + - Future plan: determine-fec module can be further enhanced to be integrated with xcvrd, which can be triggered automatically during transceiver insertion, without human intervention. (details TBD) ### API design ``` def determine_fec(lane_speed: int, num_lanes: int, optics_type: Optional[str] = None) -> str: """ - Determines the appropriate Forward Error Correction (FEC) type based on lane speed, number of lanes, and optics type for a specific port. + Determines the appropriate Forward Error Correction (FEC) type based on lane speed, number of lanes, and optics type for a specific logical port. This logic is based on FEC mapping rules common for all platforms. Parameters: @@ -85,24 +85,27 @@ def determine_fec(lane_speed: int, num_lanes: int, optics_type: Optional[str] = | 400G | rs | | ALL_OTHER | rs | - #### Table 2: FEC Mapping Based on Lane Speed and Number of Lanes -| Lane Speed | Number of Lanes | FEC | -|------------|-----------------|------| -| 10 | 4 | none | -| 20 | 2 | none | -| 25 | 2 | rs | -| 25 | 4 | rs | -| 25 | 8 | rs | -| 50 | 1 | rs | -| 50 | 2 | rs | -| 50 | 4 | rs | -| 50 | 8 | rs | -| 50 | 16 | rs | +| Lane Speed | Number of Lanes (per Logical Port) | FEC | +|------------|-----------------------------------|------| +| 10 | 1 | none | +| 10 | 4 | none | +| 20 | 2 | none | +| 25 | 1 | rs | +| 25 | 2 | rs | +| 25 | 4 | rs | +| 25 | 8 | rs | +| 50 | 1 | rs | +| 50 | 2 | rs | +| 50 | 4 | rs | +| 50 | 8 | rs | +| 50 | 16 | rs | + +Above tables can be defined as JSON file, and be loaded by determine-fec module. Platform can also override the default FEC mapping by providing its own JSON file. > [!NOTE] -> If a port has matched FEC entry in both above tables, then prefers FEC entry in first table. -> For example: A port with 100G-DR optics running in non-breakout mode (`optics_type=100G-DR, lane_speed=25, num_lane=4`) will have a match in both rules, the matched FEC entry in table 1 will be preferably choosen, which is ```none``` in this case. +> If a port has matched FEC entry in both above tables, then prefers FEC entry in first table. (Only exception: For `lane_speed=10, num_lane=1 or 4`, we prefer FEC entry in second table) + ### Diagram For Different Use Cases @@ -111,7 +114,7 @@ sequenceDiagram title FEC determination in DPB case actor user as User - participant dpb_cli as today's DPB CLI + participant dpb_cli as DPB CLI participant determine_fec as determine-fec module participant config_db as CONFIG_DB participant syncd as SYNCD @@ -172,8 +175,7 @@ sequenceDiagram ``` > [!NOTE] -> 1. In the above use cases, automatically determined FEC mode is saved in running config, user needs to do ```config save``` to save it permanently. -> 2. For non-DPB use case, in the future, determine-fec module can be further enhanced to integrated with xcvrd, which can be triggered automatically during transceiver insertion, without human intervention. +> In the above use cases, automatically determined FEC mode is saved in running config, user needs to do ```config save``` to save it permanently. ### Dependency A new ```optics_type``` field (human-readable type for optics, such as ```100G-DR```, ```100G-FR```, etc) will be added to TRANSCEIVER_INFO table, so that determine-fec module can read it for the non-DPB use case.