Skip to content

Commit cd69212

Browse files
[SFP-Refactor] Implement CMIS Low Power mode (#237)
* [SFP-Refactor] Implement CMIS LP mode
1 parent 9cea07f commit cd69212

File tree

6 files changed

+62
-10
lines changed

6 files changed

+62
-10
lines changed

sonic_platform_base/sonic_xcvr/api/public/c_cmis.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,11 @@ def set_laser_freq(self, freq):
122122
assert channel_number % 3 == 0
123123
if channel_number > hi_ch_num or channel_number < low_ch_num:
124124
raise ValueError('Provisioned frequency out of range. Max Freq: 196100; Min Freq: 191300 GHz.')
125-
self.set_low_power(True)
125+
self.set_lpmode(True)
126126
time.sleep(5)
127127
status = self.xcvr_eeprom.write(consts.LASER_CONFIG_CHANNEL, channel_number)
128128
time.sleep(1)
129-
self.set_low_power(False)
129+
self.set_lpmode(False)
130130
time.sleep(1)
131131
return status
132132

sonic_platform_base/sonic_xcvr/api/public/cmis.py

+31-5
Original file line numberDiff line numberDiff line change
@@ -871,15 +871,41 @@ def reset_module(self, reset = False):
871871
else:
872872
return True
873873

874-
def set_low_power(self, AssertLowPower):
874+
def get_lpmode(self):
875+
'''
876+
Retrieves Low power module status
877+
Returns True if module in low power else returns False.
878+
'''
879+
if self.is_flat_memory() or not self.get_lpmode_support():
880+
return False
881+
882+
lpmode = self.xcvr_eeprom.read(consts.TRANS_MODULE_STATUS_FIELD)
883+
if lpmode is not None:
884+
if lpmode.get('ModuleState') == 'ModuleLowPwr':
885+
return True
886+
return False
887+
888+
def set_lpmode(self, lpmode):
875889
'''
876890
This function sets the module to low power state.
877-
AssertLowPower being 0 means "set to high power"
878-
AssertLowPower being 1 means "set to low power"
891+
lpmode being False means "set to high power"
892+
lpmode being True means "set to low power"
879893
Return True if the provision succeeds, False if it fails
880894
'''
881-
low_power_control = AssertLowPower << 6
882-
return self.xcvr_eeprom.write(consts.MODULE_LEVEL_CONTROL, low_power_control)
895+
896+
if self.is_flat_memory() or not self.get_lpmode_support():
897+
return False
898+
899+
lpmode_val = self.xcvr_eeprom.read(consts.MODULE_LEVEL_CONTROL)
900+
if lpmode_val is not None:
901+
if lpmode is True:
902+
lpmode_val = lpmode_val | (1 << 4)
903+
else:
904+
lpmode_val = lpmode_val & ~(1 << 4)
905+
self.xcvr_eeprom.write(consts.MODULE_LEVEL_CONTROL, lpmode_val)
906+
time.sleep(0.1)
907+
return self.get_lpmode()
908+
return False
883909

884910
def get_loopback_capability(self):
885911
'''

sonic_platform_base/sonic_xcvr/fields/consts.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@
260260
LASER_TUNING_DETAIL = "TxTuningDetail"
261261

262262
# CONFIG
263-
TRANS_CONFIG_FIELD = "TransceriverConfig"
263+
TRANS_CONFIG_FIELD = "TransceiverConfig"
264264
MODULE_LEVEL_CONTROL = "ModuleControl"
265265

266266
CTRLS_ADVT_FIELD = "Supported Controls Advertisement"

sonic_platform_base/sonic_xcvr/sfp_optoe_base.py

+18
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,24 @@ def set_power_override(self, power_override, power_set):
128128
def get_eeprom_path(self):
129129
raise NotImplementedError
130130

131+
def get_lpmode(self):
132+
"""
133+
This common API is applicable only for CMIS as Low Power mode can be verified
134+
using EEPROM registers.For other media types like QSFP28/QSFP+ etc., platform
135+
vendors has to implement accordingly.
136+
"""
137+
api = self.get_xcvr_api()
138+
return api.get_lpmode() if api is not None else None
139+
140+
def set_lpmode(self, lpmode):
141+
"""
142+
This common API is applicable only for CMIS as Low Power mode can be controlled
143+
via EEPROM registers.For other media types like QSFP28/QSFP+ etc., platform
144+
vendors has to implement accordingly.
145+
"""
146+
api = self.get_xcvr_api()
147+
return api.set_lp_mode(lpmode) if api is not None else None
148+
131149
def read_eeprom(self, offset, num_bytes):
132150
try:
133151
with open(self.get_eeprom_path(), mode='rb', buffering=0) as f:

tests/sonic_xcvr/test_ccmis.py

+4
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ def test_get_supported_freq_config(self, mock_response, expected):
9797
(195950, (0xff, -72, 120, 191300, 196100)),
9898
])
9999
def test_set_laser_freq(self, input_param, mock_response):
100+
self.api.is_flat_memory = MagicMock()
101+
self.api.is_flat_memory.return_value = False
102+
self.api.get_lpmode_support = MagicMock()
103+
self.api.get_lpmode_support.return_value = False
100104
self.api.get_supported_freq_config = MagicMock()
101105
self.api.get_supported_freq_config.return_value = mock_response
102106
self.api.set_laser_freq(input_param)

tests/sonic_xcvr/test_cmis.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -747,8 +747,12 @@ def test_get_supported_power_config(self, mock_response, expected):
747747
def test_reset_module(self):
748748
self.api.reset_module(True)
749749

750-
def test_set_low_power(self, ):
751-
self.api.set_low_power(True)
750+
def test_set_low_power(self):
751+
self.api.is_flat_memory = MagicMock()
752+
self.api.is_flat_memory.return_value = False
753+
self.api.get_lpmode_support = MagicMock()
754+
self.api.get_lpmode_support.return_value = False
755+
self.api.set_lpmode(True)
752756

753757
@pytest.mark.parametrize("mock_response, expected", [
754758
(127,

0 commit comments

Comments
 (0)