diff --git a/sonic_platform_base/sonic_pcie/pcie_base.py b/sonic_platform_base/sonic_pcie/pcie_base.py index 17055aa3259c..3155401ffbbf 100644 --- a/sonic_platform_base/sonic_pcie/pcie_base.py +++ b/sonic_platform_base/sonic_pcie/pcie_base.py @@ -1,41 +1,65 @@ -# -# pcie_base.py -# -# Abstract base class for implementing platform-specific -# PCIE functionality for SONiC -# - -try: - import abc -except ImportError as e: - raise ImportError (str(e) + " - required module not found") - -class PcieBase(object): - def __init__(self, path): - """ - Constructor - - Args: - pcieutil file and config file path - """ - - @abc.abstractmethod - def get_pcie_device(self): - """ - get current device pcie info - - Returns: - A list including pcie device info - """ - return [] - - - @abc.abstractmethod - def get_pcie_check(self): - """ - Check Pcie device with config file - - Returns: - A list including pcie device and test result info - """ - return [] +# +# pcie_base.py +# +# Abstract base class for implementing platform-specific +# PCIE functionality for SONiC +# + +try: + import abc +except ImportError as e: + raise ImportError(str(e) + " - required module not found") + + +class PcieBase(object): + def __init__(self, path): + """ + Constructor + + Args: + pcieutil file and config file path + """ + + @abc.abstractmethod + def get_pcie_device(self): + """ + get current device pcie info + + Returns: + A list including pcie device info + """ + return [] + + @abc.abstractmethod + def get_pcie_check(self): + """ + Check Pcie device with config file + + Returns: + A list including pcie device and test result info + """ + return [] + + @abc.abstractmethod + def get_pcie_aer_stats(self, domain, bus, dev, fn): + """ + Returns a nested dictionary containing the AER stats belonging to a + PCIe device + + Args: + domain, bus, dev, fn: Domain, bus, device, function of the PCIe + device respectively + + Returns: + A nested dictionary where key is severity 'correctable', 'fatal' or + 'non_fatal', value is a dictionary of key, value pairs in the format: + {'AER Error type': Error count} + + Ex. {'correctable': {'BadDLLP': 0, 'BadTLP': 0}, + 'fatal': {'RxOF': 0, 'MalfTLP': 0}, + 'non_fatal': {'RxOF': 0, 'MalfTLP': 0}} + + For PCIe devices that do not support AER, the value for each + severity key is an empty dictionary. + """ + return {} diff --git a/sonic_platform_base/sonic_pcie/pcie_common.py b/sonic_platform_base/sonic_pcie/pcie_common.py index 0af53c46e01b..b212ddaa212f 100644 --- a/sonic_platform_base/sonic_pcie/pcie_common.py +++ b/sonic_platform_base/sonic_pcie/pcie_common.py @@ -98,6 +98,42 @@ def get_pcie_check(self): item_conf["result"] = "Failed" return self.confInfo + # return AER stats of PCIe device + def get_pcie_aer_stats(self, domain=0, bus=0, device=0, func=0): + aer_stats = {'correctable': {}, 'fatal': {}, 'non_fatal': {}} + dev_path = os.path.join('/sys/bus/pci/devices', '%04x:%02x:%02x.%d' % (domain, bus, device, func)) + + # construct AER sysfs filepath + correctable_path = os.path.join(dev_path, "aer_dev_correctable") + fatal_path = os.path.join(dev_path, "aer_dev_fatal") + non_fatal_path = os.path.join(dev_path, "aer_dev_nonfatal") + + # update AER-correctable fields + if os.path.isfile(correctable_path): + with open(correctable_path, 'r') as fh: + lines = fh.readlines() + for line in lines: + correctable_field, value = line.split() + aer_stats['correctable'][correctable_field] = value + + # update AER-Fatal fields + if os.path.isfile(fatal_path): + with open(fatal_path, 'r') as fh: + lines = fh.readlines() + for line in lines: + fatal_field, value = line.split() + aer_stats['fatal'][fatal_field] = value + + # update AER-Non Fatal fields + if os.path.isfile(non_fatal_path): + with open(non_fatal_path, 'r') as fh: + lines = fh.readlines() + for line in lines: + non_fatal_field, value = line.split() + aer_stats['non_fatal'][non_fatal_field] = value + + return aer_stats + # generate the config file with current pci device def dump_conf_yaml(self): curInfo = self.get_pcie_device()