Skip to content

Commit 2909a8a

Browse files
Add fec: rs to port config for ports with >=50G per lane (#23978)
Why I did it Ports with lane speed >=50G use PAM4 modulation and should indicate "fec": "rs" in the port config. This fixes issue Enhancement:FEC not configured for PAM4 speeds #23561 How I did it Check the lane speed and add "fec": "rs" for lanes with speed at least 50G. How to verify it sonic-cfggen -k <device-name> --print-data | grep Ethernet0 -C 10 Make sure that fec rs is there by default if it's a PAM4 speed. Otherwise don’t insert anything To verify whether “fec”: “rs” is only being added for lane speeds above 50G, we used these 3 test inputs and show their respective
1 parent 0d06ed3 commit 2909a8a

File tree

2 files changed

+139
-1
lines changed

2 files changed

+139
-1
lines changed

src/sonic-config-engine/portconfig.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,13 +385,19 @@ def get_config(self):
385385
else:
386386
subport = "0" if total_num_ports == 1 else str(alias_id + 1)
387387

388-
ports[interface_name] = {
388+
port_config = {
389389
'alias': alias,
390390
'lanes': ','.join(lanes),
391391
'speed': str(entry.default_speed),
392392
'index': self._indexes[lane_id],
393393
'subport': subport
394394
}
395+
396+
# If the lane speed is greater than 50G, enable FEC
397+
if entry.default_speed // lanes_per_port >= 50000:
398+
port_config['fec'] = 'rs'
399+
400+
ports[interface_name] = port_config
395401

396402
lane_id += lanes_per_port
397403
alias_id += 1

src/sonic-config-engine/tests/test_cfggen_platformJson.py

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,135 @@ def test_platform_json_no_interfaces(self):
116116
(ports, _, _) = get_port_config(port_config_file=self.platform_json)
117117
self.assertNotEqual(ports, None)
118118
self.assertEqual(ports, {})
119+
120+
# Check that FEC 'rs' is properly set for lanes with speed >= 50G per lane
121+
def test_fec_rs(self):
122+
# Ethernet0 is 1x100G
123+
argument = ['-m', self.platform_sample_graph, '-p', self.platform_json, '-S', self.hwsku_json, '-v', "PORT[\'Ethernet0\']"]
124+
output = self.run_script(argument)
125+
port_config = utils.to_dict(output.strip())
126+
self.assertIn('fec', port_config)
127+
self.assertEqual(port_config['fec'], 'rs')
128+
129+
# Ethernet4 is 2x50G
130+
argument = ['-m', self.platform_sample_graph, '-p', self.platform_json, '-S', self.hwsku_json, '-v', "PORT[\'Ethernet4\']"]
131+
output = self.run_script(argument)
132+
port_config = utils.to_dict(output.strip())
133+
self.assertNotIn('fec', port_config)
134+
135+
# Check FEC logic with custom platform.json
136+
def test_fec_rs_custom(self):
137+
test_platform_json = {
138+
"interfaces": {
139+
"Ethernet200": {
140+
"index": "50,50,50,50,50,50,50,50",
141+
"lanes": "200,201,202,203,204,205,206,207",
142+
"breakout_modes": {
143+
"8x800G": ["Eth50/1", "Eth50/2", "Eth50/3", "Eth50/4", "Eth50/5", "Eth50/6", "Eth50/7", "Eth50/8"]
144+
}
145+
},
146+
"Ethernet208": {
147+
"index": "51,51,51,51",
148+
"lanes": "208,209,210,211",
149+
"breakout_modes": {
150+
"4x25G": ["Eth51/1", "Eth51/2", "Eth51/3", "Eth51/4"]
151+
}
152+
}
153+
}
154+
}
155+
156+
test_hwsku_json = {
157+
"interfaces": {
158+
"Ethernet200": {"default_brkout_mode": "8x800G"},
159+
"Ethernet208": {"default_brkout_mode": "4x25G"},
160+
}
161+
}
162+
163+
with mock.patch('portconfig.readJson') as mock_read_json:
164+
def side_effect(filename):
165+
if 'platform' in filename:
166+
return test_platform_json
167+
elif 'hwsku' in filename:
168+
return test_hwsku_json
169+
return None
170+
171+
mock_read_json.side_effect = side_effect
172+
173+
from portconfig import get_child_ports
174+
ports = get_child_ports("Ethernet200", "8x800G", "test_platform.json")
175+
self.assertIn('fec', ports['Ethernet200'])
176+
self.assertEqual(ports['Ethernet200']['fec'], 'rs')
177+
178+
ports = get_child_ports("Ethernet208", "4x25G", "test_platform.json")
179+
self.assertNotIn('fec', ports['Ethernet208'])
180+
181+
# Check FEC logic for edge cases around the 50G per lane threshold
182+
def test_fec_rs_for_edge_cases(self):
183+
test_platform_json = {
184+
"interfaces": {
185+
"Ethernet200": {
186+
"index": "50,50",
187+
"lanes": "200,201",
188+
"breakout_modes": {
189+
"1x100G": ["Eth50/1"],
190+
"2x50G": ["Eth50/1", "Eth50/2"]
191+
}
192+
},
193+
"Ethernet204": {
194+
"index": "51,51",
195+
"lanes": "204,205",
196+
"breakout_modes": {
197+
"1x102G": ["Eth51/1"]
198+
}
199+
},
200+
"Ethernet208": {
201+
"index": "52",
202+
"lanes": "208",
203+
"breakout_modes": {
204+
"1x50G": ["Eth52/1"]
205+
}
206+
},
207+
"Ethernet212": {
208+
"index": "53",
209+
"lanes": "212",
210+
"breakout_modes": {
211+
"1x49G": ["Eth53/1"]
212+
}
213+
}
214+
}
215+
}
216+
217+
test_hwsku_json = {
218+
"interfaces": {
219+
"Ethernet200": {"default_brkout_mode": "1x100G"},
220+
"Ethernet204": {"default_brkout_mode": "1x102G"},
221+
"Ethernet208": {"default_brkout_mode": "1x50G"},
222+
"Ethernet212": {"default_brkout_mode": "1x49G"}
223+
}
224+
}
225+
226+
with mock.patch('portconfig.readJson') as mock_read_json:
227+
def side_effect(filename):
228+
if 'platform' in filename:
229+
return test_platform_json
230+
elif 'hwsku' in filename:
231+
return test_hwsku_json
232+
return None
233+
234+
mock_read_json.side_effect = side_effect
235+
236+
from portconfig import get_child_ports
237+
ports = get_child_ports("Ethernet200", "1x100G", "test_platform.json")
238+
self.assertIn('fec', ports['Ethernet200'])
239+
self.assertEqual(ports['Ethernet200']['fec'], 'rs')
240+
241+
ports = get_child_ports("Ethernet204", "1x102G", "test_platform.json")
242+
self.assertIn('fec', ports['Ethernet204'])
243+
self.assertEqual(ports['Ethernet204']['fec'], 'rs')
244+
245+
ports = get_child_ports("Ethernet208", "1x50G", "test_platform.json")
246+
self.assertIn('fec', ports['Ethernet208'])
247+
self.assertEqual(ports['Ethernet208']['fec'], 'rs')
248+
249+
ports = get_child_ports("Ethernet212", "1x49G", "test_platform.json")
250+
self.assertNotIn('fec', ports['Ethernet212'])

0 commit comments

Comments
 (0)