[Mellanox] Implement Hardware Revision Platform API Call for Mellanox Chassis and PSU (#7552)
#### Why I did it This pull request allows calls to be made through the platform 2.0 API that retrieve the PSU and Chassis hardware revision on Mellanox platforms. Access to these values will aid customers in determining their hardware revisions for debugging and technical support. These values are intended to be eventually exposed through the CLI. #### How I did it For the PSU hardware revision I used the existing VPD function calls implemented in https://github.com/Azure/sonic-buildimage/pull/7382 For the Chassis hardware revision I parsed the SMBIOS / DMI type 2 information to retrieve the information.
This commit is contained in:
parent
f744f9354c
commit
6a9d1e584d
@ -26,6 +26,23 @@ MAX_SELECT_DELAY = 3600
|
||||
|
||||
MLNX_NUM_PSU = 2
|
||||
|
||||
DMI_FILE = '/sys/firmware/dmi/entries/2-0/raw'
|
||||
DMI_HEADER_LEN = 15
|
||||
DMI_PRODUCT_NAME = "Product Name"
|
||||
DMI_MANUFACTURER = "Manufacturer"
|
||||
DMI_VERSION = "Version"
|
||||
DMI_SERIAL = "Serial Number"
|
||||
DMI_ASSET_TAG = "Asset Tag"
|
||||
DMI_LOC = "Location In Chassis"
|
||||
DMI_TABLE_MAP = {
|
||||
DMI_PRODUCT_NAME: 0,
|
||||
DMI_MANUFACTURER: 1,
|
||||
DMI_VERSION: 2,
|
||||
DMI_SERIAL: 3,
|
||||
DMI_ASSET_TAG: 4,
|
||||
DMI_LOC: 5
|
||||
}
|
||||
|
||||
EEPROM_CACHE_ROOT = '/var/cache/sonic/decode-syseeprom'
|
||||
EEPROM_CACHE_FILE = 'syseeprom_cache'
|
||||
|
||||
@ -67,6 +84,9 @@ class Chassis(ChassisBase):
|
||||
# Initialize Platform name
|
||||
self.platform_name = device_info.get_platform()
|
||||
|
||||
# Initialize DMI data
|
||||
self.dmi_data = None
|
||||
|
||||
# move the initialization of each components to their dedicated initializer
|
||||
# which will be called from platform
|
||||
#
|
||||
@ -240,6 +260,18 @@ class Chassis(ChassisBase):
|
||||
string: Model/part number of device
|
||||
"""
|
||||
return self.model
|
||||
|
||||
def get_revision(self):
|
||||
"""
|
||||
Retrieves the hardware revision of the device
|
||||
|
||||
Returns:
|
||||
string: Revision value of device
|
||||
"""
|
||||
if self.dmi_data is None:
|
||||
self.dmi_data = self._parse_dmi(DMI_FILE)
|
||||
|
||||
return self.dmi_data.get(DMI_VERSION, "N/A")
|
||||
|
||||
##############################################
|
||||
# SFP methods
|
||||
@ -394,6 +426,31 @@ class Chassis(ChassisBase):
|
||||
return '0'
|
||||
|
||||
|
||||
def _parse_dmi(self, filename):
|
||||
"""
|
||||
Read DMI data chassis data and returns a dictionary of values
|
||||
|
||||
Returns:
|
||||
A dictionary containing the dmi table of the switch chassis info
|
||||
"""
|
||||
result = {}
|
||||
try:
|
||||
fileobj = open(filename, "rb")
|
||||
data = fileobj.read()
|
||||
fileobj.close()
|
||||
|
||||
body = data[DMI_HEADER_LEN:]
|
||||
records = body.split(b'\x00')
|
||||
|
||||
for k, v in DMI_TABLE_MAP.items():
|
||||
result[k] = records[v].decode("utf-8")
|
||||
|
||||
except Exception as e:
|
||||
logger.log_error("Fail to decode DMI {} due to {}".format(filename, repr(e)))
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def _verify_reboot_cause(self, filename):
|
||||
'''
|
||||
Open and read the reboot cause file in
|
||||
|
@ -31,6 +31,7 @@ PSU_VPD = "vpd"
|
||||
|
||||
SN_VPD_FIELD = "SN_VPD_FIELD"
|
||||
PN_VPD_FIELD = "PN_VPD_FIELD"
|
||||
REV_VPD_FIELD = "REV_VPD_FIELD"
|
||||
|
||||
# in most platforms the file psuX_curr, psuX_volt and psuX_power contain current, voltage and power data respectively.
|
||||
# but there are exceptions which will be handled by the following dictionary
|
||||
@ -105,6 +106,12 @@ class Psu(PsuBase):
|
||||
self.serial = ""
|
||||
logger.log_error("Fail to read PSU{} serial number: No key {} in VPD {}".format(self.index, SN_VPD_FIELD, self.psu_vpd))
|
||||
|
||||
if REV_VPD_FIELD in self.vpd_data:
|
||||
self.rev = self.vpd_data[REV_VPD_FIELD]
|
||||
else:
|
||||
self.rev = ""
|
||||
logger.log_error("Fail to read PSU{} serial number: No key {} in VPD {}".format(self.index, REV_VPD_FIELD, self.psu_vpd))
|
||||
|
||||
else:
|
||||
logger.log_info("Not reading PSU{} VPD data: Platform is fixed".format(self.index))
|
||||
|
||||
@ -210,6 +217,16 @@ class Psu(PsuBase):
|
||||
return self.serial
|
||||
|
||||
|
||||
def get_revision(self):
|
||||
"""
|
||||
Retrieves the hardware revision of the device
|
||||
|
||||
Returns:
|
||||
string: Revision value of device
|
||||
"""
|
||||
return self.rev
|
||||
|
||||
|
||||
def get_powergood_status(self):
|
||||
"""
|
||||
Retrieves the operational status of power supply unit (PSU) defined
|
||||
|
Reference in New Issue
Block a user