Skip to content

Commit c54a03f

Browse files
authored
[as7312-54x] Support platform API2.0 (#6272)
Add platform 2.0 support for Accton as7312-54x platform
1 parent cea8c18 commit c54a03f

File tree

14 files changed

+2427
-7
lines changed

14 files changed

+2427
-7
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
__all__ = ['chassis', 'eeprom', 'platform', 'psu', 'sfp', 'thermal', 'fan']
2+
from . import platform
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
#############################################################################
2+
# Edgecore
3+
#
4+
# Module contains an implementation of SONiC Platform Base API and
5+
# provides the Chassis information which are available in the platform
6+
#
7+
#############################################################################
8+
9+
import os
10+
11+
try:
12+
from sonic_platform_base.chassis_base import ChassisBase
13+
from .helper import APIHelper
14+
except ImportError as e:
15+
raise ImportError(str(e) + "- required module not found")
16+
17+
NUM_FAN_TRAY = 6
18+
NUM_FAN = 2
19+
NUM_PSU = 2
20+
NUM_THERMAL = 4
21+
PORT_END = 54
22+
NUM_COMPONENT = 4
23+
HOST_REBOOT_CAUSE_PATH = "/host/reboot-cause/"
24+
PMON_REBOOT_CAUSE_PATH = "/usr/share/sonic/platform/api_files/reboot-cause/"
25+
REBOOT_CAUSE_FILE = "reboot-cause.txt"
26+
PREV_REBOOT_CAUSE_FILE = "previous-reboot-cause.txt"
27+
HOST_CHK_CMD = "docker > /dev/null 2>&1"
28+
29+
30+
class Chassis(ChassisBase):
31+
"""Platform-specific Chassis class"""
32+
33+
def __init__(self):
34+
ChassisBase.__init__(self)
35+
self._api_helper = APIHelper()
36+
self._api_helper = APIHelper()
37+
self.is_host = self._api_helper.is_host()
38+
39+
self.config_data = {}
40+
41+
self.__initialize_fan()
42+
self.__initialize_psu()
43+
self.__initialize_thermals()
44+
self.__initialize_components()
45+
self.__initialize_sfp()
46+
self.__initialize_eeprom()
47+
48+
def __initialize_sfp(self):
49+
from sonic_platform.sfp import Sfp
50+
for index in range(0, PORT_END):
51+
sfp = Sfp(index)
52+
self._sfp_list.append(sfp)
53+
self.sfp_module_initialized = True
54+
55+
def __initialize_fan(self):
56+
from sonic_platform.fan import Fan
57+
for fant_index in range(0, NUM_FAN_TRAY):
58+
for fan_index in range(0, NUM_FAN):
59+
fan = Fan(fant_index, fan_index)
60+
self._fan_list.append(fan)
61+
62+
def __initialize_psu(self):
63+
from sonic_platform.psu import Psu
64+
for index in range(0, NUM_PSU):
65+
psu = Psu(index)
66+
self._psu_list.append(psu)
67+
68+
def __initialize_thermals(self):
69+
from sonic_platform.thermal import Thermal
70+
for index in range(0, NUM_THERMAL):
71+
thermal = Thermal(index)
72+
self._thermal_list.append(thermal)
73+
74+
def __initialize_eeprom(self):
75+
from sonic_platform.eeprom import Tlv
76+
self._eeprom = Tlv()
77+
78+
def __initialize_components(self):
79+
from sonic_platform.component import Component
80+
for index in range(0, NUM_COMPONENT):
81+
component = Component(index)
82+
self._component_list.append(component)
83+
84+
def __initialize_watchdog(self):
85+
from sonic_platform.watchdog import Watchdog
86+
self._watchdog = Watchdog()
87+
88+
89+
def __is_host(self):
90+
return os.system(HOST_CHK_CMD) == 0
91+
92+
def __read_txt_file(self, file_path):
93+
try:
94+
with open(file_path, 'r') as fd:
95+
data = fd.read()
96+
return data.strip()
97+
except IOError:
98+
pass
99+
return None
100+
101+
def get_name(self):
102+
"""
103+
Retrieves the name of the device
104+
Returns:
105+
string: The name of the device
106+
"""
107+
108+
return self._api_helper.hwsku
109+
110+
def get_presence(self):
111+
"""
112+
Retrieves the presence of the Chassis
113+
Returns:
114+
bool: True if Chassis is present, False if not
115+
"""
116+
return True
117+
118+
def get_status(self):
119+
"""
120+
Retrieves the operational status of the device
121+
Returns:
122+
A boolean value, True if device is operating properly, False if not
123+
"""
124+
return True
125+
126+
def get_base_mac(self):
127+
"""
128+
Retrieves the base MAC address for the chassis
129+
Returns:
130+
A string containing the MAC address in the format
131+
'XX:XX:XX:XX:XX:XX'
132+
"""
133+
return self._eeprom.get_mac()
134+
135+
def get_serial_number(self):
136+
"""
137+
Retrieves the hardware serial number for the chassis
138+
Returns:
139+
A string containing the hardware serial number for this chassis.
140+
"""
141+
return self._eeprom.get_serial()
142+
143+
def get_system_eeprom_info(self):
144+
"""
145+
Retrieves the full content of system EEPROM information for the chassis
146+
Returns:
147+
A dictionary where keys are the type code defined in
148+
OCP ONIE TlvInfo EEPROM format and values are their corresponding
149+
values.
150+
"""
151+
return self._eeprom.get_eeprom()
152+
153+
def get_reboot_cause(self):
154+
"""
155+
Retrieves the cause of the previous reboot
156+
157+
Returns:
158+
A tuple (string, string) where the first element is a string
159+
containing the cause of the previous reboot. This string must be
160+
one of the predefined strings in this class. If the first string
161+
is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used
162+
to pass a description of the reboot cause.
163+
"""
164+
165+
reboot_cause_path = (HOST_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE)
166+
sw_reboot_cause = self._api_helper.read_txt_file(
167+
reboot_cause_path) or "Unknown"
168+
169+
170+
return ('REBOOT_CAUSE_NON_HARDWARE', sw_reboot_cause)
171+
172+
def get_sfp(self, index):
173+
"""
174+
Retrieves sfp represented by (1-based) index <index>
175+
Args:
176+
index: An integer, the index (1-based) of the sfp to retrieve.
177+
The index should be the sequence of a physical port in a chassis,
178+
starting from 1.
179+
For example, 1 for Ethernet0, 2 for Ethernet4 and so on.
180+
Returns:
181+
An object dervied from SfpBase representing the specified sfp
182+
"""
183+
sfp = None
184+
if not self.sfp_module_initialized:
185+
self.__initialize_sfp()
186+
187+
try:
188+
# The index will start from 1
189+
sfp = self._sfp_list[index-1]
190+
except IndexError:
191+
sys.stderr.write("SFP index {} out of range (1-{})\n".format(
192+
index, len(self._sfp_list)))
193+
return sfp
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
#############################################################################
2+
# Celestica
3+
#
4+
# Component contains an implementation of SONiC Platform Base API and
5+
# provides the components firmware management function
6+
#
7+
#############################################################################
8+
9+
import shlex
10+
import subprocess
11+
12+
try:
13+
from sonic_platform_base.component_base import ComponentBase
14+
from .helper import APIHelper
15+
except ImportError as e:
16+
raise ImportError(str(e) + "- required module not found")
17+
18+
CPLD_ADDR_MAPPING = {
19+
"CPLD1": "4-0060",
20+
"CPLD2": "5-0062",
21+
"CPLD3": "6-0064",
22+
}
23+
SYSFS_PATH = "/sys/bus/i2c/devices/"
24+
BIOS_VERSION_PATH = "/sys/class/dmi/id/bios_version"
25+
COMPONENT_LIST= [
26+
("CPLD1", "CPLD 1"),
27+
("CPLD2", "CPLD 2"),
28+
("CPLD3", "CPLD 3"),
29+
("BIOS", "Basic Input/Output System")
30+
31+
]
32+
COMPONENT_DES_LIST = ["CPLD","Basic Input/Output System"]
33+
34+
35+
class Component(ComponentBase):
36+
"""Platform-specific Component class"""
37+
38+
DEVICE_TYPE = "component"
39+
40+
def __init__(self, component_index=0):
41+
self._api_helper=APIHelper()
42+
ComponentBase.__init__(self)
43+
self.index = component_index
44+
self.name = self.get_name()
45+
46+
def __run_command(self, command):
47+
# Run bash command and print output to stdout
48+
try:
49+
process = subprocess.Popen(
50+
shlex.split(command), stdout=subprocess.PIPE)
51+
while True:
52+
output = process.stdout.readline()
53+
if output == '' and process.poll() is not None:
54+
break
55+
rc = process.poll()
56+
if rc != 0:
57+
return False
58+
except Exception:
59+
return False
60+
return True
61+
62+
def __get_bios_version(self):
63+
# Retrieves the BIOS firmware version
64+
try:
65+
with open(BIOS_VERSION_PATH, 'r') as fd:
66+
bios_version = fd.read()
67+
return bios_version.strip()
68+
except Exception as e:
69+
return None
70+
71+
def __get_cpld_version(self):
72+
# Retrieves the CPLD firmware version
73+
cpld_version = dict()
74+
for cpld_name in CPLD_ADDR_MAPPING:
75+
try:
76+
cpld_path = "{}{}{}".format(SYSFS_PATH, CPLD_ADDR_MAPPING[cpld_name], '/version')
77+
cpld_version_raw= self._api_helper.read_txt_file(cpld_path)
78+
cpld_version[cpld_name] = "{}".format(int(cpld_version_raw,16))
79+
except Exception as e:
80+
print('Get exception when read cpld')
81+
cpld_version[cpld_name] = 'None'
82+
83+
return cpld_version
84+
85+
def get_name(self):
86+
"""
87+
Retrieves the name of the component
88+
Returns:
89+
A string containing the name of the component
90+
"""
91+
return COMPONENT_LIST[self.index][0]
92+
93+
def get_description(self):
94+
"""
95+
Retrieves the description of the component
96+
Returns:
97+
A string containing the description of the component
98+
"""
99+
return COMPONENT_LIST[self.index][1]
100+
#return "testhwsku"
101+
102+
def get_firmware_version(self):
103+
"""
104+
Retrieves the firmware version of module
105+
Returns:
106+
string: The firmware versions of the module
107+
"""
108+
fw_version = None
109+
if self.name == "BIOS":
110+
fw_version = self.__get_bios_version()
111+
elif "CPLD" in self.name:
112+
cpld_version = self.__get_cpld_version()
113+
fw_version = cpld_version.get(self.name)
114+
115+
return fw_version
116+
117+
def install_firmware(self, image_path):
118+
"""
119+
Install firmware to module
120+
Args:
121+
image_path: A string, path to firmware image
122+
Returns:
123+
A boolean, True if install successfully, False if not
124+
"""
125+
raise NotImplementedError

0 commit comments

Comments
 (0)