[as5835-54x] Add to support API2.0 (#6480)
Add platform API 2.0 support for as5835-54x platform
This commit is contained in:
parent
d7b96dfdf1
commit
0c5c4872dc
@ -48,8 +48,8 @@ Ethernet45 74 tenGigE46 46 10000
|
||||
Ethernet46 75 tenGigE47 47 10000
|
||||
Ethernet47 76 tenGigE48 48 10000
|
||||
Ethernet48 37,38,39,40 hundredGigE49 49 100000
|
||||
Ethernet52 29,30,31,32 hundredGigE50 53 100000
|
||||
Ethernet56 33,34,35,36 hundredGigE51 57 100000
|
||||
Ethernet60 49,50,51,52 hundredGigE52 61 100000
|
||||
Ethernet64 45,46,47,48 hundredGigE53 65 100000
|
||||
Ethernet68 41,42,43,44 hundredGigE54 69 100000
|
||||
Ethernet52 29,30,31,32 hundredGigE50 50 100000
|
||||
Ethernet56 33,34,35,36 hundredGigE51 51 100000
|
||||
Ethernet60 49,50,51,52 hundredGigE52 52 100000
|
||||
Ethernet64 45,46,47,48 hundredGigE53 53 100000
|
||||
Ethernet68 41,42,43,44 hundredGigE54 54 100000
|
||||
|
@ -0,0 +1,2 @@
|
||||
__all__ = ['chassis', 'eeprom', 'platform', 'psu', 'sfp', 'thermal', 'fan']
|
||||
from . import platform
|
@ -0,0 +1,214 @@
|
||||
#############################################################################
|
||||
# Edgecore
|
||||
#
|
||||
# Module contains an implementation of SONiC Platform Base API and
|
||||
# provides the Chassis information which are available in the platform
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
try:
|
||||
from sonic_platform_base.chassis_base import ChassisBase
|
||||
from .helper import APIHelper
|
||||
from .event import SfpEvent
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
NUM_FAN_TRAY = 5
|
||||
NUM_FAN = 2
|
||||
NUM_PSU = 2
|
||||
NUM_THERMAL = 4
|
||||
NUM_QSFP = 54
|
||||
PORT_START = 1
|
||||
PORT_END = 54
|
||||
NUM_COMPONENT = 4
|
||||
HOST_REBOOT_CAUSE_PATH = "/host/reboot-cause/"
|
||||
PMON_REBOOT_CAUSE_PATH = "/usr/share/sonic/platform/api_files/reboot-cause/"
|
||||
REBOOT_CAUSE_FILE = "reboot-cause.txt"
|
||||
PREV_REBOOT_CAUSE_FILE = "previous-reboot-cause.txt"
|
||||
HOST_CHK_CMD = "docker > /dev/null 2>&1"
|
||||
|
||||
|
||||
class Chassis(ChassisBase):
|
||||
"""Platform-specific Chassis class"""
|
||||
|
||||
def __init__(self):
|
||||
ChassisBase.__init__(self)
|
||||
self._api_helper = APIHelper()
|
||||
self._api_helper = APIHelper()
|
||||
self.is_host = self._api_helper.is_host()
|
||||
|
||||
self.config_data = {}
|
||||
|
||||
self.__initialize_fan()
|
||||
self.__initialize_psu()
|
||||
self.__initialize_thermals()
|
||||
self.__initialize_components()
|
||||
self.__initialize_sfp()
|
||||
self.__initialize_eeprom()
|
||||
|
||||
def __initialize_sfp(self):
|
||||
from sonic_platform.sfp import Sfp
|
||||
for index in range(0, PORT_END):
|
||||
sfp = Sfp(index)
|
||||
self._sfp_list.append(sfp)
|
||||
self.sfp_module_initialized = True
|
||||
|
||||
def __initialize_fan(self):
|
||||
from sonic_platform.fan import Fan
|
||||
for fant_index in range(0, NUM_FAN_TRAY):
|
||||
for fan_index in range(0, NUM_FAN):
|
||||
fan = Fan(fant_index, fan_index)
|
||||
self._fan_list.append(fan)
|
||||
|
||||
def __initialize_psu(self):
|
||||
from sonic_platform.psu import Psu
|
||||
for index in range(0, NUM_PSU):
|
||||
psu = Psu(index)
|
||||
self._psu_list.append(psu)
|
||||
|
||||
def __initialize_thermals(self):
|
||||
from sonic_platform.thermal import Thermal
|
||||
for index in range(0, NUM_THERMAL):
|
||||
thermal = Thermal(index)
|
||||
self._thermal_list.append(thermal)
|
||||
|
||||
def __initialize_eeprom(self):
|
||||
from sonic_platform.eeprom import Tlv
|
||||
self._eeprom = Tlv()
|
||||
|
||||
def __initialize_components(self):
|
||||
from sonic_platform.component import Component
|
||||
for index in range(0, NUM_COMPONENT):
|
||||
component = Component(index)
|
||||
self._component_list.append(component)
|
||||
|
||||
def __initialize_watchdog(self):
|
||||
from sonic_platform.watchdog import Watchdog
|
||||
self._watchdog = Watchdog()
|
||||
|
||||
|
||||
def __is_host(self):
|
||||
return os.system(HOST_CHK_CMD) == 0
|
||||
|
||||
def __read_txt_file(self, file_path):
|
||||
try:
|
||||
with open(file_path, 'r') as fd:
|
||||
data = fd.read()
|
||||
return data.strip()
|
||||
except IOError:
|
||||
pass
|
||||
return None
|
||||
|
||||
def get_model(self):
|
||||
"""
|
||||
Retrieves the model number (or part number) of the device
|
||||
Returns:
|
||||
string: Model/part number of device
|
||||
"""
|
||||
return self._eeprom.get_pn()
|
||||
|
||||
def get_name(self):
|
||||
"""
|
||||
Retrieves the name of the device
|
||||
Returns:
|
||||
string: The name of the device
|
||||
"""
|
||||
|
||||
return self._api_helper.hwsku
|
||||
|
||||
def get_presence(self):
|
||||
"""
|
||||
Retrieves the presence of the Chassis
|
||||
Returns:
|
||||
bool: True if Chassis is present, False if not
|
||||
"""
|
||||
return True
|
||||
|
||||
def get_status(self):
|
||||
"""
|
||||
Retrieves the operational status of the device
|
||||
Returns:
|
||||
A boolean value, True if device is operating properly, False if not
|
||||
"""
|
||||
return True
|
||||
|
||||
def get_base_mac(self):
|
||||
"""
|
||||
Retrieves the base MAC address for the chassis
|
||||
Returns:
|
||||
A string containing the MAC address in the format
|
||||
'XX:XX:XX:XX:XX:XX'
|
||||
"""
|
||||
return self._eeprom.get_mac()
|
||||
|
||||
def get_serial_number(self):
|
||||
"""
|
||||
Retrieves the hardware serial number for the chassis
|
||||
Returns:
|
||||
A string containing the hardware serial number for this chassis.
|
||||
"""
|
||||
return self._eeprom.get_serial()
|
||||
|
||||
def get_system_eeprom_info(self):
|
||||
"""
|
||||
Retrieves the full content of system EEPROM information for the chassis
|
||||
Returns:
|
||||
A dictionary where keys are the type code defined in
|
||||
OCP ONIE TlvInfo EEPROM format and values are their corresponding
|
||||
values.
|
||||
"""
|
||||
return self._eeprom.get_eeprom()
|
||||
|
||||
def get_reboot_cause(self):
|
||||
"""
|
||||
Retrieves the cause of the previous reboot
|
||||
|
||||
Returns:
|
||||
A tuple (string, string) where the first element is a string
|
||||
containing the cause of the previous reboot. This string must be
|
||||
one of the predefined strings in this class. If the first string
|
||||
is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used
|
||||
to pass a description of the reboot cause.
|
||||
"""
|
||||
|
||||
reboot_cause_path = (HOST_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE)
|
||||
sw_reboot_cause = self._api_helper.read_txt_file(
|
||||
reboot_cause_path) or "Unknown"
|
||||
|
||||
|
||||
return ('REBOOT_CAUSE_NON_HARDWARE', sw_reboot_cause)
|
||||
|
||||
def get_change_event(self, timeout=0):
|
||||
# SFP event
|
||||
if not self.sfp_module_initialized:
|
||||
self.__initialize_sfp()
|
||||
|
||||
status, sfp_event = SfpEvent(self._sfp_list).get_sfp_event(timeout)
|
||||
|
||||
return status, sfp_event
|
||||
|
||||
def get_sfp(self, index):
|
||||
"""
|
||||
Retrieves sfp represented by (1-based) index <index>
|
||||
Args:
|
||||
index: An integer, the index (1-based) of the sfp to retrieve.
|
||||
The index should be the sequence of a physical port in a chassis,
|
||||
starting from 1.
|
||||
For example, 1 for Ethernet0, 2 for Ethernet4 and so on.
|
||||
Returns:
|
||||
An object dervied from SfpBase representing the specified sfp
|
||||
"""
|
||||
sfp = None
|
||||
if not self.sfp_module_initialized:
|
||||
self.__initialize_sfp()
|
||||
|
||||
try:
|
||||
# The index will start from 1
|
||||
sfp = self._sfp_list[index-1]
|
||||
except IndexError:
|
||||
sys.stderr.write("SFP index {} out of range (1-{})\n".format(
|
||||
index, len(self._sfp_list)))
|
||||
return sfp
|
@ -0,0 +1,128 @@
|
||||
#############################################################################
|
||||
# Celestica
|
||||
#
|
||||
# Component contains an implementation of SONiC Platform Base API and
|
||||
# provides the components firmware management function
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
import shlex
|
||||
import subprocess
|
||||
|
||||
|
||||
try:
|
||||
from sonic_platform_base.component_base import ComponentBase
|
||||
from .helper import APIHelper
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
CPLD_ADDR_MAPPING = {
|
||||
"CPLD1": "3-0060",
|
||||
"CPLD2": "3-0061",
|
||||
"CPLD3": "3-0062",
|
||||
}
|
||||
SYSFS_PATH = "/sys/bus/i2c/devices/"
|
||||
BIOS_VERSION_PATH = "/sys/class/dmi/id/bios_version"
|
||||
COMPONENT_LIST= [
|
||||
("CPLD1", "CPLD 1"),
|
||||
("CPLD2", "CPLD 2"),
|
||||
("CPLD3", "CPLD 3"),
|
||||
("BIOS", "Basic Input/Output System")
|
||||
|
||||
]
|
||||
COMPONENT_DES_LIST = ["CPLD","Basic Input/Output System"]
|
||||
|
||||
|
||||
class Component(ComponentBase):
|
||||
"""Platform-specific Component class"""
|
||||
|
||||
DEVICE_TYPE = "component"
|
||||
|
||||
def __init__(self, component_index=0):
|
||||
self._api_helper=APIHelper()
|
||||
ComponentBase.__init__(self)
|
||||
self.index = component_index
|
||||
self.name = self.get_name()
|
||||
|
||||
|
||||
def __run_command(self, command):
|
||||
# Run bash command and print output to stdout
|
||||
try:
|
||||
process = subprocess.Popen(
|
||||
shlex.split(command), stdout=subprocess.PIPE)
|
||||
while True:
|
||||
output = process.stdout.readline()
|
||||
if output == '' and process.poll() is not None:
|
||||
break
|
||||
rc = process.poll()
|
||||
if rc != 0:
|
||||
return False
|
||||
except Exception:
|
||||
return False
|
||||
return True
|
||||
|
||||
def __get_bios_version(self):
|
||||
# Retrieves the BIOS firmware version
|
||||
try:
|
||||
with open(BIOS_VERSION_PATH, 'r') as fd:
|
||||
bios_version = fd.read()
|
||||
return bios_version.strip()
|
||||
except Exception as e:
|
||||
print('Get exception when read bios')
|
||||
return None
|
||||
|
||||
def __get_cpld_version(self):
|
||||
# Retrieves the CPLD firmware version
|
||||
cpld_version = dict()
|
||||
for cpld_name in CPLD_ADDR_MAPPING:
|
||||
try:
|
||||
cpld_path = "{}{}{}".format(SYSFS_PATH, CPLD_ADDR_MAPPING[cpld_name], '/version')
|
||||
cpld_version_raw= self._api_helper.read_txt_file(cpld_path)
|
||||
cpld_version[cpld_name] = "{}".format(int(cpld_version_raw,16))
|
||||
except Exception as e:
|
||||
print('Get exception when read cpld')
|
||||
cpld_version[cpld_name] = 'None'
|
||||
|
||||
return cpld_version
|
||||
|
||||
def get_name(self):
|
||||
"""
|
||||
Retrieves the name of the component
|
||||
Returns:
|
||||
A string containing the name of the component
|
||||
"""
|
||||
return COMPONENT_LIST[self.index][0]
|
||||
|
||||
def get_description(self):
|
||||
"""
|
||||
Retrieves the description of the component
|
||||
Returns:
|
||||
A string containing the description of the component
|
||||
"""
|
||||
return COMPONENT_LIST[self.index][1]
|
||||
#return "testhwsku"
|
||||
|
||||
def get_firmware_version(self):
|
||||
"""
|
||||
Retrieves the firmware version of module
|
||||
Returns:
|
||||
string: The firmware versions of the module
|
||||
"""
|
||||
fw_version = None
|
||||
if self.name == "BIOS":
|
||||
fw_version = self.__get_bios_version()
|
||||
elif "CPLD" in self.name:
|
||||
cpld_version = self.__get_cpld_version()
|
||||
fw_version = cpld_version.get(self.name)
|
||||
|
||||
return fw_version
|
||||
|
||||
def install_firmware(self, image_path):
|
||||
"""
|
||||
Install firmware to module
|
||||
Args:
|
||||
image_path: A string, path to firmware image
|
||||
Returns:
|
||||
A boolean, True if install successfully, False if not
|
||||
"""
|
||||
raise NotImplementedError
|
@ -0,0 +1,131 @@
|
||||
try:
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
if sys.version_info[0] >= 3:
|
||||
from io import StringIO
|
||||
else:
|
||||
from cStringIO import StringIO
|
||||
|
||||
from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
CACHE_ROOT = '/var/cache/sonic/decode-syseeprom'
|
||||
CACHE_FILE = 'syseeprom_cache'
|
||||
NULL = 'N/A'
|
||||
|
||||
class Tlv(eeprom_tlvinfo.TlvInfoDecoder):
|
||||
|
||||
EEPROM_DECODE_HEADLINES = 6
|
||||
|
||||
def __init__(self):
|
||||
self._eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom"
|
||||
super(Tlv, self).__init__(self._eeprom_path, 0, '', True)
|
||||
self._eeprom = self._load_eeprom()
|
||||
|
||||
def __parse_output(self, decode_output):
|
||||
decode_output.replace('\0', '')
|
||||
lines = decode_output.split('\n')
|
||||
lines = lines[self.EEPROM_DECODE_HEADLINES:]
|
||||
_eeprom_info_dict = dict()
|
||||
|
||||
for line in lines:
|
||||
try:
|
||||
match = re.search(
|
||||
'(0x[0-9a-fA-F]{2})([\s]+[\S]+[\s]+)([\S]+)', line)
|
||||
if match is not None:
|
||||
idx = match.group(1)
|
||||
value = match.group(3).rstrip('\0')
|
||||
|
||||
_eeprom_info_dict[idx] = value
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return _eeprom_info_dict
|
||||
|
||||
def _load_eeprom(self):
|
||||
original_stdout = sys.stdout
|
||||
sys.stdout = StringIO()
|
||||
try:
|
||||
self.read_eeprom_db()
|
||||
except Exception:
|
||||
decode_output = sys.stdout.getvalue()
|
||||
sys.stdout = original_stdout
|
||||
return self.__parse_output(decode_output)
|
||||
|
||||
status = self.check_status()
|
||||
if 'ok' not in status:
|
||||
return False
|
||||
|
||||
if not os.path.exists(CACHE_ROOT):
|
||||
try:
|
||||
os.makedirs(CACHE_ROOT)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
#
|
||||
# only the eeprom classes that inherit from eeprom_base
|
||||
# support caching. Others will work normally
|
||||
#
|
||||
try:
|
||||
self.set_cache_name(os.path.join(CACHE_ROOT, CACHE_FILE))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
e = self.read_eeprom()
|
||||
if e is None:
|
||||
return 0
|
||||
|
||||
try:
|
||||
self.update_cache(e)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
self.decode_eeprom(e)
|
||||
decode_output = sys.stdout.getvalue()
|
||||
sys.stdout = original_stdout
|
||||
|
||||
(is_valid, valid_crc) = self.is_checksum_valid(e)
|
||||
if not is_valid:
|
||||
return False
|
||||
|
||||
return self.__parse_output(decode_output)
|
||||
|
||||
def _valid_tlv(self, eeprom_data):
|
||||
tlvinfo_type_codes_list = [
|
||||
self._TLV_CODE_PRODUCT_NAME,
|
||||
self._TLV_CODE_PART_NUMBER,
|
||||
self._TLV_CODE_SERIAL_NUMBER,
|
||||
self._TLV_CODE_MAC_BASE,
|
||||
self._TLV_CODE_MANUF_DATE,
|
||||
self._TLV_CODE_DEVICE_VERSION,
|
||||
self._TLV_CODE_LABEL_REVISION,
|
||||
self._TLV_CODE_PLATFORM_NAME,
|
||||
self._TLV_CODE_ONIE_VERSION,
|
||||
self._TLV_CODE_MAC_SIZE,
|
||||
self._TLV_CODE_MANUF_NAME,
|
||||
self._TLV_CODE_MANUF_COUNTRY,
|
||||
self._TLV_CODE_VENDOR_NAME,
|
||||
self._TLV_CODE_DIAG_VERSION,
|
||||
self._TLV_CODE_SERVICE_TAG,
|
||||
self._TLV_CODE_VENDOR_EXT,
|
||||
self._TLV_CODE_CRC_32
|
||||
]
|
||||
|
||||
for code in tlvinfo_type_codes_list:
|
||||
code_str = "0x{:X}".format(code)
|
||||
eeprom_data[code_str] = eeprom_data.get(code_str, NULL)
|
||||
return eeprom_data
|
||||
|
||||
def get_eeprom(self):
|
||||
return self._valid_tlv(self._eeprom)
|
||||
|
||||
def get_pn(self):
|
||||
return self._eeprom.get('0x22', NULL)
|
||||
|
||||
def get_serial(self):
|
||||
return self._eeprom.get('0x23', NULL)
|
||||
|
||||
def get_mac(self):
|
||||
return self._eeprom.get('0x24', NULL)
|
@ -0,0 +1,55 @@
|
||||
try:
|
||||
import time
|
||||
from .helper import APIHelper
|
||||
from sonic_py_common.logger import Logger
|
||||
except ImportError as e:
|
||||
raise ImportError(repr(e) + " - required module not found")
|
||||
|
||||
|
||||
class SfpEvent:
|
||||
''' Listen to insert/remove sfp events '''
|
||||
|
||||
def __init__(self, sfp_list):
|
||||
self._api_helper = APIHelper()
|
||||
self._sfp_list = sfp_list
|
||||
self._logger = Logger()
|
||||
|
||||
sfp_change_event_data = {'valid': 0, 'last': 0, 'present': 0}
|
||||
def get_sfp_event(self, timeout=2000):
|
||||
now = time.time()
|
||||
port_dict = {}
|
||||
change_dict = {}
|
||||
change_dict['sfp'] = port_dict
|
||||
|
||||
if timeout < 1000:
|
||||
timeout = 1000
|
||||
timeout = timeout / float(1000) # Convert to secs
|
||||
|
||||
if now < (self.sfp_change_event_data['last'] + timeout) and self.sfp_change_event_data['valid']:
|
||||
return True, change_dict
|
||||
|
||||
bitmap = 0
|
||||
for sfp in self._sfp_list:
|
||||
modpres = sfp.get_presence()
|
||||
i=sfp.port_num-1
|
||||
if modpres:
|
||||
bitmap = bitmap | (1 << i)
|
||||
|
||||
changed_ports = self.sfp_change_event_data['present'] ^ bitmap
|
||||
if changed_ports:
|
||||
for sfp in self._sfp_list:
|
||||
i=sfp.port_num-1
|
||||
if (changed_ports & (1 << i)):
|
||||
if (bitmap & (1 << i)) == 0:
|
||||
port_dict[i+1] = '0'
|
||||
else:
|
||||
port_dict[i+1] = '1'
|
||||
|
||||
|
||||
# Update the cache dict
|
||||
self.sfp_change_event_data['present'] = bitmap
|
||||
self.sfp_change_event_data['last'] = now
|
||||
self.sfp_change_event_data['valid'] = 1
|
||||
return True, change_dict
|
||||
else:
|
||||
return True, change_dict
|
179
device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/fan.py
Normal file
179
device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/fan.py
Normal file
@ -0,0 +1,179 @@
|
||||
#############################################################################
|
||||
# Edgecore
|
||||
#
|
||||
# Module contains an implementation of SONiC Platform Base API and
|
||||
# provides the fan status which are available in the platform
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
|
||||
|
||||
try:
|
||||
from sonic_platform_base.fan_base import FanBase
|
||||
from .helper import APIHelper
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
PSU_FAN_MAX_RPM = 26688
|
||||
CPLD_I2C_PATH = "/sys/bus/i2c/devices/3-0063/fan"
|
||||
PSU_HWMON_I2C_PATH ="/sys/bus/i2c/devices/{}-00{}/"
|
||||
PSU_I2C_MAPPING = {
|
||||
0: {
|
||||
"num": 11,
|
||||
"addr": "58"
|
||||
},
|
||||
1: {
|
||||
"num": 12,
|
||||
"addr": "5b"
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
class Fan(FanBase):
|
||||
"""Platform-specific Fan class"""
|
||||
|
||||
def __init__(self, fan_tray_index, fan_index=0, is_psu_fan=False, psu_index=0):
|
||||
self._api_helper=APIHelper()
|
||||
self.fan_index = fan_index
|
||||
self.fan_tray_index = fan_tray_index
|
||||
self.is_psu_fan = is_psu_fan
|
||||
if self.is_psu_fan:
|
||||
self.psu_index = psu_index
|
||||
self.psu_i2c_num = PSU_I2C_MAPPING[self.psu_index]['num']
|
||||
self.psu_i2c_addr = PSU_I2C_MAPPING[self.psu_index]['addr']
|
||||
self.psu_hwmon_path = PSU_HWMON_I2C_PATH.format(
|
||||
self.psu_i2c_num, self.psu_i2c_addr)
|
||||
|
||||
FanBase.__init__(self)
|
||||
|
||||
|
||||
def get_direction(self):
|
||||
"""
|
||||
Retrieves the direction of fan
|
||||
Returns:
|
||||
A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST
|
||||
depending on fan direction
|
||||
"""
|
||||
|
||||
|
||||
if not self.is_psu_fan:
|
||||
dir_str = "{}{}{}".format(CPLD_I2C_PATH, self.fan_tray_index, '_direction')
|
||||
val=self._api_helper.read_txt_file(dir_str)
|
||||
if val is not None:
|
||||
if val==0:
|
||||
direction=self.FAN_DIRECTION_EXHAUST
|
||||
else:
|
||||
direction=self.FAN_DIRECTION_INTAKE
|
||||
else:
|
||||
direction=self.FAN_DIRECTION_EXHAUST
|
||||
else: #For PSU
|
||||
dir_str = "{}{}".format(self.psu_hwmon_path,'psu_fan_dir')
|
||||
|
||||
val=self._api_helper.read_txt_file(dir_str)
|
||||
|
||||
if val is not None:
|
||||
if val=='F2B':
|
||||
direction=self.FAN_DIRECTION_EXHAUST
|
||||
else:
|
||||
direction=self.FAN_DIRECTION_INTAKE
|
||||
else:
|
||||
direction=self.FAN_DIRECTION_EXHAUST
|
||||
|
||||
return direction
|
||||
|
||||
def get_speed(self):
|
||||
"""
|
||||
Retrieves the speed of fan as a percentage of full speed
|
||||
Returns:
|
||||
An integer, the percentage of full fan speed, in the range 0 (off)
|
||||
to 100 (full speed)
|
||||
|
||||
"""
|
||||
speed = 0
|
||||
if self.is_psu_fan:
|
||||
psu_fan_path= "{}{}".format(self.psu_hwmon_path, 'psu_fan1_speed_rpm')
|
||||
fan_speed_rpm = self._api_helper.read_txt_file(psu_fan_path)
|
||||
if fan_speed_rpm is not None:
|
||||
speed = (int(fan_speed_rpm,10))*100/26688
|
||||
if speed > 100:
|
||||
speed=100
|
||||
else:
|
||||
return 0
|
||||
elif self.get_presence():
|
||||
speed_path = "{}{}".format(CPLD_I2C_PATH, '_duty_cycle_percentage')
|
||||
speed=self._api_helper.read_txt_file(speed_path)
|
||||
if speed is None:
|
||||
return 0
|
||||
|
||||
return int(speed)
|
||||
|
||||
def get_target_speed(self):
|
||||
"""
|
||||
Retrieves the target (expected) speed of the fan
|
||||
Returns:
|
||||
An integer, the percentage of full fan speed, in the range 0 (off)
|
||||
to 100 (full speed)
|
||||
|
||||
Note:
|
||||
speed_pc = pwm_target/255*100
|
||||
|
||||
0 : when PWM mode is use
|
||||
pwm : when pwm mode is not use
|
||||
"""
|
||||
return False #Not supported
|
||||
|
||||
def get_speed_tolerance(self):
|
||||
"""
|
||||
Retrieves the speed tolerance of the fan
|
||||
Returns:
|
||||
An integer, the percentage of variance from target speed which is
|
||||
considered tolerable
|
||||
"""
|
||||
return False #Not supported
|
||||
|
||||
def set_speed(self, speed):
|
||||
"""
|
||||
Sets the fan speed
|
||||
Args:
|
||||
speed: An integer, the percentage of full fan speed to set fan to,
|
||||
in the range 0 (off) to 100 (full speed)
|
||||
Returns:
|
||||
A boolean, True if speed is set successfully, False if not
|
||||
|
||||
"""
|
||||
|
||||
if not self.is_psu_fan and self.get_presence():
|
||||
speed_path = "{}{}".format(CPLD_I2C_PATH, '_duty_cycle_percentage')
|
||||
return self._api_helper.write_txt_file(speed_path, int(speed))
|
||||
|
||||
return False
|
||||
|
||||
def set_status_led(self, color):
|
||||
"""
|
||||
Sets the state of the fan module status LED
|
||||
Args:
|
||||
color: A string representing the color with which to set the
|
||||
fan module status LED
|
||||
Returns:
|
||||
bool: True if status LED state is set successfully, False if not
|
||||
"""
|
||||
return False #Not supported
|
||||
|
||||
def get_presence(self):
|
||||
"""
|
||||
Retrieves the presence of the FAN
|
||||
Returns:
|
||||
bool: True if FAN is present, False if not
|
||||
"""
|
||||
present_path = "{}{}{}".format(CPLD_I2C_PATH, self.fan_tray_index+1, '_present')
|
||||
val=self._api_helper.read_txt_file(present_path)
|
||||
|
||||
if not self.is_psu_fan:
|
||||
if val is not None:
|
||||
return int(val, 10)==1
|
||||
else:
|
||||
return False
|
||||
|
||||
else:
|
||||
return True
|
||||
|
@ -0,0 +1,117 @@
|
||||
import os
|
||||
import struct
|
||||
import subprocess
|
||||
from mmap import *
|
||||
from sonic_py_common import device_info
|
||||
|
||||
HOST_CHK_CMD = "docker > /dev/null 2>&1"
|
||||
EMPTY_STRING = ""
|
||||
|
||||
|
||||
class APIHelper():
|
||||
|
||||
def __init__(self):
|
||||
(self.platform, self.hwsku) = device_info.get_platform_and_hwsku()
|
||||
|
||||
def is_host(self):
|
||||
return os.system(HOST_CHK_CMD) == 0
|
||||
|
||||
def pci_get_value(self, resource, offset):
|
||||
status = True
|
||||
result = ""
|
||||
try:
|
||||
fd = os.open(resource, os.O_RDWR)
|
||||
mm = mmap(fd, 0)
|
||||
mm.seek(int(offset))
|
||||
read_data_stream = mm.read(4)
|
||||
result = struct.unpack('I', read_data_stream)
|
||||
except Exception:
|
||||
status = False
|
||||
return status, result
|
||||
|
||||
def run_command(self, cmd):
|
||||
status = True
|
||||
result = ""
|
||||
try:
|
||||
p = subprocess.Popen(
|
||||
cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
raw_data, err = p.communicate()
|
||||
if err == '':
|
||||
result = raw_data.strip()
|
||||
except Exception:
|
||||
status = False
|
||||
return status, result
|
||||
|
||||
def run_interactive_command(self, cmd):
|
||||
try:
|
||||
os.system(cmd)
|
||||
except Exception:
|
||||
return False
|
||||
return True
|
||||
|
||||
def read_txt_file(self, file_path):
|
||||
try:
|
||||
with open(file_path, 'r') as fd:
|
||||
data = fd.read()
|
||||
return data.strip()
|
||||
except IOError:
|
||||
pass
|
||||
return None
|
||||
|
||||
def write_txt_file(self, file_path, value):
|
||||
try:
|
||||
with open(file_path, 'w') as fd:
|
||||
fd.write(str(value))
|
||||
except IOError:
|
||||
return False
|
||||
return True
|
||||
|
||||
def ipmi_raw(self, netfn, cmd):
|
||||
status = True
|
||||
result = ""
|
||||
try:
|
||||
cmd = "ipmitool raw {} {}".format(str(netfn), str(cmd))
|
||||
p = subprocess.Popen(
|
||||
cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
raw_data, err = p.communicate()
|
||||
if err == '':
|
||||
result = raw_data.strip()
|
||||
else:
|
||||
status = False
|
||||
except Exception:
|
||||
status = False
|
||||
return status, result
|
||||
|
||||
def ipmi_fru_id(self, id, key=None):
|
||||
status = True
|
||||
result = ""
|
||||
try:
|
||||
cmd = "ipmitool fru print {}".format(str(
|
||||
id)) if not key else "ipmitool fru print {0} | grep '{1}' ".format(str(id), str(key))
|
||||
|
||||
p = subprocess.Popen(
|
||||
cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
raw_data, err = p.communicate()
|
||||
if err == '':
|
||||
result = raw_data.strip()
|
||||
else:
|
||||
status = False
|
||||
except Exception:
|
||||
status = False
|
||||
return status, result
|
||||
|
||||
def ipmi_set_ss_thres(self, id, threshold_key, value):
|
||||
status = True
|
||||
result = ""
|
||||
try:
|
||||
cmd = "ipmitool sensor thresh '{}' {} {}".format(str(id), str(threshold_key), str(value))
|
||||
p = subprocess.Popen(
|
||||
cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
raw_data, err = p.communicate()
|
||||
if err == '':
|
||||
result = raw_data.strip()
|
||||
else:
|
||||
status = False
|
||||
except Exception:
|
||||
status = False
|
||||
return status, result
|
@ -0,0 +1,21 @@
|
||||
#############################################################################
|
||||
# Edgecore
|
||||
#
|
||||
# Module contains an implementation of SONiC Platform Base API and
|
||||
# provides the platform information
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
try:
|
||||
from sonic_platform_base.platform_base import PlatformBase
|
||||
from sonic_platform.chassis import Chassis
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
|
||||
class Platform(PlatformBase):
|
||||
"""Platform-specific Platform class"""
|
||||
|
||||
def __init__(self):
|
||||
PlatformBase.__init__(self)
|
||||
self._chassis = Chassis()
|
252
device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/psu.py
Normal file
252
device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/psu.py
Normal file
@ -0,0 +1,252 @@
|
||||
#############################################################################
|
||||
# Edgecore
|
||||
#
|
||||
# Module contains an implementation of SONiC Platform Base API and
|
||||
# provides the PSUs status which are available in the platform
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
#import sonic_platform
|
||||
|
||||
try:
|
||||
from sonic_platform_base.psu_base import PsuBase
|
||||
#from sonic_platform.fan import Fan
|
||||
from .helper import APIHelper
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
|
||||
I2C_PATH ="/sys/bus/i2c/devices/{0}-00{1}/"
|
||||
|
||||
PSU_NAME_LIST = ["PSU-1", "PSU-2"]
|
||||
PSU_NUM_FAN = [1, 1]
|
||||
PSU_HWMON_I2C_MAPPING = {
|
||||
0: {
|
||||
"num": 11,
|
||||
"addr": "58"
|
||||
},
|
||||
1: {
|
||||
"num": 12,
|
||||
"addr": "5b"
|
||||
},
|
||||
}
|
||||
|
||||
PSU_CPLD_I2C_MAPPING = {
|
||||
0: {
|
||||
"num": 11,
|
||||
"addr": "50"
|
||||
},
|
||||
1: {
|
||||
"num": 12,
|
||||
"addr": "53"
|
||||
},
|
||||
}
|
||||
|
||||
class Psu(PsuBase):
|
||||
"""Platform-specific Psu class"""
|
||||
|
||||
def __init__(self, psu_index=0):
|
||||
PsuBase.__init__(self)
|
||||
self.index = psu_index
|
||||
self._api_helper = APIHelper()
|
||||
|
||||
self.i2c_num = PSU_HWMON_I2C_MAPPING[self.index]["num"]
|
||||
self.i2c_addr = PSU_HWMON_I2C_MAPPING[self.index]["addr"]
|
||||
self.hwmon_path = I2C_PATH.format(self.i2c_num, self.i2c_addr)
|
||||
|
||||
self.i2c_num = PSU_CPLD_I2C_MAPPING[self.index]["num"]
|
||||
self.i2c_addr = PSU_CPLD_I2C_MAPPING[self.index]["addr"]
|
||||
self.cpld_path = I2C_PATH.format(self.i2c_num, self.i2c_addr)
|
||||
self.__initialize_fan()
|
||||
|
||||
def __initialize_fan(self):
|
||||
from sonic_platform.fan import Fan
|
||||
for fan_index in range(0, PSU_NUM_FAN[self.index]):
|
||||
fan = Fan(fan_index, 0, is_psu_fan=True, psu_index=self.index)
|
||||
self._fan_list.append(fan)
|
||||
|
||||
def get_voltage(self):
|
||||
"""
|
||||
Retrieves current PSU voltage output
|
||||
Returns:
|
||||
A float number, the output voltage in volts,
|
||||
e.g. 12.1
|
||||
"""
|
||||
vout_path = "{}{}".format(self.hwmon_path, 'psu_v_out')
|
||||
vout_val=self._api_helper.read_txt_file(vout_path)
|
||||
if vout_val is not None:
|
||||
return float(vout_val)/ 1000
|
||||
else:
|
||||
return 0
|
||||
|
||||
def get_current(self):
|
||||
"""
|
||||
Retrieves present electric current supplied by PSU
|
||||
Returns:
|
||||
A float number, the electric current in amperes, e.g 15.4
|
||||
"""
|
||||
iout_path = "{}{}".format(self.hwmon_path, 'psu_i_out')
|
||||
val=self._api_helper.read_txt_file(iout_path)
|
||||
if val is not None:
|
||||
return float(val)/1000
|
||||
else:
|
||||
return 0
|
||||
|
||||
def get_power(self):
|
||||
"""
|
||||
Retrieves current energy supplied by PSU
|
||||
Returns:
|
||||
A float number, the power in watts, e.g. 302.6
|
||||
"""
|
||||
pout_path = "{}{}".format(self.hwmon_path, 'psu_p_out')
|
||||
val=self._api_helper.read_txt_file(pout_path)
|
||||
if val is not None:
|
||||
return float(val)/1000
|
||||
else:
|
||||
return 0
|
||||
|
||||
def get_powergood_status(self):
|
||||
"""
|
||||
Retrieves the powergood status of PSU
|
||||
Returns:
|
||||
A boolean, True if PSU has stablized its output voltages and passed all
|
||||
its internal self-tests, False if not.
|
||||
"""
|
||||
return self.get_status()
|
||||
|
||||
def set_status_led(self, color):
|
||||
"""
|
||||
Sets the state of the PSU status LED
|
||||
Args:
|
||||
color: A string representing the color with which to set the PSU status LED
|
||||
Note: Only support green and off
|
||||
Returns:
|
||||
bool: True if status LED state is set successfully, False if not
|
||||
"""
|
||||
|
||||
return False #Controlled by HW
|
||||
|
||||
def get_status_led(self):
|
||||
"""
|
||||
Gets the state of the PSU status LED
|
||||
Returns:
|
||||
A string, one of the predefined STATUS_LED_COLOR_* strings above
|
||||
"""
|
||||
status=self.get_status()
|
||||
if not status:
|
||||
return self.STATUS_LED_COLOR_RED
|
||||
|
||||
if status==1:
|
||||
return self.STATUS_LED_COLOR_GREEN
|
||||
else:
|
||||
return self.STATUS_LED_COLOR_RED
|
||||
|
||||
|
||||
def get_temperature(self):
|
||||
"""
|
||||
Retrieves current temperature reading from PSU
|
||||
Returns:
|
||||
A float number of current temperature in Celsius up to nearest thousandth
|
||||
of one degree Celsius, e.g. 30.125
|
||||
"""
|
||||
temp_path = "{}{}".format(self.hwmon_path, 'psu_temp1_input')
|
||||
val=self._api_helper.read_txt_file(temp_path)
|
||||
if val is not None:
|
||||
return float(val)/1000
|
||||
else:
|
||||
return 0
|
||||
|
||||
def get_temperature_high_threshold(self):
|
||||
"""
|
||||
Retrieves the high threshold temperature of PSU
|
||||
Returns:
|
||||
A float number, the high threshold temperature of PSU in Celsius
|
||||
up to nearest thousandth of one degree Celsius, e.g. 30.125
|
||||
"""
|
||||
return False #Not supported
|
||||
|
||||
def get_voltage_high_threshold(self):
|
||||
"""
|
||||
Retrieves the high threshold PSU voltage output
|
||||
Returns:
|
||||
A float number, the high threshold output voltage in volts,
|
||||
e.g. 12.1
|
||||
"""
|
||||
vout_path = "{}{}".format(self.hwmon_path, 'psu_mfr_vout_max')
|
||||
vout_val=self._api_helper.read_txt_file(vout_path)
|
||||
if vout_val is not None:
|
||||
return float(vout_val)/ 1000
|
||||
else:
|
||||
return 0
|
||||
|
||||
def get_voltage_low_threshold(self):
|
||||
"""
|
||||
Retrieves the low threshold PSU voltage output
|
||||
Returns:
|
||||
A float number, the low threshold output voltage in volts,
|
||||
e.g. 12.1
|
||||
"""
|
||||
vout_path = "{}{}".format(self.hwmon_path, 'psu_mfr_vout_min')
|
||||
vout_val=self._api_helper.read_txt_file(vout_path)
|
||||
if vout_val is not None:
|
||||
return float(vout_val)/ 1000
|
||||
else:
|
||||
return 0
|
||||
|
||||
def get_name(self):
|
||||
"""
|
||||
Retrieves the name of the device
|
||||
Returns:
|
||||
string: The name of the device
|
||||
"""
|
||||
return PSU_NAME_LIST[self.index]
|
||||
|
||||
def get_presence(self):
|
||||
"""
|
||||
Retrieves the presence of the PSU
|
||||
Returns:
|
||||
bool: True if PSU is present, False if not
|
||||
"""
|
||||
presence_path="{}{}".format(self.cpld_path, 'psu_present')
|
||||
val=self._api_helper.read_txt_file(presence_path)
|
||||
if val is not None:
|
||||
return int(val, 10) == 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def get_status(self):
|
||||
"""
|
||||
Retrieves the operational status of the device
|
||||
Returns:
|
||||
A boolean value, True if device is operating properly, False if not
|
||||
"""
|
||||
power_path="{}{}".format(self.cpld_path, 'psu_power_good')
|
||||
val=self._api_helper.read_txt_file(power_path)
|
||||
if val is not None:
|
||||
return int(val, 10) == 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def get_model(self):
|
||||
"""
|
||||
Retrieves the model number (or part number) of the device
|
||||
Returns:
|
||||
string: Model/part number of device
|
||||
"""
|
||||
model_path="{}{}".format(self.cpld_path, 'psu_model_name')
|
||||
model=self._api_helper.read_txt_file(model_path)
|
||||
if not model:
|
||||
return "N/A"
|
||||
return model
|
||||
|
||||
def get_serial(self):
|
||||
"""
|
||||
Retrieves the serial number of the device
|
||||
Returns:
|
||||
string: Serial number of device
|
||||
"""
|
||||
serial_path="{}{}".format(self.cpld_path, 'psu_serial_numer')
|
||||
serial=self._api_helper.read_txt_file(serial_path)
|
||||
if not serial:
|
||||
return "N/A"
|
||||
return serial
|
1229
device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/sfp.py
Normal file
1229
device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/sfp.py
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,148 @@
|
||||
#############################################################################
|
||||
# Edgecore
|
||||
#
|
||||
# Thermal contains an implementation of SONiC Platform Base API and
|
||||
# provides the thermal device status which are available in the platform
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
import os
|
||||
import os.path
|
||||
import glob
|
||||
|
||||
try:
|
||||
from sonic_platform_base.thermal_base import ThermalBase
|
||||
except ImportError as e:
|
||||
raise ImportError(str(e) + "- required module not found")
|
||||
|
||||
|
||||
class Thermal(ThermalBase):
|
||||
"""Platform-specific Thermal class"""
|
||||
|
||||
THERMAL_NAME_LIST = []
|
||||
SYSFS_PATH = "/sys/bus/i2c/devices"
|
||||
|
||||
def __init__(self, thermal_index=0):
|
||||
self.index = thermal_index
|
||||
|
||||
# Add thermal name
|
||||
self.THERMAL_NAME_LIST.append("Temp sensor 1")
|
||||
self.THERMAL_NAME_LIST.append("Temp sensor 2")
|
||||
self.THERMAL_NAME_LIST.append("Temp sensor 3")
|
||||
self.THERMAL_NAME_LIST.append("Temp sensor 4")
|
||||
|
||||
# Set hwmon path
|
||||
i2c_path = {
|
||||
0: "18-004b/hwmon/hwmon*/",
|
||||
1: "19-004c/hwmon/hwmon*/",
|
||||
2: "20-0049/hwmon/hwmon*/",
|
||||
3: "21-004a/hwmon/hwmon*/"
|
||||
}.get(self.index, None)
|
||||
|
||||
self.hwmon_path = "{}/{}".format(self.SYSFS_PATH, i2c_path)
|
||||
self.ss_key = self.THERMAL_NAME_LIST[self.index]
|
||||
self.ss_index = 1
|
||||
|
||||
def __read_txt_file(self, file_path):
|
||||
for filename in glob.glob(file_path):
|
||||
try:
|
||||
with open(filename, 'r') as fd:
|
||||
data =fd.readline().rstrip()
|
||||
return data
|
||||
except IOError as e:
|
||||
pass
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def __get_temp(self, temp_file):
|
||||
temp_file_path = os.path.join(self.hwmon_path, temp_file)
|
||||
raw_temp = self.__read_txt_file(temp_file_path)
|
||||
if raw_temp is not None:
|
||||
return float(raw_temp)/1000
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
def __set_threshold(self, file_name, temperature):
|
||||
temp_file_path = os.path.join(self.hwmon_path, file_name)
|
||||
for filename in glob.glob(temp_file_path):
|
||||
try:
|
||||
with open(filename, 'w') as fd:
|
||||
fd.write(str(temperature))
|
||||
return True
|
||||
except IOError as e:
|
||||
print("IOError")
|
||||
|
||||
|
||||
def get_temperature(self):
|
||||
"""
|
||||
Retrieves current temperature reading from thermal
|
||||
Returns:
|
||||
A float number of current temperature in Celsius up to nearest thousandth
|
||||
of one degree Celsius, e.g. 30.125
|
||||
"""
|
||||
temp_file = "temp{}_input".format(self.ss_index)
|
||||
return self.__get_temp(temp_file)
|
||||
|
||||
def get_high_threshold(self):
|
||||
"""
|
||||
Retrieves the high threshold temperature of thermal
|
||||
Returns:
|
||||
A float number, the high threshold temperature of thermal in Celsius
|
||||
up to nearest thousandth of one degree Celsius, e.g. 30.125
|
||||
"""
|
||||
temp_file = "temp{}_max".format(self.ss_index)
|
||||
return self.__get_temp(temp_file)
|
||||
|
||||
def set_high_threshold(self, temperature):
|
||||
"""
|
||||
Sets the high threshold temperature of thermal
|
||||
Args :
|
||||
temperature: A float number up to nearest thousandth of one degree Celsius,
|
||||
e.g. 30.125
|
||||
Returns:
|
||||
A boolean, True if threshold is set successfully, False if not
|
||||
"""
|
||||
temp_file = "temp{}_max".format(self.ss_index)
|
||||
temperature = temperature *1000
|
||||
self.__set_threshold(temp_file, temperature)
|
||||
|
||||
return True
|
||||
|
||||
def get_name(self):
|
||||
"""
|
||||
Retrieves the name of the thermal device
|
||||
Returns:
|
||||
string: The name of the thermal device
|
||||
"""
|
||||
return self.THERMAL_NAME_LIST[self.index]
|
||||
|
||||
def get_presence(self):
|
||||
"""
|
||||
Retrieves the presence of the Thermal
|
||||
Returns:
|
||||
bool: True if Thermal is present, False if not
|
||||
"""
|
||||
temp_file = "temp{}_input".format(self.ss_index)
|
||||
temp_file_path = os.path.join(self.hwmon_path, temp_file)
|
||||
raw_txt = self.__read_txt_file(temp_file_path)
|
||||
if raw_txt is not None:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def get_status(self):
|
||||
"""
|
||||
Retrieves the operational status of the device
|
||||
Returns:
|
||||
A boolean value, True if device is operating properly, False if not
|
||||
"""
|
||||
|
||||
file_str = "temp{}_input".format(self.ss_index)
|
||||
file_path = os.path.join(self.hwmon_path, file_str)
|
||||
raw_txt = self.__read_txt_file(file_path)
|
||||
if raw_txt is None:
|
||||
return False
|
||||
else:
|
||||
return int(raw_txt) != 0
|
@ -0,0 +1,34 @@
|
||||
from setuptools import setup
|
||||
|
||||
DEVICE_NAME = 'accton'
|
||||
HW_SKU = 'x86_64-accton_as5835_54x-r0'
|
||||
|
||||
setup(
|
||||
name='sonic-platform',
|
||||
version='1.0',
|
||||
description='SONiC platform API implementation on Accton Platforms',
|
||||
license='Apache 2.0',
|
||||
author='SONiC Team',
|
||||
author_email='linuxnetdev@microsoft.com',
|
||||
url='https://github.com/Azure/sonic-buildimage',
|
||||
maintainer='Jostar Yang',
|
||||
maintainer_email='jostar_yang@accton.com',
|
||||
packages=[
|
||||
'sonic_platform',
|
||||
],
|
||||
package_dir={
|
||||
'sonic_platform': '../../../../device/{}/{}/sonic_platform'.format(DEVICE_NAME, HW_SKU)},
|
||||
classifiers=[
|
||||
'Development Status :: 3 - Alpha',
|
||||
'Environment :: Plugins',
|
||||
'Intended Audience :: Developers',
|
||||
'Intended Audience :: Information Technology',
|
||||
'Intended Audience :: System Administrators',
|
||||
'License :: OSI Approved :: Apache Software License',
|
||||
'Natural Language :: English',
|
||||
'Operating System :: POSIX :: Linux',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Topic :: Utilities',
|
||||
],
|
||||
keywords='sonic SONiC platform PLATFORM',
|
||||
)
|
@ -36,6 +36,7 @@ import sys
|
||||
import logging
|
||||
import re
|
||||
import time
|
||||
import os
|
||||
|
||||
|
||||
|
||||
@ -89,6 +90,10 @@ def main():
|
||||
do_install()
|
||||
elif arg == 'clean':
|
||||
do_uninstall()
|
||||
elif arg == 'api':
|
||||
do_sonic_platform_install()
|
||||
elif arg == 'api_clean':
|
||||
do_sonic_platform_clean()
|
||||
elif arg == 'show':
|
||||
device_traversal()
|
||||
elif arg == 'sff':
|
||||
@ -364,6 +369,44 @@ def system_ready():
|
||||
return False
|
||||
return True
|
||||
|
||||
PLATFORM_ROOT_PATH = '/usr/share/sonic/device'
|
||||
PLATFORM_API2_WHL_FILE_PY3 ='sonic_platform-1.0-py3-none-any.whl'
|
||||
def do_sonic_platform_install():
|
||||
device_path = "{}{}{}{}".format(PLATFORM_ROOT_PATH, '/x86_64-accton_', PROJECT_NAME, '-r0')
|
||||
SONIC_PLATFORM_BSP_WHL_PKG_PY3 = "/".join([device_path, PLATFORM_API2_WHL_FILE_PY3])
|
||||
|
||||
#Check API2.0 on py whl file
|
||||
status, output = log_os_system("pip3 show sonic-platform > /dev/null 2>&1", 0)
|
||||
if status:
|
||||
if os.path.exists(SONIC_PLATFORM_BSP_WHL_PKG_PY3):
|
||||
status, output = log_os_system("pip3 install "+ SONIC_PLATFORM_BSP_WHL_PKG_PY3, 1)
|
||||
if status:
|
||||
print "Error: Failed to install {}".format(PLATFORM_API2_WHL_FILE_PY3)
|
||||
return status
|
||||
else:
|
||||
print "Successfully installed {} package".format(PLATFORM_API2_WHL_FILE_PY3)
|
||||
else:
|
||||
print('{} is not found'.format(PLATFORM_API2_WHL_FILE_PY3))
|
||||
else:
|
||||
print('{} has installed'.format(PLATFORM_API2_WHL_FILE_PY3))
|
||||
|
||||
return
|
||||
|
||||
def do_sonic_platform_clean():
|
||||
status, output = log_os_system("pip3 show sonic-platform > /dev/null 2>&1", 0)
|
||||
if status:
|
||||
print('{} does not install, not need to uninstall'.format(PLATFORM_API2_WHL_FILE_PY3))
|
||||
|
||||
else:
|
||||
status, output = log_os_system("pip3 uninstall sonic-platform -y", 0)
|
||||
if status:
|
||||
print('Error: Failed to uninstall {}'.format(PLATFORM_API2_WHL_FILE_PY3))
|
||||
return status
|
||||
else:
|
||||
print('{} is uninstalled'.format(PLATFORM_API2_WHL_FILE_PY3))
|
||||
|
||||
return
|
||||
|
||||
def do_install():
|
||||
print "Checking system...."
|
||||
if driver_check() == False:
|
||||
@ -382,6 +425,9 @@ def do_install():
|
||||
return status
|
||||
else:
|
||||
print PROJECT_NAME.upper()+" devices detected...."
|
||||
|
||||
do_sonic_platform_install()
|
||||
|
||||
return
|
||||
|
||||
def do_uninstall():
|
||||
@ -404,6 +450,8 @@ def do_uninstall():
|
||||
if FORCE == 0:
|
||||
return status
|
||||
|
||||
do_sonic_platform_clean()
|
||||
|
||||
return
|
||||
|
||||
def devices_info():
|
||||
|
@ -14,7 +14,7 @@ include /usr/share/dpkg/pkg-info.mk
|
||||
export INSTALL_MOD_DIR:=extra
|
||||
|
||||
PYTHON ?= python2
|
||||
PYTHON3 ?= python3
|
||||
PYTHON3 ?= python3
|
||||
|
||||
PACKAGE_PRE_NAME := sonic-platform-accton
|
||||
KVERSION ?= $(shell uname -r)
|
||||
|
@ -0,0 +1,2 @@
|
||||
as5835-54x/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/x86_64-accton_as5835_54x-r0
|
||||
|
Reference in New Issue
Block a user