grthtrhthjhtyjytjytkergtrhtrjytjerhrfh4:24 29/09/2026# Copyright (c) Sep 2019 Mellanox Technologies LTD. All rights reserved. # Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # # This software is available to you under a choice of one of two # licenses. You may choose to be licensed under the terms of the GNU # General Public License (GPL) Version 2, available from the file # COPYING in the main directory of this source tree, or the # OpenIB.org BSD license below: # # Redistribution and use in source and binary forms, with or # without modification, are permitted provided that the following # conditions are met: # # - Redistributions of source code must retain the above # copyright notice, this list of conditions and the following # disclaimer. # # - Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials # provided with the distribution. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. # -- from __future__ import print_function import sys import os import string import subprocess import re import platform import regaccess import time class FwTraceUtilities(object): @classmethod def _cmd_exec(self, cmd): """ Execute a command line and return the state and the output of the command """ p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=False, shell=True) output = p.communicate() stat = p.wait() return (stat, output[0].decode('utf-8'), output[1].decode('utf-8')) # RC, Stdout, Stderr @classmethod def _is_dev_dbdf_format(self, dev): """ Check if the input has a bdf format with domain If bdf format with domain format return True, otherwise return False """ pat = r"[0-9,A-F,a-f]{4}:[0-9,A-F,a-f]{2}:[0-9,A-F,a-f]{2}\.[0-9,A-F,a-f]{1,2}" if re.match(pat, dev): return True return False @classmethod def _is_dev_bdf_format(self, dev): """ Check if the input has a bdf format If bdf format return True, otherwise return False """ pat = r"[0-9,A-F,a-f]{2}:[0-9,A-F,a-f]{2}\.[0-9,A-F,a-f]{1,2}" if re.match(pat, dev): return True return False @classmethod def _add_domain_to_address(self, dev_addr): """ Add the domain "0000:" to the given address """ if len(dev_addr.split(":")) == 2: return "0000:" + dev_addr return dev_addr @staticmethod def get_dev_dbdf(device_name): """ retrieve the BDF according to the device name """ if FwTraceUtilities._is_dev_dbdf_format(device_name): return device_name if FwTraceUtilities._is_dev_bdf_format(device_name): return FwTraceUtilities._add_domain_to_address(device_name) operatingSys = platform.system() if operatingSys == "FreeBSD": if not(device_name.startswith("pci")): raise RuntimeError("Unexpected device name format") return device_name[3:] elif operatingSys == "Linux": cmd = "mstdevices_info -vv" (rc, out, _) = FwTraceUtilities._cmd_exec(cmd) if rc != 0: raise RuntimeError("Failed to get device PCI address") # extract bdf bdf = None for line in out.split('\n'): if device_name in line: if len(line.split()) > 2: bdf = line.split()[2] if not bdf: raise RuntimeError("Failed to get device PCI Address") return FwTraceUtilities._add_domain_to_address(bdf) elif operatingSys == "Windows": cmd = "mdevices status -vv" (rc, out, _) = FwTraceUtilities._cmd_exec(cmd) if rc != 0: raise RuntimeError("Failed to get device PCI address") # extract bdf bdf = None for line in out.split('\n'): l = line.split() if (len(l) > 1) and (device_name in l[0]) and ("seg:bus:dev.fn" in l[1]): bdf = line.split('=')[1] if not bdf: raise RuntimeError("Failed to get device PCI Address") return bdf else: raise RuntimeError("Unsupported OS") @staticmethod def is_driver_mem_mode_supported(): """ Check if driver mem mode is suported If supported return True, otherwise return False """ is_supported = False if os.name == "nt": # future capability - windows pass else: if os.path.exists("/sys/kernel/debug/tracing/events/mlx5/fw_tracer/") or \ os.path.exists("/sys/kernel/debug/tracing/events/mlx5/mlx5_fw/"): is_supported = True return is_supported @staticmethod def is_secure_fw(mst_device): """ Check if the firmware is secure or not If secure return True, otherwise return False """ is_secure = False if mst_device is None: return is_secure # in case that reg access fail, we cant determain a secure fw and return false try: reg_access_obj = regaccess.RegAccess(mst_device) is_secure = reg_access_obj.getSecureFWStatus() except BaseException: is_secure = False return is_secure @staticmethod def ts_to_real_ts(ts, freq): """ The method calculate a real time stamp and return is as [hh:mm:ss:nsec] format """ if freq <= 0: raise RuntimeError("device frequency is not above Zero - can't calc real time stamp") nano_seconds = int(1000 / freq) * ts # calc hours time_in_seconds = int(nano_seconds / 1000000000) hours = int(time_in_seconds / 3600) # calc minutes time_in_seconds = time_in_seconds - (hours * 3600) minutes = int(time_in_seconds / 60) # calc seconds time_in_seconds = time_in_seconds - (minutes * 60) seconds = time_in_seconds # calc the reminder in nano seconds nsecs = nano_seconds - int(nano_seconds / 1000000000) * 1000000000 return "{:02d}:{:02d}:{:02d}:{:09d}".format(hours, minutes, seconds, nsecs) @staticmethod def get_device_frequency(device): """ The method call mlxuptime, parse the device frequency and return it as integer (mlxuptime can take 1 sec) """ cmd = "mlxuptime -d" + device (rc, out, _) = FwTraceUtilities._cmd_exec(cmd) freq_num = 0 if rc != 0: raise RuntimeError("Failed to get device frequency (necessary for real ts calculation)") else: for line in out.split('\n'): if "Measured core frequency" in line: freq_str = line.split(": ")[1].split(" ")[0] freq_num = int(round(float(freq_str))) break return freq_num ########################################## if __name__ == "__main__": sys.exit(ExtractStrings())