Skip to content

Commit 4312bba

Browse files
AndriiSlguohan
AndriiS
authored andcommitted
Added LPM and reset support to sfputil for MLNX msn2700 platform [NOT FOR master] (sonic-net#10)
* Added LPM and reset support to sfputil for MLNX msn2700 platform * added LPM and reset for all MLNX platforms * [sfputil] Move disabling SFP port before LPM set on a SONiC layer
1 parent faf058d commit 4312bba

File tree

16 files changed

+1105
-14
lines changed

16 files changed

+1105
-14
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#!/usr/bin/env python
2+
3+
import sys, errno
4+
import os
5+
from python_sdk_api.sxd_api import *
6+
from python_sdk_api.sx_api import *
7+
8+
# Check if SFP port number is provided
9+
if len(sys.argv) < 2:
10+
print "SFP module number is missed."
11+
print "Usage: sfplpmget.py <SFP module>"
12+
sys.exit(errno.EINVAL)
13+
14+
# Init SDK API
15+
rc, handle = sx_api_open(None)
16+
if (rc != SX_STATUS_SUCCESS):
17+
print "Failed to open api handle.\nPlease check that SDK is running."
18+
sys.exit(errno.EACCES)
19+
20+
pid = os.getpid()
21+
rc = sxd_access_reg_init(pid, None, 0)
22+
if (rc != 0):
23+
print "Failed to initializing register access.\nPlease check that SDK is running."
24+
sys.exit(errno.EACCES)
25+
26+
# Get SFP module number
27+
sfp_module = int(sys.argv[1])
28+
29+
# Get MCION
30+
mcion = ku_mcion_reg()
31+
mcion.module = sfp_module
32+
meta = sxd_reg_meta_t()
33+
meta.dev_id = 1
34+
meta.swid = 0
35+
meta.access_cmd = SXD_ACCESS_CMD_GET
36+
37+
rc = sxd_access_reg_mcion(mcion, meta, 1, None, None)
38+
assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_mcion failed, rc = %d" % rc
39+
40+
# Get low power mode status
41+
lpm_mask = 1 << 8
42+
lpm_status = (lpm_mask & mcion.module_status_bits) != 0
43+
print "LPM ON" if lpm_status else "LPM OFF"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
#!/usr/bin/env python
2+
3+
import sys, errno
4+
import time
5+
import os
6+
from python_sdk_api.sxd_api import *
7+
from python_sdk_api.sx_api import *
8+
9+
def get_log_ports(handle, sfp_module):
10+
port_attributes_list = new_sx_port_attributes_t_arr(64)
11+
port_cnt_p = new_uint32_t_p()
12+
uint32_t_p_assign(port_cnt_p, 64)
13+
14+
rc = sx_api_port_device_get(handle, 1 , 0, port_attributes_list, port_cnt_p)
15+
assert rc == SX_STATUS_SUCCESS, "sx_api_port_device_get failed, rc = %d" % rc
16+
17+
port_cnt = uint32_t_p_value(port_cnt_p)
18+
log_port_list = []
19+
for i in range(0, port_cnt):
20+
port_attributes = sx_port_attributes_t_arr_getitem(port_attributes_list, i)
21+
if port_attributes.port_mapping.module_port == sfp_module:
22+
log_port_list.append(port_attributes.log_port)
23+
24+
return log_port_list
25+
26+
def set_sfp_admin_status(handle, meta, sfp_module, sfp_log_port_list, admin_status):
27+
# Get PMAOS
28+
pmaos = ku_pmaos_reg()
29+
pmaos.module = sfp_module
30+
meta.access_cmd = SXD_ACCESS_CMD_GET
31+
rc = sxd_access_reg_pmaos(pmaos, meta, 1, None, None)
32+
assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmaos failed, rc = %d" % rc
33+
34+
# Set admin status to PMAOS
35+
pmaos.ase = 1
36+
pmaos.ee = 1
37+
pmaos.e = 2
38+
pmaos.rst = 0
39+
if admin_status == SX_PORT_ADMIN_STATUS_DOWN:
40+
pmaos.admin_status = 2
41+
else:
42+
pmaos.admin_status = 1
43+
44+
meta.access_cmd = SXD_ACCESS_CMD_SET
45+
rc = sxd_access_reg_pmaos(pmaos, meta, 1, None, None)
46+
assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmaos failed, rc = %d" % rc
47+
48+
# Check if SFP port number is provided
49+
if len(sys.argv) < 3:
50+
print "SFP module number or LPM is missed."
51+
print "Usage: sfplpmset.py <SFP module> <on|off>"
52+
sys.exit(errno.EINVAL)
53+
54+
lpm_enable = None
55+
if sys.argv[2] == 'on':
56+
lpm_enable = True
57+
elif sys.argv[2] == 'off':
58+
lpm_enable = False
59+
else:
60+
print "Unrecognized LPM parameter. Please use <on> or <off> values"
61+
sys.exit(errno.EINVAL)
62+
63+
# Init SDK API
64+
rc, handle = sx_api_open(None)
65+
if (rc != SX_STATUS_SUCCESS):
66+
print "Failed to open api handle.\nPlease check that SDK is running."
67+
sys.exit(errno.EACCES)
68+
69+
pid = os.getpid()
70+
rc = sxd_access_reg_init(pid, None, 0)
71+
if (rc != 0):
72+
print "Failed to initializing register access.\nPlease check that SDK is running."
73+
sys.exit(errno.EACCES);
74+
75+
# Get SFP module and log ports number and LPM status
76+
sfp_module = int(sys.argv[1])
77+
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)
81+
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
91+
92+
# Disable admin status before LPM settings
93+
set_sfp_admin_status(handle, meta, sfp_module, log_port_list, SX_PORT_ADMIN_STATUS_DOWN)
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, 1, None, None)
104+
assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmmp failed, rc = %d" % rc
105+
106+
# Enable admin status after LPM settings
107+
set_sfp_admin_status(handle, meta, sfp_module, log_port_list, SX_PORT_ADMIN_STATUS_UP)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#!/usr/bin/env python
2+
3+
import sys, errno
4+
import os
5+
from python_sdk_api.sxd_api import *
6+
from python_sdk_api.sx_api import *
7+
8+
# Check if SFP port number is provided
9+
if len(sys.argv) < 2:
10+
print "SFP module number or LPM is missed."
11+
print "Usage: sfpreset.py <SFP module>"
12+
sys.exit(errno.EINVAL)
13+
14+
# Init SDK API
15+
rc, handle = sx_api_open(None)
16+
if (rc != SX_STATUS_SUCCESS):
17+
print "Failed to open api handle.\nPlease check that SDK is running."
18+
sys.exit(errno.EACCES)
19+
20+
pid = os.getpid()
21+
rc = sxd_access_reg_init(pid, None, 0)
22+
if (rc != 0):
23+
print "Failed to initializing register access.\nPlease check that SDK is running."
24+
sys.exit(errno.EACCES)
25+
26+
# Get SFP module number
27+
sfp_module = int(sys.argv[1])
28+
29+
# Get PMAOS
30+
pmaos = ku_pmaos_reg()
31+
pmaos.module = sfp_module
32+
meta = sxd_reg_meta_t()
33+
meta.dev_id = 1
34+
meta.swid = 0
35+
meta.access_cmd = SXD_ACCESS_CMD_GET
36+
37+
rc = sxd_access_reg_pmaos(pmaos, meta, 1, None, None)
38+
assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmaos failed, rc = %d" % rc
39+
40+
# Reset SFP
41+
pmaos.rst = 1
42+
meta.access_cmd = SXD_ACCESS_CMD_SET
43+
rc = sxd_access_reg_pmaos(pmaos, meta, 1, None, None)
44+
assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmaos failed, rc = %d" % rc
45+
print "Reset flag is set"

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

+94-5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
try:
77
import time
8+
import subprocess
89
from sonic_sfp.sfputilbase import SfpUtilBase
910
except ImportError as e:
1011
raise ImportError("%s - required module not found" % str(e))
@@ -46,17 +47,105 @@ def __init__(self):
4647
SfpUtilBase.__init__(self)
4748

4849
def get_presence(self, port_num):
50+
# Check for invalid port_num
51+
if port_num < self.port_start or port_num > self.port_end:
52+
return False
4953

50-
raise NotImplementedError
54+
try:
55+
reg_file = open("/bsp/qsfp/qsfp%d_status" % (port_num+1))
56+
except IOError as e:
57+
print "Error: unable to open file: %s" % str(e)
58+
return False
59+
60+
content = reg_file.readline().rstrip()
61+
62+
# content is a string with the qsfp status
63+
if content == "good":
64+
return True
65+
66+
return False
5167

5268
def get_low_power_mode(self, port_num):
69+
# Check for invalid port_num
70+
if port_num < self.port_start or port_num > self.port_end:
71+
return False
5372

54-
raise NotImplementedError
73+
lpm_cmd = "docker exec syncd python /usr/share/sonic/platform/plugins/sfplpmget.py {}".format(port_num)
5574

56-
def set_low_power_mode(self, port_num, lpmode):
75+
try:
76+
output = subprocess.check_output(lpm_cmd, shell=True)
77+
if 'LPM ON' in output:
78+
return True
79+
except subprocess.CalledProcessError as e:
80+
print "Error! Unable to get LPM for {}, rc = {}, err msg: {}".format(port_num, e.returncode, e.output)
81+
return False
5782

58-
raise NotImplementedError
83+
return False
84+
85+
def set_low_power_mode(self, port_num, lpmode):
86+
# Check for invalid port_num
87+
if port_num < self.port_start or port_num > self.port_end:
88+
return False
89+
90+
curr_lpmode = self.get_low_power_mode(port_num)
91+
if curr_lpmode == lpmode:
92+
return True
93+
94+
lpm = 'on' if lpmode else 'off'
95+
lpm_cmd = "docker exec syncd python /usr/share/sonic/platform/plugins/sfplpmset.py {} {}".format(port_num, lpm)
96+
sfp_port_names = self.physical_to_logical[port_num]
97+
98+
# Get port admin status
99+
try:
100+
enabled_ports = subprocess.check_output("ip link show up", shell=True)
101+
except subprocess.CalledProcessError as e:
102+
print "Error! Unable to get ports status, err msg: {}".format(e.output)
103+
return False
104+
105+
port_to_disable = []
106+
for port in sfp_port_names:
107+
if port in enabled_ports:
108+
port_to_disable.append(port)
109+
110+
# Disable ports before LPM settings
111+
for port in port_to_disable:
112+
try:
113+
subprocess.check_output("ifconfig {} down".format(port), shell=True)
114+
except subprocess.CalledProcessError as e:
115+
print "Error! Unable to set admin status to DOWN for {}, rc = {}, err msg: {}".format(port, e.returncode, e.output)
116+
return False
117+
118+
time.sleep(3)
119+
120+
# Set LPM
121+
try:
122+
subprocess.check_output(lpm_cmd, shell=True)
123+
except subprocess.CalledProcessError as e:
124+
print "Error! Unable to set LPM for {}, rc = {}, err msg: {}".format(port_num, e.returncode, e.output)
125+
return False
126+
127+
# Enable ports after LPM settings
128+
for port in port_to_disable:
129+
try:
130+
subprocess.check_output("ifconfig {} up".format(port), shell=True)
131+
except subprocess.CalledProcessError as e:
132+
print "Error! Unable to set admin status to UP for {}, rc = {}, err msg: {}".format(port, e.returncode, e.output)
133+
return False
134+
135+
return True
59136

60137
def reset(self, port_num):
138+
# Check for invalid port_num
139+
if port_num < self.port_start or port_num > self.port_end:
140+
return False
141+
142+
lpm_cmd = "docker exec syncd python /usr/share/sonic/platform/plugins/sfpreset.py {}".format(port_num)
143+
144+
try:
145+
subprocess.check_output(lpm_cmd, shell=True)
146+
return True
147+
except subprocess.CalledProcessError as e:
148+
print "Error! Unable to set LPM for {}, rc = {}, err msg: {}".format(port_num, e.returncode, e.output)
149+
return False
61150

62-
raise NotImplementedError
151+
return False
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#!/usr/bin/env python
2+
3+
import sys, errno
4+
import os
5+
from python_sdk_api.sxd_api import *
6+
from python_sdk_api.sx_api import *
7+
8+
# Check if SFP port number is provided
9+
if len(sys.argv) < 2:
10+
print "SFP module number is missed."
11+
print "Usage: sfplpmget.py <SFP module>"
12+
sys.exit(errno.EINVAL)
13+
14+
# Init SDK API
15+
rc, handle = sx_api_open(None)
16+
if (rc != SX_STATUS_SUCCESS):
17+
print "Failed to open api handle.\nPlease check that SDK is running."
18+
sys.exit(errno.EACCES)
19+
20+
pid = os.getpid()
21+
rc = sxd_access_reg_init(pid, None, 0)
22+
if (rc != 0):
23+
print "Failed to initializing register access.\nPlease check that SDK is running."
24+
sys.exit(errno.EACCES)
25+
26+
# Get SFP module number
27+
sfp_module = int(sys.argv[1])
28+
29+
# Get MCION
30+
mcion = ku_mcion_reg()
31+
mcion.module = sfp_module
32+
meta = sxd_reg_meta_t()
33+
meta.dev_id = 1
34+
meta.swid = 0
35+
meta.access_cmd = SXD_ACCESS_CMD_GET
36+
37+
rc = sxd_access_reg_mcion(mcion, meta, 1, None, None)
38+
assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_mcion failed, rc = %d" % rc
39+
40+
# Get low power mode status
41+
lpm_mask = 1 << 8
42+
lpm_status = (lpm_mask & mcion.module_status_bits) != 0
43+
print "LPM ON" if lpm_status else "LPM OFF"

0 commit comments

Comments
 (0)