|
4 | 4 | import os
|
5 | 5 | import traceback
|
6 | 6 | import subprocess
|
| 7 | +import json |
| 8 | +import ast |
7 | 9 | from operator import itemgetter
|
8 | 10 | from itertools import groupby
|
9 | 11 | from collections import defaultdict
|
| 12 | +from collections import OrderedDict |
10 | 13 |
|
11 | 14 | try:
|
12 | 15 | from sonic_py_common import multi_asic
|
|
49 | 52 | FILE_PATH = '/usr/share/sonic/device'
|
50 | 53 | PORTMAP_FILE = 'port_config.ini'
|
51 | 54 | ALLOWED_HEADER = ['name', 'lanes', 'alias', 'index', 'asic_port_name', 'role', 'speed']
|
| 55 | +PLATFORM_FILE = 'platform.json' |
| 56 | +HWSKU_FILE = 'hwsku.json' |
52 | 57 |
|
53 | 58 | MACHINE_CONF = '/host/machine.conf'
|
54 | 59 | ONIE_PLATFORM_KEY = 'onie_platform'
|
@@ -89,11 +94,98 @@ def get_portconfig_path(self, asic_id=None):
|
89 | 94 | return portconfig
|
90 | 95 | return None
|
91 | 96 |
|
| 97 | + def get_platform_path(self): |
| 98 | + platform = self.get_platform_type() |
| 99 | + if platform is None: |
| 100 | + return None |
| 101 | + platform_path = os.path.join(FILE_PATH, platform, PLATFORM_FILE) |
| 102 | + if os.path.exists(platform_path): |
| 103 | + return platform_path |
| 104 | + return None |
| 105 | + |
| 106 | + def get_hwsku_path(self): |
| 107 | + platform = self.get_platform_type() |
| 108 | + if platform is None: |
| 109 | + return None |
| 110 | + hwsku_path = os.path.join(FILE_PATH, platform, self.hwsku, HWSKU_FILE) |
| 111 | + if os.path.exists(hwsku_path): |
| 112 | + return hwsku_path |
| 113 | + return None |
| 114 | + |
| 115 | + def get_portmap_from_platform_hwsku(self, platform_file, hwsku_file, aliases, portmap, aliasmap, portspeed): |
| 116 | + decoder = json.JSONDecoder(object_pairs_hook=OrderedDict) |
| 117 | + brkout_pattern = r'(\d{1,3})x(\d{1,3}G)(\[\d{1,3}G\])?(\((\d{1,3})\))?' |
| 118 | + with open(platform_file) as f: |
| 119 | + data = json.load(f, object_pairs_hook=OrderedDict) |
| 120 | + platform_dict = decoder.decode(json.dumps(data)) |
| 121 | + with open(hwsku_file) as f: |
| 122 | + data = json.load(f) |
| 123 | + hwsku_dict = ast.literal_eval(json.dumps(data)) |
| 124 | + for interface in platform_dict["interfaces"]: |
| 125 | + if interface not in hwsku_dict["interfaces"]: |
| 126 | + raise Exception("interface {} not in hwsku dict".format(interface)) |
| 127 | + alias_at_lanes = platform_dict["interfaces"][interface]['alias_at_lanes'] |
| 128 | + lanes = platform_dict["interfaces"][interface]['lanes'] |
| 129 | + breakout_mode = hwsku_dict["interfaces"][interface]["default_brkout_mode"] |
| 130 | + |
| 131 | + # Asymmetric breakout mode |
| 132 | + if re.search("\+", breakout_mode) is not None: |
| 133 | + breakout_parts = breakout_mode.split("+") |
| 134 | + match_list = [re.match(brkout_pattern, i).groups() for i in breakout_parts] |
| 135 | + # Symmetric breakout mode |
| 136 | + else: |
| 137 | + match_list = [re.match(brkout_pattern, breakout_mode).groups()] |
| 138 | + |
| 139 | + offset = 0 |
| 140 | + parent_intf_id = int(re.search("Ethernet(\d+)", interface).group(1)) |
| 141 | + for k in match_list: |
| 142 | + if k is None: |
| 143 | + continue |
| 144 | + num_lane_used, speed, assigned_lane = k[0], k[1], k[4] |
| 145 | + |
| 146 | + if assigned_lane is None: |
| 147 | + assigned_lane = len(lanes.split(",")) |
| 148 | + parent_intf_id = int(offset)+int(parent_intf_id) |
| 149 | + |
| 150 | + alias_start = 0 + offset |
| 151 | + step = int(assigned_lane)//int(num_lane_used) |
| 152 | + for i in range(0, int(assigned_lane), step): |
| 153 | + intf_name = "Ethernet" + str(parent_intf_id) |
| 154 | + alias = alias_at_lanes.split(",")[alias_start] |
| 155 | + aliases.append(alias) |
| 156 | + portmap[intf_name] = alias |
| 157 | + aliasmap[alias] = intf_name |
| 158 | + if speed: |
| 159 | + speed_pat = re.search("^((\d+)G|\d+)$", speed.upper()) |
| 160 | + if speed_pat is None: |
| 161 | + raise Exception('{} speed is not Supported...'.format(speed)) |
| 162 | + speed_G, speed_orig = speed_pat.group(2), speed_pat.group(1) |
| 163 | + if speed_G: |
| 164 | + portspeed[intf_name] = str(int(speed_G)*1000) |
| 165 | + else: |
| 166 | + portspeed[intf_name] = speed_orig |
| 167 | + else: |
| 168 | + raise Exception('Regex return for speed is None...') |
| 169 | + |
| 170 | + parent_intf_id += step |
| 171 | + alias_start += step |
| 172 | + parent_intf_id = 0 |
| 173 | + offset = int(assigned_lane) + int(offset) |
| 174 | + |
92 | 175 | def get_portmap(self, asic_id=None):
|
93 | 176 | aliases = []
|
94 | 177 | portmap = {}
|
95 | 178 | aliasmap = {}
|
96 | 179 | portspeed = {}
|
| 180 | + |
| 181 | + # if platform.json and hwsku.json exist, than get portmap from hwsku |
| 182 | + platform_file = self.get_platform_path() |
| 183 | + hwsku_file = self.get_hwsku_path() |
| 184 | + if platform_file and hwsku_file: |
| 185 | + self.get_portmap_from_platform_hwsku(platform_file, hwsku_file, aliases, portmap, aliasmap, portspeed) |
| 186 | + return (aliases, portmap, aliasmap, portspeed) |
| 187 | + |
| 188 | + # platform.json or hwsku.json does not exist so get portmap from port_config.ini |
97 | 189 | filename = self.get_portconfig_path(asic_id)
|
98 | 190 | if filename is None:
|
99 | 191 | raise Exception("Something wrong when trying to find the portmap file, either the hwsku is not available or file location is not correct")
|
|
0 commit comments