diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py index 6d0e8b8c12..1041561db4 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/chassis.py @@ -13,8 +13,8 @@ try: from sonic_platform.psu import psu_list_get from sonic_platform.fan_drawer import fan_drawer_list_get from sonic_platform.thermal import thermal_list_get - from eeprom import Eeprom - from platform_utils import file_create + from sonic_platform.platform_utils import file_create + from sonic_platform.eeprom import Eeprom from sonic_platform.platform_thrift_client import pltfm_mgr_ready from sonic_platform.platform_thrift_client import thrift_try @@ -40,7 +40,10 @@ class Chassis(ChassisBase): def __init__(self): ChassisBase.__init__(self) - self.__eeprom = None + self._eeprom = Eeprom() + self.__tlv_bin_eeprom = self._eeprom.get_raw_data() + self.__tlv_dict_eeprom = self._eeprom.get_data() + self.__fan_drawers = None self.__fan_list = None self.__thermals = None @@ -57,16 +60,6 @@ class Chassis(ChassisBase): file_create(config_dict['handlers']['file']['filename'], '646') logging.config.dictConfig(config_dict) - @property - def _eeprom(self): - if self.__eeprom is None: - self.__eeprom = Eeprom() - return self.__eeprom - - @_eeprom.setter - def _eeprom(self, value): - pass - @property def _fan_drawer_list(self): if self.__fan_drawers is None: @@ -152,7 +145,7 @@ class Chassis(ChassisBase): Returns: string: The name of the chassis """ - return self._eeprom.modelstr() + return self._eeprom.modelstr(self.__tlv_bin_eeprom) def get_presence(self): """ @@ -168,7 +161,7 @@ class Chassis(ChassisBase): Returns: string: Model/part number of chassis """ - return self._eeprom.part_number_str() + return self._eeprom.part_number_str(self.__tlv_bin_eeprom) def get_serial(self): """ @@ -176,7 +169,7 @@ class Chassis(ChassisBase): Returns: string: Serial number of chassis """ - return self._eeprom.serial_number_str() + return self._eeprom.serial_number_str(self.__tlv_bin_eeprom) def get_revision(self): """ @@ -184,7 +177,8 @@ class Chassis(ChassisBase): Returns: string: Revision number of chassis """ - return self._eeprom.revision_str() + return self.__tlv_dict_eeprom.get( + "0x{:X}".format(Eeprom._TLV_CODE_LABEL_REVISION), 'N/A') def get_sfp(self, index): """ @@ -225,7 +219,7 @@ class Chassis(ChassisBase): A string containing the MAC address in the format 'XX:XX:XX:XX:XX:XX' """ - return self._eeprom.base_mac_addr() + return self._eeprom.base_mac_addr(self.__tlv_bin_eeprom) def get_system_eeprom_info(self): """ @@ -236,7 +230,7 @@ class Chassis(ChassisBase): OCP ONIE TlvInfo EEPROM format and values are their corresponding values. """ - return self._eeprom.system_eeprom_info() + return self.__tlv_dict_eeprom def __get_transceiver_change_event(self, timeout=0): forever = False diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/eeprom.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/eeprom.py index 2335c02863..4b5c1e3051 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/eeprom.py +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/eeprom.py @@ -2,7 +2,8 @@ try: import os import sys import datetime - import re + import logging + import logging.config sys.path.append(os.path.dirname(__file__)) @@ -13,13 +14,15 @@ try: from sonic_platform_base.sonic_eeprom import eeprom_base from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo - from platform_utils import file_create - from platform_thrift_client import thrift_try + from sonic_py_common import device_info + + from sonic_platform.platform_thrift_client import thrift_try + from sonic_platform.platform_utils import file_create + except ImportError as e: raise ImportError (str(e) + "- required module not found") - _platform_eeprom_map = { "prod_name" : ("Product Name", "0x21", 12), "odm_pcba_part_num" : ("Part Number", "0x22", 13), @@ -44,25 +47,55 @@ class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): def __init__(self): file_create(_EEPROM_SYMLINK, '646') file_create(_EEPROM_STATUS, '646') - with open(_EEPROM_STATUS, 'w') as f: - f.write("initializing..") + super(Eeprom, self).__init__(_EEPROM_SYMLINK, 0, _EEPROM_STATUS, True) - self.eeprom_path = _EEPROM_SYMLINK - super(Eeprom, self).__init__(self.eeprom_path, 0, _EEPROM_STATUS, True) - - def sys_eeprom_get(client): - return client.pltfm_mgr.pltfm_mgr_sys_eeprom_get() + self._eeprom_bin = bytearray() + self.report_status("initializing..") try: - platform_eeprom = thrift_try(sys_eeprom_get) - except Exception: - raise RuntimeError("eeprom.py: Initialization failed") + try: + if device_info.get_platform() in ["x86_64-accton_as9516_32d-r0", + "x86_64-accton_as9516bf_32d-r0"]: + def tlv_eeprom_get(client): + return client.pltfm_mgr.pltfm_mgr_tlv_eeprom_get() + try: + self._eeprom_bin = bytearray.fromhex( + thrift_try(tlv_eeprom_get, 1).raw_content_hex) + except TApplicationException as e: + raise RuntimeError("api is not supported") + except Exception as e: + self._eeprom_bin = bytearray.fromhex( + thrift_try(tlv_eeprom_get).raw_content_hex) + else: + raise RuntimeError("platform is not supported") - self.__eeprom_init(platform_eeprom) + except RuntimeError as e: + logging.warning("Tlv eeprom fetching failed: %s, using OpenBMC" % (str(e))) - def __eeprom_init(self, platform_eeprom): - with open(_EEPROM_STATUS, 'w') as f: - f.write("ok") + def sys_eeprom_get(client): + return client.pltfm_mgr.pltfm_mgr_sys_eeprom_get() + eeprom_params = self.platfrom_eeprom_to_params(thrift_try(sys_eeprom_get)) + stdout_stream = sys.stdout + sys.stdout = open(os.devnull, 'w') + self._eeprom_bin = self.set_eeprom(self._eeprom_bin, [eeprom_params]) + sys.stdout.close() + sys.stdout = stdout_stream + try: + self.write_eeprom(self._eeprom_bin) + self.report_status("ok") + except IOError as e: + logging.error("Failed to write eeprom: %s" % (str(e))) + + except Exception as e: + logging.error("eeprom.py: Initialization failed: %s" % (str(e))) + raise RuntimeError("eeprom.py: Initialization failed: %s" % (str(e))) + + self._system_eeprom_info = dict() + visitor = EepromContentVisitor(self._system_eeprom_info) + self.visit_eeprom(self._eeprom_bin, visitor) + + @staticmethod + def platfrom_eeprom_to_params(platform_eeprom): eeprom_params = "" for attr, val in platform_eeprom.__dict__.items(): if val is None: @@ -86,57 +119,41 @@ class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): if len(eeprom_params) > 0: eeprom_params += "," eeprom_params += "{0:s}={1:s}".format(elem[1], value) + return eeprom_params - orig_stdout = sys.stdout - sys.stdout = StringIO() + def get_data(self): + return self._system_eeprom_info + + def get_raw_data(self): + return self._eeprom_bin + + def report_status(self, status): + status_file = None try: - eeprom_data = eeprom_tlvinfo.TlvInfoDecoder.set_eeprom(self, "", [eeprom_params]) + status_file = open(_EEPROM_STATUS, "w") + status_file.write(status) + except IOError as e: + logging.error("Failed to report state: %s" % (str(e))) finally: - decode_output = sys.stdout.getvalue() - sys.stdout = orig_stdout + if status_file is not None: + status_file.close() - eeprom_base.EepromDecoder.write_eeprom(self, eeprom_data) - self.__eeprom_tlv_dict = self.__parse_output(decode_output) +class EepromContentVisitor(eeprom_tlvinfo.EepromDefaultVisitor): + def __init__(self, content_dict): + self.content_dict = content_dict - def __parse_output(self, decode_output): - EEPROM_DECODE_HEADLINES = 6 - lines = decode_output.replace('\0', '').split('\n') - lines = lines[EEPROM_DECODE_HEADLINES:] - res = dict() - - for line in lines: - try: - # match whitespace-separated tag hex, length and value (value is mathced with its whitespaces) - match = re.search('(0x[0-9a-fA-F]{2})([\s]+[\S]+[\s]+)([\S]+[\s]*[\S]*)', line) - if match is not None: - code = match.group(1) - value = match.group(3).rstrip('\0') - res[code] = value - except Exception: - pass - return res - - def __tlv_get(self, code): - return self.__eeprom_tlv_dict.get("0x{:X}".format(code), 'N/A') - - def system_eeprom_info(self): - return self.__eeprom_tlv_dict - - def serial_number_str(self): - return self.__tlv_get(self._TLV_CODE_SERIAL_NUMBER) - - def serial_str(self): - return self.serial_number_str() - - def base_mac_addr(self): - return self.__tlv_get(self._TLV_CODE_MAC_BASE) - - def part_number_str(self): - return self.__tlv_get(self._TLV_CODE_PART_NUMBER) - - def modelstr(self): - return self.__tlv_get(self._TLV_CODE_PRODUCT_NAME) - - def revision_str(self): - return self.__tlv_get(self._TLV_CODE_LABEL_REVISION) + def visit_tlv(self, name, code, length, value): + if code != Eeprom._TLV_CODE_VENDOR_EXT: + self.content_dict["0x{:X}".format(code)] = value.rstrip('\0') + else: + if value: + value = value.rstrip('\0') + if value: + code = "0x{:X}".format(code) + if code not in self.content_dict: + self.content_dict[code] = [value] + else: + self.content_dict[code].append(value) + def set_error(self, error): + logging.error("EepromContentVisitor error: %s" % (str(error))) diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/pltfm_mgr_rpc.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/pltfm_mgr_rpc.py index 0fa03d58b3..b671be1be3 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/pltfm_mgr_rpc.py +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/pltfm_mgr_rpc.py @@ -33,6 +33,9 @@ class Iface(object): def pltfm_mgr_sys_eeprom_get(self): pass + def pltfm_mgr_tlv_eeprom_get(self): + pass + def pltfm_mgr_pwr_supply_present_get(self, ps_num): """ Parameters: @@ -403,6 +406,34 @@ class Client(Iface): raise result.ouch raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_sys_eeprom_get failed: unknown result") + def pltfm_mgr_tlv_eeprom_get(self): + self.send_pltfm_mgr_tlv_eeprom_get() + return self.recv_pltfm_mgr_tlv_eeprom_get() + + def send_pltfm_mgr_tlv_eeprom_get(self): + self._oprot.writeMessageBegin('pltfm_mgr_tlv_eeprom_get', TMessageType.CALL, self._seqid) + args = pltfm_mgr_tlv_eeprom_get_args() + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_pltfm_mgr_tlv_eeprom_get(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = pltfm_mgr_tlv_eeprom_get_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + if result.ouch is not None: + raise result.ouch + raise TApplicationException(TApplicationException.MISSING_RESULT, "pltfm_mgr_tlv_eeprom_get failed: unknown result") + def pltfm_mgr_pwr_supply_present_get(self, ps_num): """ Parameters: @@ -1579,6 +1610,7 @@ class Processor(Iface, TProcessor): self._processMap["pltfm_mgr_dummy"] = Processor.process_pltfm_mgr_dummy self._processMap["pltfm_mgr_sys_tmp_get"] = Processor.process_pltfm_mgr_sys_tmp_get self._processMap["pltfm_mgr_sys_eeprom_get"] = Processor.process_pltfm_mgr_sys_eeprom_get + self._processMap["pltfm_mgr_tlv_eeprom_get"] = Processor.process_pltfm_mgr_tlv_eeprom_get self._processMap["pltfm_mgr_pwr_supply_present_get"] = Processor.process_pltfm_mgr_pwr_supply_present_get self._processMap["pltfm_mgr_pwr_supply_info_get"] = Processor.process_pltfm_mgr_pwr_supply_info_get self._processMap["pltfm_mgr_pwr_rail_info_get"] = Processor.process_pltfm_mgr_pwr_rail_info_get @@ -1710,6 +1742,32 @@ class Processor(Iface, TProcessor): oprot.writeMessageEnd() oprot.trans.flush() + def process_pltfm_mgr_tlv_eeprom_get(self, seqid, iprot, oprot): + args = pltfm_mgr_tlv_eeprom_get_args() + args.read(iprot) + iprot.readMessageEnd() + result = pltfm_mgr_tlv_eeprom_get_result() + try: + result.success = self._handler.pltfm_mgr_tlv_eeprom_get() + msg_type = TMessageType.REPLY + except TTransport.TTransportException: + raise + except InvalidPltfmMgrOperation as ouch: + msg_type = TMessageType.REPLY + result.ouch = ouch + except TApplicationException as ex: + logging.exception('TApplication exception in handler') + msg_type = TMessageType.EXCEPTION + result = ex + except Exception: + logging.exception('Unexpected exception in handler') + msg_type = TMessageType.EXCEPTION + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("pltfm_mgr_tlv_eeprom_get", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + def process_pltfm_mgr_pwr_supply_present_get(self, seqid, iprot, oprot): args = pltfm_mgr_pwr_supply_present_get_args() args.read(iprot) @@ -2954,6 +3012,123 @@ pltfm_mgr_sys_eeprom_get_result.thrift_spec = ( ) +class pltfm_mgr_tlv_eeprom_get_args(object): + + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec]) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec])) + return + oprot.writeStructBegin('pltfm_mgr_tlv_eeprom_get_args') + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) +all_structs.append(pltfm_mgr_tlv_eeprom_get_args) +pltfm_mgr_tlv_eeprom_get_args.thrift_spec = ( +) + + +class pltfm_mgr_tlv_eeprom_get_result(object): + """ + Attributes: + - success + - ouch + + """ + + + def __init__(self, success=None, ouch=None,): + self.success = success + self.ouch = ouch + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec]) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.STRUCT: + self.success = pltfm_mgr_tlv_sys_eeprom_t() + self.success.read(iprot) + else: + iprot.skip(ftype) + elif fid == 1: + if ftype == TType.STRUCT: + self.ouch = InvalidPltfmMgrOperation.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec])) + return + oprot.writeStructBegin('pltfm_mgr_tlv_eeprom_get_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.STRUCT, 0) + self.success.write(oprot) + oprot.writeFieldEnd() + if self.ouch is not None: + oprot.writeFieldBegin('ouch', TType.STRUCT, 1) + self.ouch.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) +all_structs.append(pltfm_mgr_tlv_eeprom_get_result) +pltfm_mgr_tlv_eeprom_get_result.thrift_spec = ( + (0, TType.STRUCT, 'success', [pltfm_mgr_tlv_sys_eeprom_t, None], None, ), # 0 + (1, TType.STRUCT, 'ouch', [InvalidPltfmMgrOperation, None], None, ), # 1 +) + + class pltfm_mgr_pwr_supply_present_get_args(object): """ Attributes: diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/ttypes.py b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/ttypes.py index 391d4bd537..ad686b8880 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/ttypes.py +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/sonic_platform/pltfm_mgr_rpc/ttypes.py @@ -460,6 +460,63 @@ class pltfm_mgr_eeprom_t(object): return not (self == other) +class pltfm_mgr_tlv_sys_eeprom_t(object): + """ + Attributes: + - raw_content_hex + + """ + + + def __init__(self, raw_content_hex=None,): + self.raw_content_hex = raw_content_hex + + def read(self, iprot): + if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None: + iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec]) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.STRING: + self.raw_content_hex = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot._fast_encode is not None and self.thrift_spec is not None: + oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec])) + return + oprot.writeStructBegin('pltfm_mgr_tlv_sys_eeprom_t') + if self.raw_content_hex is not None: + oprot.writeFieldBegin('raw_content_hex', TType.STRING, 1) + oprot.writeString(self.raw_content_hex.encode('utf-8') if sys.version_info[0] == 2 else self.raw_content_hex) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.items()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + + class pltfm_mgr_pwr_supply_info_t(object): """ Attributes: @@ -1380,6 +1437,11 @@ pltfm_mgr_eeprom_t.thrift_spec = ( (21, TType.STRING, 'location', 'UTF8', None, ), # 21 (22, TType.I16, 'crc8', None, None, ), # 22 ) +all_structs.append(pltfm_mgr_tlv_sys_eeprom_t) +pltfm_mgr_tlv_sys_eeprom_t.thrift_spec = ( + None, # 0 + (1, TType.STRING, 'raw_content_hex', 'UTF8', None, ), # 1 +) all_structs.append(pltfm_mgr_pwr_supply_info_t) pltfm_mgr_pwr_supply_info_t.thrift_spec = ( None, # 0