From 88af7f625a7c89de1bed29ab97ae4ab0ca0215f6 Mon Sep 17 00:00:00 2001 From: "arheneus@marvell.com" <51254330+antony-rheneus@users.noreply.github.com> Date: Tue, 30 Jul 2019 21:33:36 +0530 Subject: [PATCH] [devices]: Marvell hwsku ET6448M 48x1G+4x10G Arm32 Mgmt switch (#3221) * [platform/hwsku] Added Marvell Armhf 32 bit ET6448M 52x Board 48x1G and 4x10G Management switch Signed-off-by: Antony Rheneus --- .../et6448m/buffers_defaults_t1.j2 | 45 ++++ .../et6448m/port_config.ini | 53 ++++ .../et6448m/profile.ini | 1 + .../et6448m/sai.profile | 3 + .../armhf-marvell_et6448m_52x-r0/fancontrol | 10 + .../plugins/eeprom.py | 13 + .../plugins/psuutil.py | 54 ++++ .../plugins/sfputil.py | 245 ++++++++++++++++++ .../armhf-marvell_et6448m_52x-r0/sensors.conf | 18 ++ 9 files changed, 442 insertions(+) create mode 100644 device/marvell/armhf-marvell_et6448m_52x-r0/et6448m/buffers_defaults_t1.j2 create mode 100644 device/marvell/armhf-marvell_et6448m_52x-r0/et6448m/port_config.ini create mode 100644 device/marvell/armhf-marvell_et6448m_52x-r0/et6448m/profile.ini create mode 100644 device/marvell/armhf-marvell_et6448m_52x-r0/et6448m/sai.profile create mode 100755 device/marvell/armhf-marvell_et6448m_52x-r0/fancontrol create mode 100644 device/marvell/armhf-marvell_et6448m_52x-r0/plugins/eeprom.py create mode 100755 device/marvell/armhf-marvell_et6448m_52x-r0/plugins/psuutil.py create mode 100755 device/marvell/armhf-marvell_et6448m_52x-r0/plugins/sfputil.py create mode 100644 device/marvell/armhf-marvell_et6448m_52x-r0/sensors.conf diff --git a/device/marvell/armhf-marvell_et6448m_52x-r0/et6448m/buffers_defaults_t1.j2 b/device/marvell/armhf-marvell_et6448m_52x-r0/et6448m/buffers_defaults_t1.j2 new file mode 100644 index 0000000000..38e34eb571 --- /dev/null +++ b/device/marvell/armhf-marvell_et6448m_52x-r0/et6448m/buffers_defaults_t1.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/marvell/armhf-marvell_et6448m_52x-r0/et6448m/port_config.ini b/device/marvell/armhf-marvell_et6448m_52x-r0/et6448m/port_config.ini new file mode 100644 index 0000000000..8073e8bec8 --- /dev/null +++ b/device/marvell/armhf-marvell_et6448m_52x-r0/et6448m/port_config.ini @@ -0,0 +1,53 @@ +# name lanes alias +Ethernet0 1 Ethernet0 +Ethernet1 2 Ethernet1 +Ethernet2 3 Ethernet2 +Ethernet3 4 Ethernet3 +Ethernet4 5 Ethernet4 +Ethernet5 6 Ethernet5 +Ethernet6 7 Ethernet6 +Ethernet7 8 Ethernet7 +Ethernet8 9 Ethernet8 +Ethernet9 10 Ethernet9 +Ethernet10 11 Ethernet10 +Ethernet11 12 Ethernet11 +Ethernet12 13 Ethernet12 +Ethernet13 14 Ethernet13 +Ethernet14 15 Ethernet14 +Ethernet15 16 Ethernet15 +Ethernet16 17 Ethernet16 +Ethernet17 18 Ethernet17 +Ethernet18 19 Ethernet18 +Ethernet19 20 Ethernet19 +Ethernet20 21 Ethernet20 +Ethernet21 22 Ethernet21 +Ethernet22 23 Ethernet22 +Ethernet23 24 Ethernet23 +Ethernet24 25 Ethernet24 +Ethernet25 26 Ethernet25 +Ethernet26 27 Ethernet26 +Ethernet27 28 Ethernet27 +Ethernet28 29 Ethernet28 +Ethernet29 30 Ethernet29 +Ethernet30 31 Ethernet30 +Ethernet31 32 Ethernet31 +Ethernet32 33 Ethernet32 +Ethernet33 34 Ethernet33 +Ethernet34 35 Ethernet34 +Ethernet35 36 Ethernet35 +Ethernet36 37 Ethernet36 +Ethernet37 38 Ethernet37 +Ethernet38 39 Ethernet38 +Ethernet39 40 Ethernet39 +Ethernet40 41 Ethernet40 +Ethernet41 42 Ethernet41 +Ethernet42 43 Ethernet42 +Ethernet43 44 Ethernet43 +Ethernet44 45 Ethernet44 +Ethernet45 46 Ethernet45 +Ethernet46 47 Ethernet46 +Ethernet47 48 Ethernet47 +Ethernet48 49 Ethernet48 +Ethernet49 50 Ethernet49 +Ethernet50 51 Ethernet50 +Ethernet51 52 Ethernet51 diff --git a/device/marvell/armhf-marvell_et6448m_52x-r0/et6448m/profile.ini b/device/marvell/armhf-marvell_et6448m_52x-r0/et6448m/profile.ini new file mode 100644 index 0000000000..c81a156d58 --- /dev/null +++ b/device/marvell/armhf-marvell_et6448m_52x-r0/et6448m/profile.ini @@ -0,0 +1 @@ +switchMacAddress=00:50:43:ee:ee:ee diff --git a/device/marvell/armhf-marvell_et6448m_52x-r0/et6448m/sai.profile b/device/marvell/armhf-marvell_et6448m_52x-r0/et6448m/sai.profile new file mode 100644 index 0000000000..10053fa935 --- /dev/null +++ b/device/marvell/armhf-marvell_et6448m_52x-r0/et6448m/sai.profile @@ -0,0 +1,3 @@ +mode=1 +hwId=et6448m +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/profile.ini diff --git a/device/marvell/armhf-marvell_et6448m_52x-r0/fancontrol b/device/marvell/armhf-marvell_et6448m_52x-r0/fancontrol new file mode 100755 index 0000000000..c2150eb457 --- /dev/null +++ b/device/marvell/armhf-marvell_et6448m_52x-r0/fancontrol @@ -0,0 +1,10 @@ +INTERVAL=10 +DEVPATH=hwmon0=devices/platform/soc/soc:internal-regs/f1011000.i2c/i2c-0/0-002e hwmon1=devices/platform/soc/soc:internal-regs/f1011000.i2c/i2c-0/0-004a hwmon2=devices/platform/soc/soc:internal-regs/f1011000.i2c/i2c-0/0-004b +DEVNAME=hwmon0=adt7473 hwmon1=lm75a hwmon2=lm75a +FCTEMPS=hwmon0/device/pwm2=hwmon2/temp1_input hwmon0/device/pwm1=hwmon1/temp1_input +FCFANS=hwmon0/device/pwm2=hwmon0/device/fan2_input hwmon0/device/pwm1=hwmon0/device/fan1_input +MINTEMP=hwmon0/device/pwm2=20 hwmon0/device/pwm1=20 +MAXTEMP=hwmon0/device/pwm2=60 hwmon0/device/pwm1=60 +MINSTART=hwmon0/device/pwm2=150 hwmon0/device/pwm1=150 +MINSTOP=hwmon0/device/pwm2=0 hwmon0/device/pwm1=0 + diff --git a/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/eeprom.py b/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/eeprom.py new file mode 100644 index 0000000000..ea525f5d74 --- /dev/null +++ b/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/eeprom.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python + +try: + from sonic_eeprom import eeprom_tlvinfo +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/etc/sonic/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/psuutil.py b/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/psuutil.py new file mode 100755 index 0000000000..3f155c6f15 --- /dev/null +++ b/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/psuutil.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python + +import os.path +import subprocess +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + MAX_PSUS = 2 + + def get_num_psus(self): + MAX_PSUS = 2 + return MAX_PSUS + + def get_psu_status(self, index): + if index is None: + return False + + cmdstatus, psustatus = subprocess.getstatusoutput('i2cget -y 0 0x41 0xa') #need to verify the cpld register logic + psustatus = int(psustatus, 16) + if cmdstatus == 0: + if index == 1: + psustatus = psustatus&4 + if psustatus == 4 : + return True + if index == 2: + psustatus = psustatus&8 + if psustatus == 8 : + return True + return False + + def get_psu_presence(self, index): + if index is None: + return False + + cmdstatus , psustatus = subprocess.getstatusoutput('i2cget -y 0 0x41 0xa') #need to verify the cpld register logic + psustatus = int(psustatus, 16) + if cmdstatus == 0: + if index == 1: + psustatus = psustatus&1 + if psustatus == 1 : + return True + if index == 2: + psustatus = psustatus&2 + if psustatus == 2 : + return True + return False + diff --git a/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/sfputil.py b/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/sfputil.py new file mode 100755 index 0000000000..19ef663f57 --- /dev/null +++ b/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/sfputil.py @@ -0,0 +1,245 @@ +#!/usr/bin/env python + +try: + import os + import time + import re + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +class SfpUtil(SfpUtilBase): + """Platform specific sfputil class""" + + _port_start = 49 + _port_end = 52 + ports_in_block = 4 + + _port_to_eeprom_mapping = {} + port_to_i2c_mapping = { + 49 : 0, + 50 : 0, + 51 : 0, + 52 : 0 + } + + _qsfp_ports = range(_port_start, ports_in_block + 1) + + def __init__(self): + # Override port_to_eeprom_mapping for class initialization + if not os.path.exists("/sys/class/gpio/gpio50/") : + os.system("echo 50 > /sys/class/gpio/gpiochip32/subsystem/export") + if not os.path.exists("/sys/class/gpio/gpio52/") : + os.system("echo 52 > /sys/class/gpio/gpiochip32/subsystem/export") + os.system("echo out > /sys/class/gpio/gpio50/direction") + os.system("echo out > /sys/class/gpio/gpio52/direction ") + + if not os.path.exists("/sys/bus/i2c/devices/0-0050") : + os.system("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-0/new_device") + #os.system("echo optoe 0x50 > /sys/bus/i2c/devices/i2c-0/new_device") + + #enable optic + os.system("i2cset -y -m 0x0f 0 0x41 0x5 0x00") + eeprom_path = '/sys/bus/i2c/devices/0-0050/eeprom' + for x in range(self.port_start, self.port_end + 1): + port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x]) + self.port_to_eeprom_mapping[x] = port_eeprom_path + SfpUtilBase.__init__(self) + + def reset(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_port_reset" + port_ps = path.format(self.port_to_i2c_mapping[port_num+1]) + + try: + reg_file = open(port_ps, 'w') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + #toggle reset + reg_file.seek(0) + reg_file.write('1') + time.sleep(1) + reg_file.seek(0) + reg_file.write('0') + reg_file.close() + return True + + def set_low_power_mode(self, port_nuM, lpmode): + raise NotImplementedError + + def get_low_power_mode(self, port_num): + raise NotImplementedError + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + prt = port_num % 49 + prt = "{0:02b}".format(prt) + p = prt[0] + q = prt[1] + cmd1 = "echo " + q + " > /sys/class/gpio/gpio50/value" + cmd2 = "echo " + p + " > /sys/class/gpio/gpio52/value" + os.system(cmd1) + os.system(cmd2) + + '''if port_num == 49 : + os.system("echo 0 > /sys/class/gpio/gpio50/value") + os.system("echo 0 > /sys/class/gpio/gpio52/value") + if port_num == 50 : + os.system("echo 0 > /sys/class/gpio/gpio50/value") + os.system("echo 0 > /sys/class/gpio/gpio52/value") + if port_num == 51 : + os.system("echo 0 > /sys/class/gpio/gpio50/value") + os.system("echo 0 > /sys/class/gpio/gpio52/value") + if port_num == 52: + os.system("echo 0 > /sys/class/gpio/gpio50/value") + os.system("echo 0 > /sys/class/gpio/gpio52/value")''' + path = "/sys/bus/i2c/devices/0-0050/eeprom" + #port_ps = path.format(self.port_to_i2c_mapping[port_num+1]) + + try: + reg_file = open(path) + reg_file.seek(01) + reg_file.read(02) + except IOError as e: + #print "Error: unable to open file: %s" % str(e) + + return False + + #reg_value = reg_file.readline().rstrip() + #if reg_value == '1': + # return True + + return True + + def read_porttab_mappings(self, porttabfile): + logical = [] + logical_to_bcm = {} + logical_to_physical = {} + physical_to_logical = {} + last_fp_port_index = 0 + last_portname = "" + first = 1 + port_pos_in_file = 0 + parse_fmt_port_config_ini = False + + try: + f = open(porttabfile) + except: + raise + + parse_fmt_port_config_ini = (os.path.basename(porttabfile) == "port_config.ini") + + # Read the porttab file and generate dicts + # with mapping for future reference. + # + # TODO: Refactor this to use the portconfig.py module that now + # exists as part of the sonic-config-engine package. + title = [] + for line in f: + line.strip() + if re.search("^#", line) is not None: + # The current format is: # name lanes alias index speed + # Where the ordering of the columns can vary + title = line.split()[1:] + continue + + # Parsing logic for 'port_config.ini' file + if (parse_fmt_port_config_ini): + # bcm_port is not explicitly listed in port_config.ini format + # Currently we assume ports are listed in numerical order according to bcm_port + # so we use the port's position in the file (zero-based) as bcm_port + portname = line.split()[0] + + bcm_port = str(port_pos_in_file) + #print("portname " + portname) + + 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: + fp_port_index = int(line.split()[3]) + else: + fp_port_index = portname.split("Ethernet").pop() + fp_port_index = int(fp_port_index.split("s").pop(0))+1 + #print(fp_port_index) + else: # Parsing logic for older 'portmap.ini' file + (portname, bcm_port) = line.split("=")[1].split(",")[:2] + + fp_port_index = portname.split("Ethernet").pop() + fp_port_index = int(fp_port_index.split("s").pop(0))+1 + + if ((len(self.sfp_ports) > 0) and (fp_port_index not in self.sfp_ports)): + continue + + if first == 1: + # Initialize last_[physical|logical]_port + # to the first valid port + last_fp_port_index = fp_port_index + last_portname = portname + first = 0 + + logical.append(portname) + + logical_to_bcm[portname] = "xe" + bcm_port + logical_to_physical[portname] = [fp_port_index] + if physical_to_logical.get(fp_port_index) is None: + physical_to_logical[fp_port_index] = [portname] + else: + physical_to_logical[fp_port_index].append( + portname) + + if (fp_port_index - last_fp_port_index) > 1: + # last port was a gang port + for p in range(last_fp_port_index+1, fp_port_index): + logical_to_physical[last_portname].append(p) + if physical_to_logical.get(p) is None: + physical_to_logical[p] = [last_portname] + else: + physical_to_logical[p].append(last_portname) + + last_fp_port_index = fp_port_index + last_portname = portname + + 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 + + + #print(self.logical_to_physical) + '''print("logical: " + self.logical) + print("logical to bcm: " + self.logical_to_bcm) + print("logical to physical: " + self.logical_to_physical) + print("physical to logical: " + self.physical_to_logical)''' + + + + @property + def port_start(self): + return self._port_start + + @property + def port_end(self): + return self._port_end + + @property + def qsfp_ports(self): + return self._qsfp_ports + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + @property + def get_transceiver_change_event(self): + raise NotImplementedError diff --git a/device/marvell/armhf-marvell_et6448m_52x-r0/sensors.conf b/device/marvell/armhf-marvell_et6448m_52x-r0/sensors.conf new file mode 100644 index 0000000000..5f9b97162e --- /dev/null +++ b/device/marvell/armhf-marvell_et6448m_52x-r0/sensors.conf @@ -0,0 +1,18 @@ +chip "adt7473-*" + label fan1 "rear fan 1" + label fan2 "rear fan 2" + ignore fan3 + ignore fan4 + ignore in1 + +chip "lm75a-i2c-*-4a" + label temp1 "MAC temp sensor" + set temp1_max 65 + set temp1_crit 75 + +chip "lm75a-i2c-*-4b" + label temp1 "Board temp sensor" + set temp2_max 65 + set temp2_crit 75 +chip "armada_thermal-*" + ignore temp1