From 32ad7444f9d0db6a88dd8ea255b3b386d793e038 Mon Sep 17 00:00:00 2001 From: LuiSzee Date: Wed, 27 Oct 2021 03:55:24 +0800 Subject: [PATCH] [centec] support TM.MX board v682-48y8c_d (#8747) Adding platform support for centec v682-48y8c_d. Why I did it Adding platform support for centec v682-48y8c_d. This switch has 48 SFP+ (1G/10G/25G) ports, 8 QSFP28 (40G/100G) ports on CENTEC TsingMa.MX. CPU used in v682-48y8c_d is Intel(R) Xeon(R) CPU D-1527. How I did it Modify related code in platform and device directory. Upgrade sai to v1.8. fix bug for parallel compile centec platform modules. How to verify it Build centec amd64 sonic image, verify platform functions (port, sfp, led etc) on centec v682-48y8c_d board. Co-authored-by: Shi Lei --- .../V682-48y8c-d/buffers.json.j2 | 70 +++ .../V682-48y8c-d/pg_profile_lookup.ini | 21 + .../V682-48y8c-d/port_config.ini | 57 +++ .../V682-48y8c-d/qos.json.j2 | 1 + .../V682-48y8c-d/sai.profile | 2 + .../x86_64-centec_v682_48y8c_d-r0/default_sku | 1 + .../installer.conf | 0 .../platform_components.json | 8 + .../platform_reboot | 24 ++ .../plugins/led_control.py | 213 +++++++++ .../plugins/sfputil.py | 248 +++++++++++ .../pmon_daemon_control.json | 7 + platform/centec/one-image.mk | 3 + .../centec/platform-modules-centec-v682.mk | 14 + platform/centec/rules.mk | 1 + platform/centec/sdk.mk | 4 +- .../sonic-platform-modules-e582/debian/rules | 11 +- .../debian/rules | 11 +- .../48y8c-d/modules/Makefile | 1 + .../modules/centec_v682_48y8c_d_platform.c | 404 ++++++++++++++++++ .../48y8c-d/service/48y8c_d_platform.service | 13 + .../48y8c-d/service/release.py | 70 +++ .../48y8c-d/setup.py | 15 + .../48y8c-d/sonic_platform/__init__.py | 2 + .../48y8c-d/sonic_platform/chassis.py | 181 ++++++++ .../48y8c-d/sonic_platform/platform.py | 21 + .../48y8c-d/sonic_platform/sfp.py | 102 +++++ .../sonic-platform-modules-v682/LICENSE | 15 + .../sonic-platform-modules-v682/README.md | 1 + .../debian/changelog | 5 + .../sonic-platform-modules-v682/debian/compat | 1 + .../debian/control | 11 + .../debian/platform-modules-v682-48y8c-d.init | 90 ++++ .../platform-modules-v682-48y8c-d.install | 5 + .../platform-modules-v682-48y8c-d.postinst | 2 + .../sonic-platform-modules-v682/debian/rules | 100 +++++ 36 files changed, 1725 insertions(+), 10 deletions(-) create mode 100644 device/centec/x86_64-centec_v682_48y8c_d-r0/V682-48y8c-d/buffers.json.j2 create mode 100644 device/centec/x86_64-centec_v682_48y8c_d-r0/V682-48y8c-d/pg_profile_lookup.ini create mode 100644 device/centec/x86_64-centec_v682_48y8c_d-r0/V682-48y8c-d/port_config.ini create mode 100644 device/centec/x86_64-centec_v682_48y8c_d-r0/V682-48y8c-d/qos.json.j2 create mode 100644 device/centec/x86_64-centec_v682_48y8c_d-r0/V682-48y8c-d/sai.profile create mode 100644 device/centec/x86_64-centec_v682_48y8c_d-r0/default_sku create mode 100644 device/centec/x86_64-centec_v682_48y8c_d-r0/installer.conf create mode 100644 device/centec/x86_64-centec_v682_48y8c_d-r0/platform_components.json create mode 100755 device/centec/x86_64-centec_v682_48y8c_d-r0/platform_reboot create mode 100644 device/centec/x86_64-centec_v682_48y8c_d-r0/plugins/led_control.py create mode 100644 device/centec/x86_64-centec_v682_48y8c_d-r0/plugins/sfputil.py create mode 100644 device/centec/x86_64-centec_v682_48y8c_d-r0/pmon_daemon_control.json create mode 100644 platform/centec/platform-modules-centec-v682.mk create mode 100644 platform/centec/sonic-platform-modules-v682/48y8c-d/modules/Makefile create mode 100644 platform/centec/sonic-platform-modules-v682/48y8c-d/modules/centec_v682_48y8c_d_platform.c create mode 100644 platform/centec/sonic-platform-modules-v682/48y8c-d/service/48y8c_d_platform.service create mode 100644 platform/centec/sonic-platform-modules-v682/48y8c-d/service/release.py create mode 100644 platform/centec/sonic-platform-modules-v682/48y8c-d/setup.py create mode 100644 platform/centec/sonic-platform-modules-v682/48y8c-d/sonic_platform/__init__.py create mode 100644 platform/centec/sonic-platform-modules-v682/48y8c-d/sonic_platform/chassis.py create mode 100644 platform/centec/sonic-platform-modules-v682/48y8c-d/sonic_platform/platform.py create mode 100644 platform/centec/sonic-platform-modules-v682/48y8c-d/sonic_platform/sfp.py create mode 100644 platform/centec/sonic-platform-modules-v682/LICENSE create mode 100644 platform/centec/sonic-platform-modules-v682/README.md create mode 100644 platform/centec/sonic-platform-modules-v682/debian/changelog create mode 100644 platform/centec/sonic-platform-modules-v682/debian/compat create mode 100644 platform/centec/sonic-platform-modules-v682/debian/control create mode 100644 platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48y8c-d.init create mode 100644 platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48y8c-d.install create mode 100644 platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48y8c-d.postinst create mode 100755 platform/centec/sonic-platform-modules-v682/debian/rules diff --git a/device/centec/x86_64-centec_v682_48y8c_d-r0/V682-48y8c-d/buffers.json.j2 b/device/centec/x86_64-centec_v682_48y8c_d-r0/V682-48y8c-d/buffers.json.j2 new file mode 100644 index 0000000000..08e21e428b --- /dev/null +++ b/device/centec/x86_64-centec_v682_48y8c_d-r0/V682-48y8c-d/buffers.json.j2 @@ -0,0 +1,70 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '40m' %} +{% set default_ports_num = 54 -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) -%} + {%- set cable_len = [] -%} + {%- for local_port in DEVICE_NEIGHBOR -%} + {%- if local_port == port_name -%} + {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor_role = neighbor.type -%} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role -%} + {%- set roles1 = roles1 | lower -%} + {%- set roles2 = roles2 | lower -%} + {%- if roles1 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%} + {%- elif roles2 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif -%} +{% endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(1,default_ports_num+1) %} + {% if PORT.append("Ethernet%d" % (port_idx)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT %} + {% set cable = cable_length(port) -%} + "{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %} + + {% endfor %} + } + } +} + diff --git a/device/centec/x86_64-centec_v682_48y8c_d-r0/V682-48y8c-d/pg_profile_lookup.ini b/device/centec/x86_64-centec_v682_48y8c_d-r0/V682-48y8c-d/pg_profile_lookup.ini new file mode 100644 index 0000000000..a65244e69b --- /dev/null +++ b/device/centec/x86_64-centec_v682_48y8c_d-r0/V682-48y8c-d/pg_profile_lookup.ini @@ -0,0 +1,21 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 1000 5m 34816 18432 16384 0 + 10000 5m 34816 18432 16384 0 + 25000 5m 34816 18432 16384 0 + 40000 5m 34816 18432 16384 0 + 50000 5m 34816 18432 16384 0 + 100000 5m 36864 18432 18432 0 + 1000 40m 36864 18432 18432 0 + 10000 40m 36864 18432 18432 0 + 25000 40m 39936 18432 21504 0 + 40000 40m 41984 18432 23552 0 + 50000 40m 41984 18432 23552 0 + 100000 40m 54272 18432 35840 0 + 1000 300m 49152 18432 30720 0 + 10000 300m 49152 18432 30720 0 + 25000 300m 71680 18432 53248 0 + 40000 300m 94208 18432 75776 0 + 50000 300m 94208 18432 75776 0 + 100000 300m 184320 18432 165888 0 + diff --git a/device/centec/x86_64-centec_v682_48y8c_d-r0/V682-48y8c-d/port_config.ini b/device/centec/x86_64-centec_v682_48y8c_d-r0/V682-48y8c-d/port_config.ini new file mode 100644 index 0000000000..45206015c9 --- /dev/null +++ b/device/centec/x86_64-centec_v682_48y8c_d-r0/V682-48y8c-d/port_config.ini @@ -0,0 +1,57 @@ +# name lanes alias index speed fec +Ethernet0 32 eth-0-1 0 25000 none +Ethernet1 33 eth-0-2 1 25000 none +Ethernet2 34 eth-0-3 2 25000 none +Ethernet3 35 eth-0-4 3 25000 none +Ethernet4 0 eth-0-5 4 25000 none +Ethernet5 4 eth-0-6 5 25000 none +Ethernet6 8 eth-0-7 6 25000 none +Ethernet7 12 eth-0-8 7 25000 none +Ethernet8 16 eth-0-9 8 25000 none +Ethernet9 20 eth-0-10 9 25000 none +Ethernet10 24 eth-0-11 10 25000 none +Ethernet11 28 eth-0-12 11 25000 none +Ethernet12 40 eth-0-13 12 25000 none +Ethernet13 44 eth-0-14 13 25000 none +Ethernet14 48 eth-0-15 14 25000 none +Ethernet15 52 eth-0-16 15 25000 none +Ethernet16 56 eth-0-17 16 25000 none +Ethernet17 60 eth-0-18 17 25000 none +Ethernet18 64 eth-0-19 18 25000 none +Ethernet19 68 eth-0-20 19 25000 none +Ethernet20 72 eth-0-21 20 25000 none +Ethernet21 73 eth-0-22 21 25000 none +Ethernet22 74 eth-0-23 22 25000 none +Ethernet23 75 eth-0-24 23 25000 none +Ethernet24 232 eth-0-25 24 25000 none +Ethernet25 233 eth-0-26 25 25000 none +Ethernet26 234 eth-0-27 26 25000 none +Ethernet27 235 eth-0-28 27 25000 none +Ethernet28 200 eth-0-29 28 25000 none +Ethernet29 204 eth-0-30 29 25000 none +Ethernet30 208 eth-0-31 30 25000 none +Ethernet31 212 eth-0-32 31 25000 none +Ethernet32 216 eth-0-33 32 25000 none +Ethernet33 220 eth-0-34 33 25000 none +Ethernet34 224 eth-0-35 34 25000 none +Ethernet35 228 eth-0-36 35 25000 none +Ethernet36 160 eth-0-37 36 25000 none +Ethernet37 164 eth-0-38 37 25000 none +Ethernet38 168 eth-0-39 38 25000 none +Ethernet39 172 eth-0-40 39 25000 none +Ethernet40 176 eth-0-41 40 25000 none +Ethernet41 180 eth-0-42 41 25000 none +Ethernet42 184 eth-0-43 42 25000 none +Ethernet43 188 eth-0-44 43 25000 none +Ethernet44 192 eth-0-45 44 25000 none +Ethernet45 193 eth-0-46 45 25000 none +Ethernet46 194 eth-0-47 46 25000 none +Ethernet47 195 eth-0-48 47 25000 none +Ethernet48 120,121,122,123 eth-0-49 48 100000 none +Ethernet49 124,125,126,127 eth-0-50 49 100000 none +Ethernet50 80,81,82,83 eth-0-51 50 100000 none +Ethernet51 84,85,86,87 eth-0-52 51 100000 none +Ethernet52 240,241,242,243 eth-0-53 52 100000 none +Ethernet53 244,245,246,247 eth-0-54 53 100000 none +Ethernet54 280,281,282,283 eth-0-55 54 100000 none +Ethernet55 284,285,286,287 eth-0-56 55 100000 none diff --git a/device/centec/x86_64-centec_v682_48y8c_d-r0/V682-48y8c-d/qos.json.j2 b/device/centec/x86_64-centec_v682_48y8c_d-r0/V682-48y8c-d/qos.json.j2 new file mode 100644 index 0000000000..3e548325ea --- /dev/null +++ b/device/centec/x86_64-centec_v682_48y8c_d-r0/V682-48y8c-d/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/centec/x86_64-centec_v682_48y8c_d-r0/V682-48y8c-d/sai.profile b/device/centec/x86_64-centec_v682_48y8c_d-r0/V682-48y8c-d/sai.profile new file mode 100644 index 0000000000..c04f2aa6f4 --- /dev/null +++ b/device/centec/x86_64-centec_v682_48y8c_d-r0/V682-48y8c-d/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/etc/centec/V682-48y8c-d-chip-profile.txt +SAI_HW_PORT_PROFILE_ID_CONFIG_FILE=/etc/centec/V682-48y8c-d-datapath.txt diff --git a/device/centec/x86_64-centec_v682_48y8c_d-r0/default_sku b/device/centec/x86_64-centec_v682_48y8c_d-r0/default_sku new file mode 100644 index 0000000000..9b70952dab --- /dev/null +++ b/device/centec/x86_64-centec_v682_48y8c_d-r0/default_sku @@ -0,0 +1 @@ +V682-48y8c-d l2 diff --git a/device/centec/x86_64-centec_v682_48y8c_d-r0/installer.conf b/device/centec/x86_64-centec_v682_48y8c_d-r0/installer.conf new file mode 100644 index 0000000000..e69de29bb2 diff --git a/device/centec/x86_64-centec_v682_48y8c_d-r0/platform_components.json b/device/centec/x86_64-centec_v682_48y8c_d-r0/platform_components.json new file mode 100644 index 0000000000..e2525c95ae --- /dev/null +++ b/device/centec/x86_64-centec_v682_48y8c_d-r0/platform_components.json @@ -0,0 +1,8 @@ +{ + "chassis": { + "V682-48Y8C-D": { + "component": { + } + } + } +} diff --git a/device/centec/x86_64-centec_v682_48y8c_d-r0/platform_reboot b/device/centec/x86_64-centec_v682_48y8c_d-r0/platform_reboot new file mode 100755 index 0000000000..89e521978c --- /dev/null +++ b/device/centec/x86_64-centec_v682_48y8c_d-r0/platform_reboot @@ -0,0 +1,24 @@ +#!/usr/bin/python2 + +import os +import sys + +susi4_lib = '/usr/local/lib/python2.7/dist-packages' +if not susi4_lib in os.environ.setdefault('LD_LIBRARY_PATH', ''): + os.environ['LD_LIBRARY_PATH'] += (':' + susi4_lib) + try: + os.execv(sys.argv[0], sys.argv) + except Exception as e: + sys.exit('failed to execute under modified environment!') + +from _Susi4 import * + +def main(): + SusiLibInitialize() + + SusiI2CWriteTransfer(0, 0x36 * 2, 0x23, '\x01') + + SusiLibUninitialize() + +if __name__ == '__main__': + main() diff --git a/device/centec/x86_64-centec_v682_48y8c_d-r0/plugins/led_control.py b/device/centec/x86_64-centec_v682_48y8c_d-r0/plugins/led_control.py new file mode 100644 index 0000000000..5d23afb0ea --- /dev/null +++ b/device/centec/x86_64-centec_v682_48y8c_d-r0/plugins/led_control.py @@ -0,0 +1,213 @@ +#!/usr/bin/env python +# +# led_control.py +# +# Platform-specific LED control functionality for SONiC +# + +try: + import os + import re + import syslog + import collections + from sonic_led.led_control_base import LedControlBase + from sonic_py_common import device_info +except ImportError as e: + raise ImportError(str(e) + " - required module not found") + +USR_SHARE_SONIC_PATH = "/usr/share/sonic" +HOST_DEVICE_PATH = USR_SHARE_SONIC_PATH + "/device" +CONTAINER_PLATFORM_PATH = USR_SHARE_SONIC_PATH + "/platform" + +def DBG_PRINT(str): + syslog.openlog("centec-led") + syslog.syslog(syslog.LOG_INFO, str) + syslog.closelog() + +class LedControl(LedControlBase): + """Platform specific LED control class""" + + # Constructor + def __init__(self): + + self.mac_to_led = { + 32 : 0, + 33 : 1, + 34 : 2, + 35 : 3, + 0 : 4, + 4 : 5, + 8 : 6, + 12 : 7, + 16 : 8, + 20 : 9, + 24 : 10, + 28 : 11, + 40 : 12, + 44 : 13, + 48 : 14, + 52 : 15, + 56 : 16, + 60 : 17, + 64 : 18, + 68 : 19, + 72 : 20, + 73 : 21, + 74 : 22, + 75 : 23, + 232: 24, + 233: 25, + 234: 26, + 235: 27, + 200: 28, + 204: 29, + 208: 30, + 212: 31, + 216: 32, + 220: 33, + 224: 34, + 228: 35, + 160: 36, + 164: 37, + 168: 38, + 172: 39, + 176: 40, + 180: 41, + 184: 42, + 188: 43, + 192: 44, + 193: 45, + 194: 46, + 195: 47, + 120: 48, + 121: -1, + 122: -1, + 123: -1, + 124: 49, + 125: -1, + 126: -1, + 127: -1, + 80 : 50, + 81 : -1, + 82 : -1, + 83 : -1, + 84 : 51, + 85 : -1, + 86 : -1, + 87 : -1, + 240: 52, + 241: -1, + 242: -1, + 243: -1, + 244: 53, + 245: -1, + 246: -1, + 247: -1, + 280: 54, + 281: -1, + 282: -1, + 283: -1, + 284: 55, + 285: -1, + 286: -1, + 287: -1, + } + + if os.path.isdir(CONTAINER_PLATFORM_PATH): + platform_path = CONTAINER_PLATFORM_PATH + else: + platform = device_info.get_platform() + if platform is None: + raise + platform_path = os.path.join(HOST_DEVICE_PATH, platform) + + port_config_file = "/".join([platform_path, "V682-48y8c-d", "port_config.ini"]) + try: + f = open(port_config_file) + except: + raise + for line in f: + line.strip() + if re.search('^#', line) is not None: + Port_cfg = collections.namedtuple('Port_cfg', line.split()[1:]) + break + f.close() + f = open(port_config_file) + self._port_cfgs = [Port_cfg(*tuple((line.strip().split()))) + for line in f if re.search('^#', line) is None] + f.close() + + self.LED_MODE_UP = [11, 11] + self.LED_MODE_DOWN = [7, 7] + self.f_led = "/sys/class/leds/{}/brightness" + self._initDefaultConfig() + + # Helper method to map SONiC port name to index + def _port_name_to_index(self, port_name): + for port_cfg in self._port_cfgs: + if port_name == port_cfg.name: + macs = [int(x) for x in (port_cfg.lanes.split(','))] + led = self.mac_to_led[min(macs)] + if led < 0: + return None + return led + return None + + def _port_state_to_mode(self, port_idx, state): + if state == "up": + return self.LED_MODE_UP[1] if port_idx >= 48 else self.LED_MODE_UP[0] + else: + return self.LED_MODE_DOWN[1] if port_idx >= 48 else self.LED_MODE_DOWN[0] + + def _port_led_mode_update(self, port_idx, ledMode): + with open(self.f_led.format("port{}".format(port_idx)), 'w') as led_file: + led_file.write(str(ledMode)) + + def _initSystemLed(self): + try: + with open(self.f_led.format("system"), 'w') as led_file: + led_file.write("1") + DBG_PRINT("init system led to normal") + with open(self.f_led.format("idn"), 'w') as led_file: + led_file.write("1") + DBG_PRINT("init idn led to off") + except IOError as e: + DBG_PRINT(str(e)) + + def _initPanelLed(self): + with open(self.f_led.format("port1"), 'r') as led_file: + shouldInit = (int(led_file.read()) == 0) + + if shouldInit == True: + for port_cfg in self._port_cfgs: + macs = [int(x) for x in (port_cfg.lanes.split(','))] + led = self.mac_to_led[min(macs)] + if led < 0: + continue + defmode = self._port_state_to_mode(led, "down") + with open(self.f_led.format("port{}".format(led)), 'w') as led_file: + led_file.write(str(defmode)) + DBG_PRINT("init port{} led to mode={}".format(led, defmode)) + + def _initDefaultConfig(self): + DBG_PRINT("start init led") + + self._initSystemLed() + self._initPanelLed() + + DBG_PRINT("init led done") + + # Concrete implementation of port_link_state_change() method + def port_link_state_change(self, portname, state): + port_idx = self._port_name_to_index(portname) + if port_idx is None: + return + ledMode = self._port_state_to_mode(port_idx, state) + with open(self.f_led.format("port{}".format(port_idx)), 'r') as led_file: + saveMode = int(led_file.read()) + + if ledMode == saveMode: + return + + self._port_led_mode_update(port_idx, ledMode) + DBG_PRINT("update {} led mode from {} to {}".format(portname, saveMode, ledMode)) diff --git a/device/centec/x86_64-centec_v682_48y8c_d-r0/plugins/sfputil.py b/device/centec/x86_64-centec_v682_48y8c_d-r0/plugins/sfputil.py new file mode 100644 index 0000000000..cc1bbbd285 --- /dev/null +++ b/device/centec/x86_64-centec_v682_48y8c_d-r0/plugins/sfputil.py @@ -0,0 +1,248 @@ +#!/usr/bin/env python + +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import os + import re + import time + import collections + from sonic_sfp.sfputilbase import SfpUtilBase + from sonic_py_common import device_info +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + +SFP_STATUS_INSERTED = '1' +SFP_STATUS_REMOVED = '0' +USR_SHARE_SONIC_PATH = "/usr/share/sonic" +HOST_DEVICE_PATH = USR_SHARE_SONIC_PATH + "/device" +CONTAINER_PLATFORM_PATH = USR_SHARE_SONIC_PATH + "/platform" + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + def __init__(self): + self.mac_to_sfp = { + 32 : 0, + 33 : 1, + 34 : 2, + 35 : 3, + 0 : 4, + 4 : 5, + 8 : 6, + 12 : 7, + 16 : 8, + 20 : 9, + 24 : 10, + 28 : 11, + 40 : 12, + 44 : 13, + 48 : 14, + 52 : 15, + 56 : 16, + 60 : 17, + 64 : 18, + 68 : 19, + 72 : 20, + 73 : 21, + 74 : 22, + 75 : 23, + 232: 24, + 233: 25, + 234: 26, + 235: 27, + 200: 28, + 204: 29, + 208: 30, + 212: 31, + 216: 32, + 220: 33, + 224: 34, + 228: 35, + 160: 36, + 164: 37, + 168: 38, + 172: 39, + 176: 40, + 180: 41, + 184: 42, + 188: 43, + 192: 44, + 193: 45, + 194: 46, + 195: 47, + 120: 48, + 121: 48, + 122: 48, + 123: 48, + 124: 49, + 125: 49, + 126: 49, + 127: 49, + 80 : 50, + 81 : 50, + 82 : 50, + 83 : 50, + 84 : 51, + 85 : 51, + 86 : 51, + 87 : 51, + 240: 52, + 241: 52, + 242: 52, + 243: 52, + 244: 53, + 245: 53, + 246: 53, + 247: 53, + 280: 54, + 281: 54, + 282: 54, + 283: 54, + 284: 55, + 285: 55, + 286: 55, + 287: 55, + } + self.logical = [] + self.physical_to_logical = {} + self.logical_to_physical = {} + self.logical_to_asic = {} + self.data = {'valid':0, 'last':0} + self.f_sfp_present = "/sys/class/sfp/sfp{}/sfp_presence" + self.f_sfp_enable = "/sys/class/sfp/sfp{}/sfp_enable" + + if os.path.isdir(CONTAINER_PLATFORM_PATH): + platform_path = CONTAINER_PLATFORM_PATH + else: + platform = device_info.get_platform() + if platform is None: + raise + platform_path = os.path.join(HOST_DEVICE_PATH, platform) + + port_config_file = "/".join([platform_path, "V682-48y8c-d", "port_config.ini"]) + try: + f = open(port_config_file) + except: + raise + for line in f: + line.strip() + if re.search('^#', line) is not None: + Port_cfg = collections.namedtuple('Port_cfg', line.split()[1:]) + break + f.close() + f = open(port_config_file) + self._port_cfgs = [Port_cfg(*tuple((line.strip().split()))) + for line in f if re.search('^#', line) is None] + f.close() + + self.PORT_START = 256 + self.PORT_END = 0 + for port_cfg in self._port_cfgs: + if int(port_cfg.index) <= self.PORT_START: + self.PORT_START = int(port_cfg.index) + elif int(port_cfg.index) >= self.PORT_END: + self.PORT_END = int(port_cfg.index) + + self.eeprom_mapping = {} + self.presence = {} + for port_cfg in self._port_cfgs: + sfp_idx = self.mac_to_sfp[int(port_cfg.lanes.split(',')[0])] + if sfp_idx >= 0: + self.eeprom_mapping[int(port_cfg.index)] = "/sys/class/sfp/sfp{}/sfp_eeprom".format(sfp_idx) + self.logical.append(port_cfg.name) + else: + self.eeprom_mapping[int(port_cfg.index)] = None + self.presence[int(port_cfg.index)] = False + + SfpUtilBase.__init__(self) + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def sfp_base(self): + return self.PORT_START + + @property + def qsfp_ports(self): + start = 256 + end = 0 + for port_cfg in self._port_cfgs: + sfp_idx = self.mac_to_sfp[int(port_cfg.lanes.split(',')[0])] + if sfp_idx >= 48: + if int(port_cfg.index) <= start: + start = int(port_cfg.index) + elif int(port_cfg.index) >= end: + end = int(port_cfg.index) + return range(start, end + 1) + + @property + def port_to_eeprom_mapping(self): + return self.eeprom_mapping + + def is_logical_port(self, port_name): + return True + + def get_presence(self, port_num): + for port_cfg in self._port_cfgs: + if int(port_cfg.index) == port_num: + sfp_idx = self.mac_to_sfp[int(port_cfg.lanes.split(',')[0])] + if sfp_idx >= 0: + try: + with open(self.f_sfp_present.format(sfp_idx), 'r') as sfp_file: + return 1 == int(sfp_file.read()) + except IOError as e: + DBG_PRINT(str(e)) + return False + + def get_low_power_mode(self, port_num): + return False + + def set_low_power_mode(self, port_num, lpmode): + return False + + def reset(self, port_num): + return False + + def read_porttab_mappings(self, porttabfile, asic_inst = 0): + for port_cfg in self._port_cfgs: + self.logical_to_physical[port_cfg.name] = [int(port_cfg.index)] + self.logical_to_asic[port_cfg.name] = 0 + self.physical_to_logical[int(port_cfg.index)] = [port_cfg.name] + + def get_transceiver_change_event(self, timeout=2000): + now = time.time() + port_dict = {} + + if timeout < 1000: + timeout = 1000 + timeout = (timeout) / float(1000) # Convert to secs + + if now < (self.data['last'] + timeout) and self.data['valid']: + return True, {} + + for port_cfg in self._port_cfgs: + presence = self.get_presence(int(port_cfg.index)) + if presence != self.presence[int(port_cfg.index)]: + self.presence[int(port_cfg.index)] = presence + if presence: + port_dict[int(port_cfg.index)] = SFP_STATUS_INSERTED + else: + port_dict[int(port_cfg.index)] = SFP_STATUS_REMOVED + + if bool(port_dict): + self.data['last'] = now + self.data['valid'] = 1 + return True, port_dict + else: + time.sleep(0.5) + return True, {} diff --git a/device/centec/x86_64-centec_v682_48y8c_d-r0/pmon_daemon_control.json b/device/centec/x86_64-centec_v682_48y8c_d-r0/pmon_daemon_control.json new file mode 100644 index 0000000000..44a5ed9bb0 --- /dev/null +++ b/device/centec/x86_64-centec_v682_48y8c_d-r0/pmon_daemon_control.json @@ -0,0 +1,7 @@ +{ + "skip_fancontrol": true, + "skip_psud": true, + "skip_pcied": true, + "skip_thermalctld": true, + "skip_syseepromd": true +} diff --git a/platform/centec/one-image.mk b/platform/centec/one-image.mk index a92c970788..da129addb2 100644 --- a/platform/centec/one-image.mk +++ b/platform/centec/one-image.mk @@ -7,6 +7,9 @@ $(SONIC_ONE_IMAGE)_INSTALLS = $(SYSTEMD_SONIC_GENERATOR) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(CENTEC_E582_48X6Q_PLATFORM_MODULE) \ $(CENTEC_E582_48X2Q4Z_PLATFORM_MODULE) \ $(EMBEDWAY_ES6220_PLATFORM_MODULE) + +$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(CENTEC_V682_48Y8C_D_PLATFORM_MODULE) + ifeq ($(INSTALL_DEBUG_TOOLS),y) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES) $(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES)) diff --git a/platform/centec/platform-modules-centec-v682.mk b/platform/centec/platform-modules-centec-v682.mk new file mode 100644 index 0000000000..1736279fdc --- /dev/null +++ b/platform/centec/platform-modules-centec-v682.mk @@ -0,0 +1,14 @@ +# Centec V682-48Y8C-D Platform modules + + +CENTEC_V682_48Y8C_D_PLATFORM_MODULE_VERSION =1.0 + +export CENTEC_V682_48Y8C_D_PLATFORM_MODULE_VERSION + +CENTEC_V682_48Y8C_D_PLATFORM_MODULE = platform-modules-v682-48y8c-d_$(CENTEC_V682_48Y8C_D_PLATFORM_MODULE_VERSION)_amd64.deb + +$(CENTEC_V682_48Y8C_D_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-v682 +$(CENTEC_V682_48Y8C_D_PLATFORM_MODULE)_PLATFORM = x86_64-centec_v682_48y8c_d-r0 +$(CENTEC_V682_48Y8C_D_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +SONIC_STRETCH_DEBS += $(CENTEC_V682_48Y8C_D_PLATFORM_MODULE) +SONIC_DPKG_DEBS += $(CENTEC_V682_48Y8C_D_PLATFORM_MODULE) diff --git a/platform/centec/rules.mk b/platform/centec/rules.mk index 182248ec1a..6c75897e8b 100644 --- a/platform/centec/rules.mk +++ b/platform/centec/rules.mk @@ -1,5 +1,6 @@ include $(PLATFORM_PATH)/platform-modules-centec-e582.mk include $(PLATFORM_PATH)/platform-modules-embedway.mk +include $(PLATFORM_PATH)/platform-modules-centec-v682.mk include $(PLATFORM_PATH)/sdk.mk include $(PLATFORM_PATH)/docker-syncd-centec.mk include $(PLATFORM_PATH)/docker-syncd-centec-rpc.mk diff --git a/platform/centec/sdk.mk b/platform/centec/sdk.mk index 588b2b2441..ead6de87dd 100644 --- a/platform/centec/sdk.mk +++ b/platform/centec/sdk.mk @@ -1,6 +1,6 @@ # Centec SAI -CENTEC_SAI = libsai_1.6.3-1_amd64.deb -$(CENTEC_SAI)_URL = https://github.com/CentecNetworks/sonic-binaries/raw/master/amd64/$(CENTEC_SAI) +CENTEC_SAI = libsai_1.8.1-0_amd64.deb +$(CENTEC_SAI)_URL = https://github.com/CentecNetworks/sonic-binaries/raw/master/amd64/sai/$(CENTEC_SAI) $(eval $(call add_conflict_package,$(CENTEC_SAI),$(LIBSAIVS_DEV))) SONIC_ONLINE_DEBS += $(CENTEC_SAI) diff --git a/platform/centec/sonic-platform-modules-e582/debian/rules b/platform/centec/sonic-platform-modules-e582/debian/rules index b726f62c8c..45fd499e24 100755 --- a/platform/centec/sonic-platform-modules-e582/debian/rules +++ b/platform/centec/sonic-platform-modules-e582/debian/rules @@ -14,7 +14,9 @@ override_dh_auto_build: (for mod in $(MODULE_DIRS); do \ make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ done) - make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/../centec-dal + rm $(MOD_SRC_DIR)/centec-dal -rf + cp $(MOD_SRC_DIR)/../centec-dal $(MOD_SRC_DIR)/centec-dal -rf + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/centec-dal override_dh_auto_install: (for mod in $(MODULE_DIRS); do \ @@ -22,7 +24,7 @@ override_dh_auto_install: $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ cp -f $(MOD_SRC_DIR)/$${mod}/modules/*.ko \ debian/platform-modules-e582-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ - cp -f $(MOD_SRC_DIR)/../centec-dal/*.ko debian/platform-modules-e582-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp -f $(MOD_SRC_DIR)/centec-dal/*.ko debian/platform-modules-e582-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ done) override_dh_usrlocal: @@ -34,6 +36,7 @@ override_dh_clean: rm -rf $(MOD_SRC_DIR)/$${mod}/modules/*.ko; \ rm -rf debian/platform-modules-e582-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR)/*.ko; \ done) - make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/../centec-dal clean; \ - rm -rf $(MOD_SRC_DIR)/../centec-dal/*.ko + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/centec-dal clean; \ + rm -rf $(MOD_SRC_DIR)/centec-dal/*.ko; \ + rm $(MOD_SRC_DIR)/centec-dal -rf diff --git a/platform/centec/sonic-platform-modules-embedway/debian/rules b/platform/centec/sonic-platform-modules-embedway/debian/rules index 250c0861e1..9ac9db1093 100755 --- a/platform/centec/sonic-platform-modules-embedway/debian/rules +++ b/platform/centec/sonic-platform-modules-embedway/debian/rules @@ -10,16 +10,19 @@ MOD_SRC_DIR:= $(shell pwd) dh $@ override_dh_auto_build: - make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/../centec-dal + rm $(MOD_SRC_DIR)/centec-dal -rf + cp $(MOD_SRC_DIR)/../centec-dal $(MOD_SRC_DIR)/centec-dal -rf + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/centec-dal override_dh_auto_install: dh_installdirs -pplatform-modules-embedway-es6220 \ $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ - cp -f $(MOD_SRC_DIR)/../centec-dal/*.ko debian/platform-modules-embedway-es6220/$(KERNEL_SRC)/$(INSTALL_MOD_DIR) + cp -f $(MOD_SRC_DIR)/centec-dal/*.ko debian/platform-modules-embedway-es6220/$(KERNEL_SRC)/$(INSTALL_MOD_DIR) override_dh_usrlocal: override_dh_clean: dh_clean - make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/../centec-dal clean; \ - rm -rf $(MOD_SRC_DIR)/../centec-dal/*.ko + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/centec-dal clean; \ + rm -rf $(MOD_SRC_DIR)/centec-dal/*.ko; \ + rm $(MOD_SRC_DIR)/centec-dal/ -rf diff --git a/platform/centec/sonic-platform-modules-v682/48y8c-d/modules/Makefile b/platform/centec/sonic-platform-modules-v682/48y8c-d/modules/Makefile new file mode 100644 index 0000000000..0fa3cfba90 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48y8c-d/modules/Makefile @@ -0,0 +1 @@ +obj-m := centec_v682_48y8c_d_platform.o diff --git a/platform/centec/sonic-platform-modules-v682/48y8c-d/modules/centec_v682_48y8c_d_platform.c b/platform/centec/sonic-platform-modules-v682/48y8c-d/modules/centec_v682_48y8c_d_platform.c new file mode 100644 index 0000000000..f909e8ac9d --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48y8c-d/modules/centec_v682_48y8c_d_platform.c @@ -0,0 +1,404 @@ +#include +#include +#include +#include +#include +#include + +#define SEP(XXX) 1 +#define IS_INVALID_PTR(_PTR_) ((_PTR_ == NULL) || IS_ERR(_PTR_)) +#define IS_VALID_PTR(_PTR_) (!IS_INVALID_PTR(_PTR_)) + +#if SEP("defines") +#define SFP_NUM 48 +#define QSFP_NUM 8 +#define PORT_NUM (SFP_NUM + QSFP_NUM) +#endif + +#if SEP("drivers:leds") +extern void v682_48y8c_d_led_port_set(struct led_classdev *led_cdev, enum led_brightness set_value); +extern enum led_brightness v682_48y8c_d_led_port_get(struct led_classdev *led_cdev); + +static struct led_classdev led_dev_port[PORT_NUM] = { +{ .name = "port0", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port1", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port2", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port3", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port4", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port5", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port6", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port7", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port8", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port9", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port10", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port11", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port12", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port13", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port14", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port15", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port16", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port17", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port18", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port19", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port20", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port21", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port22", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port23", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port24", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port25", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port26", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port27", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port28", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port29", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port30", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port31", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port32", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port33", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port34", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port35", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port36", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port37", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port38", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port39", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port40", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port41", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port42", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port43", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port44", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port45", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port46", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port47", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port48", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port49", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port50", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port51", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port52", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port53", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port54", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +{ .name = "port55", .brightness_set = v682_48y8c_d_led_port_set, .brightness_get = v682_48y8c_d_led_port_get,}, +}; +static unsigned char port_led_mode[PORT_NUM] = {0}; + +void v682_48y8c_d_led_port_set(struct led_classdev *led_cdev, enum led_brightness set_value) +{ + int portNum = 0; + + sscanf(led_cdev->name, "port%d", &portNum); + + port_led_mode[portNum] = set_value; + + return; +} + +enum led_brightness v682_48y8c_d_led_port_get(struct led_classdev *led_cdev) +{ + int portNum = 0; + + sscanf(led_cdev->name, "port%d", &portNum); + + return port_led_mode[portNum]; +} + +static int v682_48y8c_d_init_led(void) +{ + int ret = 0; + int i = 0; + + for (i = 0; i < PORT_NUM; i++) + { + ret = led_classdev_register(NULL, &(led_dev_port[i])); + if (ret != 0) + { + printk(KERN_CRIT "create v682_48y8c_d led_dev_port%d device failed\n", i); + continue; + } + } + + return ret; +} + +static int v682_48y8c_d_exit_led(void) +{ + int i = 0; + + for (i = 0; i < PORT_NUM; i++) + { + led_classdev_unregister(&(led_dev_port[i])); + } + + return 0; +} +#endif + +#if SEP("drivers:sfp") +#define MAX_SFP_EEPROM_DATA_LEN 256 +#define MAX_SFP_EEPROM_NUM 3 +struct sfp_info_t { + char eeprom[MAX_SFP_EEPROM_NUM][MAX_SFP_EEPROM_DATA_LEN + 1]; + unsigned short data_len[MAX_SFP_EEPROM_NUM]; + int presence; + int enable; + spinlock_t lock; +}; +static struct class *sfp_class = NULL; +static struct device *sfp_dev[SFP_NUM+QSFP_NUM + 1] = {NULL}; +static struct sfp_info_t sfp_info[SFP_NUM+QSFP_NUM + 1]; + +static ssize_t v682_48y8c_d_sfp_read_presence(struct device *dev, struct device_attribute *attr, char *buf) +{ + int portNum = 0; + const char *name = dev_name(dev); + unsigned long flags = 0; + int presence = 0; + + sscanf(name, "sfp%d", &portNum); + + if ((portNum < 0) || (portNum >= SFP_NUM + QSFP_NUM)) + { + printk(KERN_CRIT "sfp read presence, invalid port number!\n"); + buf[0] = '\0'; + return 0; + } + + spin_lock_irqsave(&(sfp_info[portNum].lock), flags); + presence = sfp_info[portNum].presence; + spin_unlock_irqrestore(&(sfp_info[portNum].lock), flags); + return sprintf(buf, "%d\n", presence); +} + +static ssize_t v682_48y8c_d_sfp_write_presence(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + int portNum = 0; + const char *name = dev_name(dev); + unsigned long flags = 0; + int presence = simple_strtol(buf, NULL, 10); + + sscanf(name, "sfp%d", &portNum); + + if ((portNum < 0) || (portNum >= SFP_NUM + QSFP_NUM)) + { + printk(KERN_CRIT "sfp read presence, invalid port number!\n"); + return size; + } + + spin_lock_irqsave(&(sfp_info[portNum].lock), flags); + sfp_info[portNum].presence = presence; + spin_unlock_irqrestore(&(sfp_info[portNum].lock), flags); + + return size; +} + +static ssize_t v682_48y8c_d_sfp_read_enable(struct device *dev, struct device_attribute *attr, char *buf) +{ + int portNum = 0; + const char *name = dev_name(dev); + unsigned long flags = 0; + int enable = 0; + + sscanf(name, "sfp%d", &portNum); + + if ((portNum < 0) || (portNum >= SFP_NUM + QSFP_NUM)) + { + printk(KERN_CRIT "sfp read enable, invalid port number!\n"); + buf[0] = '\0'; + return 0; + } + + spin_lock_irqsave(&(sfp_info[portNum].lock), flags); + enable = sfp_info[portNum].enable; + spin_unlock_irqrestore(&(sfp_info[portNum].lock), flags); + return sprintf(buf, "%d\n", enable); +} + +static ssize_t v682_48y8c_d_sfp_write_enable(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + int portNum = 0; + const char *name = dev_name(dev); + unsigned long flags = 0; + int enable = simple_strtol(buf, NULL, 10); + + sscanf(name, "sfp%d", &portNum); + + if ((portNum < 0) || (portNum >= SFP_NUM + QSFP_NUM)) + { + printk(KERN_CRIT "sfp read enable, invalid port number!\n"); + return size; + } + + spin_lock_irqsave(&(sfp_info[portNum].lock), flags); + sfp_info[portNum].enable = enable; + spin_unlock_irqrestore(&(sfp_info[portNum].lock), flags); + + return size; +} + +static ssize_t v682_48y8c_d_sfp_read_eeprom(struct device *dev, struct device_attribute *attr, char *buf) +{ + int portNum = 0; + const char *name = dev_name(dev); + unsigned long flags = 0; + size_t size = 0; + + sscanf(name, "sfp%d", &portNum); + + if ((portNum < 0) || (portNum >= SFP_NUM + QSFP_NUM)) + { + printk(KERN_CRIT "sfp read eeprom, invalid port number!\n"); + buf[0] = '\0'; + return 0; + } + + spin_lock_irqsave(&(sfp_info[portNum].lock), flags); + memcpy(buf, sfp_info[portNum].eeprom[0], sfp_info[portNum].data_len[0]); + size = sfp_info[portNum].data_len[0]; + spin_unlock_irqrestore(&(sfp_info[portNum].lock), flags); + + return size; +} + +static ssize_t v682_48y8c_d_sfp_write_eeprom(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + int portNum = 0; + const char *name = dev_name(dev); + unsigned long flags = 0; + + sscanf(name, "sfp%d", &portNum); + + if ((portNum < 0) || (portNum >= SFP_NUM + QSFP_NUM)) + { + printk(KERN_CRIT "sfp write eeprom, invalid port number!\n"); + return size; + } + + spin_lock_irqsave(&(sfp_info[portNum].lock), flags); + memcpy(sfp_info[portNum].eeprom[0], buf, size); + sfp_info[portNum].data_len[0] = size; + spin_unlock_irqrestore(&(sfp_info[portNum].lock), flags); + + return size; +} + +static DEVICE_ATTR(sfp_presence, S_IRUGO|S_IWUSR, v682_48y8c_d_sfp_read_presence, v682_48y8c_d_sfp_write_presence); +static DEVICE_ATTR(sfp_enable, S_IRUGO|S_IWUSR, v682_48y8c_d_sfp_read_enable, v682_48y8c_d_sfp_write_enable); +static DEVICE_ATTR(sfp_eeprom, S_IRUGO|S_IWUSR, v682_48y8c_d_sfp_read_eeprom, v682_48y8c_d_sfp_write_eeprom); + +static int v682_48y8c_d_init_sfp(void) +{ + int ret = 0; + int i = 0; + + sfp_class = class_create(THIS_MODULE, "sfp"); + if (IS_INVALID_PTR(sfp_class)) + { + sfp_class = NULL; + printk(KERN_CRIT "create v682_48y8c_d class sfp failed\n"); + return -1; + } + + for (i = 0; i < SFP_NUM + QSFP_NUM; i++) + { + memset(&(sfp_info[i].eeprom), 0, sizeof(sfp_info[i].eeprom)); + memset(&(sfp_info[i].data_len), 0, sizeof(sfp_info[i].data_len)); + spin_lock_init(&(sfp_info[i].lock)); + + sfp_dev[i] = device_create(sfp_class, NULL, MKDEV(223, i), NULL, "sfp%d", i); + if (IS_INVALID_PTR(sfp_dev[i])) + { + sfp_dev[i] = NULL; + printk(KERN_CRIT "create v682_48y8c_d sfp[%d] device failed\n", i); + continue; + } + + ret = device_create_file(sfp_dev[i], &dev_attr_sfp_presence); + if (ret != 0) + { + printk(KERN_CRIT "create v682_48y8c_d sfp[%d] device attr:presence failed\n", i); + continue; + } + + ret = device_create_file(sfp_dev[i], &dev_attr_sfp_enable); + if (ret != 0) + { + printk(KERN_CRIT "create v682_48y8c_d sfp[%d] device attr:enable failed\n", i); + continue; + } + + ret = device_create_file(sfp_dev[i], &dev_attr_sfp_eeprom); + if (ret != 0) + { + printk(KERN_CRIT "create v682_48y8c_d sfp[%d] device attr:eeprom failed\n", i); + continue; + } + } + + return ret; +} + +static int v682_48y8c_d_exit_sfp(void) +{ + int i = 0; + + for (i = 0; i < SFP_NUM + QSFP_NUM; i++) + { + if (IS_VALID_PTR(sfp_dev[i])) + { + device_remove_file(sfp_dev[i], &dev_attr_sfp_presence); + device_remove_file(sfp_dev[i], &dev_attr_sfp_enable); + device_remove_file(sfp_dev[i], &dev_attr_sfp_eeprom); + device_destroy(sfp_class, MKDEV(223, i)); + sfp_dev[i] = NULL; + } + } + + if (IS_VALID_PTR(sfp_class)) + { + class_destroy(sfp_class); + sfp_class = NULL; + } + + return 0; +} +#endif + +static int v682_48y8c_d_init(void) +{ + int ret = 0; + int failed = 0; + + printk(KERN_ALERT "init v682_48y8c_d board dirver...\n"); + + ret = v682_48y8c_d_init_led(); + if (ret != 0) + { + failed = 1; + } + + ret = v682_48y8c_d_init_sfp(); + if (ret != 0) + { + failed = 1; + } + + if (failed) + printk(KERN_INFO "init v682_48y8c_d board driver failed\n"); + else + printk(KERN_ALERT "init v682_48y8c_d board dirver...ok\n"); + + return 0; +} + +static void v682_48y8c_d_exit(void) +{ + printk(KERN_INFO "deinit v682_48y8c_d board dirver...\n"); + + v682_48y8c_d_exit_sfp(); + v682_48y8c_d_exit_led(); + + printk(KERN_INFO "deinit v682_48y8c_d board dirver...ok\n"); +} + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_AUTHOR("shil centecNetworks, Inc"); +MODULE_DESCRIPTION("v682-48y8c-d board driver"); +module_init(v682_48y8c_d_init); +module_exit(v682_48y8c_d_exit); diff --git a/platform/centec/sonic-platform-modules-v682/48y8c-d/service/48y8c_d_platform.service b/platform/centec/sonic-platform-modules-v682/48y8c-d/service/48y8c_d_platform.service new file mode 100644 index 0000000000..44098afdd7 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48y8c-d/service/48y8c_d_platform.service @@ -0,0 +1,13 @@ +[Unit] +Description=Centec modules init +After=local-fs.target +Before=syncd.service + +[Service] +Type=oneshot +ExecStart=-/etc/init.d/platform-modules-v682-48y8c-d start +ExecStop=-/etc/init.d/platform-modules-v682-48y8c-d stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/centec/sonic-platform-modules-v682/48y8c-d/service/release.py b/platform/centec/sonic-platform-modules-v682/48y8c-d/service/release.py new file mode 100644 index 0000000000..2c799e6ef3 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48y8c-d/service/release.py @@ -0,0 +1,70 @@ +#!/usr/bin/python2 + +import os +import sys +import time + +susi4_lib = '/usr/local/lib/python2.7/dist-packages/' +if not susi4_lib in os.environ.setdefault('LD_LIBRARY_PATH', ''): + os.environ['LD_LIBRARY_PATH'] += (':' + susi4_lib) + try: + os.execv(sys.argv[0], sys.argv) + except Exception as e: + sys.exit('failed to execute under modified environment!') + +from _Susi4 import * + +def release_board(): + SusiLibInitialize() + + SusiI2CWriteTransfer(0, 0x36 * 2, 0x0e, '\x00') + SusiI2CWriteTransfer(0, 0x36 * 2, 0x0f, '\x00') + SusiI2CWriteTransfer(0, 0x36 * 2, 0x10, '\x00') + SusiI2CWriteTransfer(0, 0x37 * 2, 0x0e, '\x00') + SusiI2CWriteTransfer(0, 0x37 * 2, 0x0f, '\x00') + SusiI2CWriteTransfer(0, 0x37 * 2, 0x10, '\x00') + + SusiI2CWriteTransfer(0, 0x71 * 2, 0x00, '\x04') + SusiI2CWriteTransfer(0, 0x2c * 2, 0x32, '\x7f') + SusiI2CWriteTransfer(0, 0x71 * 2, 0x00, '\x00') + + SusiI2CWriteTransfer(0, 0x71 * 2, 0x00, '\x04') + SusiI2CWriteTransfer(0, 0x2c * 2, 0x33, '\x7f') + SusiI2CWriteTransfer(0, 0x71 * 2, 0x00, '\x00') + + SusiI2CWriteTransfer(0, 0x71 * 2, 0x00, '\x04') + SusiI2CWriteTransfer(0, 0x2c * 2, 0x34, '\x7f') + SusiI2CWriteTransfer(0, 0x71 * 2, 0x00, '\x00') + + SusiI2CWriteTransfer(0, 0x71 * 2, 0x00, '\x04') + SusiI2CWriteTransfer(0, 0x2c * 2, 0x35, '\x7f') + SusiI2CWriteTransfer(0, 0x71 * 2, 0x00, '\x00') + + SusiI2CWriteTransfer(0, 0x71 * 2, 0x00, '\x08') + SusiI2CWriteTransfer(0, 0x2c * 2, 0x32, '\x7f') + SusiI2CWriteTransfer(0, 0x71 * 2, 0x00, '\x00') + + SusiI2CWriteTransfer(0, 0x71 * 2, 0x00, '\x08') + SusiI2CWriteTransfer(0, 0x2c * 2, 0x33, '\x7f') + SusiI2CWriteTransfer(0, 0x71 * 2, 0x00, '\x00') + + SusiI2CWriteTransfer(0, 0x71 * 2, 0x00, '\x08') + SusiI2CWriteTransfer(0, 0x2c * 2, 0x34, '\x7f') + SusiI2CWriteTransfer(0, 0x71 * 2, 0x00, '\x00') + + SusiI2CWriteTransfer(0, 0x71 * 2, 0x00, '\x08') + SusiI2CWriteTransfer(0, 0x2c * 2, 0x35, '\x7f') + SusiI2CWriteTransfer(0, 0x71 * 2, 0x00, '\x00') + + SusiI2CWriteTransfer(0, 0x37 * 2, 0x4, '\x00') + time.sleep(1) + SusiI2CWriteTransfer(0, 0x37 * 2, 0x4, '\x01') + time.sleep(3) + os.system('echo 1 > /sys/bus/pci/devices/0000\:00\:1c.0/remove') + time.sleep(1) + os.system('echo 1 > /sys/bus/pci/rescan') + + SusiLibUninitialize() + +if __name__ == '__main__': + release_board() diff --git a/platform/centec/sonic-platform-modules-v682/48y8c-d/setup.py b/platform/centec/sonic-platform-modules-v682/48y8c-d/setup.py new file mode 100644 index 0000000000..e9260dedc6 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48y8c-d/setup.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +import os +from setuptools import setup +os.listdir + +setup( + name='sonic_platform', + version='1.0', + description='Module to initialize centec v682-48y8c-d platforms', + + packages=['sonic_platform'], + package_dir={'sonic_platform': 'sonic_platform'}, +) + diff --git a/platform/centec/sonic-platform-modules-v682/48y8c-d/sonic_platform/__init__.py b/platform/centec/sonic-platform-modules-v682/48y8c-d/sonic_platform/__init__.py new file mode 100644 index 0000000000..aab1ee3402 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48y8c-d/sonic_platform/__init__.py @@ -0,0 +1,2 @@ +__all__ = ["platform", "chassis", "sfp"] +from . import platform diff --git a/platform/centec/sonic-platform-modules-v682/48y8c-d/sonic_platform/chassis.py b/platform/centec/sonic-platform-modules-v682/48y8c-d/sonic_platform/chassis.py new file mode 100644 index 0000000000..b36a050c91 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48y8c-d/sonic_platform/chassis.py @@ -0,0 +1,181 @@ +#!/usr/bin/env python +# +# Name: chassis.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# + +try: + import os + import re + import collections + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.sfp import Sfp + from sonic_py_common import device_info +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +USR_SHARE_SONIC_PATH = "/usr/share/sonic" +HOST_DEVICE_PATH = USR_SHARE_SONIC_PATH + "/device" +CONTAINER_PLATFORM_PATH = USR_SHARE_SONIC_PATH + "/platform" + +class Chassis(ChassisBase): + + def __init__(self): + ChassisBase.__init__(self) + + if os.path.isdir(CONTAINER_PLATFORM_PATH): + platform_path = CONTAINER_PLATFORM_PATH + else: + platform = device_info.get_platform() + if platform is None: + raise + platform_path = os.path.join(HOST_DEVICE_PATH, platform) + + port_config_file = "/".join([platform_path, "V682-48y8c-d", "port_config.ini"]) + try: + f = open(port_config_file) + except: + raise + for line in f: + line.strip() + if re.search('^#', line) is not None: + Port_cfg = collections.namedtuple('Port_cfg', line.split()[1:]) + break + f.close() + f = open(port_config_file) + _port_cfgs = [Port_cfg(*tuple((line.strip().split()))) + for line in f if re.search('^#', line) is None] + f.close() + + # Initialize SFP + for port_cfg in _port_cfgs: + sfp = Sfp(int(port_cfg.index)) + self._sfp_list.append(sfp) + +############################################## +# Device methods +############################################## + + def get_name(self): + """ + Retrieves the name of the chassis + Returns: + string: The name of the chassis + """ + return self._eeprom.modelstr() + + def get_presence(self): + """ + Retrieves the presence of the chassis + Returns: + bool: True if chassis is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the chassis + Returns: + string: Model/part number of chassis + """ + return self._eeprom.part_number_str() + + def get_serial(self): + """ + Retrieves the serial number of the chassis + Returns: + string: Serial number of chassis + """ + return self._eeprom.serial_number_str() + + def get_status(self): + """ + Retrieves the operational status of the chassis + Returns: + bool: A boolean value, True if chassis is operating properly + False if not + """ + return True + +############################################## +# Chassis methods +############################################## + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + return self._eeprom.base_mac_addr() + + def get_serial_number(self): + """ + Retrieves the hardware serial number for the chassis + + Returns: + A string containing the hardware serial number for this chassis. + """ + return self._eeprom.serial_number_str() + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the chassis + + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. + Ex. { '0x21':'AG9064', '0x22':'V1.0', '0x23':'AG9064-0109867821', + '0x24':'001c0f000fcd0a', '0x25':'02/03/2018 16:22:00', + '0x26':'01', '0x27':'REV01', '0x28':'AG9064-C2358-16G'} + """ + return self._eeprom.system_eeprom_info() + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + return (None, None) + + def get_change_event(self, timeout=2000): + """ + Returns a nested dictionary containing all devices which have + experienced a change at chassis level + + Args: + timeout: Timeout in milliseconds (optional). If timeout == 0, + this method will block until a change is detected. + + Returns: + (bool, dict): + - True if call successful, False if not; + - A nested dictionary where key is a device type, + value is a dictionary with key:value pairs in the + format of {'device_id':'device_event'}, + where device_id is the device ID for this device and + device_event, + status='1' represents device inserted, + status='0' represents device removed. + Ex. {'fan':{'0':'0', '2':'1'}, 'sfp':{'11':'0'}} + indicates that fan 0 has been removed, fan 2 + has been inserted and sfp 11 has been removed. + """ + ret, port_dict = self._sfp_list[0].get_transceiver_change_event(timeout) + ret_dict = {"sfp": port_dict} + return ret, ret_dict + + def get_num_psus(self): + return 0 + + def get_psu(self, psu_index): + return None diff --git a/platform/centec/sonic-platform-modules-v682/48y8c-d/sonic_platform/platform.py b/platform/centec/sonic-platform-modules-v682/48y8c-d/sonic_platform/platform.py new file mode 100644 index 0000000000..358edc6f19 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48y8c-d/sonic_platform/platform.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python +# +# Name: platform.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs for Centec V682-48Y8C-D +# + + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() + diff --git a/platform/centec/sonic-platform-modules-v682/48y8c-d/sonic_platform/sfp.py b/platform/centec/sonic-platform-modules-v682/48y8c-d/sonic_platform/sfp.py new file mode 100644 index 0000000000..4a92fecfa6 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/48y8c-d/sonic_platform/sfp.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python + +from __future__ import print_function + +import imp +import os + +try: + from sonic_platform_base.sfp_base import SfpBase + from sonic_py_common import device_info +except ImportError as e: + raise ImportError("%s - required module not found" % e) + +USR_SHARE_SONIC_PATH = "/usr/share/sonic" +HOST_DEVICE_PATH = USR_SHARE_SONIC_PATH + "/device" +CONTAINER_PLATFORM_PATH = USR_SHARE_SONIC_PATH + "/platform" + +class Sfp(SfpBase): + """ + Platform-specific sfp class + + Unimplemented methods: + - get_model + - get_serial + - get_status + - get_transceiver_info + - get_transceiver_bulk_status + - get_transceiver_threshold_info + - get_reset_status + - get_rx_los + - get_tx_fault + - get_tx_disable_channel + - get_power_override + - get_temperature + - get_voltage + - get_tx_bias + - get_rx_power + - get_tx_power + - tx_disable_channel + - set_power_override + """ + + def __init__(self, index): + self._index = index + + if os.path.isdir(CONTAINER_PLATFORM_PATH): + platform_path = CONTAINER_PLATFORM_PATH + else: + platform = device_info.get_platform() + if platform is None: + return + platform_path = os.path.join(HOST_DEVICE_PATH, platform) + + module_file = "/".join([platform_path, "plugins", "sfputil.py"]) + module = imp.load_source("sfputil", module_file) + sfp_util_class = getattr(module, "SfpUtil") + self._sfputil = sfp_util_class() + + def get_id(self): + return self._index + + def get_name(self): + return "Ethernet{}".format(self._index) + + def get_lpmode(self): + return False + + def set_lpmode(self, lpmode): + return False + + def get_tx_disable(self): + return False + + def tx_disable(self, tx_disable): + return False + + def reset(self): + pass + + def clear_interrupt(self): + return False + + def get_interrupt_file(self): + return None + + def _get_sfputil(self): + return self._sfputil + + def get_presence(self): + return self._get_sfputil().get_presence(self._index) + + def get_transceiver_info(self): + return self._get_sfputil().get_transceiver_info_dict(self._index) + + def get_transceiver_bulk_status(self): + return self._get_sfputil().get_transceiver_dom_info_dict(self._index) + + def get_transceiver_threshold_info(self): + return self._get_sfputil().get_transceiver_dom_threshold_info_dict(self._index) + + def get_transceiver_change_event(self, timeout): + return self._get_sfputil().get_transceiver_change_event(timeout) diff --git a/platform/centec/sonic-platform-modules-v682/LICENSE b/platform/centec/sonic-platform-modules-v682/LICENSE new file mode 100644 index 0000000000..865221641c --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/LICENSE @@ -0,0 +1,15 @@ +Copyright (C) 2020 Centec, Inc + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. diff --git a/platform/centec/sonic-platform-modules-v682/README.md b/platform/centec/sonic-platform-modules-v682/README.md new file mode 100644 index 0000000000..333262027a --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/README.md @@ -0,0 +1 @@ +platform drivers for Centec V682 for the SONiC project diff --git a/platform/centec/sonic-platform-modules-v682/debian/changelog b/platform/centec/sonic-platform-modules-v682/debian/changelog new file mode 100644 index 0000000000..9be0e0dea8 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/debian/changelog @@ -0,0 +1,5 @@ +sonic-centec-platform-modules (1.0) unstable; urgency=low + + * Initial release + + -- shil Mon, 30 Nov 2020 16:14:50 +0800 diff --git a/platform/centec/sonic-platform-modules-v682/debian/compat b/platform/centec/sonic-platform-modules-v682/debian/compat new file mode 100644 index 0000000000..ec635144f6 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/debian/compat @@ -0,0 +1 @@ +9 diff --git a/platform/centec/sonic-platform-modules-v682/debian/control b/platform/centec/sonic-platform-modules-v682/debian/control new file mode 100644 index 0000000000..2c79ea7193 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/debian/control @@ -0,0 +1,11 @@ +Source: sonic-centec-platform-modules +Section: main +Priority: extra +Maintainer: shil +Build-Depends: debhelper (>= 8.0.0), bzip2 +Standards-Version: 3.9.3 + +Package: platform-modules-v682-48y8c-d +Architecture: amd64 +Depends: linux-image-4.19.0-12-2-amd64-unsigned +Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48y8c-d.init b/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48y8c-d.init new file mode 100644 index 0000000000..92ce88465d --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48y8c-d.init @@ -0,0 +1,90 @@ +#!/bin/bash +# This script load/unload centec kernel modules + +### BEGIN INIT INFO +# Provides: platform-modules-v682-48y8c-d +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Load Centec kernel modules +### END INIT INFO + +function install_python_api_package() +{ + device="/usr/share/sonic/device" + platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) + + rv=$(pip2 show sonic-platform > /dev/null 2>/dev/null) + if [ $? -ne 0 ]; then + rv=$(pip2 install $device/$platform/sonic_platform-1.0-py2-none-any.whl) + fi + rv=$(pip3 show sonic-platform > /dev/null 2>/dev/null) + if [ $? -ne 0 ]; then + rv=$(pip3 install $device/$platform/sonic_platform-1.0-py3-none-any.whl) + fi +} + +function load_kernel_modules() +{ + depmod -a + modprobe i2c-dev + modprobe centec_v682_48y8c_d_platform + modprobe dal + modprobe tun + modprobe tap +} + +function remove_kernel_modules() +{ + modprobe -r tap + modprobe -r tun + modprobe -r dal + modprobe -r centec_v682_48y8c_d_platform + modprobe -r i2c-dev +} + +function release_board() +{ + systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target + + chmod a+x /usr/local/lib/python2.7/dist-packages/libSUSI-4.00.so.1 + chmod a+x /usr/local/lib/python2.7/dist-packages/_Susi4.so + chmod a+x /usr/local/lib/python2.7/dist-packages/release.py + /usr/local/lib/python2.7/dist-packages/release.py +} + + +case "$1" in +start) + echo -n "Load Centec kernel modules... " + + release_board + load_kernel_modules + install_python_api_package + + echo "done." + ;; + +stop) + echo -n "Unload Centec kernel modules... " + + remove_kernel_modules + + echo "done." + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/platform-modules-v682-48y8c-d {start|stop}" + exit 1 + ;; +esac + +exit 0 + diff --git a/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48y8c-d.install b/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48y8c-d.install new file mode 100644 index 0000000000..e3f3758b33 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48y8c-d.install @@ -0,0 +1,5 @@ +48y8c-d/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-centec_v682_48y8c_d-r0 +48y8c-d/modules/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/x86_64-centec_v682_48y8c_d-r0 +48y8c-d/service/release.py usr/local/lib/python2.7/dist-packages +48y8c-d/service/_Susi4.so usr/local/lib/python2.7/dist-packages +48y8c-d/service/libSUSI-4.00.so.1 usr/local/lib/python2.7/dist-packages diff --git a/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48y8c-d.postinst b/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48y8c-d.postinst new file mode 100644 index 0000000000..448ad2a10d --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/debian/platform-modules-v682-48y8c-d.postinst @@ -0,0 +1,2 @@ +systemctl enable 48y8c_d_platform.service +systemctl start 48y8c_d_platform.service diff --git a/platform/centec/sonic-platform-modules-v682/debian/rules b/platform/centec/sonic-platform-modules-v682/debian/rules new file mode 100755 index 0000000000..c50356d451 --- /dev/null +++ b/platform/centec/sonic-platform-modules-v682/debian/rules @@ -0,0 +1,100 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. + +include /usr/share/dpkg/pkg-info.mk + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +export INSTALL_MOD_DIR:=extra + +PACKAGE_PRE_NAME := platform-modules-v682 +KVERSION ?= $(shell uname -r) +KERNEL_SRC := /lib/modules/$(KVERSION) +MOD_SRC_DIR:= $(shell pwd) +MODULE_DIRS:= 48y8c-d +MODULE_DIR := modules +SERVICE_DIR := service +CLASSES_DIR := classes +CONF_DIR := conf +KDAL_DIR := centec-dal/ + +%: + dh $@ + +clean: + dh_testdir + dh_testroot + dh_clean + +build: + rm $(MOD_SRC_DIR)/$(KDAL_DIR) -rf + cp ../../centec/centec-dal/ $(MOD_SRC_DIR)/$(KDAL_DIR) -rf + (for mod in $(KDAL_DIR); do \ + make modules -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/; \ + done) + (for mod in $(MODULE_DIRS); do \ + make modules -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ + cd $${mod}; \ + python2.7 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ + python3 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ + cd -; \ + done) + # third party driver for cpu card + (for mod in $(MODULE_DIRS); do \ + rm $(MOD_SRC_DIR)/$${mod}/service/_Susi4.so $(MOD_SRC_DIR)/$${mod}/service/libSUSI-4.00.so.1 -rf; \ + cd $(MOD_SRC_DIR)/$${mod}/service; \ + wget https://github.com/CentecNetworks/sonic-binaries/raw/master/amd64/third_party/advantech/_Susi4.so; \ + wget https://github.com/CentecNetworks/sonic-binaries/raw/master/amd64/third_party/advantech/libSUSI-4.00.so.1; \ + cd -; \ + chmod a+x $(MOD_SRC_DIR)/$${mod}/service/_Susi4.so $(MOD_SRC_DIR)/$${mod}/service/libSUSI-4.00.so.1; \ + done) + +binary: binary-arch binary-indep + # Nothing to do + +binary-arch: + # Nothing to do + +#install: build + #dh_testdir + #dh_testroot + #dh_clean -k + #dh_installdirs + +binary-indep: + dh_testdir + dh_installdirs + + # Custom package commands + (for mod in $(MODULE_DIRS); do \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} lib/systemd/system; \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} etc; \ + cp $(MOD_SRC_DIR)/$${mod}/$(MODULE_DIR)/*.ko debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp $(MOD_SRC_DIR)/$${mod}/$(SERVICE_DIR)/*.service debian/$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system/; \ + cp $(MOD_SRC_DIR)/$(KDAL_DIR)/*.ko debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + done) + rm $(MOD_SRC_DIR)/$(KDAL_DIR) -rf + # Resuming debhelper scripts + dh_testroot + dh_install + dh_installchangelogs + dh_installdocs + dh_systemd_enable + dh_installinit + dh_systemd_start + dh_link + dh_fixperms + dh_compress + dh_strip + dh_installdeb + dh_gencontrol + dh_md5sums + dh_builddeb +.PHONY: build binary binary-arch binary-indep clean