Skip to content

Commit f0b2190

Browse files
keboliulguohan
authored andcommitted
[Mellanox sfputil ] fix lpmode set failure on Mellanox platform (#2408)
* fix set lpmode failure issue * fix review comments
1 parent b84dbd8 commit f0b2190

File tree

2 files changed

+88
-71
lines changed

2 files changed

+88
-71
lines changed
Lines changed: 87 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,108 @@
11
#!/usr/bin/env python
22

33
import sys, errno
4-
import time
54
import os
65
from python_sdk_api.sxd_api import *
76
from python_sdk_api.sx_api import *
87

8+
REGISTER_NUM = 1
9+
SXD_LOG_VERBOSITY_LEVEL = 0
10+
DEVICE_ID = 1
11+
SWITCH_ID = 0
12+
SX_PORT_ATTR_ARR_SIZE = 64
13+
14+
PMAOS_ASE = 1
15+
PMAOS_EE = 1
16+
PMAOS_E = 2
17+
PMAOS_RST = 0
18+
PMAOS_ENABLE = 1
19+
PMAOS_DISABLE = 2
20+
21+
def get_port_admin_status_by_log_port(log_port):
22+
oper_state_p = new_sx_port_oper_state_t_p()
23+
admin_state_p = new_sx_port_admin_state_t_p()
24+
module_state_p = new_sx_port_module_state_t_p()
25+
rc = sx_api_port_state_get(handle, log_port, oper_state_p, admin_state_p, module_state_p)
26+
assert rc == SXD_STATUS_SUCCESS, "sx_api_port_state_get failed, rc = %d" % rc
27+
28+
admin_state = sx_port_admin_state_t_p_value(admin_state_p)
29+
if admin_state == SX_PORT_ADMIN_STATUS_UP:
30+
return True
31+
else:
32+
return False
33+
34+
def set_port_admin_status_by_log_port(handle, log_port, admin_status):
35+
rc = sx_api_port_state_set(handle, log_port, admin_status)
36+
assert rc == SX_STATUS_SUCCESS, "sx_api_port_state_set failed, rc = %d" % rc
37+
38+
# Get all the ports related to the sfp, if port admin status is up, put it to list
939
def get_log_ports(handle, sfp_module):
10-
port_attributes_list = new_sx_port_attributes_t_arr(64)
40+
port_attributes_list = new_sx_port_attributes_t_arr(SX_PORT_ATTR_ARR_SIZE)
1141
port_cnt_p = new_uint32_t_p()
12-
uint32_t_p_assign(port_cnt_p, 64)
42+
uint32_t_p_assign(port_cnt_p, SX_PORT_ATTR_ARR_SIZE)
1343

14-
rc = sx_api_port_device_get(handle, 1 , 0, port_attributes_list, port_cnt_p)
44+
rc = sx_api_port_device_get(handle, DEVICE_ID , SWITCH_ID, port_attributes_list, port_cnt_p)
1545
assert rc == SX_STATUS_SUCCESS, "sx_api_port_device_get failed, rc = %d" % rc
1646

1747
port_cnt = uint32_t_p_value(port_cnt_p)
1848
log_port_list = []
1949
for i in range(0, port_cnt):
2050
port_attributes = sx_port_attributes_t_arr_getitem(port_attributes_list, i)
2151
if port_attributes.port_mapping.module_port == sfp_module:
22-
log_port_list.append(port_attributes.log_port)
52+
if get_port_admin_status_by_log_port(port_attributes.log_port):
53+
log_port_list.append(port_attributes.log_port)
2354

2455
return log_port_list
2556

26-
def set_sfp_admin_status(handle, meta, sfp_module, sfp_log_port_list, admin_status):
57+
def init_sx_meta_data():
58+
meta = sxd_reg_meta_t()
59+
meta.dev_id = DEVICE_ID
60+
meta.swid = SWITCH_ID
61+
return meta
62+
63+
def set_sfp_admin_status(sfp_module, admin_status):
2764
# Get PMAOS
2865
pmaos = ku_pmaos_reg()
2966
pmaos.module = sfp_module
67+
meta = init_sx_meta_data()
3068
meta.access_cmd = SXD_ACCESS_CMD_GET
31-
rc = sxd_access_reg_pmaos(pmaos, meta, 1, None, None)
69+
rc = sxd_access_reg_pmaos(pmaos, meta, REGISTER_NUM, None, None)
3270
assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmaos failed, rc = %d" % rc
3371

3472
# Set admin status to PMAOS
35-
pmaos.ase = 1
36-
pmaos.ee = 1
37-
pmaos.e = 2
38-
pmaos.rst = 0
73+
pmaos.ase = PMAOS_ASE
74+
pmaos.ee = PMAOS_EE
75+
pmaos.e = PMAOS_E
76+
pmaos.rst = PMAOS_RST
3977
if admin_status == SX_PORT_ADMIN_STATUS_DOWN:
40-
pmaos.admin_status = 2
78+
pmaos.admin_status = PMAOS_DISABLE
4179
else:
42-
pmaos.admin_status = 1
80+
pmaos.admin_status = PMAOS_ENABLE
4381

4482
meta.access_cmd = SXD_ACCESS_CMD_SET
45-
rc = sxd_access_reg_pmaos(pmaos, meta, 1, None, None)
83+
rc = sxd_access_reg_pmaos(pmaos, meta, REGISTER_NUM, None, None)
4684
assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmaos failed, rc = %d" % rc
4785

86+
def set_sfp_lpmode(sfp_module, lpm_enable):
87+
# Get PMMP
88+
pmmp = ku_pmmp_reg()
89+
pmmp.module = sfp_module
90+
meta = init_sx_meta_data()
91+
meta.access_cmd = SXD_ACCESS_CMD_GET
92+
rc = sxd_access_reg_pmmp(pmmp, meta, REGISTER_NUM, None, None)
93+
assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmmp failed, rc = %d" % rc
94+
95+
# Set low power mode status
96+
lpm_mask = 1 << 8
97+
if lpm_enable:
98+
pmmp.eeprom_override = pmmp.eeprom_override | lpm_mask
99+
else:
100+
pmmp.eeprom_override = pmmp.eeprom_override & (~lpm_mask)
101+
102+
meta.access_cmd = SXD_ACCESS_CMD_SET
103+
rc = sxd_access_reg_pmmp(pmmp, meta, REGISTER_NUM, None, None)
104+
assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmmp failed, rc = %d" % rc
105+
48106
# Check if SFP port number is provided
49107
if len(sys.argv) < 3:
50108
print "SFP module number or LPM is missed."
@@ -67,41 +125,30 @@ def set_sfp_admin_status(handle, meta, sfp_module, sfp_log_port_list, admin_stat
67125
sys.exit(errno.EACCES)
68126

69127
pid = os.getpid()
70-
rc = sxd_access_reg_init(pid, None, 0)
71-
if (rc != 0):
128+
rc = sxd_access_reg_init(pid, None, SXD_LOG_VERBOSITY_LEVEL)
129+
if (rc != SXD_STATUS_SUCCESS):
72130
print "Failed to initializing register access.\nPlease check that SDK is running."
73131
sys.exit(errno.EACCES);
74132

75-
# Get SFP module and log ports number and LPM status
133+
# Get SFP module
76134
sfp_module = int(sys.argv[1])
135+
136+
# Get all ports at admin up status that related to the SFP module
77137
log_port_list = get_log_ports(handle, sfp_module)
78-
if not log_port_list:
79-
print "Failed to get log ports"
80-
sys.exit(errno.EACCES)
81138

82-
# Get PMMP
83-
pmmp = ku_pmmp_reg()
84-
pmmp.module = sfp_module
85-
meta = sxd_reg_meta_t()
86-
meta.dev_id = 1
87-
meta.swid = 0
88-
meta.access_cmd = SXD_ACCESS_CMD_GET
89-
rc = sxd_access_reg_pmmp(pmmp, meta, 1, None, None)
90-
assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmmp failed, rc = %d" % rc
139+
# SET SFP related ports to admin down status
140+
for log_port in log_port_list:
141+
set_port_admin_status_by_log_port(handle, log_port, SX_PORT_ADMIN_STATUS_DOWN)
91142

92143
# Disable admin status before LPM settings
93-
set_sfp_admin_status(handle, meta, sfp_module, log_port_list, SX_PORT_ADMIN_STATUS_DOWN)
144+
set_sfp_admin_status(sfp_module, SX_PORT_ADMIN_STATUS_DOWN)
94145

95146
# Set low power mode status
96-
lpm_mask = 1 << 8
97-
if lpm_enable:
98-
pmmp.eeprom_override = pmmp.eeprom_override | lpm_mask
99-
else:
100-
pmmp.eeprom_override = pmmp.eeprom_override & (~lpm_mask)
101-
102-
meta.access_cmd = SXD_ACCESS_CMD_SET
103-
rc = sxd_access_reg_pmmp(pmmp, meta, 1, None, None)
104-
assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmmp failed, rc = %d" % rc
147+
set_sfp_lpmode(sfp_module, lpm_enable)
105148

106149
# Enable admin status after LPM settings
107-
set_sfp_admin_status(handle, meta, sfp_module, log_port_list, SX_PORT_ADMIN_STATUS_UP)
150+
set_sfp_admin_status(sfp_module, SX_PORT_ADMIN_STATUS_UP)
151+
152+
# SET SFP related ports to admin up status
153+
for log_port in log_port_list:
154+
set_port_admin_status_by_log_port(handle, log_port, SX_PORT_ADMIN_STATUS_UP)

device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -123,31 +123,9 @@ def set_low_power_mode(self, port_num, lpmode):
123123
if curr_lpmode == lpmode:
124124
return True
125125

126+
# Compose LPM command
126127
lpm = 'on' if lpmode else 'off'
127128
lpm_cmd = "docker exec syncd python /usr/share/sonic/platform/plugins/sfplpmset.py {} {}".format(port_num, lpm)
128-
sfp_port_names = self.physical_to_logical[port_num]
129-
130-
# Get port admin status
131-
try:
132-
enabled_ports = subprocess.check_output("ip link show up", shell=True)
133-
except subprocess.CalledProcessError as e:
134-
print "Error! Unable to get ports status, err msg: {}".format(e.output)
135-
return False
136-
137-
port_to_disable = []
138-
for port in sfp_port_names:
139-
if port in enabled_ports:
140-
port_to_disable.append(port)
141-
142-
# Disable ports before LPM settings
143-
for port in port_to_disable:
144-
try:
145-
subprocess.check_output("ifconfig {} down".format(port), shell=True)
146-
except subprocess.CalledProcessError as e:
147-
print "Error! Unable to set admin status to DOWN for {}, rc = {}, err msg: {}".format(port, e.returncode, e.output)
148-
return False
149-
150-
time.sleep(3)
151129

152130
# Set LPM
153131
try:
@@ -156,14 +134,6 @@ def set_low_power_mode(self, port_num, lpmode):
156134
print "Error! Unable to set LPM for {}, rc = {}, err msg: {}".format(port_num, e.returncode, e.output)
157135
return False
158136

159-
# Enable ports after LPM settings
160-
for port in port_to_disable:
161-
try:
162-
subprocess.check_output("ifconfig {} up".format(port), shell=True)
163-
except subprocess.CalledProcessError as e:
164-
print "Error! Unable to set admin status to UP for {}, rc = {}, err msg: {}".format(port, e.returncode, e.output)
165-
return False
166-
167137
return True
168138

169139
def reset(self, port_num):

0 commit comments

Comments
 (0)