Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Mellanox sfputil ] fix lpmode set failure on Mellanox platform #2408

Merged
merged 2 commits into from
Jan 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 87 additions & 40 deletions device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py
Original file line number Diff line number Diff line change
@@ -1,50 +1,108 @@
#!/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 *

REGISTER_NUM = 1
SXD_LOG_VERBOSITY_LEVEL = 0
DEVICE_ID = 1
SWITCH_ID = 0
SX_PORT_ATTR_ARR_SIZE = 64

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(64)
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, 64)
uint32_t_p_assign(port_cnt_p, SX_PORT_ATTR_ARR_SIZE)

rc = sx_api_port_device_get(handle, 1 , 0, port_attributes_list, port_cnt_p)
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)
log_port_list = []
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."
Expand All @@ -67,41 +125,30 @@ def set_sfp_admin_status(handle, meta, sfp_module, sfp_log_port_list, admin_stat
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])

# Get all ports at admin up status that related to the SFP module
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
# 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)
32 changes: 1 addition & 31 deletions device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,31 +123,9 @@ def set_low_power_mode(self, port_num, lpmode):
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:
Expand All @@ -156,14 +134,6 @@ def set_low_power_mode(self, port_num, lpmode):
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):
Expand Down