Skip to content

Commit 2155455

Browse files
authored
[202205] [Mellanox] Revert LPM implementation to the old way (#17179)
* Revert "[202205] [Mellanox] Fix issue: user must set admin down before toggling LPM (#14370)" This reverts commit f74c69e. * update copyright header Signed-off-by: Kebo Liu <[email protected]>
1 parent 4897953 commit 2155455

File tree

2 files changed

+102
-8
lines changed

2 files changed

+102
-8
lines changed

platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py

+93-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copyright (c) 2019-2021 NVIDIA CORPORATION & AFFILIATES.
2+
# Copyright (c) 2019-2023 NVIDIA CORPORATION & AFFILIATES.
33
# Apache-2.0
44
#
55
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -481,6 +481,80 @@ def _reset(cls, sdk_handle, sdk_index, slot_id):
481481

482482
return rc == SX_STATUS_SUCCESS
483483

484+
485+
@classmethod
486+
def is_nve(cls, port):
487+
return (port & NVE_MASK) != 0
488+
489+
490+
@classmethod
491+
def is_cpu(cls, port):
492+
return (port & CPU_MASK) != 0
493+
494+
495+
@classmethod
496+
def _fetch_port_status(cls, sdk_handle, log_port):
497+
oper_state_p = new_sx_port_oper_state_t_p()
498+
admin_state_p = new_sx_port_admin_state_t_p()
499+
module_state_p = new_sx_port_module_state_t_p()
500+
rc = sx_api_port_state_get(sdk_handle, log_port, oper_state_p, admin_state_p, module_state_p)
501+
assert rc == SXD_STATUS_SUCCESS, "sx_api_port_state_get failed, rc = %d" % rc
502+
503+
admin_state = sx_port_admin_state_t_p_value(admin_state_p)
504+
oper_state = sx_port_oper_state_t_p_value(oper_state_p)
505+
506+
delete_sx_port_oper_state_t_p(oper_state_p)
507+
delete_sx_port_admin_state_t_p(admin_state_p)
508+
delete_sx_port_module_state_t_p(module_state_p)
509+
510+
return oper_state, admin_state
511+
512+
513+
@classmethod
514+
def is_port_admin_status_up(cls, sdk_handle, log_port):
515+
_, admin_state = cls._fetch_port_status(sdk_handle, log_port);
516+
return admin_state == SX_PORT_ADMIN_STATUS_UP
517+
518+
519+
@classmethod
520+
def set_port_admin_status_by_log_port(cls, sdk_handle, log_port, admin_status):
521+
rc = sx_api_port_state_set(sdk_handle, log_port, admin_status)
522+
if SX_STATUS_SUCCESS != rc:
523+
logger.log_error("sx_api_port_state_set failed, rc = %d" % rc)
524+
525+
return SX_STATUS_SUCCESS == rc
526+
527+
528+
@classmethod
529+
def get_logical_ports(cls, sdk_handle, sdk_index, slot_id):
530+
# Get all the ports related to the sfp, if port admin status is up, put it to list
531+
port_cnt_p = new_uint32_t_p()
532+
uint32_t_p_assign(port_cnt_p, 0)
533+
rc = sx_api_port_device_get(sdk_handle, DEVICE_ID, SWITCH_ID, None, port_cnt_p)
534+
535+
assert rc == SX_STATUS_SUCCESS, "sx_api_port_device_get failed, rc = %d" % rc
536+
port_cnt = uint32_t_p_value(port_cnt_p)
537+
port_attributes_list = new_sx_port_attributes_t_arr(port_cnt)
538+
539+
rc = sx_api_port_device_get(sdk_handle, DEVICE_ID , SWITCH_ID, port_attributes_list, port_cnt_p)
540+
assert rc == SX_STATUS_SUCCESS, "sx_api_port_device_get failed, rc = %d" % rc
541+
542+
port_cnt = uint32_t_p_value(port_cnt_p)
543+
log_port_list = []
544+
for i in range(0, port_cnt):
545+
port_attributes = sx_port_attributes_t_arr_getitem(port_attributes_list, i)
546+
if not cls.is_nve(int(port_attributes.log_port)) \
547+
and not cls.is_cpu(int(port_attributes.log_port)) \
548+
and port_attributes.port_mapping.module_port == sdk_index \
549+
and port_attributes.port_mapping.slot == slot_id \
550+
and cls.is_port_admin_status_up(sdk_handle, port_attributes.log_port):
551+
log_port_list.append(port_attributes.log_port)
552+
553+
delete_sx_port_attributes_t_arr(port_attributes_list)
554+
delete_uint32_t_p(port_cnt_p)
555+
return log_port_list
556+
557+
484558
@classmethod
485559
def mgmt_phy_mod_pwr_attr_set(cls, sdk_handle, sdk_index, slot_id, power_attr_type, admin_pwr_mode):
486560
result = False
@@ -506,14 +580,27 @@ def mgmt_phy_mod_pwr_attr_set(cls, sdk_handle, sdk_index, slot_id, power_attr_ty
506580

507581
return result
508582

583+
509584
@classmethod
510-
def _set_lpmode_raw(cls, sdk_handle, sdk_index, slot_id, attr_type, power_mode):
585+
def _set_lpmode_raw(cls, sdk_handle, sdk_index, slot_id, ports, attr_type, power_mode):
586+
result = False
511587
# Check if the module already works in the same mode
512588
admin_pwr_mode, oper_pwr_mode = cls.mgmt_phy_mod_pwr_attr_get(attr_type, sdk_handle, sdk_index, slot_id)
513589
if (power_mode == SX_MGMT_PHY_MOD_PWR_MODE_LOW_E and oper_pwr_mode == SX_MGMT_PHY_MOD_PWR_MODE_LOW_E) \
514590
or (power_mode == SX_MGMT_PHY_MOD_PWR_MODE_AUTO_E and admin_pwr_mode == SX_MGMT_PHY_MOD_PWR_MODE_AUTO_E):
515591
return True
516-
return cls.mgmt_phy_mod_pwr_attr_set(sdk_handle, sdk_index, slot_id, attr_type, power_mode)
592+
try:
593+
# Bring the port down
594+
for port in ports:
595+
cls.set_port_admin_status_by_log_port(sdk_handle, port, SX_PORT_ADMIN_STATUS_DOWN)
596+
# Set the desired power mode
597+
result = cls.mgmt_phy_mod_pwr_attr_set(sdk_handle, sdk_index, slot_id, attr_type, power_mode)
598+
finally:
599+
# Bring the port up
600+
for port in ports:
601+
cls.set_port_admin_status_by_log_port(sdk_handle, port, SX_PORT_ADMIN_STATUS_UP)
602+
603+
return result
517604

518605

519606
def set_lpmode(self, lpmode):
@@ -539,23 +626,22 @@ def set_lpmode(self, lpmode):
539626
# Set LPM
540627
try:
541628
output = subprocess.check_output(lpm_cmd, shell=True, universal_newlines=True)
542-
for line in output.splitlines():
543-
if line.startswith('Error') or line.startswith('Notice'):
544-
print('\n' + line)
545629
return 'True' in output
546630
except subprocess.CalledProcessError as e:
547631
print("Error! Unable to set LPM for {}, rc = {}, err msg: {}".format(self.sdk_index, e.returncode, e.output))
548632
return False
549633
else:
550634
return self._set_lpmode(lpmode, self.sdk_handle, self.sdk_index, self.slot_id)
551635

636+
552637
@classmethod
553638
def _set_lpmode(cls, lpmode, sdk_handle, sdk_index, slot_id):
554-
print('\nNotice: please set port admin status to down before setting power mode, ignore this message if already set')
639+
log_port_list = cls.get_logical_ports(sdk_handle, sdk_index, slot_id)
555640
sdk_lpmode = SX_MGMT_PHY_MOD_PWR_MODE_LOW_E if lpmode else SX_MGMT_PHY_MOD_PWR_MODE_AUTO_E
556641
cls._set_lpmode_raw(sdk_handle,
557642
sdk_index,
558643
slot_id,
644+
log_port_list,
559645
SX_MGMT_PHY_MOD_PWR_ATTR_PWR_MODE_E,
560646
sdk_lpmode)
561647
logger.log_info("{} low power mode for module {}, slot {}".format("Enabled" if lpmode else "Disabled", sdk_index, slot_id))

platform/mellanox/mlnx-platform-api/tests/test_sfp.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES.
2+
# Copyright (c) 2019-2023 NVIDIA CORPORATION & AFFILIATES.
33
# Apache-2.0
44
#
55
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -143,6 +143,14 @@ def test_sfp_read_eeprom(self, mock_get_page):
143143
handle.read.side_effect = OSError('')
144144
assert sfp.read_eeprom(0, 1) is None
145145

146+
@mock.patch('sonic_platform.sfp.SFP._fetch_port_status')
147+
def test_is_port_admin_status_up(self, mock_port_status):
148+
mock_port_status.return_value = (0, True)
149+
assert SFP.is_port_admin_status_up(None, None)
150+
151+
mock_port_status.return_value = (0, False)
152+
assert not SFP.is_port_admin_status_up(None, None)
153+
146154
@mock.patch('sonic_platform.sfp.SFP._get_eeprom_path', mock.MagicMock(return_value = None))
147155
@mock.patch('sonic_platform.sfp.SFP._get_sfp_type_str')
148156
def test_is_write_protected(self, mock_get_type_str):

0 commit comments

Comments
 (0)