[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 <shil@centecnetworks.com>
This commit is contained in:
LuiSzee 2021-10-27 03:55:24 +08:00 committed by GitHub
parent f01076ea2a
commit 32ad7444f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 1725 additions and 10 deletions

View File

@ -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 %}
}
}
}

View File

@ -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

View File

@ -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

View File

@ -0,0 +1 @@
{%- include 'qos_config.j2' %}

View File

@ -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

View File

@ -0,0 +1 @@
V682-48y8c-d l2

View File

@ -0,0 +1,8 @@
{
"chassis": {
"V682-48Y8C-D": {
"component": {
}
}
}
}

View File

@ -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()

View File

@ -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))

View File

@ -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, {}

View File

@ -0,0 +1,7 @@
{
"skip_fancontrol": true,
"skip_psud": true,
"skip_pcied": true,
"skip_thermalctld": true,
"skip_syseepromd": true
}

View File

@ -7,6 +7,9 @@ $(SONIC_ONE_IMAGE)_INSTALLS = $(SYSTEMD_SONIC_GENERATOR)
$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(CENTEC_E582_48X6Q_PLATFORM_MODULE) \ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(CENTEC_E582_48X6Q_PLATFORM_MODULE) \
$(CENTEC_E582_48X2Q4Z_PLATFORM_MODULE) \ $(CENTEC_E582_48X2Q4Z_PLATFORM_MODULE) \
$(EMBEDWAY_ES6220_PLATFORM_MODULE) $(EMBEDWAY_ES6220_PLATFORM_MODULE)
$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(CENTEC_V682_48Y8C_D_PLATFORM_MODULE)
ifeq ($(INSTALL_DEBUG_TOOLS),y) ifeq ($(INSTALL_DEBUG_TOOLS),y)
$(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES) $(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)) $(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES))

View File

@ -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)

View File

@ -1,5 +1,6 @@
include $(PLATFORM_PATH)/platform-modules-centec-e582.mk include $(PLATFORM_PATH)/platform-modules-centec-e582.mk
include $(PLATFORM_PATH)/platform-modules-embedway.mk include $(PLATFORM_PATH)/platform-modules-embedway.mk
include $(PLATFORM_PATH)/platform-modules-centec-v682.mk
include $(PLATFORM_PATH)/sdk.mk include $(PLATFORM_PATH)/sdk.mk
include $(PLATFORM_PATH)/docker-syncd-centec.mk include $(PLATFORM_PATH)/docker-syncd-centec.mk
include $(PLATFORM_PATH)/docker-syncd-centec-rpc.mk include $(PLATFORM_PATH)/docker-syncd-centec-rpc.mk

View File

@ -1,6 +1,6 @@
# Centec SAI # Centec SAI
CENTEC_SAI = libsai_1.6.3-1_amd64.deb CENTEC_SAI = libsai_1.8.1-0_amd64.deb
$(CENTEC_SAI)_URL = https://github.com/CentecNetworks/sonic-binaries/raw/master/amd64/$(CENTEC_SAI) $(CENTEC_SAI)_URL = https://github.com/CentecNetworks/sonic-binaries/raw/master/amd64/sai/$(CENTEC_SAI)
$(eval $(call add_conflict_package,$(CENTEC_SAI),$(LIBSAIVS_DEV))) $(eval $(call add_conflict_package,$(CENTEC_SAI),$(LIBSAIVS_DEV)))
SONIC_ONLINE_DEBS += $(CENTEC_SAI) SONIC_ONLINE_DEBS += $(CENTEC_SAI)

View File

@ -14,7 +14,9 @@ override_dh_auto_build:
(for mod in $(MODULE_DIRS); do \ (for mod in $(MODULE_DIRS); do \
make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \
done) 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: override_dh_auto_install:
(for mod in $(MODULE_DIRS); do \ (for mod in $(MODULE_DIRS); do \
@ -22,7 +24,7 @@ override_dh_auto_install:
$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \
cp -f $(MOD_SRC_DIR)/$${mod}/modules/*.ko \ cp -f $(MOD_SRC_DIR)/$${mod}/modules/*.ko \
debian/platform-modules-e582-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ 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) done)
override_dh_usrlocal: override_dh_usrlocal:
@ -34,6 +36,7 @@ override_dh_clean:
rm -rf $(MOD_SRC_DIR)/$${mod}/modules/*.ko; \ rm -rf $(MOD_SRC_DIR)/$${mod}/modules/*.ko; \
rm -rf debian/platform-modules-e582-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR)/*.ko; \ rm -rf debian/platform-modules-e582-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR)/*.ko; \
done) done)
make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/../centec-dal clean; \ make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/centec-dal clean; \
rm -rf $(MOD_SRC_DIR)/../centec-dal/*.ko rm -rf $(MOD_SRC_DIR)/centec-dal/*.ko; \
rm $(MOD_SRC_DIR)/centec-dal -rf

View File

@ -10,16 +10,19 @@ MOD_SRC_DIR:= $(shell pwd)
dh $@ dh $@
override_dh_auto_build: 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: override_dh_auto_install:
dh_installdirs -pplatform-modules-embedway-es6220 \ dh_installdirs -pplatform-modules-embedway-es6220 \
$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ $(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_usrlocal:
override_dh_clean: override_dh_clean:
dh_clean dh_clean
make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/../centec-dal clean; \ make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/centec-dal clean; \
rm -rf $(MOD_SRC_DIR)/../centec-dal/*.ko rm -rf $(MOD_SRC_DIR)/centec-dal/*.ko; \
rm $(MOD_SRC_DIR)/centec-dal/ -rf

View File

@ -0,0 +1 @@
obj-m := centec_v682_48y8c_d_platform.o

View File

@ -0,0 +1,404 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/kdev_t.h>
#include <linux/leds.h>
#include <linux/spinlock.h>
#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);

View File

@ -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

View File

@ -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()

View File

@ -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'},
)

View File

@ -0,0 +1,2 @@
__all__ = ["platform", "chassis", "sfp"]
from . import platform

View File

@ -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

View File

@ -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()

View File

@ -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)

View File

@ -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.

View File

@ -0,0 +1 @@
platform drivers for Centec V682 for the SONiC project

View File

@ -0,0 +1,5 @@
sonic-centec-platform-modules (1.0) unstable; urgency=low
* Initial release
-- shil <shil@centecnetworks.com> Mon, 30 Nov 2020 16:14:50 +0800

View File

@ -0,0 +1 @@
9

View File

@ -0,0 +1,11 @@
Source: sonic-centec-platform-modules
Section: main
Priority: extra
Maintainer: shil <shil@centecnetworks.com>
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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,2 @@
systemctl enable 48y8c_d_platform.service
systemctl start 48y8c_d_platform.service

View File

@ -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