From f0b2190b23d3da0c8c3857d906c30d9136632926 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Sat, 5 Jan 2019 01:37:03 +0800 Subject: [PATCH] [Mellanox sfputil ] fix lpmode set failure on Mellanox platform (#2408) * fix set lpmode failure issue * fix review comments --- .../plugins/sfplpmset.py | 133 ++++++++++++------ .../x86_64-mlnx_msn2700-r0/plugins/sfputil.py | 32 +---- 2 files changed, 91 insertions(+), 74 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py index 3f31af9f29..9713873ed2 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py @@ -1,17 +1,47 @@ #!/usr/bin/env python import sys, errno -import time import os from python_sdk_api.sxd_api import * from python_sdk_api.sx_api import * -def get_log_ports(handle, sfp_module): - port_attributes_list = new_sx_port_attributes_t_arr(64) - port_cnt_p = new_uint32_t_p() - uint32_t_p_assign(port_cnt_p, 64) +REGISTER_NUM = 1 +SXD_LOG_VERBOSITY_LEVEL = 0 +DEVICE_ID = 1 +SWITCH_ID = 0 +SX_PORT_ATTR_ARR_SIZE = 64 - rc = sx_api_port_device_get(handle, 1 , 0, port_attributes_list, port_cnt_p) +PMAOS_ASE = 1 +PMAOS_EE = 1 +PMAOS_E = 2 +PMAOS_RST = 0 +PMAOS_ENABLE = 1 +PMAOS_DISABLE = 2 + +def get_port_admin_status_by_log_port(log_port): + oper_state_p = new_sx_port_oper_state_t_p() + admin_state_p = new_sx_port_admin_state_t_p() + module_state_p = new_sx_port_module_state_t_p() + rc = sx_api_port_state_get(handle, log_port, oper_state_p, admin_state_p, module_state_p) + assert rc == SXD_STATUS_SUCCESS, "sx_api_port_state_get failed, rc = %d" % rc + + admin_state = sx_port_admin_state_t_p_value(admin_state_p) + if admin_state == SX_PORT_ADMIN_STATUS_UP: + return True + else: + return False + +def set_port_admin_status_by_log_port(handle, log_port, admin_status): + rc = sx_api_port_state_set(handle, log_port, admin_status) + assert rc == SX_STATUS_SUCCESS, "sx_api_port_state_set failed, rc = %d" % rc + +# Get all the ports related to the sfp, if port admin status is up, put it to list +def get_log_ports(handle, sfp_module): + port_attributes_list = new_sx_port_attributes_t_arr(SX_PORT_ATTR_ARR_SIZE) + port_cnt_p = new_uint32_t_p() + uint32_t_p_assign(port_cnt_p, SX_PORT_ATTR_ARR_SIZE) + + rc = sx_api_port_device_get(handle, DEVICE_ID , SWITCH_ID, port_attributes_list, port_cnt_p) assert rc == SX_STATUS_SUCCESS, "sx_api_port_device_get failed, rc = %d" % rc port_cnt = uint32_t_p_value(port_cnt_p) @@ -19,32 +49,60 @@ def get_log_ports(handle, sfp_module): for i in range(0, port_cnt): port_attributes = sx_port_attributes_t_arr_getitem(port_attributes_list, i) if port_attributes.port_mapping.module_port == sfp_module: - log_port_list.append(port_attributes.log_port) + if get_port_admin_status_by_log_port(port_attributes.log_port): + log_port_list.append(port_attributes.log_port) return log_port_list -def set_sfp_admin_status(handle, meta, sfp_module, sfp_log_port_list, admin_status): +def init_sx_meta_data(): + meta = sxd_reg_meta_t() + meta.dev_id = DEVICE_ID + meta.swid = SWITCH_ID + return meta + +def set_sfp_admin_status(sfp_module, admin_status): # Get PMAOS pmaos = ku_pmaos_reg() pmaos.module = sfp_module + meta = init_sx_meta_data() meta.access_cmd = SXD_ACCESS_CMD_GET - rc = sxd_access_reg_pmaos(pmaos, meta, 1, None, None) + rc = sxd_access_reg_pmaos(pmaos, meta, REGISTER_NUM, None, None) assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmaos failed, rc = %d" % rc # Set admin status to PMAOS - pmaos.ase = 1 - pmaos.ee = 1 - pmaos.e = 2 - pmaos.rst = 0 + pmaos.ase = PMAOS_ASE + pmaos.ee = PMAOS_EE + pmaos.e = PMAOS_E + pmaos.rst = PMAOS_RST if admin_status == SX_PORT_ADMIN_STATUS_DOWN: - pmaos.admin_status = 2 + pmaos.admin_status = PMAOS_DISABLE else: - pmaos.admin_status = 1 + pmaos.admin_status = PMAOS_ENABLE meta.access_cmd = SXD_ACCESS_CMD_SET - rc = sxd_access_reg_pmaos(pmaos, meta, 1, None, None) + rc = sxd_access_reg_pmaos(pmaos, meta, REGISTER_NUM, None, None) assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmaos failed, rc = %d" % rc +def set_sfp_lpmode(sfp_module, lpm_enable): + # Get PMMP + pmmp = ku_pmmp_reg() + pmmp.module = sfp_module + meta = init_sx_meta_data() + meta.access_cmd = SXD_ACCESS_CMD_GET + rc = sxd_access_reg_pmmp(pmmp, meta, REGISTER_NUM, None, None) + assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmmp failed, rc = %d" % rc + + # Set low power mode status + lpm_mask = 1 << 8 + if lpm_enable: + pmmp.eeprom_override = pmmp.eeprom_override | lpm_mask + else: + pmmp.eeprom_override = pmmp.eeprom_override & (~lpm_mask) + + meta.access_cmd = SXD_ACCESS_CMD_SET + rc = sxd_access_reg_pmmp(pmmp, meta, REGISTER_NUM, None, None) + assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmmp failed, rc = %d" % rc + # Check if SFP port number is provided if len(sys.argv) < 3: print "SFP module number or LPM is missed." @@ -67,41 +125,30 @@ if (rc != SX_STATUS_SUCCESS): sys.exit(errno.EACCES) pid = os.getpid() -rc = sxd_access_reg_init(pid, None, 0) -if (rc != 0): +rc = sxd_access_reg_init(pid, None, SXD_LOG_VERBOSITY_LEVEL) +if (rc != SXD_STATUS_SUCCESS): print "Failed to initializing register access.\nPlease check that SDK is running." sys.exit(errno.EACCES); -# Get SFP module and log ports number and LPM status +# Get SFP module sfp_module = int(sys.argv[1]) -log_port_list = get_log_ports(handle, sfp_module) -if not log_port_list: - print "Failed to get log ports" - sys.exit(errno.EACCES) -# Get PMMP -pmmp = ku_pmmp_reg() -pmmp.module = sfp_module -meta = sxd_reg_meta_t() -meta.dev_id = 1 -meta.swid = 0 -meta.access_cmd = SXD_ACCESS_CMD_GET -rc = sxd_access_reg_pmmp(pmmp, meta, 1, None, None) -assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmmp failed, rc = %d" % rc +# Get all ports at admin up status that related to the SFP module +log_port_list = get_log_ports(handle, sfp_module) + +# SET SFP related ports to admin down status +for log_port in log_port_list: + set_port_admin_status_by_log_port(handle, log_port, SX_PORT_ADMIN_STATUS_DOWN) # Disable admin status before LPM settings -set_sfp_admin_status(handle, meta, sfp_module, log_port_list, SX_PORT_ADMIN_STATUS_DOWN) +set_sfp_admin_status(sfp_module, SX_PORT_ADMIN_STATUS_DOWN) # Set low power mode status -lpm_mask = 1 << 8 -if lpm_enable: - pmmp.eeprom_override = pmmp.eeprom_override | lpm_mask -else: - pmmp.eeprom_override = pmmp.eeprom_override & (~lpm_mask) - -meta.access_cmd = SXD_ACCESS_CMD_SET -rc = sxd_access_reg_pmmp(pmmp, meta, 1, None, None) -assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmmp failed, rc = %d" % rc +set_sfp_lpmode(sfp_module, lpm_enable) # Enable admin status after LPM settings -set_sfp_admin_status(handle, meta, sfp_module, log_port_list, SX_PORT_ADMIN_STATUS_UP) +set_sfp_admin_status(sfp_module, SX_PORT_ADMIN_STATUS_UP) + +# SET SFP related ports to admin up status +for log_port in log_port_list: + set_port_admin_status_by_log_port(handle, log_port, SX_PORT_ADMIN_STATUS_UP) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py index 98a7477aa6..1a02b9ff39 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py @@ -123,31 +123,9 @@ class SfpUtil(SfpUtilBase): if curr_lpmode == lpmode: return True + # Compose LPM command lpm = 'on' if lpmode else 'off' lpm_cmd = "docker exec syncd python /usr/share/sonic/platform/plugins/sfplpmset.py {} {}".format(port_num, lpm) - sfp_port_names = self.physical_to_logical[port_num] - - # Get port admin status - try: - enabled_ports = subprocess.check_output("ip link show up", shell=True) - except subprocess.CalledProcessError as e: - print "Error! Unable to get ports status, err msg: {}".format(e.output) - return False - - port_to_disable = [] - for port in sfp_port_names: - if port in enabled_ports: - port_to_disable.append(port) - - # Disable ports before LPM settings - for port in port_to_disable: - try: - subprocess.check_output("ifconfig {} down".format(port), shell=True) - except subprocess.CalledProcessError as e: - print "Error! Unable to set admin status to DOWN for {}, rc = {}, err msg: {}".format(port, e.returncode, e.output) - return False - - time.sleep(3) # Set LPM try: @@ -156,14 +134,6 @@ class SfpUtil(SfpUtilBase): print "Error! Unable to set LPM for {}, rc = {}, err msg: {}".format(port_num, e.returncode, e.output) return False - # Enable ports after LPM settings - for port in port_to_disable: - try: - subprocess.check_output("ifconfig {} up".format(port), shell=True) - except subprocess.CalledProcessError as e: - print "Error! Unable to set admin status to UP for {}, rc = {}, err msg: {}".format(port, e.returncode, e.output) - return False - return True def reset(self, port_num):