From b60f46cd1fb0ced1ffbff382e0125517f8c74b9e Mon Sep 17 00:00:00 2001 From: judyjoseph <53951155+judyjoseph@users.noreply.github.com> Date: Tue, 25 Aug 2020 09:34:59 -0700 Subject: [PATCH] Sfputil base and helper class changes for multi-ASIC (#100) * Sfputil base and helper class changes for multi-ASIC > adding the logical interface to asic id mapping * Updated based on new sonic-py-common API's. --- sonic_platform_base/sonic_sfp/sfputilbase.py | 40 ++++++++++++++++--- .../sonic_sfp/sfputilhelper.py | 39 +++++++++++++++--- 2 files changed, 68 insertions(+), 11 deletions(-) diff --git a/sonic_platform_base/sonic_sfp/sfputilbase.py b/sonic_platform_base/sonic_sfp/sfputilbase.py index 56845c579..1f3d2470a 100644 --- a/sonic_platform_base/sonic_sfp/sfputilbase.py +++ b/sonic_platform_base/sonic_sfp/sfputilbase.py @@ -16,6 +16,7 @@ from natsort import natsorted from portconfig import get_port_config from sonic_py_common import device_info + from sonic_py_common.interface import backplane_prefix from . import bcmshell # Dot module supports both Python 2 and Python 3 using explicit relative import methods from sonic_eeprom import eeprom_dts @@ -157,6 +158,9 @@ class SfpUtilBase(object): """ ["swp1", "swp5", "swp6", "swp7", "swp8" ...] """ logical = [] + # Mapping of logical port names available on a system to ASIC num + logical_to_asic = {} + # dicts for easier conversions between logical, physical and bcm ports logical_to_bcm = {} logical_to_physical = {} @@ -371,7 +375,7 @@ def _is_valid_port(self, port_num): return False - def read_porttab_mappings(self, porttabfile): + def read_porttab_mappings(self, porttabfile, asic_inst=0): logical = [] logical_to_bcm = {} logical_to_physical = {} @@ -455,12 +459,16 @@ def read_porttab_mappings(self, porttabfile): # so we use the port's position in the file (zero-based) as bcm_port portname = line.split()[0] + # Ignore if this is an internal backplane interface + if portname.startswith(backplane_prefix()): + continue + bcm_port = str(port_pos_in_file) if "index" in title: fp_port_index = int(line.split()[title.index("index")]) # Leave the old code for backward compatibility - elif len(line.split()) >= 4: + elif "asic_port_name" not in title and len(line.split()) >= 4: fp_port_index = int(line.split()[3]) else: fp_port_index = portname.split("Ethernet").pop() @@ -483,6 +491,9 @@ def read_porttab_mappings(self, porttabfile): logical.append(portname) + # Mapping of logical port names available on a system to ASIC instance + self.logical_to_asic[portname] = asic_inst + logical_to_bcm[portname] = "xe" + bcm_port logical_to_physical[portname] = [fp_port_index] if physical_to_logical.get(fp_port_index) is None: @@ -495,10 +506,10 @@ def read_porttab_mappings(self, porttabfile): port_pos_in_file += 1 - self.logical = logical - self.logical_to_bcm = logical_to_bcm - self.logical_to_physical = logical_to_physical - self.physical_to_logical = physical_to_logical + self.logical.extend(logical) + self.logical_to_bcm.update(logical_to_bcm) + self.logical_to_physical.update(logical_to_physical) + self.physical_to_logical.update(physical_to_logical) """ print("logical: " + self.logical) @@ -506,6 +517,19 @@ def read_porttab_mappings(self, porttabfile): print("logical to physical: " + self.logical_to_physical) print("physical to logical: " + self.physical_to_logical) """ + + def read_all_porttab_mappings(self, platform_dir, num_asic_inst): + # In multi asic scenario, get all the port_config files for different asics + for inst in range(num_asic_inst): + port_map_dir = os.path.join(platform_dir, str(inst)) + port_map_file = os.path.join(port_map_dir, PORT_CONFIG_INI) + if os.path.exists(port_map_file): + self.read_porttab_mappings(port_map_file, inst) + else: + port_json_file = os.path.join(port_map_dir, PLATFORM_JSON) + if os.path.exists(port_json_file): + self.read_porttab_mappings(port_json_file, inst) + def read_phytab_mappings(self, phytabfile): logical = [] phytab_mappings = {} @@ -615,6 +639,10 @@ def is_logical_port(self, port): else: return 0 + def get_asic_id_for_logical_port(self, logical_port): + """Returns the asic_id list of physical ports for the given logical port""" + return self.logical_to_asic.get(logical_port) + def is_logical_port_ganged_40_by_4(self, logical_port): physical_port_list = self.logical_to_physical[logical_port] if len(physical_port_list) > 1: diff --git a/sonic_platform_base/sonic_sfp/sfputilhelper.py b/sonic_platform_base/sonic_sfp/sfputilhelper.py index 5d17132ec..eed5396d5 100644 --- a/sonic_platform_base/sonic_sfp/sfputilhelper.py +++ b/sonic_platform_base/sonic_sfp/sfputilhelper.py @@ -16,6 +16,8 @@ from natsort import natsorted from portconfig import get_port_config from sonic_py_common import device_info + from sonic_py_common.interface import backplane_prefix + except ImportError as e: raise ImportError("%s - required module not found" % str(e)) @@ -33,6 +35,9 @@ class SfpUtilHelper(object): """ ["swp1", "swp5", "swp6", "swp7", "swp8" ...] """ logical = [] + # Mapping of logical port names available on a system to ASIC num + logical_to_asic = {} + # dicts for easier conversions between logical, physical and bcm ports logical_to_physical = {} @@ -42,7 +47,7 @@ class SfpUtilHelper(object): def __init__(self): pass - def read_porttab_mappings(self, porttabfile): + def read_porttab_mappings(self, porttabfile, asic_inst=0): logical = [] logical_to_physical = {} physical_to_logical = {} @@ -122,12 +127,16 @@ def read_porttab_mappings(self, porttabfile): # so we use the port's position in the file (zero-based) as bcm_port portname = line.split()[0] + # Ignore if this is an internal backplane interface + if portname.startswith(backplane_prefix()): + continue + bcm_port = str(port_pos_in_file) if "index" in title: fp_port_index = int(line.split()[title.index("index")]) # Leave the old code for backward compatibility - elif len(line.split()) >= 4: + elif "asic_port_name" not in title and len(line.split()) >= 4: fp_port_index = int(line.split()[3]) else: fp_port_index = portname.split("Ethernet").pop() @@ -150,6 +159,9 @@ def read_porttab_mappings(self, porttabfile): logical.append(portname) + # Mapping of logical port names available on a system to ASIC instance + self.logical_to_asic[portname] = asic_inst + logical_to_physical[portname] = [fp_port_index] if physical_to_logical.get(fp_port_index) is None: physical_to_logical[fp_port_index] = [portname] @@ -161,15 +173,28 @@ def read_porttab_mappings(self, porttabfile): port_pos_in_file += 1 - self.logical = logical - self.logical_to_physical = logical_to_physical - self.physical_to_logical = physical_to_logical + self.logical.extend(logical) + self.logical_to_physical.update(logical_to_physical) + self.physical_to_logical.update(physical_to_logical) """ print("logical: " + self.logical) print("logical to physical: " + self.logical_to_physical) print("physical to logical: " + self.physical_to_logical) """ + + def read_all_porttab_mappings(self, platform_dir, num_asic_inst): + # In multi asic scenario, get all the port_config files for different asics + for inst in range(num_asic_inst): + port_map_dir = os.path.join(platform_dir, str(inst)) + port_map_file = os.path.join(port_map_dir, PORT_CONFIG_INI) + if os.path.exists(port_map_file): + self.read_porttab_mappings(port_map_file, inst) + else: + port_json_file = os.path.join(port_map_dir, PLATFORM_JSON) + if os.path.exists(port_json_file): + self.read_porttab_mappings(port_json_file, inst) + def get_physical_to_logical(self, port_num): """Returns list of logical ports for the given physical port""" @@ -185,3 +210,7 @@ def is_logical_port(self, port): return 1 else: return 0 + + def get_asic_id_for_logical_port(self, logical_port): + """Returns the asic_id list of physical ports for the given logical port""" + return self.logical_to_asic.get(logical_port)