Skip to content
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
__all__ = ["platform", "chassis"]
from sonic_platform import *
114 changes: 114 additions & 0 deletions device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
#!/usr/bin/env python

#############################################################################
# Celestica
#
# Module contains an implementation of SONiC Platform Base API and
# provides the Chassis information which are available in the platform
#
#############################################################################

import sys
import re
import os
import subprocess
import json

try:
from sonic_platform_base.chassis_base import ChassisBase
from sonic_platform.eeprom import Tlv
from sonic_platform.fan import Fan
from helper import APIHelper
except ImportError as e:
raise ImportError(str(e) + "- required module not found")

NUM_FAN_TRAY = 7
NUM_FAN = 2
NUM_PSU = 2
NUM_THERMAL = 5
NUM_SFP = 32
NUM_COMPONENT = 5

IPMI_OEM_NETFN = "0x3A"
IPMI_GET_REBOOT_CAUSE = "0x03 0x00 0x01 0x06"


class Chassis(ChassisBase):
"""Platform-specific Chassis class"""

def __init__(self):
self.config_data = {}
ChassisBase.__init__(self)
self._eeprom = Tlv()
self._api_helper = APIHelper()

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 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.
"""

status, raw_cause = self._api_helper.ipmi_raw(
IPMI_OEM_NETFN, IPMI_GET_REBOOT_CAUSE)
hx_cause = raw_cause.split()[0] if status else 00
reboot_cause = {
"00": self.REBOOT_CAUSE_HARDWARE_OTHER,
"11": self.REBOOT_CAUSE_POWER_LOSS,
"22": self.REBOOT_CAUSE_NON_HARDWARE,
"33": self.REBOOT_CAUSE_HARDWARE_OTHER,
"44": self.REBOOT_CAUSE_NON_HARDWARE,
"55": self.REBOOT_CAUSE_NON_HARDWARE,
"66": self.REBOOT_CAUSE_WATCHDOG,
"77": self.REBOOT_CAUSE_NON_HARDWARE
}.get(hx_cause, self.REBOOT_CAUSE_HARDWARE_OTHER)

description = {
"00": "Unknown reason",
"11": "The last reset is Power on reset",
"22": "The last reset is soft-set CPU warm reset",
"33": "The last reset is soft-set CPU cold reset",
"44": "The last reset is CPU warm reset",
"55": "The last reset is CPU cold reset",
"66": "The last reset is watchdog reset",
"77": "The last reset is power cycle reset"
}.get(hx_cause, "Unknown reason")

return (reboot_cause, description)
113 changes: 113 additions & 0 deletions device/celestica/x86_64-cel_silverstone-r0/sonic_platform/eeprom.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#!/usr/bin/env python

#############################################################################
# Celestica Silverstone
#
# Platform and model specific eeprom subclass, inherits from the base class,
# and provides the followings:
# - the eeprom format definition
# - specific encoder/decoder if there is special need
#############################################################################

try:
import glob
import os
import sys
import imp
import re
from array import array
from cStringIO import StringIO
from sonic_platform_base.sonic_eeprom import eeprom_dts
from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo
except ImportError, e:
raise ImportError(str(e) + "- required module not found")

CACHE_ROOT = '/var/cache/sonic/decode-syseeprom'
CACHE_FILE = 'syseeprom_cache'
TLV_EEPROM_I2C_BUS = 0
TLV_EEPROM_I2C_ADDR = 56

class Tlv(eeprom_tlvinfo.TlvInfoDecoder):

EEPROM_DECODE_HEADLINES = 6

def __init__(self):
self._eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-00{1}/eeprom".format(TLV_EEPROM_I2C_BUS, TLV_EEPROM_I2C_ADDR)
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:
pass
return _eeprom_info_dict

def _load_eeprom(self):
original_stdout = sys.stdout
sys.stdout = StringIO()
try:
self.read_eeprom_db()
except:
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:
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:
pass

e = self.read_eeprom()
if e is None:
return 0

try:
self.update_cache(e)
except:
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 get_eeprom(self):
return self._eeprom

def get_serial(self):
return self._eeprom.get('0x23', "Undefined.")

def get_mac(self):
return self._eeprom.get('0x24', "Undefined.")
Loading