-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
DellEMC S6000 : Platform2.0 API implementation for EEPROM (#3295)
- Loading branch information
1 parent
e547b0d
commit f0c0fac
Showing
1 changed file
with
201 additions
and
0 deletions.
There are no files selected for viewing
201 changes: 201 additions & 0 deletions
201
platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,201 @@ | ||
#!/usr/bin/env python | ||
|
||
######################################################################## | ||
# DellEMC S6000 | ||
# | ||
# Module contains platform specific implementation of SONiC Platform | ||
# Base API and provides the EEPROMs' information. | ||
# | ||
# The different EEPROMs available are as follows: | ||
# - System EEPROM : Contains Serial number, Service tag, Base MA | ||
# address, etc. in ONIE TlvInfo EEPROM format. | ||
# - PSU EEPROM : Contains Serial number, Part number, Service Tag, | ||
# PSU type, Revision. | ||
# - Fan EEPROM : Contains Serial number, Part number, Service Tag, | ||
# Fan type, Number of Fans in Fantray, Revision. | ||
######################################################################## | ||
|
||
|
||
try: | ||
import os | ||
from sonic_platform_base.sonic_eeprom.eeprom_base import EepromDecoder | ||
from sonic_platform_base.sonic_eeprom.eeprom_tlvinfo import TlvInfoDecoder | ||
except ImportError as e: | ||
raise ImportError(str(e) + "- required module not found") | ||
|
||
|
||
# PSU eeprom fields in format required by EepromDecoder | ||
psu_eeprom_format = [ | ||
('PPID', 's', 20), ('DPN Rev', 's', 3), ('Service Tag', 's', 7), | ||
('Part Number', 's', 10), ('Part Num Revision', 's', 3), | ||
('Mfg Test', 's', 2), ('PSU Type', 's', 1), ('Fab Rev', 's', 2) | ||
] | ||
|
||
# Fan eeprom fields in format required by EepromDecoder | ||
fan_eeprom_format = [ | ||
('PPID', 's', 20), ('DPN Rev', 's', 3), ('Service Tag', 's', 7), | ||
('Part Number', 's', 10), ('Part Num Revision', 's', 3), | ||
('Mfg Test', 's', 2), ('Number of Fans', 's', 2), ('Fan Type', 's', 1), | ||
('Fab Rev', 's', 2) | ||
] | ||
|
||
|
||
class Eeprom(TlvInfoDecoder): | ||
"""DellEMC Platform-specific EEPROM class""" | ||
|
||
I2C_DIR = "/sys/class/i2c-adapter/" | ||
|
||
def __init__(self, is_psu=False, psu_index=0, is_fan=False, fan_index=0): | ||
self.is_psu_eeprom = is_psu | ||
self.is_fan_eeprom = is_fan | ||
self.is_sys_eeprom = not (is_psu | is_fan) | ||
|
||
if self.is_sys_eeprom: | ||
self.start_offset = 0 | ||
self.eeprom_path = self.I2C_DIR + "i2c-10/10-0053/eeprom" | ||
# System EEPROM is in ONIE TlvInfo EEPROM format | ||
super(Eeprom, self).__init__(self.eeprom_path, | ||
self.start_offset, '', True) | ||
self._load_system_eeprom() | ||
else: | ||
self.start_offset = 6 | ||
if self.is_psu_eeprom: | ||
self.index = psu_index | ||
self.eeprom_path = self.I2C_DIR \ | ||
+ "i2c-1/1-005{}/eeprom".format(2 - self.index) | ||
self.format = psu_eeprom_format | ||
else: | ||
self.index = fan_index | ||
self.eeprom_path = self.I2C_DIR \ | ||
+ "i2c-11/11-005{}/eeprom".format(4 - self.index) | ||
self.format = fan_eeprom_format | ||
EepromDecoder.__init__(self, self.eeprom_path, self.format, | ||
self.start_offset, '', True) | ||
self._load_device_eeprom() | ||
|
||
def _load_system_eeprom(self): | ||
""" | ||
Reads the system EEPROM and retrieves the values corresponding | ||
to the codes defined as per ONIE TlvInfo EEPROM format and fills | ||
them in a dictionary. | ||
""" | ||
try: | ||
# Read System EEPROM as per ONIE TlvInfo EEPROM format. | ||
self.eeprom_data = self.read_eeprom() | ||
except: | ||
self.base_mac = 'NA' | ||
self.serial_number = 'NA' | ||
self.part_number = 'NA' | ||
self.eeprom_tlv_dict = dict() | ||
else: | ||
eeprom = self.eeprom_data | ||
self.eeprom_tlv_dict = dict() | ||
|
||
if not self.is_valid_tlvinfo_header(eeprom): | ||
self.base_mac = 'NA' | ||
self.serial_number = 'NA' | ||
self.part_number = 'NA' | ||
return | ||
|
||
total_length = (ord(eeprom[9]) << 8) | ord(eeprom[10]) | ||
tlv_index = self._TLV_INFO_HDR_LEN | ||
tlv_end = self._TLV_INFO_HDR_LEN + total_length | ||
|
||
while (tlv_index + 2) < len(eeprom) and tlv_index < tlv_end: | ||
if not self.is_valid_tlv(eeprom[tlv_index:]): | ||
break | ||
|
||
tlv = eeprom[tlv_index:tlv_index + 2 | ||
+ ord(eeprom[tlv_index + 1])] | ||
code = "0x%02X" % (ord(tlv[0])) | ||
|
||
if ord(tlv[0]) == self._TLV_CODE_VENDOR_EXT: | ||
value = str((ord(tlv[2]) << 24) | (ord(tlv[3]) << 16) | | ||
(ord(tlv[4]) << 8) | ord(tlv[5])) | ||
value += str(tlv[6:6 + ord(tlv[1])]) | ||
else: | ||
name, value = self.decoder(None, tlv) | ||
|
||
self.eeprom_tlv_dict[code] = value | ||
if ord(eeprom[tlv_index]) == self._TLV_CODE_CRC_32: | ||
break | ||
|
||
tlv_index += ord(eeprom[tlv_index+1]) + 2 | ||
|
||
self.base_mac = self.eeprom_tlv_dict.get( | ||
hex(self._TLV_CODE_MAC_BASE), 'NA') | ||
self.serial_number = self.eeprom_tlv_dict.get( | ||
hex(self._TLV_CODE_SERIAL_NUMBER), 'NA') | ||
self.part_number = self.eeprom_tlv_dict.get( | ||
hex(self._TLV_CODE_PART_NUMBER), 'NA') | ||
|
||
def _load_device_eeprom(self): | ||
""" | ||
Reads the Fan/PSU EEPROM and retrieves the serial number and | ||
model number of the device. | ||
""" | ||
try: | ||
# Read Fan/PSU EEPROM as per the specified format. | ||
self.eeprom_data = EepromDecoder.read_eeprom(self) | ||
except: | ||
self.serial_number = 'NA' | ||
self.part_number = 'NA' | ||
else: | ||
(valid, data) = self._get_eeprom_field("PPID") | ||
if valid: | ||
ppid = data | ||
self.serial_number = (ppid[:2] + "-" + ppid[2:8] + "-" | ||
+ ppid[8:13] + "-" + ppid[13:16] | ||
+ "-" + ppid[16:]) | ||
(valid, data) = self._get_eeprom_field("DPN Rev") | ||
if valid: | ||
self.serial_number += "-" + data | ||
else: | ||
seld.serial_number = 'NA' | ||
|
||
(valid, data) = self._get_eeprom_field("Part Number") | ||
if valid: | ||
self.part_number = data | ||
else: | ||
self.part_number = 'NA' | ||
|
||
def _get_eeprom_field(self, field_name): | ||
""" | ||
For a field name specified in the EEPROM format, returns the | ||
presence of the field and the value for the same. | ||
""" | ||
field_start = 0 | ||
for field in self.format: | ||
field_end = field_start + field[2] | ||
if field[0] == field_name: | ||
return (True, self.eeprom_data[field_start:field_end]) | ||
field_start = field_end | ||
|
||
return (False, None) | ||
|
||
def serial_number_str(self): | ||
""" | ||
Returns the serial number. | ||
""" | ||
return self.serial_number | ||
|
||
def part_number_str(self): | ||
""" | ||
Returns the part number. | ||
""" | ||
return self.part_number | ||
|
||
# System EEPROM specific methods | ||
def base_mac_addr(self): | ||
""" | ||
Returns the base MAC address found in the system EEPROM. | ||
""" | ||
return self.base_mac | ||
|
||
def system_eeprom_info(self): | ||
""" | ||
Returns a dictionary, where keys are the type code defined in | ||
ONIE EEPROM format and values are their corresponding values | ||
found in the system EEPROM. | ||
""" | ||
return self.eeprom_tlv_dict |