From 5d8cbee0c6dbdd518ff62bf066221dc0021533f0 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Wed, 4 Apr 2018 23:42:11 -0700 Subject: [PATCH 001/219] [installer]: Suppress tar xz warning about time stamp in the future, if date is not correctly set (#1562) Signed-off-by: Qi Luo --- installer/x86_64/install.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/installer/x86_64/install.sh b/installer/x86_64/install.sh index 825e4636d0af..949c052acb89 100755 --- a/installer/x86_64/install.sh +++ b/installer/x86_64/install.sh @@ -446,7 +446,11 @@ fi # Decompress the file for the file system directly to the partition unzip -o $ONIE_INSTALLER_PAYLOAD -x "$FILESYSTEM_DOCKERFS" -d $demo_mnt/$image_dir -TAR_EXTRA_OPTION="--numeric-owner" +if [ "$install_env" = "onie" ]; then + TAR_EXTRA_OPTION="--numeric-owner" +else + TAR_EXTRA_OPTION="--numeric-owner --warning=no-timestamp" +fi mkdir -p $demo_mnt/$image_dir/$DOCKERFS_DIR unzip -op $ONIE_INSTALLER_PAYLOAD "$FILESYSTEM_DOCKERFS" | tar xz $TAR_EXTRA_OPTION -f - -C $demo_mnt/$image_dir/$DOCKERFS_DIR From 2c084262c3e3e91963aef45fa02f11c1ceb7ee23 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Fri, 6 Apr 2018 05:55:17 -0700 Subject: [PATCH 002/219] [sonic-platform-common] Update submodule (#1563) - Includes the following commits: - [bcmshell.py] Match extra whitespace before prompt in regex (#3) - add support for qsfp28 eeprom (#2) --- src/sonic-platform-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-common b/src/sonic-platform-common index 0581611b7be5..560b465cb516 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit 0581611b7be5cc52aea2877199785fe72f759a58 +Subproject commit 560b465cb5166d0ad0c56312292bba990a122419 From 6fe95bce89cf9a8023b4dba3fbb979448e68764c Mon Sep 17 00:00:00 2001 From: lguohan Date: Sun, 1 Apr 2018 21:36:43 -0700 Subject: [PATCH 003/219] [baseimage]: bring down eth0 before restart networking (#1555) cfggen generates new eth0 configuration. Need to first clean existing configuration on eth0 before bring up new configuration on eth0. Thus, we need to first bring down eth0 before putting new configuration into /etc/network/ interfaces Signed-off-by: Guohan Lu --- files/image_config/interfaces/interfaces-config.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/files/image_config/interfaces/interfaces-config.sh b/files/image_config/interfaces/interfaces-config.sh index 06174790f04a..75660e713e7f 100755 --- a/files/image_config/interfaces/interfaces-config.sh +++ b/files/image_config/interfaces/interfaces-config.sh @@ -1,5 +1,7 @@ #!/bin/bash +ifdown eth0 + sonic-cfggen -d -t /usr/share/sonic/templates/interfaces.j2 > /etc/network/interfaces [ -f /var/run/dhclient.eth0.pid ] && kill `cat /var/run/dhclient.eth0.pid` && rm -f /var/run/dhclient.eth0.pid From 6da6e07bc73392fb5e3a8816de32036b77dfa151 Mon Sep 17 00:00:00 2001 From: Volodymyr Samotiy Date: Tue, 3 Apr 2018 05:02:48 +0300 Subject: [PATCH 004/219] [mellanox]: Update MLNX SAI pointer (#1557) Signed-off-by: Volodymyr Samotiy --- platform/mellanox/mlnx-sai.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index afb080413f64..23ef8c60458b 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,7 +1,7 @@ # Mellanox SAI MLNX_SAI_VERSION = SAIRel1.11.4-master -MLNX_SAI_REVISION = 6367854b48b73470a6e093f6fbbd45b3341edaba +MLNX_SAI_REVISION = 1a44c29b22e1f36f4856f4aee92ad513c963c2b8 export MLNX_SAI_VERSION MLNX_SAI_REVISION From 5cf05f879a15cf0d8ce48b4e46a461afb6c37b8c Mon Sep 17 00:00:00 2001 From: Taoyu Li Date: Mon, 2 Apr 2018 09:17:47 -0700 Subject: [PATCH 005/219] [minigraph.py] Add support to parse tacacs server information (#1549) * [minigraph.py] Add support to parse tacacs server information --- src/sonic-config-engine/minigraph.py | 11 +- .../tests/simple-sample-graph-metadata.xml | 317 ++++++++++++++++++ src/sonic-config-engine/tests/test_cfggen.py | 17 + 3 files changed, 342 insertions(+), 3 deletions(-) create mode 100644 src/sonic-config-engine/tests/simple-sample-graph-metadata.xml diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 34fcf1bcee25..f989129a439e 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -286,6 +286,7 @@ def parse_meta(meta, hname): syslog_servers = [] dhcp_servers = [] ntp_servers = [] + tacacs_servers = [] mgmt_routes = [] erspan_dst = [] deployment_id = None @@ -296,20 +297,22 @@ def parse_meta(meta, hname): for device_property in properties.findall(str(QName(ns1, "DeviceProperty"))): name = device_property.find(str(QName(ns1, "Name"))).text value = device_property.find(str(QName(ns1, "Value"))).text - value_group = value.split(';') if value and value != "" else [] + value_group = value.strip().split(';') if value and value != "" else [] if name == "DhcpResources": dhcp_servers = value_group elif name == "NtpResources": ntp_servers = value_group elif name == "SyslogResources": syslog_servers = value_group + elif name == "TacacsServer": + tacacs_servers = value_group elif name == "ForcedMgmtRoutes": mgmt_routes = value_group elif name == "ErspanDestinationIpv4": erspan_dst = value_group elif name == "DeploymentId": deployment_id = value - return syslog_servers, dhcp_servers, ntp_servers, mgmt_routes, erspan_dst, deployment_id + return syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id def parse_deviceinfo(meta, hwsku): port_speeds = {} @@ -352,6 +355,7 @@ def parse_xml(filename, platform=None, port_config_file=None): syslog_servers = [] dhcp_servers = [] ntp_servers = [] + tacacs_servers = [] mgmt_routes = [] erspan_dst = [] bgp_peers_with_range = None @@ -377,7 +381,7 @@ def parse_xml(filename, platform=None, port_config_file=None): elif child.tag == str(QName(ns, "UngDec")): (u_neighbors, u_devices, _, _, _, _) = parse_png(child, hostname) elif child.tag == str(QName(ns, "MetadataDeclaration")): - (syslog_servers, dhcp_servers, ntp_servers, mgmt_routes, erspan_dst, deployment_id) = parse_meta(child, hostname) + (syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id) = parse_meta(child, hostname) elif child.tag == str(QName(ns, "DeviceInfos")): (port_speeds, port_descriptions) = parse_deviceinfo(child, hwsku) @@ -433,6 +437,7 @@ def parse_xml(filename, platform=None, port_config_file=None): results['SYSLOG_SERVER'] = dict((item, {}) for item in syslog_servers) results['DHCP_SERVER'] = dict((item, {}) for item in dhcp_servers) results['NTP_SERVER'] = dict((item, {}) for item in ntp_servers) + results['TACPLUS_SERVER'] = dict((item, {'priority': '1', 'tcp_port': '49'}) for item in tacacs_servers) results['ACL_TABLE'] = acls mirror_sessions = {} diff --git a/src/sonic-config-engine/tests/simple-sample-graph-metadata.xml b/src/sonic-config-engine/tests/simple-sample-graph-metadata.xml new file mode 100644 index 000000000000..28044f1c8780 --- /dev/null +++ b/src/sonic-config-engine/tests/simple-sample-graph-metadata.xml @@ -0,0 +1,317 @@ + + + + + + false + switch-t0 + 10.0.0.56 + ARISTA01T1 + 10.0.0.57 + 1 + 180 + 60 + + + switch-t0 + FC00::71 + ARISTA01T1 + FC00::72 + 1 + 180 + 60 + + + false + switch-t0 + 10.0.0.58 + ARISTA02T1 + 10.0.0.59 + 1 + 180 + 60 + + + switch-t0 + FC00::75 + ARISTA02T1 + FC00::76 + 1 + 180 + 60 + + + + + 65100 + switch-t0 + + +
10.0.0.57
+ + + +
+ +
10.0.0.59
+ + + +
+
+ +
+ + 64600 + ARISTA01T1 + + + + 64600 + ARISTA02T1 + + + + 64600 + ARISTA03T1 + + + + 64600 + ARISTA04T1 + + +
+
+ + + + + + HostIP + Loopback0 + + 10.1.0.32/32 + + 10.1.0.32/32 + + + HostIP1 + Loopback0 + + FC00:1::32/128 + + FC00:1::32/128 + + + + + HostIP + eth0 + + 10.0.0.100/24 + + 10.0.0.100/24 + + + + + + + switch-t0 + + + PortChannel01 + fortyGigE0/4 + + + + + + ab1 + fortyGigE0/8 + 192.0.0.1;192.0.0.2 + 1000 + 1000 + 192.168.0.0/27 + + + + + + PortChannel01 + 10.0.0.56/31 + + + + PortChannel01 + FC00::71/126 + + + + fortyGigE0/0 + 10.0.0.58/31 + + + + fortyGigE0/0 + FC00::75/126 + + + + ab1 + 192.168.0.1/27 + + + + + + PortChannel01 + DataAcl + DataPlane + + + SNMP + SNMP_ACL + SNMP + + + + + + + + + + + switch-t0 + Force10-S6000 + + + ARISTA01T1 + Arista + + + ARISTA02T1 + Arista + + + ARISTA03T1 + Arista + + + ARISTA04T1 + Arista + + + + + + + switch-t0 + + + DeploymentId + + 1 + + + ErspanDestinationIpv4 + + 10.0.100.1 + + + NtpResources + + 10.0.10.1;10.0.10.2 + + + + SnmpResources + + 10.0.10.3;10.0.10.4 + + + + SyslogResources + + 10.0.10.5;10.0.10.6; + + + + TacacsServer + + 10.0.10.7;10.0.10.8 + + + + + + + + + true + + + DeviceInterface + + true + true + 1 + fortyGigE0/0 + + false + 0 + 0 + 10000 + + + DeviceInterface + + true + true + 1 + fortyGigE0/4 + + false + 0 + 0 + 25000 + + + DeviceInterface + + true + true + 1 + fortyGigE0/8 + + false + 0 + 0 + 40000 + Interface description + + + DeviceInterface + + true + true + 1 + fortyGigE0/12 + + false + 0 + 0 + 100000 + Interface description + + + true + 0 + Force10-S6000 + + + switch-t0 + Force10-S6000 +
diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 3ee689622577..d187cfd26b8b 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -10,6 +10,7 @@ def setUp(self): self.sample_graph = os.path.join(self.test_dir, 'sample_graph.xml') self.sample_graph_t0 = os.path.join(self.test_dir, 't0-sample-graph.xml') self.sample_graph_simple = os.path.join(self.test_dir, 'simple-sample-graph.xml') + self.sample_graph_metadata = os.path.join(self.test_dir, 'simple-sample-graph-metadata.xml') self.sample_graph_pc_test = os.path.join(self.test_dir, 'pc-test-graph.xml') self.sample_graph_bgp_speaker = os.path.join(self.test_dir, 't0-sample-bgp-speaker.xml') self.sample_device_desc = os.path.join(self.test_dir, 'device.xml') @@ -143,3 +144,19 @@ def test_minigraph_ethernet_interfaces(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet12\']"' output = self.run_script(argument) self.assertEqual(output.strip(), "{'alias': 'fortyGigE0/12', 'lanes': '33,34,35,36', 'fec': 'rs', 'speed': '100000', 'description': 'Interface description'}") + + def test_metadata_everflow(self): + argument = '-m "' + self.sample_graph_metadata + '" -p "' + self.port_config + '" -v "MIRROR_SESSION"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "{'everflow0': {'src_ip': '10.1.0.32', 'dst_ip': '10.0.100.1'}}") + + def test_metadata_tacacs(self): + argument = '-m "' + self.sample_graph_metadata + '" -p "' + self.port_config + '" -v "TACPLUS_SERVER"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "{'10.0.10.7': {'priority': '1', 'tcp_port': '49'}, '10.0.10.8': {'priority': '1', 'tcp_port': '49'}}") + + def test_metadata_ntp(self): + argument = '-m "' + self.sample_graph_metadata + '" -p "' + self.port_config + '" -v "NTP_SERVER"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "{'10.0.10.1': {}, '10.0.10.2': {}}") + From 8951e3033f34751c09ab0c4cf19743514e9655fb Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Fri, 6 Apr 2018 19:24:18 -0700 Subject: [PATCH 006/219] [router advertiser] Only start radvd process if device role is 'ToRRouter' (#1569) --- .../docker-router-advertiser.supervisord.conf | 1 + dockers/docker-router-advertiser/start.sh | 13 ++++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf b/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf index 08a3e0a94872..f0bb4d5b3bbd 100644 --- a/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf +++ b/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf @@ -8,6 +8,7 @@ command=/usr/bin/start.sh priority=1 autostart=true autorestart=false +startsecs=0 stdout_logfile=syslog stderr_logfile=syslog diff --git a/dockers/docker-router-advertiser/start.sh b/dockers/docker-router-advertiser/start.sh index cbd5ec383bd6..7fcaf65a79c9 100755 --- a/dockers/docker-router-advertiser/start.sh +++ b/dockers/docker-router-advertiser/start.sh @@ -1,11 +1,18 @@ #!/usr/bin/env bash -# Generate /etc/radvd.conf config file -sonic-cfggen -d -t /usr/share/sonic/templates/radvd.conf.j2 > /etc/radvd.conf - rm -f /var/run/rsyslogd.pid supervisorctl start rsyslogd +# Router advertiser should only run on ToR (T0) devices +DEVICE_ROLE=$(sonic-cfggen -d -v "DEVICE_METADATA.localhost.type") +if [ "$DEVICE_ROLE" != "ToRRouter" ]; then + echo "Device role is not ToRRouter. Not starting router advertiser process." + exit 0 +fi + +# Generate /etc/radvd.conf config file +sonic-cfggen -d -t /usr/share/sonic/templates/radvd.conf.j2 > /etc/radvd.conf + # Start the router advertiser supervisorctl start radvd From a67952a8f9c20c9ba09e3525efb53665976857d5 Mon Sep 17 00:00:00 2001 From: lguohan Date: Sat, 7 Apr 2018 10:19:55 -0700 Subject: [PATCH 007/219] [submodules]: update sonic-swss (#1570) Signed-off-by: Guohan Lu --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index e217519c20c6..d711d2cf5783 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit e217519c20c60f7cf4e24688dd3eca6d380a1dd6 +Subproject commit d711d2cf57839589aa7d6653b252305c31f8c2b0 From 765bf0a7836c64558c61383794547a22842605b2 Mon Sep 17 00:00:00 2001 From: lguohan Date: Sat, 7 Apr 2018 15:50:37 -0700 Subject: [PATCH 008/219] [submodules]: update sonic-utilities (#1571) Signed-off-by: Guohan Lu --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 68c3fbf79738..3f2d7bb4beaf 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 68c3fbf79738253ca5b1c8f225152a1cab55c5a1 +Subproject commit 3f2d7bb4beaf3987db0c3e6fb57ae7ba51390a16 From d81d665bb085c40212c41ab1876d8ecf3d5bdf13 Mon Sep 17 00:00:00 2001 From: lguohan Date: Mon, 9 Apr 2018 16:41:51 -0700 Subject: [PATCH 009/219] [cfggen]: ignore acl when its type is not defined (#1568) Signed-off-by: Guohan Lu --- src/sonic-config-engine/minigraph.py | 14 +++++++++----- .../tests/t0-sample-graph.xml | 14 ++++++++++++++ src/sonic-config-engine/tests/test_cfggen.py | 18 ++++++++++++------ 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index f989129a439e..fb098cee3268 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -207,11 +207,15 @@ def parse_dpg(dpg, hname): 'type': 'MIRROR' if is_mirror else 'L3'} else: # This ACL has no interfaces to attach to -- consider this a control plane ACL - aclservice = aclintf.find(str(QName(ns, "Type"))).text - acls[aclname] = {'policy_desc': aclname, - 'ports': acl_intfs, - 'type': 'CTRLPLANE', - 'service': aclservice if aclservice is not None else 'UNKNOWN'} + try: + aclservice = aclintf.find(str(QName(ns, "Type"))).text + acls[aclname] = {'policy_desc': aclname, + 'ports': acl_intfs, + 'type': 'CTRLPLANE', + 'service': aclservice if aclservice is not None else 'UNKNOWN'} + except: + print >> sys.stderr, "Warning: Ingore Control Plane ACL %s without type" % aclname + return intfs, lo_intfs, mgmt_intf, vlans, vlan_members, pcs, acls return None, None, None, None, None, None, None diff --git a/src/sonic-config-engine/tests/t0-sample-graph.xml b/src/sonic-config-engine/tests/t0-sample-graph.xml index f3d05cbc22c1..a12605c8c3e1 100644 --- a/src/sonic-config-engine/tests/t0-sample-graph.xml +++ b/src/sonic-config-engine/tests/t0-sample-graph.xml @@ -271,6 +271,20 @@ SNMP_ACL SNMP + + NTP + NTP_ACL + NTP + + + SSH + SSH_ACL + SSH + + + NTP + NTP_ACL + diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index d187cfd26b8b..64162e49417e 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -16,9 +16,13 @@ def setUp(self): self.sample_device_desc = os.path.join(self.test_dir, 'device.xml') self.port_config = os.path.join(self.test_dir, 't0-sample-port-config.ini') - def run_script(self, argument): + def run_script(self, argument, check_stderr=False): print '\n Running sonic-cfggen ' + argument - output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + if check_stderr: + output = subprocess.check_output(self.script_file + ' ' + argument, stderr=subprocess.STDOUT, shell=True) + else: + output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + linecount = output.strip().count('\n') if linecount <= 0: print ' Output: ' + output.strip() @@ -73,10 +77,12 @@ def test_render_template(self): def test_minigraph_acl(self): argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v ACL_TABLE' - output = self.run_script(argument) - self.assertEqual(output.strip(), "{'SNMP_ACL': {'type': 'CTRLPLANE', 'policy_desc': 'SNMP_ACL', 'service': 'SNMP', 'ports': []}," - " 'DATAACL': {'type': 'L3', 'policy_desc': 'DATAACL', 'ports': ['Ethernet112', 'Ethernet116', 'Ethernet120', 'Ethernet124']}}") - + output = self.run_script(argument, True) + self.assertEqual(output.strip(), "Warning: Ingore Control Plane ACL NTP_ACL without type\n" + "{'SSH_ACL': {'type': 'CTRLPLANE', 'policy_desc': 'SSH_ACL', 'service': 'SSH', 'ports': []}," + " 'SNMP_ACL': {'type': 'CTRLPLANE', 'policy_desc': 'SNMP_ACL', 'service': 'SNMP', 'ports': []}," + " 'DATAACL': {'type': 'L3', 'policy_desc': 'DATAACL', 'ports': ['Ethernet112', 'Ethernet116', 'Ethernet120', 'Ethernet124']}," + " 'NTP_ACL': {'type': 'CTRLPLANE', 'policy_desc': 'NTP_ACL', 'service': 'NTP', 'ports': []}}") def test_minigraph_everflow(self): argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v MIRROR_SESSION' output = self.run_script(argument) From df34960dd3f7bbd51a92e158f357f12a2c81eacc Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Mon, 9 Apr 2018 23:51:43 -0700 Subject: [PATCH 010/219] [installer]: Umount before delete partition (#1575) Signed-off-by: Qi Luo --- installer/x86_64/install.sh | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/installer/x86_64/install.sh b/installer/x86_64/install.sh index 949c052acb89..91dd57a74ba1 100755 --- a/installer/x86_64/install.sh +++ b/installer/x86_64/install.sh @@ -163,11 +163,21 @@ create_demo_gpt_partition() while read -r part_index; do if [ "$blk_dev$part_index" = "$cur_part" ]; then continue; fi echo "deleting partition $part_index ..." + # if the partition is already mounted, umount first + df $blk_dev$part_index 2>/dev/null && { + umount $blk_dev$part_index || { + echo "Error: Unable to umount $blk_dev$part_index" + exit 1 + } + } sgdisk -d $part_index $blk_dev || { echo "Error: Unable to delete partition $part_index on $blk_dev" exit 1 } - partprobe + partprobe || { + echo "Error: Unable to partprobe" + exit 1 + } done < $tmpfifo fi From d54b9ef49a38775a92c27d309aba7fe1d36994ba Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Tue, 10 Apr 2018 13:37:46 -0700 Subject: [PATCH 011/219] Use eth0 interface only to generate lldpd SystemId (#1577) --- dockers/docker-lldp-sv2/supervisord.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockers/docker-lldp-sv2/supervisord.conf b/dockers/docker-lldp-sv2/supervisord.conf index 60334e1b8ede..e8022a9a5fa6 100644 --- a/dockers/docker-lldp-sv2/supervisord.conf +++ b/dockers/docker-lldp-sv2/supervisord.conf @@ -25,7 +25,7 @@ stderr_logfile=syslog # - `-dd` means to stay in foreground, log warnings to console # - `-ddd` means to stay in foreground, log warnings and info to console # - `-dddd` means to stay in foreground, log all to console -command=/usr/sbin/lldpd -d -I Ethernet*,eth* +command=/usr/sbin/lldpd -d -I Ethernet*,eth* -C eth0 priority=3 autostart=false autorestart=false From 7b3674441a2a65d69f48f6e4f0d4a188d39a6ac9 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 10 Apr 2018 18:14:12 -0700 Subject: [PATCH 012/219] Allow one Service ACL to bind to multiple services (#1576) * [caclmgrd] Also ignore IP protocol if found in rule; we will only use our predefined protocols --- dockers/docker-snmp-sv2/snmpd-config-updater | 4 +- files/image_config/caclmgrd/caclmgrd | 138 +++++++++--------- files/image_config/ssh/sshd-config-updater | 2 +- src/sonic-config-engine/minigraph.py | 24 ++- .../tests/t0-sample-graph.xml | 10 ++ src/sonic-config-engine/tests/test_cfggen.py | 10 +- src/sonic-utilities | 2 +- 7 files changed, 106 insertions(+), 84 deletions(-) diff --git a/dockers/docker-snmp-sv2/snmpd-config-updater b/dockers/docker-snmp-sv2/snmpd-config-updater index 10c2a2b57ef3..ea837e5a787f 100755 --- a/dockers/docker-snmp-sv2/snmpd-config-updater +++ b/dockers/docker-snmp-sv2/snmpd-config-updater @@ -48,8 +48,8 @@ class ConfigUpdater(object): if table_data["type"] != self.ACL_TABLE_TYPE_CTRLPLANE: continue - # Ignore non-SSH service ACLs - if table_data["service"] != self.ACL_SERVICE_SNMP: + # Ignore non-SNMP service ACLs + if self.ACL_SERVICE_SNMP not in table_data["services"]: continue acl_rules = {} diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index a61c2437a5b7..dee85d2e26ed 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -123,80 +123,76 @@ class ControlPlaneAclManager(object): if table_data["type"] != self.ACL_TABLE_TYPE_CTRLPLANE: continue - acl_service = table_data["service"] + acl_services = table_data["services"] - if acl_service not in self.ACL_SERVICES: - log_warning("Ignoring control plane ACL '{}' with unrecognized service '{}'" - .format(table_name, acl_service)) - continue - - log_info("Translating ACL rules for control plane ACL '{}' (service: '{}')" - .format(table_name, acl_service)) - - # Obtain default IP protocol(s) and destination port(s) for this service - ip_protocols = self.ACL_SERVICES[acl_service]["ip_protocols"] - dst_ports = self.ACL_SERVICES[acl_service]["dst_ports"] - - acl_rules = {} - - for ((rule_table_name, rule_id), rule_props) in self._rules_db_info.iteritems(): - if rule_table_name == table_name: - acl_rules[rule_props["PRIORITY"]] = rule_props - - # For each ACL rule in this table (in descending order of priority) - for priority in sorted(acl_rules.iterkeys(), reverse=True): - rule_props = acl_rules[priority] - - if "PACKET_ACTION" not in rule_props: - log_error("ACL rule does not contain PACKET_ACTION property") + for acl_service in acl_services: + if acl_service not in self.ACL_SERVICES: + log_warning("Ignoring control plane ACL '{}' with unrecognized service '{}'" + .format(table_name, acl_service)) continue - # If the rule contains an IP protocol, we will use it. - # Otherwise, we will apply the rule to the default - # protocol(s) for this ACL service - if "IP_PROTOCOL" in rule_props: - ip_protocols = [rule_props["IP_PROTOCOL"]] - - for ip_protocol in ip_protocols: - for dst_port in dst_ports: - rule_cmd = "iptables -A INPUT -p {}".format(ip_protocol) - - if "SRC_IP" in rule_props and rule_props["SRC_IP"]: - rule_cmd += " -s {}".format(rule_props["SRC_IP"]) - - rule_cmd += " --dport {}".format(dst_port) - - # If there are TCP flags present, append them - if "TCP_FLAGS" in rule_props and rule_props["TCP_FLAGS"]: - tcp_flags = int(rule_props["TCP_FLAGS"], 16) - - if tcp_flags > 0: - rule_cmd += " --tcp-flags " - - if tcp_flags & 0x01: - rule_cmd += "FIN," - if tcp_flags & 0x02: - rule_cmd += "SYN," - if tcp_flags & 0x04: - rule_cmd += "RST," - if tcp_flags & 0x08: - rule_cmd += "PSH," - if tcp_flags & 0x10: - rule_cmd += "ACK," - if tcp_flags & 0x20: - rule_cmd += "URG," - if tcp_flags & 0x40: - rule_cmd += "ECE," - if tcp_flags & 0x80: - rule_cmd += "CWR," - - # Delete the trailing comma - rule_cmd = rule_cmd[:-1] - - # Append the packet action as the jump target - rule_cmd += " -j {}".format(rule_props["PACKET_ACTION"]) - - iptables_cmds.append(rule_cmd) + log_info("Translating ACL rules for control plane ACL '{}' (service: '{}')" + .format(table_name, acl_service)) + + # Obtain default IP protocol(s) and destination port(s) for this service + ip_protocols = self.ACL_SERVICES[acl_service]["ip_protocols"] + dst_ports = self.ACL_SERVICES[acl_service]["dst_ports"] + + acl_rules = {} + + for ((rule_table_name, rule_id), rule_props) in self._rules_db_info.iteritems(): + if rule_table_name == table_name: + acl_rules[rule_props["PRIORITY"]] = rule_props + + # For each ACL rule in this table (in descending order of priority) + for priority in sorted(acl_rules.iterkeys(), reverse=True): + rule_props = acl_rules[priority] + + if "PACKET_ACTION" not in rule_props: + log_error("ACL rule does not contain PACKET_ACTION property") + continue + + # Apply the rule to the default protocol(s) for this ACL service + for ip_protocol in ip_protocols: + for dst_port in dst_ports: + rule_cmd = "iptables -A INPUT -p {}".format(ip_protocol) + + if "SRC_IP" in rule_props and rule_props["SRC_IP"]: + rule_cmd += " -s {}".format(rule_props["SRC_IP"]) + + rule_cmd += " --dport {}".format(dst_port) + + # If there are TCP flags present, append them + if "TCP_FLAGS" in rule_props and rule_props["TCP_FLAGS"]: + tcp_flags = int(rule_props["TCP_FLAGS"], 16) + + if tcp_flags > 0: + rule_cmd += " --tcp-flags " + + if tcp_flags & 0x01: + rule_cmd += "FIN," + if tcp_flags & 0x02: + rule_cmd += "SYN," + if tcp_flags & 0x04: + rule_cmd += "RST," + if tcp_flags & 0x08: + rule_cmd += "PSH," + if tcp_flags & 0x10: + rule_cmd += "ACK," + if tcp_flags & 0x20: + rule_cmd += "URG," + if tcp_flags & 0x40: + rule_cmd += "ECE," + if tcp_flags & 0x80: + rule_cmd += "CWR," + + # Delete the trailing comma + rule_cmd = rule_cmd[:-1] + + # Append the packet action as the jump target + rule_cmd += " -j {}".format(rule_props["PACKET_ACTION"]) + + iptables_cmds.append(rule_cmd) return iptables_cmds diff --git a/files/image_config/ssh/sshd-config-updater b/files/image_config/ssh/sshd-config-updater index ad1ee000febe..5f7a4ce17f98 100755 --- a/files/image_config/ssh/sshd-config-updater +++ b/files/image_config/ssh/sshd-config-updater @@ -49,7 +49,7 @@ class ConfigUpdater(object): continue # Ignore non-SSH service ACLs - if table_data["service"] != self.ACL_SERVICE_SSH: + if self.ACL_SERVICE_SSH not in table_data["services"]: continue acl_rules = {} diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index fb098cee3268..731f449ab028 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -188,6 +188,10 @@ def parse_dpg(dpg, hname): aclattach = aclintf.find(str(QName(ns, "AttachTo"))).text.split(';') acl_intfs = [] is_mirror = False + + # TODO: Ensure that acl_intfs will only ever contain front-panel interfaces (e.g., + # maybe we should explicity ignore management and loopback interfaces?) because we + # decide an ACL is a Control Plane ACL if acl_intfs is empty below. for member in aclattach: member = member.strip() if pcs.has_key(member): @@ -209,12 +213,22 @@ def parse_dpg(dpg, hname): # This ACL has no interfaces to attach to -- consider this a control plane ACL try: aclservice = aclintf.find(str(QName(ns, "Type"))).text - acls[aclname] = {'policy_desc': aclname, - 'ports': acl_intfs, - 'type': 'CTRLPLANE', - 'service': aclservice if aclservice is not None else 'UNKNOWN'} + + # If we already have an ACL with this name and this ACL is bound to a different service, + # append the service to our list of services + if aclname in acls: + if acls[aclname]['type'] != 'CTRLPLANE': + print >> sys.stderr, "Warning: ACL '%s' type mismatch. Not updating ACL." % aclname + elif acls[aclname]['services'] == aclservice: + print >> sys.stderr, "Warning: ACL '%s' already contains service '%s'. Not updating ACL." % (aclname, aclservice) + else: + acls[aclname]['services'].append(aclservice) + else: + acls[aclname] = {'policy_desc': aclname, + 'type': 'CTRLPLANE', + 'services': [aclservice]} except: - print >> sys.stderr, "Warning: Ingore Control Plane ACL %s without type" % aclname + print >> sys.stderr, "Warning: Ignoring Control Plane ACL %s without type" % aclname return intfs, lo_intfs, mgmt_intf, vlans, vlan_members, pcs, acls return None, None, None, None, None, None, None diff --git a/src/sonic-config-engine/tests/t0-sample-graph.xml b/src/sonic-config-engine/tests/t0-sample-graph.xml index a12605c8c3e1..bda5517771e5 100644 --- a/src/sonic-config-engine/tests/t0-sample-graph.xml +++ b/src/sonic-config-engine/tests/t0-sample-graph.xml @@ -281,6 +281,16 @@ SSH_ACL SSH + + SSH + ROUTER-PROTECT + SSH + + + SNMP + ROUTER-PROTECT + SNMP + NTP NTP_ACL diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 64162e49417e..6059798cbd6e 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -78,11 +78,13 @@ def test_render_template(self): def test_minigraph_acl(self): argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v ACL_TABLE' output = self.run_script(argument, True) - self.assertEqual(output.strip(), "Warning: Ingore Control Plane ACL NTP_ACL without type\n" - "{'SSH_ACL': {'type': 'CTRLPLANE', 'policy_desc': 'SSH_ACL', 'service': 'SSH', 'ports': []}," - " 'SNMP_ACL': {'type': 'CTRLPLANE', 'policy_desc': 'SNMP_ACL', 'service': 'SNMP', 'ports': []}," + self.assertEqual(output.strip(), "Warning: Ignoring Control Plane ACL NTP_ACL without type\n" + "{'SSH_ACL': {'services': ['SSH'], 'type': 'CTRLPLANE', 'policy_desc': 'SSH_ACL'}," + " 'SNMP_ACL': {'services': ['SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'SNMP_ACL'}," " 'DATAACL': {'type': 'L3', 'policy_desc': 'DATAACL', 'ports': ['Ethernet112', 'Ethernet116', 'Ethernet120', 'Ethernet124']}," - " 'NTP_ACL': {'type': 'CTRLPLANE', 'policy_desc': 'NTP_ACL', 'service': 'NTP', 'ports': []}}") + " 'NTP_ACL': {'services': ['NTP'], 'type': 'CTRLPLANE', 'policy_desc': 'NTP_ACL'}," + " 'ROUTER_PROTECT': {'services': ['SSH', 'SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'ROUTER_PROTECT'}}") + def test_minigraph_everflow(self): argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v MIRROR_SESSION' output = self.run_script(argument) diff --git a/src/sonic-utilities b/src/sonic-utilities index 3f2d7bb4beaf..5e476d6d549c 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 3f2d7bb4beaf3987db0c3e6fb57ae7ba51390a16 +Subproject commit 5e476d6d549cf40b68e86ae01dcb703b567b85e3 From 6a5afcf47a8a90b5ec17b1047db6dfc1e187ea57 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Tue, 10 Apr 2018 20:15:20 -0700 Subject: [PATCH 013/219] [snmp]: Bind snmpd to all ip addresses (#1587) Signed-off-by: Qi Luo --- dockers/docker-snmp-sv2/snmpd.conf.j2 | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/dockers/docker-snmp-sv2/snmpd.conf.j2 b/dockers/docker-snmp-sv2/snmpd.conf.j2 index b46871dfd6f8..18b7af1e925d 100644 --- a/dockers/docker-snmp-sv2/snmpd.conf.j2 +++ b/dockers/docker-snmp-sv2/snmpd.conf.j2 @@ -13,24 +13,9 @@ # AGENT BEHAVIOUR # -{% if MGMT_INTERFACE %} -# Listen for connections on localhost, loopback ip and mgmt (eth0) ip -agentAddress udp:127.0.0.1:161 -{% for (name, prefix) in MGMT_INTERFACE %} -{% if prefix | ipv4 %} -agentAddress udp:{{ prefix | ip }}:161 -{% endif %} -{% endfor %} -# TODO: only support ipv4 lo addresses, add ipv6 support later -{% for (name, prefix) in LOOPBACK_INTERFACE %} -{% if prefix | ipv4 %} -agentAddress udp:{{ prefix | ip }}:161 -{% endif %} -{% endfor %} -{% else %} -# Listen on all addresses as mgmt ip not specified +# Listen for connections on all ip addresses, including eth0, ipv4 lo agentAddress udp:161 -{% endif %} +# TODO: only support ipv4 lo addresses, add ipv6 support later ############################################################################### # From eb7a26bf0efd7325b4e1e8abb17d3e0d061861ad Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Tue, 10 Apr 2018 20:16:07 -0700 Subject: [PATCH 014/219] [device] Update Arista driver submodule (#1585) Watchdog timeout increased --- platform/broadcom/sonic-platform-modules-arista | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index 6fe9de4dd52b..86221d907f27 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 6fe9de4dd52bba4c5856567a8f5624e75e9af66d +Subproject commit 86221d907f27e7f6df40393a5bfe217bf22b19af From f3ff10f4330217368f6838ea12fb54e14fee80df Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Tue, 10 Apr 2018 22:45:59 -0700 Subject: [PATCH 015/219] [devices]: Fix type for qos.json in 7060 and S6100 (#1582) --- .../x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/qos.json | 6 +++--- .../dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/qos.json b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/qos.json index 7e00e14d1974..b724b48c2c23 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/qos.json +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/qos.json @@ -154,13 +154,13 @@ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0-1" : { "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]" }, - "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124!3-4" : { + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3-4" : { "scheduler" : "[SCHEDULER|scheduler.0]" }, - "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124!0" : { + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0" : { "scheduler" : "[SCHEDULER|scheduler.1]" }, - "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124!1" : { + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|1" : { "scheduler" : "[SCHEDULER|scheduler.2]" } } diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json index d63cbfb8c558..99642cf8cf4c 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json +++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json @@ -154,13 +154,13 @@ "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63|0-1" : { "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]" }, - "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63!3-4" : { + "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63|3-4" : { "scheduler" : "[SCHEDULER|scheduler.0]" }, - "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63!0" : { + "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63|0" : { "scheduler" : "[SCHEDULER|scheduler.1]" }, - "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63!1" : { + "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63|1" : { "scheduler" : "[SCHEDULER|scheduler.2]" } } From f8aac10ab4d66dfc82e033f28d930ae858498ba7 Mon Sep 17 00:00:00 2001 From: lguohan Date: Thu, 12 Apr 2018 04:04:32 -0700 Subject: [PATCH 016/219] [minigraph]: ignore minigraph ports which are not in port_config.ini (#1593) Signed-off-by: Guohan Lu --- src/sonic-config-engine/minigraph.py | 8 ++++ .../tests/simple-sample-graph.xml | 13 +++++++ src/sonic-config-engine/tests/test_cfggen.py | 37 +++++++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 731f449ab028..570f5de24188 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -439,10 +439,18 @@ def parse_xml(filename, platform=None, port_config_file=None): results['PORTCHANNEL_INTERFACE'] = pc_intfs for port_name in port_speeds: + # ignore port not in port_config.ini + if not ports.has_key(port_name): + continue + ports.setdefault(port_name, {})['speed'] = port_speeds[port_name] if port_speeds[port_name] == '100000': ports.setdefault(port_name, {})['fec'] = 'rs' for port_name in port_descriptions: + # ignore port not in port_config.ini + if not ports.has_key(port_name): + continue + ports.setdefault(port_name, {})['description'] = port_descriptions[port_name] results['PORT'] = ports diff --git a/src/sonic-config-engine/tests/simple-sample-graph.xml b/src/sonic-config-engine/tests/simple-sample-graph.xml index d42a2650321e..33e8a6d616d9 100644 --- a/src/sonic-config-engine/tests/simple-sample-graph.xml +++ b/src/sonic-config-engine/tests/simple-sample-graph.xml @@ -222,6 +222,19 @@ 0 10000 + + DeviceInterface + + true + true + 1 + fortyGigE0/1 + + false + 0 + 0 + 10000 + DeviceInterface diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 6059798cbd6e..fbec671aff56 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -153,6 +153,43 @@ def test_minigraph_ethernet_interfaces(self): output = self.run_script(argument) self.assertEqual(output.strip(), "{'alias': 'fortyGigE0/12', 'lanes': '33,34,35,36', 'fec': 'rs', 'speed': '100000', 'description': 'Interface description'}") + def test_minigraph_extra_ethernet_interfaces(self): + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORT"' + output = self.run_script(argument) + self.assertEqual(output.strip(), \ + "{'Ethernet8': {'alias': 'fortyGigE0/8', 'lanes': '37,38,39,40', 'description': 'Interface description', 'speed': '40000'}, " + "'Ethernet0': {'alias': 'fortyGigE0/0', 'lanes': '29,30,31,32', 'speed': '10000'}, " + "'Ethernet4': {'alias': 'fortyGigE0/4', 'lanes': '25,26,27,28', 'speed': '25000'}, " + "'Ethernet108': {'alias': 'fortyGigE0/108', 'lanes': '81,82,83,84'}, " + "'Ethernet100': {'alias': 'fortyGigE0/100', 'lanes': '125,126,127,128'}, " + "'Ethernet104': {'alias': 'fortyGigE0/104', 'lanes': '85,86,87,88'}, " + "'Ethernet68': {'alias': 'fortyGigE0/68', 'lanes': '69,70,71,72'}, " + "'Ethernet96': {'alias': 'fortyGigE0/96', 'lanes': '121,122,123,124'}, " + "'Ethernet124': {'alias': 'fortyGigE0/124', 'lanes': '101,102,103,104'}, " + "'Ethernet92': {'alias': 'fortyGigE0/92', 'lanes': '113,114,115,116'}, " + "'Ethernet120': {'alias': 'fortyGigE0/120', 'lanes': '97,98,99,100'}, " + "'Ethernet52': {'alias': 'fortyGigE0/52', 'lanes': '53,54,55,56'}, " + "'Ethernet56': {'alias': 'fortyGigE0/56', 'lanes': '61,62,63,64'}, " + "'Ethernet76': {'alias': 'fortyGigE0/76', 'lanes': '73,74,75,76'}, " + "'Ethernet72': {'alias': 'fortyGigE0/72', 'lanes': '77,78,79,80'}, " + "'Ethernet64': {'alias': 'fortyGigE0/64', 'lanes': '65,66,67,68'}, " + "'Ethernet32': {'alias': 'fortyGigE0/32', 'lanes': '9,10,11,12'}, " + "'Ethernet16': {'alias': 'fortyGigE0/16', 'lanes': '41,42,43,44'}, " + "'Ethernet36': {'alias': 'fortyGigE0/36', 'lanes': '13,14,15,16'}, " + "'Ethernet12': {'alias': 'fortyGigE0/12', 'lanes': '33,34,35,36', 'fec': 'rs', 'speed': '100000', 'description': 'Interface description'}, " + "'Ethernet88': {'alias': 'fortyGigE0/88', 'lanes': '117,118,119,120'}, " + "'Ethernet116': {'alias': 'fortyGigE0/116', 'lanes': '93,94,95,96'}, " + "'Ethernet80': {'alias': 'fortyGigE0/80', 'lanes': '105,106,107,108'}, " + "'Ethernet112': {'alias': 'fortyGigE0/112', 'lanes': '89,90,91,92'}, " + "'Ethernet84': {'alias': 'fortyGigE0/84', 'lanes': '109,110,111,112'}, " + "'Ethernet48': {'alias': 'fortyGigE0/48', 'lanes': '49,50,51,52'}, " + "'Ethernet44': {'alias': 'fortyGigE0/44', 'lanes': '17,18,19,20'}, " + "'Ethernet40': {'alias': 'fortyGigE0/40', 'lanes': '21,22,23,24'}, " + "'Ethernet28': {'alias': 'fortyGigE0/28', 'lanes': '1,2,3,4'}, " + "'Ethernet60': {'alias': 'fortyGigE0/60', 'lanes': '57,58,59,60'}, " + "'Ethernet20': {'alias': 'fortyGigE0/20', 'lanes': '45,46,47,48'}, " + "'Ethernet24': {'alias': 'fortyGigE0/24', 'lanes': '5,6,7,8'}}") + def test_metadata_everflow(self): argument = '-m "' + self.sample_graph_metadata + '" -p "' + self.port_config + '" -v "MIRROR_SESSION"' output = self.run_script(argument) From 2f4ce211e23e9e177d198774fa485077a44c8504 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Thu, 12 Apr 2018 15:44:57 -0700 Subject: [PATCH 017/219] [minigraph] Fix parser on PNG DeviceInterfaceLink Bandwidth (#1592) * [minigraph] Fix parser on PNG DeviceInterfaceLink Bandwidth Signed-off-by: Qi Luo --- src/sonic-config-engine/minigraph.py | 35 ++++++++++++++----- .../tests/sample_output/ports.json | 2 +- .../tests/simple-sample-graph.xml | 14 +++++++- src/sonic-config-engine/tests/test_cfggen.py | 4 +-- 4 files changed, 42 insertions(+), 13 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 570f5de24188..4ac7e9d68c92 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -62,6 +62,7 @@ def parse_png(png, hname): console_port = '' mgmt_dev = '' mgmt_port = '' + port_speeds = {} for child in png: if child.tag == str(QName(ns, "DeviceInterfaceLinks")): for link in child.findall(str(QName(ns, "DeviceLinkBase"))): @@ -73,15 +74,21 @@ def parse_png(png, hname): endport = link.find(str(QName(ns, "EndPort"))).text startdevice = link.find(str(QName(ns, "StartDevice"))).text startport = link.find(str(QName(ns, "StartPort"))).text + bandwidth_node = link.find(str(QName(ns, "Bandwidth"))) + bandwidth = bandwidth_node.text if bandwidth_node is not None else None if enddevice == hname: if port_alias_map.has_key(endport): endport = port_alias_map[endport] neighbors[endport] = {'name': startdevice, 'port': startport} + if bandwidth: + port_speeds[endport] = bandwidth else: if port_alias_map.has_key(startport): startport = port_alias_map[startport] neighbors[startport] = {'name': enddevice, 'port': endport} + if bandwidth: + port_speeds[startport] = bandwidth if child.tag == str(QName(ns, "Devices")): for device in child.findall(str(QName(ns, "Device"))): @@ -106,7 +113,7 @@ def parse_png(png, hname): elif node.tag == str(QName(ns, "EndDevice")): mgmt_dev = node.text - return (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port) + return (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speeds) def parse_dpg(dpg, hname): @@ -368,7 +375,8 @@ def parse_xml(filename, platform=None, port_config_file=None): neighbors = None devices = None hostname = None - port_speeds = {} + port_speeds_default = {} + port_speed_png = {} port_descriptions = {} syslog_servers = [] dhcp_servers = [] @@ -395,13 +403,13 @@ def parse_xml(filename, platform=None, port_config_file=None): elif child.tag == str(QName(ns, "CpgDec")): (bgp_sessions, bgp_asn, bgp_peers_with_range) = parse_cpg(child, hostname) elif child.tag == str(QName(ns, "PngDec")): - (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port) = parse_png(child, hostname) + (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speed_png) = parse_png(child, hostname) elif child.tag == str(QName(ns, "UngDec")): - (u_neighbors, u_devices, _, _, _, _) = parse_png(child, hostname) + (u_neighbors, u_devices, _, _, _, _, _) = parse_png(child, hostname) elif child.tag == str(QName(ns, "MetadataDeclaration")): (syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id) = parse_meta(child, hostname) elif child.tag == str(QName(ns, "DeviceInfos")): - (port_speeds, port_descriptions) = parse_deviceinfo(child, hwsku) + (port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku) results = {} results['DEVICE_METADATA'] = {'localhost': { @@ -438,14 +446,23 @@ def parse_xml(filename, platform=None, port_config_file=None): results['VLAN_INTERFACE'] = vlan_intfs results['PORTCHANNEL_INTERFACE'] = pc_intfs - for port_name in port_speeds: + for port_name in port_speeds_default: # ignore port not in port_config.ini if not ports.has_key(port_name): continue - ports.setdefault(port_name, {})['speed'] = port_speeds[port_name] - if port_speeds[port_name] == '100000': - ports.setdefault(port_name, {})['fec'] = 'rs' + ports.setdefault(port_name, {})['speed'] = port_speeds_default[port_name] + + for port_name in port_speed_png: + # if port_name is not in port_config.ini, still consider it. + # and later swss will pick up and behave on-demand port break-up. + # if on-deman port break-up is not supported on a specific platform, swss will return error. + ports.setdefault(port_name, {})['speed'] = port_speed_png[port_name] + + for port_name, port in ports.items(): + if port.get('speed') == '100000': + port['fec'] = 'rs' + for port_name in port_descriptions: # ignore port not in port_config.ini if not ports.has_key(port_name): diff --git a/src/sonic-config-engine/tests/sample_output/ports.json b/src/sonic-config-engine/tests/sample_output/ports.json index 7533fb7377ef..3fa2e29a8b0a 100644 --- a/src/sonic-config-engine/tests/sample_output/ports.json +++ b/src/sonic-config-engine/tests/sample_output/ports.json @@ -1,7 +1,7 @@ [ { "PORT_TABLE:Ethernet8": { - "speed": "40000", + "speed": "1000", "description": "Interface description" }, "OP": "SET" diff --git a/src/sonic-config-engine/tests/simple-sample-graph.xml b/src/sonic-config-engine/tests/simple-sample-graph.xml index 33e8a6d616d9..6e351e1cd003 100644 --- a/src/sonic-config-engine/tests/simple-sample-graph.xml +++ b/src/sonic-config-engine/tests/simple-sample-graph.xml @@ -181,7 +181,19 @@ - + + + DeviceInterfaceLink + true + 1000 + ARISTA01T1 + et1 + true + switch-t0 + fortyGigE0/8 + true + + switch-t0 diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index fbec671aff56..901b882f7048 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -148,7 +148,7 @@ def test_minigraph_deployment_id(self): def test_minigraph_ethernet_interfaces(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet8\']"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'alias': 'fortyGigE0/8', 'lanes': '37,38,39,40', 'description': 'Interface description', 'speed': '40000'}") + self.assertEqual(output.strip(), "{'alias': 'fortyGigE0/8', 'lanes': '37,38,39,40', 'description': 'Interface description', 'speed': '1000'}") argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet12\']"' output = self.run_script(argument) self.assertEqual(output.strip(), "{'alias': 'fortyGigE0/12', 'lanes': '33,34,35,36', 'fec': 'rs', 'speed': '100000', 'description': 'Interface description'}") @@ -157,7 +157,7 @@ def test_minigraph_extra_ethernet_interfaces(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORT"' output = self.run_script(argument) self.assertEqual(output.strip(), \ - "{'Ethernet8': {'alias': 'fortyGigE0/8', 'lanes': '37,38,39,40', 'description': 'Interface description', 'speed': '40000'}, " + "{'Ethernet8': {'alias': 'fortyGigE0/8', 'lanes': '37,38,39,40', 'description': 'Interface description', 'speed': '1000'}, " "'Ethernet0': {'alias': 'fortyGigE0/0', 'lanes': '29,30,31,32', 'speed': '10000'}, " "'Ethernet4': {'alias': 'fortyGigE0/4', 'lanes': '25,26,27,28', 'speed': '25000'}, " "'Ethernet108': {'alias': 'fortyGigE0/108', 'lanes': '81,82,83,84'}, " From 062d60092f7c642c83c55643d938106949751e4f Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Thu, 12 Apr 2018 17:55:08 -0700 Subject: [PATCH 018/219] [Broadcom SAI] upgrade Broadcom SAI to version 3.1.3.4-10 (#1591) * [Broadcom SAI] upgrade Broadcom SAI to version 3.1.3.4-9 Includes configuration files for following devices: - Quanta 1X1B-32X - Dell Z9264F - Inventec D7054Q28B and D7032Q28B * [bcm sai] upgrade sai version to 3.1.3.4-10 include configuration change to 7060 T0. --- platform/broadcom/sai.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 1f124e1b9232..5120b1518f6e 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,9 +1,9 @@ -BRCM_SAI = libsaibcm_3.1.3.4-7_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm_3.1.3.4-7_amd64.deb?sv=2015-04-05&sr=b&sig=elzOgHCA3G8oKKMfWcbFa%2BvQzAh727mtYJnnVOzVJtY%3D&se=2155-02-07T23%3A37%3A54Z&sp=r" +BRCM_SAI = libsaibcm_3.1.3.4-10_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm_3.1.3.4-10_amd64.deb?sv=2015-04-05&sr=b&sig=72n19AElVmbqo3ahrEFVBwMgR%2FoQ7fhUj4tcadx8pVE%3D&se=2031-12-20T20%3A27%3A14Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.1.3.4-7_amd64.deb +BRCM_SAI_DEV = libsaibcm-dev_3.1.3.4-10_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm-dev_3.1.3.4-7_amd64.deb?sv=2015-04-05&sr=b&sig=rysxdbCA%2BaqBgDnxztdRA2ixiME3ypqRvzyEds8hLw4%3D&se=2155-02-07T23%3A38%3A39Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm-dev_3.1.3.4-10_amd64.deb?sv=2015-04-05&sr=b&sig=cN4qsWX8XW04ZObBDonwh5Uzgmp5A0iRBkpZA9N5Zb8%3D&se=2031-12-20T20%3A26%3A45Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) From 30d289f6aea97182d2941d91065b9bcd7bed669f Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Thu, 12 Apr 2018 18:06:26 -0700 Subject: [PATCH 019/219] 50G support for Arista 7060 (#1580) * 50G SKU for Arista 7060 --- .../Arista-7060CX-32S-D48C8/buffers.json.j2 | 2 + .../buffers_defaults_t0.j2 | 61 +++++++ .../pg_profile_lookup.ini | 17 ++ .../Arista-7060CX-32S-D48C8/port_config.ini | 57 ++++++ .../Arista-7060CX-32S-D48C8/qos.json | 167 ++++++++++++++++++ .../Arista-7060CX-32S-D48C8/sai.profile | 1 + 6 files changed, 305 insertions(+) create mode 100644 device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers.json.j2 create mode 100644 device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers_defaults_t0.j2 create mode 100644 device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/pg_profile_lookup.ini create mode 100644 device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/port_config.ini create mode 100644 device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/qos.json create mode 100644 device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/sai.profile diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers.json.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers.json.j2 new file mode 100644 index 000000000000..1083a6210fc9 --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't0' %} +{%- include 'buffers_config.j2' %} diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..2b7215243f12 --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers_defaults_t0.j2 @@ -0,0 +1,61 @@ +{%- set default_cable = '5m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0,6) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(10,22) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(24,32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(6,10) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(22,24) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11213696", + "type": "ingress", + "mode": "dynamic", + "xoff": "8356608" + }, + "egress_lossy_pool": { + "size": "9532224", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "15982720", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "static_th":"3995680" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/pg_profile_lookup.ini b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/pg_profile_lookup.ini new file mode 100644 index 000000000000..7222f8014925 --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 1248 2288 35776 -4 2288 + 25000 5m 1248 2288 53248 -4 2288 + 40000 5m 1248 2288 66560 -4 2288 + 50000 5m 1248 2288 79872 -4 2288 + 100000 5m 1248 2288 165568 -4 2288 + 10000 40m 1248 2288 37024 -4 2288 + 25000 40m 1248 2288 56160 -4 2288 + 40000 40m 1248 2288 71552 -4 2288 + 50000 40m 1248 2288 85696 -4 2288 + 100000 40m 1248 2288 177632 -4 2288 + 10000 300m 1248 2288 46176 -4 2288 + 25000 300m 1248 2288 79040 -4 2288 + 40000 300m 1248 2288 108160 -4 2288 + 50000 300m 1248 2288 131456 -4 2288 + 100000 300m 1248 2288 268736 -4 2288 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/port_config.ini b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/port_config.ini new file mode 100644 index 000000000000..0366a339f6f9 --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/port_config.ini @@ -0,0 +1,57 @@ +# name lanes alias index speed +Ethernet0 33,34 Ethernet1/1 1 50000 +Ethernet2 35,36 Ethernet1/3 1 50000 +Ethernet4 37,38 Ethernet2/1 2 50000 +Ethernet6 39,40 Ethernet2/3 2 50000 +Ethernet8 41,42 Ethernet3/1 3 50000 +Ethernet10 43,44 Ethernet3/3 3 50000 +Ethernet12 45,46 Ethernet4/1 4 50000 +Ethernet14 47,48 Ethernet4/3 4 50000 +Ethernet16 49,50 Ethernet5/1 5 50000 +Ethernet18 51,52 Ethernet5/3 5 50000 +Ethernet20 53,54 Ethernet6/1 6 50000 +Ethernet22 55,56 Ethernet6/3 6 50000 +Ethernet24 57,58,59,60 Ethernet7/1 7 100000 +Ethernet28 61,62,63,64 Ethernet8/1 8 100000 +Ethernet32 65,66,67,68 Ethernet9/1 9 100000 +Ethernet36 69,70,71,72 Ethernet10/1 10 100000 +Ethernet40 73,74 Ethernet11/1 11 50000 +Ethernet42 75,76 Ethernet11/3 11 50000 +Ethernet44 77,78 Ethernet12/1 12 50000 +Ethernet46 79,80 Ethernet12/3 12 50000 +Ethernet48 81,82 Ethernet13/1 13 50000 +Ethernet50 83,84 Ethernet13/3 13 50000 +Ethernet52 85,86 Ethernet14/1 14 50000 +Ethernet54 87,88 Ethernet14/3 14 50000 +Ethernet56 89,90 Ethernet15/1 15 50000 +Ethernet58 91,92 Ethernet15/3 15 50000 +Ethernet60 93,94 Ethernet16/1 16 50000 +Ethernet62 95,96 Ethernet16/3 16 50000 +Ethernet64 97,98 Ethernet17/1 17 50000 +Ethernet66 99,100 Ethernet17/3 17 50000 +Ethernet68 101,102 Ethernet18/1 18 50000 +Ethernet70 103,104 Ethernet18/3 18 50000 +Ethernet72 105,106 Ethernet19/1 19 50000 +Ethernet74 107,108 Ethernet19/3 19 50000 +Ethernet76 109,110 Ethernet20/1 20 50000 +Ethernet78 111,112 Ethernet20/3 20 50000 +Ethernet80 113,114 Ethernet21/1 21 50000 +Ethernet82 115,116 Ethernet21/3 21 50000 +Ethernet84 117,118 Ethernet22/1 22 50000 +Ethernet86 119,120 Ethernet22/3 22 50000 +Ethernet88 121,122,123,124 Ethernet23/1 23 100000 +Ethernet92 125,126,127,128 Ethernet24/1 24 100000 +Ethernet96 1,2,3,4 Ethernet25/1 25 100000 +Ethernet100 5,6,7,8 Ethernet26/1 26 100000 +Ethernet104 9,10 Ethernet27/1 27 50000 +Ethernet106 11,12 Ethernet27/3 27 50000 +Ethernet108 13,14 Ethernet28/1 28 50000 +Ethernet110 15,16 Ethernet28/3 28 50000 +Ethernet112 17,18 Ethernet29/1 29 50000 +Ethernet114 19,20 Ethernet29/3 29 50000 +Ethernet116 21,22 Ethernet30/1 30 50000 +Ethernet118 23,24 Ethernet30/3 30 50000 +Ethernet120 25,26 Ethernet31/1 31 50000 +Ethernet122 27,28 Ethernet31/3 31 50000 +Ethernet124 29,30 Ethernet32/1 32 50000 +Ethernet126 31,32 Ethernet32/3 32 50000 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/qos.json b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/qos.json new file mode 100644 index 000000000000..8149f1f111ce --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/qos.json @@ -0,0 +1,167 @@ +{ + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "MAP_PFC_PRIORITY_TO_QUEUE": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"3", + "4":"4", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "SCHEDULER": { + "scheduler.0" : { + "type":"DWRR", + "weight": "25" + }, + "scheduler.1" : { + "type":"DWRR", + "weight": "30" + }, + "scheduler.2" : { + "type":"DWRR", + "weight": "20" + } + }, + "PORT_QOS_MAP": { + "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable": "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSY" : { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"512000", + "red_min_threshold":"512000", + "yellow_max_threshold":"512000", + "yellow_min_threshold":"512000", + "green_max_threshold": "184320", + "green_min_threshold": "184320" + }, + "AZURE_LOSSLESS" : { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"512000", + "red_min_threshold":"512000", + "yellow_max_threshold":"512000", + "yellow_min_threshold":"512000", + "green_max_threshold": "184320", + "green_min_threshold": "184320" + } + }, + "QUEUE": { + "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126|0-1": { + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]" + }, + "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126|3-4": { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, + "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126|0": { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, + "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126|1": { + "scheduler" : "[SCHEDULER|scheduler.2]" + } + } +} diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/sai.profile b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/sai.profile new file mode 100644 index 000000000000..0c3ab159868b --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/etc/bcm/th-a7060-cx32s-8x100G+48x50G.config.bcm From 960148a1a3652a72f2c28c1d806d1db173a903ce Mon Sep 17 00:00:00 2001 From: ZivErlich <32637684+ZivErlich@users.noreply.github.com> Date: Thu, 12 Apr 2018 02:52:58 +0300 Subject: [PATCH 020/219] Marvell's updates for SONiC 201803 over SAI v1.2 (#1588) --- platform/marvell/rules.mk | 2 +- platform/marvell/sai.mk | 4 ++-- platform/marvell/sdk.mk | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/platform/marvell/rules.mk b/platform/marvell/rules.mk index 185b7b5fd7a9..c5df6bab194e 100644 --- a/platform/marvell/rules.mk +++ b/platform/marvell/rules.mk @@ -12,7 +12,7 @@ SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_SYNCD_MRVL_RPC) # Inject mrvl sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(MRVL_FPA) $(MRVL_SAI) #$(LIBSAITHRIFT_DEV_MRVL) +$(LIBSAIREDIS)_DEPENDS += $(MRVL_FPA) $(MRVL_SAI) $(LIBSAITHRIFT_DEV_MRVL) # Runtime dependency on mrvl sai is set only for syncd $(SYNCD)_RDEPENDS += $(MRVL_SAI) diff --git a/platform/marvell/sai.mk b/platform/marvell/sai.mk index d2722971f1dd..5016b47f19a9 100644 --- a/platform/marvell/sai.mk +++ b/platform/marvell/sai.mk @@ -1,7 +1,7 @@ # Marvell SAI -export MRVL_SAI_VERSION = 1.0.1 -export MRVL_SAI_TAG = SONiC.201712 +export MRVL_SAI_VERSION = 1.2.1 +export MRVL_SAI_TAG = SONiC.201803 export MRVL_SAI = mrvllibsai_$(MRVL_SAI_VERSION).deb $(MRVL_SAI)_SRC_PATH = $(PLATFORM_PATH)/sai diff --git a/platform/marvell/sdk.mk b/platform/marvell/sdk.mk index 12050df5d34b..3d1ce8e04c88 100644 --- a/platform/marvell/sdk.mk +++ b/platform/marvell/sdk.mk @@ -1,7 +1,7 @@ # Marvell FPA -export MRVL_FPA_VERSION = 1.0.1 -export MRVL_FPA_TAG = SONiC.201712 +export MRVL_FPA_VERSION = 1.2.1 +export MRVL_FPA_TAG = SONiC.201803 export MRVL_FPA = mrvllibfpa_$(MRVL_FPA_VERSION).deb $(MRVL_FPA)_SRC_PATH = $(PLATFORM_PATH)/sdk From 5147d19e3dfb7867aed464eb6a1c8b2f7f6061b7 Mon Sep 17 00:00:00 2001 From: Andriy Moroz Date: Wed, 11 Apr 2018 12:30:16 +0300 Subject: [PATCH 021/219] [Mellanox] Add support for a new platform LS-SN2700 Signed-off-by: Andriy Moroz --- .../LS-SN2700/buffers.json.j2 | 162 +++ .../LS-SN2700/pg_profile_lookup.ini | 17 + .../LS-SN2700/port_config.ini | 33 + .../LS-SN2700/qos.json | 166 +++ .../LS-SN2700/sai.profile | 1 + .../x86_64-mlnx_lssn2700-r0/hw-management | 1 + .../x86_64-mlnx_lssn2700-r0/installer.conf | 1 + .../x86_64-mlnx_lssn2700-r0/minigraph.xml | 1079 +++++++++++++++++ .../x86_64-mlnx_lssn2700-r0/plugins/eeprom.py | 32 + .../plugins/psuutil.py | 74 ++ .../plugins/sfplpmget.py | 43 + .../plugins/sfplpmset.py | 107 ++ .../plugins/sfpreset.py | 45 + .../plugins/sfputil.py | 151 +++ .../x86_64-mlnx_lssn2700-r0/sensors.conf | 21 + 15 files changed, 1933 insertions(+) create mode 100644 device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/buffers.json.j2 create mode 100644 device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/pg_profile_lookup.ini create mode 100644 device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/port_config.ini create mode 100644 device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/qos.json create mode 100644 device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/sai.profile create mode 120000 device/mellanox/x86_64-mlnx_lssn2700-r0/hw-management create mode 100644 device/mellanox/x86_64-mlnx_lssn2700-r0/installer.conf create mode 100644 device/mellanox/x86_64-mlnx_lssn2700-r0/minigraph.xml create mode 100644 device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/eeprom.py create mode 100644 device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/psuutil.py create mode 100644 device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/sfplpmget.py create mode 100644 device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/sfplpmset.py create mode 100644 device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/sfpreset.py create mode 100644 device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/sfputil.py create mode 100644 device/mellanox/x86_64-mlnx_lssn2700-r0/sensors.conf diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/buffers.json.j2 b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/buffers.json.j2 new file mode 100644 index 000000000000..da9c764db92b --- /dev/null +++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/buffers.json.j2 @@ -0,0 +1,162 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '300m' %} +{% set default_ports_num = 32 -%} + +{# 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(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% 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 %} + } + }, +{%if switch_role == 'ToRRouter' %} +{% set ingress_lossless_pool_size = '4194304' %} +{% set ingress_lossy_pool_size = '7340032' %} +{% set egress_lossless_pool_size = '16777152' %} +{% set egress_lossy_pool_size = '7340032' %} +{% else %} +{% set ingress_lossless_pool_size = '2097152' %} +{% set ingress_lossy_pool_size = '5242880' %} +{% set egress_lossless_pool_size = '16777152' %} +{% set egress_lossy_pool_size = '5242880' %} +{%endif %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"0" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "pg_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + }, + "q_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, + "BUFFER_PORT_INGRESS_PROFILE_LIST": { + "{{ port_names }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { + "{{ port_names }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + } + }, + "BUFFER_PG": { + "{{ port_names }}|0-1": { + "profile" : "[BUFFER_PROFILE|pg_lossy_profile]" + } + }, + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|q_lossless_profile]" + }, + "{{ port_names }}|0-1": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + } + } +} diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/pg_profile_lookup.ini new file mode 100644 index 000000000000..b66b129fe43f --- /dev/null +++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 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 + 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 + 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/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/port_config.ini b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/port_config.ini new file mode 100644 index 000000000000..816bb0e94a70 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/port_config.ini @@ -0,0 +1,33 @@ +# name lanes +Ethernet0 0,1,2,3 +Ethernet4 4,5,6,7 +Ethernet8 8,9,10,11 +Ethernet12 12,13,14,15 +Ethernet16 16,17,18,19 +Ethernet20 20,21,22,23 +Ethernet24 24,25,26,27 +Ethernet28 28,29,30,31 +Ethernet32 32,33,34,35 +Ethernet36 36,37,38,39 +Ethernet40 40,41,42,43 +Ethernet44 44,45,46,47 +Ethernet48 48,49,50,51 +Ethernet52 52,53,54,55 +Ethernet56 56,57,58,59 +Ethernet60 60,61,62,63 +Ethernet64 64,65,66,67 +Ethernet68 68,69,70,71 +Ethernet72 72,73,74,75 +Ethernet76 76,77,78,79 +Ethernet80 80,81,82,83 +Ethernet84 84,85,86,87 +Ethernet88 88,89,90,91 +Ethernet92 92,93,94,95 +Ethernet96 96,97,98,99 +Ethernet100 100,101,102,103 +Ethernet104 104,105,106,107 +Ethernet108 108,109,110,111 +Ethernet112 112,113,114,115 +Ethernet116 116,117,118,119 +Ethernet120 120,121,122,123 +Ethernet124 124,125,126,127 diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/qos.json b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/qos.json new file mode 100644 index 000000000000..3e01af3f2c64 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/qos.json @@ -0,0 +1,166 @@ +{ + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4" + } + }, + "MAP_PFC_PRIORITY_TO_QUEUE": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4" + } + }, + "TC_TO_QUEUE_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"3", + "4":"4", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type":"DWRR", + "weight": "25" + }, + "scheduler.1": { + "type":"DWRR", + "weight": "30" + }, + "scheduler.2": { + "type":"DWRR", + "weight": "20" + } + }, + "PFC_PRIORITY_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4" + } + }, + "PORT_QOS_MAP": { + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_to_pg_map" : "[PFC_PRIORITY_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_enable": "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSY": { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"516096", + "red_min_threshold":"516096", + "yellow_max_threshold":"516096", + "yellow_min_threshold":"516096", + "green_max_threshold": "184320", + "green_min_threshold": "184320" + }, + "AZURE_LOSSLESS": { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"516096", + "red_min_threshold":"516096", + "yellow_max_threshold":"516096", + "yellow_min_threshold":"516096", + "green_max_threshold": "184320", + "green_min_threshold": "184320" + } + }, + "QUEUE": { + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0": { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|1": { + "scheduler" : "[SCHEDULER|scheduler.2]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0-1": { + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3-4": { + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" + } + } +} + diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/sai.profile b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/sai.profile new file mode 100644 index 000000000000..9a9a38aeb068 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sai_2700.xml diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/hw-management b/device/mellanox/x86_64-mlnx_lssn2700-r0/hw-management new file mode 120000 index 000000000000..eb5e941daad7 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/hw-management @@ -0,0 +1 @@ +/etc/mlnx/msn2700 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/installer.conf b/device/mellanox/x86_64-mlnx_lssn2700-r0/installer.conf new file mode 100644 index 000000000000..c9c9493a5404 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/installer.conf @@ -0,0 +1 @@ +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="acpi_enforce_resources=lax acpi=noirq" diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/minigraph.xml b/device/mellanox/x86_64-mlnx_lssn2700-r0/minigraph.xml new file mode 100644 index 000000000000..40eb5252610b --- /dev/null +++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/minigraph.xml @@ -0,0 +1,1079 @@ + + + + + + ARISTA01T0 + 10.0.0.33 + sonic + 10.0.0.32 + 1 + 180 + 60 + + + sonic + 10.0.0.0 + ARISTA01T2 + 10.0.0.1 + 1 + 180 + 60 + + + ARISTA02T0 + 10.0.0.35 + sonic + 10.0.0.34 + 1 + 180 + 60 + + + sonic + 10.0.0.2 + ARISTA02T2 + 10.0.0.3 + 1 + 180 + 60 + + + ARISTA03T0 + 10.0.0.37 + sonic + 10.0.0.36 + 1 + 180 + 60 + + + sonic + 10.0.0.4 + ARISTA03T2 + 10.0.0.5 + 1 + 180 + 60 + + + ARISTA04T0 + 10.0.0.39 + sonic + 10.0.0.38 + 1 + 180 + 60 + + + sonic + 10.0.0.6 + ARISTA04T2 + 10.0.0.7 + 1 + 180 + 60 + + + ARISTA05T0 + 10.0.0.41 + sonic + 10.0.0.40 + 1 + 180 + 60 + + + sonic + 10.0.0.8 + ARISTA05T2 + 10.0.0.9 + 1 + 180 + 60 + + + ARISTA06T0 + 10.0.0.43 + sonic + 10.0.0.42 + 1 + 180 + 60 + + + sonic + 10.0.0.10 + ARISTA06T2 + 10.0.0.11 + 1 + 180 + 60 + + + ARISTA07T0 + 10.0.0.45 + sonic + 10.0.0.44 + 1 + 180 + 60 + + + sonic + 10.0.0.12 + ARISTA07T2 + 10.0.0.13 + 1 + 180 + 60 + + + ARISTA08T0 + 10.0.0.47 + sonic + 10.0.0.46 + 1 + 180 + 60 + + + sonic + 10.0.0.14 + ARISTA08T2 + 10.0.0.15 + 1 + 180 + 60 + + + ARISTA09T0 + 10.0.0.49 + sonic + 10.0.0.48 + 1 + 180 + 60 + + + sonic + 10.0.0.16 + ARISTA09T2 + 10.0.0.17 + 1 + 180 + 60 + + + ARISTA10T0 + 10.0.0.51 + sonic + 10.0.0.50 + 1 + 180 + 60 + + + sonic + 10.0.0.18 + ARISTA10T2 + 10.0.0.19 + 1 + 180 + 60 + + + ARISTA11T0 + 10.0.0.53 + sonic + 10.0.0.52 + 1 + 180 + 60 + + + sonic + 10.0.0.20 + ARISTA11T2 + 10.0.0.21 + 1 + 180 + 60 + + + ARISTA12T0 + 10.0.0.55 + sonic + 10.0.0.54 + 1 + 180 + 60 + + + sonic + 10.0.0.22 + ARISTA12T2 + 10.0.0.23 + 1 + 180 + 60 + + + ARISTA13T0 + 10.0.0.57 + sonic + 10.0.0.56 + 1 + 180 + 60 + + + sonic + 10.0.0.24 + ARISTA13T2 + 10.0.0.25 + 1 + 180 + 60 + + + ARISTA14T0 + 10.0.0.59 + sonic + 10.0.0.58 + 1 + 180 + 60 + + + sonic + 10.0.0.26 + ARISTA14T2 + 10.0.0.27 + 1 + 180 + 60 + + + ARISTA15T0 + 10.0.0.61 + sonic + 10.0.0.60 + 1 + 180 + 60 + + + sonic + 10.0.0.28 + ARISTA15T2 + 10.0.0.29 + 1 + 180 + 60 + + + ARISTA16T0 + 10.0.0.63 + sonic + 10.0.0.62 + 1 + 180 + 60 + + + sonic + 10.0.0.30 + ARISTA16T2 + 10.0.0.31 + 1 + 180 + 60 + + + + + 65100 + sonic + + +
10.0.0.33
+ + +
+ +
10.0.0.1
+ + +
+ +
10.0.0.35
+ + +
+ +
10.0.0.3
+ + +
+ +
10.0.0.37
+ + +
+ +
10.0.0.5
+ + +
+ +
10.0.0.39
+ + +
+ +
10.0.0.7
+ + +
+ +
10.0.0.41
+ + +
+ +
10.0.0.9
+ + +
+ +
10.0.0.43
+ + +
+ +
10.0.0.11
+ + +
+ +
10.0.0.45
+ + +
+ +
10.0.0.13
+ + +
+ +
10.0.0.47
+ + +
+ +
10.0.0.15
+ + +
+ +
10.0.0.49
+ + +
+ +
10.0.0.17
+ + +
+ +
10.0.0.51
+ + +
+ +
10.0.0.19
+ + +
+ +
10.0.0.53
+ + +
+ +
10.0.0.21
+ + +
+ +
10.0.0.55
+ + +
+ +
10.0.0.23
+ + +
+ +
10.0.0.57
+ + +
+ +
10.0.0.25
+ + +
+ +
10.0.0.59
+ + +
+ +
10.0.0.27
+ + +
+ +
10.0.0.61
+ + +
+ +
10.0.0.29
+ + +
+ +
10.0.0.63
+ + +
+ +
10.0.0.31
+ + +
+
+ +
+ + 64001 + ARISTA01T0 + + + + 65200 + ARISTA01T2 + + + + 64002 + ARISTA02T0 + + + + 65200 + ARISTA02T2 + + + + 64003 + ARISTA03T0 + + + + 65200 + ARISTA03T2 + + + + 64004 + ARISTA04T0 + + + + 65200 + ARISTA04T2 + + + + 64005 + ARISTA05T0 + + + + 65200 + ARISTA05T2 + + + + 64006 + ARISTA06T0 + + + + 65200 + ARISTA06T2 + + + + 64007 + ARISTA07T0 + + + + 65200 + ARISTA07T2 + + + + 64008 + ARISTA08T0 + + + + 65200 + ARISTA08T2 + + + + 64009 + ARISTA09T0 + + + + 65200 + ARISTA09T2 + + + + 64010 + ARISTA10T0 + + + + 65200 + ARISTA10T2 + + + + 64011 + ARISTA11T0 + + + + 65200 + ARISTA11T2 + + + + 64012 + ARISTA12T0 + + + + 65200 + ARISTA12T2 + + + + 64013 + ARISTA13T0 + + + + 65200 + ARISTA13T2 + + + + 64014 + ARISTA14T0 + + + + 65200 + ARISTA14T2 + + + + 64015 + ARISTA15T0 + + + + 65200 + ARISTA15T2 + + + + 64016 + ARISTA16T0 + + + + 65200 + ARISTA16T2 + + +
+
+ + + + + + HostIP + Loopback0 + + 10.1.0.32/32 + + 10.1.0.32/32 + + + + + + + + sonic + + + + + + Ethernet0 + 10.0.0.0/31 + + + + Ethernet4 + 10.0.0.2/31 + + + + Ethernet8 + 10.0.0.4/31 + + + + Ethernet12 + 10.0.0.6/31 + + + + Ethernet16 + 10.0.0.8/31 + + + + Ethernet20 + 10.0.0.10/31 + + + + Ethernet24 + 10.0.0.12/31 + + + + Ethernet28 + 10.0.0.14/31 + + + + Ethernet32 + 10.0.0.16/31 + + + + Ethernet36 + 10.0.0.18/31 + + + + Ethernet40 + 10.0.0.20/31 + + + + Ethernet44 + 10.0.0.22/31 + + + + Ethernet48 + 10.0.0.24/31 + + + + Ethernet52 + 10.0.0.26/31 + + + + Ethernet56 + 10.0.0.28/31 + + + + Ethernet60 + 10.0.0.30/31 + + + + Ethernet64 + 10.0.0.32/31 + + + + Ethernet68 + 10.0.0.34/31 + + + + Ethernet72 + 10.0.0.36/31 + + + + Ethernet76 + 10.0.0.38/31 + + + + Ethernet80 + 10.0.0.40/31 + + + + Ethernet84 + 10.0.0.42/31 + + + + Ethernet88 + 10.0.0.44/31 + + + + Ethernet92 + 10.0.0.46/31 + + + + Ethernet96 + 10.0.0.48/31 + + + + Ethernet100 + 10.0.0.50/31 + + + + Ethernet104 + 10.0.0.52/31 + + + + Ethernet108 + 10.0.0.54/31 + + + + Ethernet112 + 10.0.0.56/31 + + + + Ethernet116 + 10.0.0.58/31 + + + + Ethernet120 + 10.0.0.60/31 + + + + Ethernet124 + 10.0.0.62/31 + + + + + + + + + + + + DeviceInterfaceLink + sonic + Ethernet0 + ARISTA01T2 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet4 + ARISTA02T2 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet8 + ARISTA03T2 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet12 + ARISTA04T2 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet16 + ARISTA05T2 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet20 + ARISTA06T2 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet24 + ARISTA07T2 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet28 + ARISTA08T2 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet32 + ARISTA09T2 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet36 + ARISTA10T2 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet40 + ARISTA11T2 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet44 + ARISTA12T2 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet48 + ARISTA13T2 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet52 + ARISTA14T2 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet56 + ARISTA15T2 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet60 + ARISTA16T2 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet64 + ARISTA01T0 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet68 + ARISTA02T0 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet72 + ARISTA03T0 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet76 + ARISTA04T0 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet80 + ARISTA05T0 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet84 + ARISTA06T0 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet88 + ARISTA07T0 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet92 + ARISTA08T0 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet96 + ARISTA09T0 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet100 + ARISTA10T0 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet104 + ARISTA11T0 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet108 + ARISTA12T0 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet112 + ARISTA13T0 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet116 + ARISTA14T0 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet120 + ARISTA15T0 + Ethernet1 + + + DeviceInterfaceLink + sonic + Ethernet124 + ARISTA16T0 + Ethernet1 + + + + + sonic + LS-SN2700 + + + + + + + sonic + + + DhcpResources + + + + + NtpResources + + 0.debian.pool.ntp.org;1.debian.pool.ntp.org;2.debian.pool.ntp.org;3.debian.pool.ntp.org + + + SyslogResources + + + + + ErspanDestinationIpv4 + + 2.2.2.2 + + + + + + + sonic + LS-SN2700 +
diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/eeprom.py b/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/eeprom.py new file mode 100644 index 000000000000..3650d9c8b70b --- /dev/null +++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/eeprom.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python + +############################################################################# +# Mellanox +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +try: + import exceptions + import binascii + import time + import optparse + import warnings + import os + import sys + from sonic_eeprom import eeprom_base + from sonic_eeprom import eeprom_tlvinfo + import subprocess +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + _TLV_INFO_MAX_LEN = 256 + + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/bsp/eeprom/sys_eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/psuutil.py b/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/psuutil.py new file mode 100644 index 000000000000..301569c13a94 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/psuutil.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python + +############################################################################# +# Mellanox +# +# Module contains an implementation of SONiC PSU Base API and +# provides the PSUs status which are available in the platform +# +############################################################################# + +import os.path + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + + self.psu_path = "/sys/bus/i2c/devices/2-0060/" + self.psu_presence = "psu{}_status" + self.psu_oper_status = "psu{}_pg_status" + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + + :return: An integer, the number of PSUs available on the device + """ + return 2 + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by 1-based index + + :param index: An integer, 1-based index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is faulty + """ + if index is None: + return False + + status = 0 + try: + with open(self.psu_path + self.psu_oper_status.format(index), 'r') as power_status: + status = int(power_status.read()) + except IOError: + return False + + return status == 1 + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by 1-based index + + :param index: An integer, 1-based index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + if index is None: + return False + + status = 0 + try: + with open(self.psu_path + self.psu_presence.format(index), 'r') as presence_status: + status = int(presence_status.read()) + except IOError: + return False + + return status == 1 diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/sfplpmget.py b/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/sfplpmget.py new file mode 100644 index 000000000000..170766e9bce4 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/sfplpmget.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python + +import sys, errno +import os +from python_sdk_api.sxd_api import * +from python_sdk_api.sx_api import * + +# Check if SFP port number is provided +if len(sys.argv) < 2: + print "SFP module number is missed." + print "Usage: sfplpmget.py " + sys.exit(errno.EINVAL) + +# Init SDK API +rc, handle = sx_api_open(None) +if (rc != SX_STATUS_SUCCESS): + print "Failed to open api handle.\nPlease check that SDK is running." + sys.exit(errno.EACCES) + +pid = os.getpid() +rc = sxd_access_reg_init(pid, None, 0) +if (rc != 0): + print "Failed to initializing register access.\nPlease check that SDK is running." + sys.exit(errno.EACCES) + +# Get SFP module number +sfp_module = int(sys.argv[1]) + +# Get MCION +mcion = ku_mcion_reg() +mcion.module = sfp_module +meta = sxd_reg_meta_t() +meta.dev_id = 1 +meta.swid = 0 +meta.access_cmd = SXD_ACCESS_CMD_GET + +rc = sxd_access_reg_mcion(mcion, meta, 1, None, None) +assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_mcion failed, rc = %d" % rc + +# Get low power mode status +lpm_mask = 1 << 8 +lpm_status = (lpm_mask & mcion.module_status_bits) != 0 +print "LPM ON" if lpm_status else "LPM OFF" diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/sfplpmset.py b/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/sfplpmset.py new file mode 100644 index 000000000000..3f31af9f2944 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/sfplpmset.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python + +import sys, errno +import time +import os +from python_sdk_api.sxd_api import * +from python_sdk_api.sx_api import * + +def get_log_ports(handle, sfp_module): + port_attributes_list = new_sx_port_attributes_t_arr(64) + port_cnt_p = new_uint32_t_p() + uint32_t_p_assign(port_cnt_p, 64) + + rc = sx_api_port_device_get(handle, 1 , 0, port_attributes_list, port_cnt_p) + assert rc == SX_STATUS_SUCCESS, "sx_api_port_device_get failed, rc = %d" % rc + + port_cnt = uint32_t_p_value(port_cnt_p) + log_port_list = [] + for i in range(0, port_cnt): + port_attributes = sx_port_attributes_t_arr_getitem(port_attributes_list, i) + if port_attributes.port_mapping.module_port == sfp_module: + log_port_list.append(port_attributes.log_port) + + return log_port_list + +def set_sfp_admin_status(handle, meta, sfp_module, sfp_log_port_list, admin_status): + # Get PMAOS + pmaos = ku_pmaos_reg() + pmaos.module = sfp_module + meta.access_cmd = SXD_ACCESS_CMD_GET + rc = sxd_access_reg_pmaos(pmaos, meta, 1, None, None) + assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmaos failed, rc = %d" % rc + + # Set admin status to PMAOS + pmaos.ase = 1 + pmaos.ee = 1 + pmaos.e = 2 + pmaos.rst = 0 + if admin_status == SX_PORT_ADMIN_STATUS_DOWN: + pmaos.admin_status = 2 + else: + pmaos.admin_status = 1 + + meta.access_cmd = SXD_ACCESS_CMD_SET + rc = sxd_access_reg_pmaos(pmaos, meta, 1, None, None) + assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmaos failed, rc = %d" % rc + +# Check if SFP port number is provided +if len(sys.argv) < 3: + print "SFP module number or LPM is missed." + print "Usage: sfplpmset.py " + sys.exit(errno.EINVAL) + +lpm_enable = None +if sys.argv[2] == 'on': + lpm_enable = True +elif sys.argv[2] == 'off': + lpm_enable = False +else: + print "Unrecognized LPM parameter. Please use or values" + sys.exit(errno.EINVAL) + +# Init SDK API +rc, handle = sx_api_open(None) +if (rc != SX_STATUS_SUCCESS): + print "Failed to open api handle.\nPlease check that SDK is running." + sys.exit(errno.EACCES) + +pid = os.getpid() +rc = sxd_access_reg_init(pid, None, 0) +if (rc != 0): + print "Failed to initializing register access.\nPlease check that SDK is running." + sys.exit(errno.EACCES); + +# Get SFP module and log ports number and LPM status +sfp_module = int(sys.argv[1]) +log_port_list = get_log_ports(handle, sfp_module) +if not log_port_list: + print "Failed to get log ports" + sys.exit(errno.EACCES) + +# Get PMMP +pmmp = ku_pmmp_reg() +pmmp.module = sfp_module +meta = sxd_reg_meta_t() +meta.dev_id = 1 +meta.swid = 0 +meta.access_cmd = SXD_ACCESS_CMD_GET +rc = sxd_access_reg_pmmp(pmmp, meta, 1, None, None) +assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmmp failed, rc = %d" % rc + +# Disable admin status before LPM settings +set_sfp_admin_status(handle, meta, sfp_module, log_port_list, SX_PORT_ADMIN_STATUS_DOWN) + +# Set low power mode status +lpm_mask = 1 << 8 +if lpm_enable: + pmmp.eeprom_override = pmmp.eeprom_override | lpm_mask +else: + pmmp.eeprom_override = pmmp.eeprom_override & (~lpm_mask) + +meta.access_cmd = SXD_ACCESS_CMD_SET +rc = sxd_access_reg_pmmp(pmmp, meta, 1, None, None) +assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmmp failed, rc = %d" % rc + +# Enable admin status after LPM settings +set_sfp_admin_status(handle, meta, sfp_module, log_port_list, SX_PORT_ADMIN_STATUS_UP) diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/sfpreset.py b/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/sfpreset.py new file mode 100644 index 000000000000..69fa2be614c2 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/sfpreset.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python + +import sys, errno +import os +from python_sdk_api.sxd_api import * +from python_sdk_api.sx_api import * + +# Check if SFP port number is provided +if len(sys.argv) < 2: + print "SFP module number or LPM is missed." + print "Usage: sfpreset.py " + sys.exit(errno.EINVAL) + +# Init SDK API +rc, handle = sx_api_open(None) +if (rc != SX_STATUS_SUCCESS): + print "Failed to open api handle.\nPlease check that SDK is running." + sys.exit(errno.EACCES) + +pid = os.getpid() +rc = sxd_access_reg_init(pid, None, 0) +if (rc != 0): + print "Failed to initializing register access.\nPlease check that SDK is running." + sys.exit(errno.EACCES) + +# Get SFP module number +sfp_module = int(sys.argv[1]) + +# Get PMAOS +pmaos = ku_pmaos_reg() +pmaos.module = sfp_module +meta = sxd_reg_meta_t() +meta.dev_id = 1 +meta.swid = 0 +meta.access_cmd = SXD_ACCESS_CMD_GET + +rc = sxd_access_reg_pmaos(pmaos, meta, 1, None, None) +assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmaos failed, rc = %d" % rc + +# Reset SFP +pmaos.rst = 1 +meta.access_cmd = SXD_ACCESS_CMD_SET +rc = sxd_access_reg_pmaos(pmaos, meta, 1, None, None) +assert rc == SXD_STATUS_SUCCESS, "sxd_access_reg_pmaos failed, rc = %d" % rc +print "Reset flag is set" diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/sfputil.py new file mode 100644 index 000000000000..6aef1310d51f --- /dev/null +++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/plugins/sfputil.py @@ -0,0 +1,151 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import time + import subprocess + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + PORT_START = 0 + PORT_END = 31 + PORTS_IN_BLOCK = 32 + + EEPROM_OFFSET = 1 + + _port_to_eeprom_mapping = {} + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def qsfp_ports(self): + return range(0, self.PORTS_IN_BLOCK + 1) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def __init__(self): + eeprom_path = "/bsp/qsfp/qsfp{0}" + + for x in range(0, self.port_end + 1): + self._port_to_eeprom_mapping[x] = eeprom_path.format(x + self.EEPROM_OFFSET) + + SfpUtilBase.__init__(self) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + try: + reg_file = open("/bsp/qsfp/qsfp%d_status" % (port_num+1)) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = reg_file.readline().rstrip() + + # content is a string with the qsfp status + if content == "good": + return True + + return False + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + lpm_cmd = "docker exec syncd python /usr/share/sonic/platform/plugins/sfplpmget.py {}".format(port_num) + + try: + output = subprocess.check_output(lpm_cmd, shell=True) + if 'LPM ON' in output: + return True + except subprocess.CalledProcessError as e: + print "Error! Unable to get LPM for {}, rc = {}, err msg: {}".format(port_num, e.returncode, e.output) + return False + + return False + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + curr_lpmode = self.get_low_power_mode(port_num) + if curr_lpmode == lpmode: + return True + + lpm = 'on' if lpmode else 'off' + lpm_cmd = "docker exec syncd python /usr/share/sonic/platform/plugins/sfplpmset.py {} {}".format(port_num, lpm) + sfp_port_names = self.physical_to_logical[port_num] + + # Get port admin status + try: + enabled_ports = subprocess.check_output("ip link show up", shell=True) + except subprocess.CalledProcessError as e: + print "Error! Unable to get ports status, err msg: {}".format(e.output) + return False + + port_to_disable = [] + for port in sfp_port_names: + if port in enabled_ports: + port_to_disable.append(port) + + # Disable ports before LPM settings + for port in port_to_disable: + try: + subprocess.check_output("ifconfig {} down".format(port), shell=True) + except subprocess.CalledProcessError as e: + print "Error! Unable to set admin status to DOWN for {}, rc = {}, err msg: {}".format(port, e.returncode, e.output) + return False + + time.sleep(3) + + # Set LPM + try: + subprocess.check_output(lpm_cmd, shell=True) + except subprocess.CalledProcessError as e: + print "Error! Unable to set LPM for {}, rc = {}, err msg: {}".format(port_num, e.returncode, e.output) + return False + + # Enable ports after LPM settings + for port in port_to_disable: + try: + subprocess.check_output("ifconfig {} up".format(port), shell=True) + except subprocess.CalledProcessError as e: + print "Error! Unable to set admin status to UP for {}, rc = {}, err msg: {}".format(port, e.returncode, e.output) + return False + + return True + + def reset(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + lpm_cmd = "docker exec syncd python /usr/share/sonic/platform/plugins/sfpreset.py {}".format(port_num) + + try: + subprocess.check_output(lpm_cmd, shell=True) + return True + except subprocess.CalledProcessError as e: + print "Error! Unable to set LPM for {}, rc = {}, err msg: {}".format(port_num, e.returncode, e.output) + return False + + return False diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/sensors.conf b/device/mellanox/x86_64-mlnx_lssn2700-r0/sensors.conf new file mode 100644 index 000000000000..a3e30391863e --- /dev/null +++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/sensors.conf @@ -0,0 +1,21 @@ +bus "i2c-7" "i2c-1-mux (chan_id 5)" +chip "lm75-i2c-7-4a" + label temp1 "Ambient Port Temp" + +bus "i2c-5" "i2c-1-mux (chan_id 3)" +chip "ucd9200-i2c-5-27" + label in1 "UCD1 vin" + label in2 "ASIC 3.3 vout" + label in3 "ASIC 1.2 vout" + label temp1 "UCD1 Temp" + label temp2 "UCD1 Temp2" + +chip "ucd9200-i2c-5-41" + label in1 "UCD2 vin" + label in2 "ASIC Vcore vout" + label temp1 "UCD2 Temp1" + label temp2 "UCD2 Temp2" + +bus "i2c-17" "i2c-1-mux (chan_id 7)" +chip "lm75-i2c-17-49" + label temp1 "Ambient Board Temp" From 9c2a33867496dd529107302fddeec4d97143c646 Mon Sep 17 00:00:00 2001 From: "Wenda Ni, Ph.D" Date: Fri, 13 Apr 2018 22:22:21 -0700 Subject: [PATCH 022/219] [devices]: Merge ingress service pools of lossless and lossy traffic for TD2 (#1578) Signed-off-by: Wenda --- .../Arista-7050-QX32/buffers.json.j2 | 19 +++++++------------ .../Arista-7050-QX-32S/buffers.json.j2 | 19 +++++++------------ .../Force10-S6000/buffers.json.j2 | 19 +++++++------------ 3 files changed, 21 insertions(+), 36 deletions(-) diff --git a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers.json.j2 b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers.json.j2 index 10f9da575a1b..551f73ca0477 100644 --- a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers.json.j2 +++ b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers.json.j2 @@ -69,22 +69,17 @@ }, "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "7274496", - "type": "ingress", - "mode": "dynamic" - }, - "ingress_lossy_pool": { - "size": "5491712", + "size": "12766208", "type": "ingress", "mode": "dynamic" }, "egress_lossless_pool": { - "size": "7274496", + "size": "12766208", "type": "egress", "mode": "static" }, "egress_lossy_pool": { - "size": "5491712", + "size": "8072396", "type": "egress", "mode": "dynamic" } @@ -95,18 +90,18 @@ "xon":"18432", "xoff":"40560", "size":"41808", - "dynamic_th":"-3", + "dynamic_th":"-4", "xon_offset":"2496" }, "ingress_lossy_profile": { - "pool":"[BUFFER_POOL|ingress_lossy_pool]", - "size":"1518", + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", "dynamic_th":"3" }, "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", - "static_th":"7274496" + "static_th":"12766208" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/buffers.json.j2 b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/buffers.json.j2 index 10f9da575a1b..551f73ca0477 100644 --- a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/buffers.json.j2 +++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/buffers.json.j2 @@ -69,22 +69,17 @@ }, "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "7274496", - "type": "ingress", - "mode": "dynamic" - }, - "ingress_lossy_pool": { - "size": "5491712", + "size": "12766208", "type": "ingress", "mode": "dynamic" }, "egress_lossless_pool": { - "size": "7274496", + "size": "12766208", "type": "egress", "mode": "static" }, "egress_lossy_pool": { - "size": "5491712", + "size": "8072396", "type": "egress", "mode": "dynamic" } @@ -95,18 +90,18 @@ "xon":"18432", "xoff":"40560", "size":"41808", - "dynamic_th":"-3", + "dynamic_th":"-4", "xon_offset":"2496" }, "ingress_lossy_profile": { - "pool":"[BUFFER_POOL|ingress_lossy_pool]", - "size":"1518", + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", "dynamic_th":"3" }, "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", - "static_th":"7274496" + "static_th":"12766208" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers.json.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers.json.j2 index 10f9da575a1b..551f73ca0477 100644 --- a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers.json.j2 +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers.json.j2 @@ -69,22 +69,17 @@ }, "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "7274496", - "type": "ingress", - "mode": "dynamic" - }, - "ingress_lossy_pool": { - "size": "5491712", + "size": "12766208", "type": "ingress", "mode": "dynamic" }, "egress_lossless_pool": { - "size": "7274496", + "size": "12766208", "type": "egress", "mode": "static" }, "egress_lossy_pool": { - "size": "5491712", + "size": "8072396", "type": "egress", "mode": "dynamic" } @@ -95,18 +90,18 @@ "xon":"18432", "xoff":"40560", "size":"41808", - "dynamic_th":"-3", + "dynamic_th":"-4", "xon_offset":"2496" }, "ingress_lossy_profile": { - "pool":"[BUFFER_POOL|ingress_lossy_pool]", - "size":"1518", + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", "dynamic_th":"3" }, "egress_lossless_profile": { "pool":"[BUFFER_POOL|egress_lossless_pool]", "size":"0", - "static_th":"7274496" + "static_th":"12766208" }, "egress_lossy_profile": { "pool":"[BUFFER_POOL|egress_lossy_pool]", From a194d65fe8e2e0b38a1d334e020c200ce2704425 Mon Sep 17 00:00:00 2001 From: hui-ma Date: Tue, 17 Apr 2018 10:14:07 -0700 Subject: [PATCH 023/219] [sonic-utilities] add pfcstat and queuestat tool (#1606) --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 5e476d6d549c..ca11c1533fce 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 5e476d6d549cf40b68e86ae01dcb703b567b85e3 +Subproject commit ca11c1533fce57365824902c9bc382cb0b269554 From 83517f5c4233b1d63ccc2cfe551816a2abd39c0e Mon Sep 17 00:00:00 2001 From: padmanarayana Date: Wed, 18 Apr 2018 06:48:09 +0530 Subject: [PATCH 024/219] Add support for S6100 switchport LEDs (#1610) --- .../x86_64-dell_s6100_c2538-r0/led_proc_init.soc | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 device/dell/x86_64-dell_s6100_c2538-r0/led_proc_init.soc diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/led_proc_init.soc b/device/dell/x86_64-dell_s6100_c2538-r0/led_proc_init.soc new file mode 100644 index 000000000000..a4a44f15bcf1 --- /dev/null +++ b/device/dell/x86_64-dell_s6100_c2538-r0/led_proc_init.soc @@ -0,0 +1,13 @@ +# LED microprocessor initialization for Dell S6100 + +led 0 stop +led 0 prog 02 00 60 FE 2E FE 67 2C 86 FE 67 5B 67 5B 67 5B 86 FE 2E FE 67 2C 86 FE 86 FE 06 FE D2 40 71 04 12 FF 85 05 D2 05 71 2A 52 00 3A A0 32 08 97 71 33 77 5B 32 00 32 01 B7 97 75 42 12 BC FE FE 02 0A 50 12 BC FE FE 95 75 4C 85 77 54 16 FF DA 02 71 5B 77 54 22 0E 87 22 0E 87 57 22 0F 87 22 0F 87 57 22 0F 87 22 0E 87 57 +led 0 auto on +led 0 start + +led 1 stop +led 1 prog 02 00 60 FE 2E FE 67 2C 86 FE 67 5B 67 5B 67 5B 86 FE 2E FE 67 2C 86 FE 86 FE 06 FE D2 40 71 04 12 FF 85 05 D2 05 71 2A 52 00 3A A0 32 08 97 71 33 77 5B 32 00 32 01 B7 97 75 42 12 BC FE FE 02 0A 50 12 BC FE FE 95 75 4C 85 77 54 16 FF DA 02 71 5B 77 54 22 0E 87 22 0E 87 57 22 0F 87 22 0F 87 57 22 0F 87 22 0E 87 57 +led 1 auto on +led 1 start + +led 2 stop From 8be17f65ab2d2f89bcf5fda6cbee1c4e7503440c Mon Sep 17 00:00:00 2001 From: Volodymyr Samotiy Date: Wed, 18 Apr 2018 19:37:27 +0300 Subject: [PATCH 025/219] [ip-in-ip]: Fix config template to apply correct platform depended values (#1619) Signed-off-by: Volodymyr Samotiy --- dockers/docker-orchagent/ipinip.json.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockers/docker-orchagent/ipinip.json.j2 b/dockers/docker-orchagent/ipinip.json.j2 index 2554755c701d..bee97f45b8ae 100644 --- a/dockers/docker-orchagent/ipinip.json.j2 +++ b/dockers/docker-orchagent/ipinip.json.j2 @@ -11,7 +11,7 @@ "tunnel_type":"IPINIP", "src_ip":"{{ ipv4_loopback_addresses | first | ip }}", "dst_ip":"{% for prefix in ipv4_loopback_addresses %}{{ prefix | ip }}{% if not loop.last %},{% endif %}{% endfor %}", -{% if onie_switch_asic == "mlnx" %} +{% if "mlnx" in DEVICE_METADATA.localhost.platform %} "dscp_mode":"uniform", "ecn_mode":"standard", {% else %} From 225a4fa640f32a99581f1767aacbb852fb432254 Mon Sep 17 00:00:00 2001 From: Shuotian Cheng Date: Wed, 18 Apr 2018 14:54:15 -0700 Subject: [PATCH 026/219] [platform-common]: Update sonic-platform-common submodule (#1620) [sfputilbase]: Add logic to parse the title of port_config.ini file Signed-off-by: Shu0T1an ChenG --- src/sonic-platform-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-common b/src/sonic-platform-common index 560b465cb516..b553dba4ca82 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit 560b465cb5166d0ad0c56312292bba990a122419 +Subproject commit b553dba4ca82997dcc60a3b3a68111d7af8d62fc From 02826667e9eeebec5a04b30d1b2b973154a69b71 Mon Sep 17 00:00:00 2001 From: Taoyu Li Date: Wed, 18 Apr 2018 18:26:09 -0700 Subject: [PATCH 027/219] [sonic-cfggen] Be case insensitive to hostname in minigraph (#1614) --- src/sonic-config-engine/minigraph.py | 19 +- .../tests/simple-sample-graph-case.xml | 317 ++++++++++++++++++ .../tests/test_minigraph_case.py | 111 ++++++ 3 files changed, 438 insertions(+), 9 deletions(-) create mode 100644 src/sonic-config-engine/tests/simple-sample-graph-case.xml create mode 100644 src/sonic-config-engine/tests/test_minigraph_case.py diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 4ac7e9d68c92..dba1a6516cf4 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -77,7 +77,7 @@ def parse_png(png, hname): bandwidth_node = link.find(str(QName(ns, "Bandwidth"))) bandwidth = bandwidth_node.text if bandwidth_node is not None else None - if enddevice == hname: + if enddevice.lower() == hname.lower(): if port_alias_map.has_key(endport): endport = port_alias_map[endport] neighbors[endport] = {'name': startdevice, 'port': startport} @@ -119,7 +119,7 @@ def parse_png(png, hname): def parse_dpg(dpg, hname): for child in dpg: hostname = child.find(str(QName(ns, "Hostname"))) - if hostname.text != hname: + if hostname.text.lower() != hname.lower(): continue ipintfs = child.find(str(QName(ns, "IPInterfaces"))) @@ -263,7 +263,7 @@ def parse_cpg(cpg, hname): else: keepalive = 60 nhopself = 1 if session.find(str(QName(ns, "NextHopSelf"))) is not None else 0 - if end_router == hname: + if end_router.lower() == hname.lower(): bgp_sessions[start_peer.lower()] = { 'name': start_router, 'local_addr': end_peer.lower(), @@ -285,7 +285,7 @@ def parse_cpg(cpg, hname): for router in child.findall(str(QName(ns1, "BGPRouterDeclaration"))): asn = router.find(str(QName(ns1, "ASN"))).text hostname = router.find(str(QName(ns1, "Hostname"))).text - if hostname == hname: + if hostname.lower() == hname.lower(): myasn = asn peers = router.find(str(QName(ns1, "Peers"))) for bgpPeer in peers.findall(str(QName(ns, "BGPPeer"))): @@ -301,7 +301,7 @@ def parse_cpg(cpg, hname): else: for peer in bgp_sessions: bgp_session = bgp_sessions[peer] - if hostname == bgp_session['name']: + if hostname.lower() == bgp_session['name'].lower(): bgp_session['asn'] = asn bgp_sessions = { key: bgp_sessions[key] for key in bgp_sessions if bgp_sessions[key].has_key('asn') and int(bgp_sessions[key]['asn']) != 0 } return bgp_sessions, myasn, bgp_peers_with_range @@ -317,7 +317,7 @@ def parse_meta(meta, hname): deployment_id = None device_metas = meta.find(str(QName(ns, "Devices"))) for device in device_metas.findall(str(QName(ns1, "DeviceMetadata"))): - if device.find(str(QName(ns1, "Name"))).text == hname: + if device.find(str(QName(ns1, "Name"))).text.lower() == hname.lower(): properties = device.find(str(QName(ns1, "Properties"))) for device_property in properties.findall(str(QName(ns1, "DeviceProperty"))): name = device_property.find(str(QName(ns1, "Name"))).text @@ -411,13 +411,14 @@ def parse_xml(filename, platform=None, port_config_file=None): elif child.tag == str(QName(ns, "DeviceInfos")): (port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku) - results = {} + current_device = [devices[key] for key in devices if key.lower() == hostname.lower()][0] + results = {} results['DEVICE_METADATA'] = {'localhost': { 'bgp_asn': bgp_asn, 'deployment_id': deployment_id, 'hostname': hostname, 'hwsku': hwsku, - 'type': devices[hostname]['type'] + 'type': current_device['type'] }} results['BGP_NEIGHBOR'] = bgp_sessions results['BGP_PEER_RANGE'] = bgp_peers_with_range @@ -476,7 +477,7 @@ def parse_xml(filename, platform=None, port_config_file=None): results['VLAN_MEMBER'] = vlan_members results['DEVICE_NEIGHBOR'] = neighbors - results['DEVICE_NEIGHBOR_METADATA'] = { key:devices[key] for key in devices if key != hostname } + results['DEVICE_NEIGHBOR_METADATA'] = { key:devices[key] for key in devices if key.lower() != hostname.lower() } results['SYSLOG_SERVER'] = dict((item, {}) for item in syslog_servers) results['DHCP_SERVER'] = dict((item, {}) for item in dhcp_servers) results['NTP_SERVER'] = dict((item, {}) for item in ntp_servers) diff --git a/src/sonic-config-engine/tests/simple-sample-graph-case.xml b/src/sonic-config-engine/tests/simple-sample-graph-case.xml new file mode 100644 index 000000000000..2d2f08f4d0d2 --- /dev/null +++ b/src/sonic-config-engine/tests/simple-sample-graph-case.xml @@ -0,0 +1,317 @@ + + + + + + false + switch-t0 + 10.0.0.56 + ARISTA01T1 + 10.0.0.57 + 1 + 180 + 60 + + + switch-t0 + FC00::71 + ARISTA01T1 + FC00::72 + 1 + 180 + 60 + + + false + switch-t0 + 10.0.0.58 + ARISTA02T1 + 10.0.0.59 + 1 + 180 + 60 + + + switch-t0 + FC00::75 + ARISTA02T1 + FC00::76 + 1 + 180 + 60 + + + + + 65100 + switch-t0 + + +
10.0.0.57
+ + + +
+ +
10.0.0.59
+ + + +
+
+ +
+ + 64600 + ARISTA01T1 + + + + 64600 + ARISTA02T1 + + + + 64600 + ARISTA03T1 + + + + 64600 + ARISTA04T1 + + +
+
+ + + + + + HostIP + Loopback0 + + 10.1.0.32/32 + + 10.1.0.32/32 + + + HostIP1 + Loopback0 + + FC00:1::32/128 + + FC00:1::32/128 + + + + + HostIP + eth0 + + 10.0.0.100/24 + + 10.0.0.100/24 + + + + + + + switch-t0 + + + PortChannel01 + fortyGigE0/4 + + + + + + ab1 + fortyGigE0/8 + 192.0.0.1;192.0.0.2 + 1000 + 1000 + 192.168.0.0/27 + + + + + + PortChannel01 + 10.0.0.56/31 + + + + PortChannel01 + FC00::71/126 + + + + fortyGigE0/0 + 10.0.0.58/31 + + + + fortyGigE0/0 + FC00::75/126 + + + + ab1 + 192.168.0.1/27 + + + + + + PortChannel01 + DataAcl + DataPlane + + + SNMP + SNMP_ACL + SNMP + + + + + + + + + + + switch-t0 + Force10-S6000 + + + ARISTA01T1 + Arista + + + ARISTA02T1 + Arista + + + ARISTA03T1 + Arista + + + ARISTA04T1 + Arista + + + + + + + switch-t0 + + + DeploymentId + + 1 + + + ErspanDestinationIpv4 + + 10.0.100.1 + + + NtpResources + + 10.0.10.1;10.0.10.2 + + + + SnmpResources + + 10.0.10.3;10.0.10.4 + + + + SyslogResources + + 10.0.10.5;10.0.10.6; + + + + TacacsServer + + 10.0.10.7;10.0.10.8 + + + + + + + + + true + + + DeviceInterface + + true + true + 1 + fortyGigE0/0 + + false + 0 + 0 + 10000 + + + DeviceInterface + + true + true + 1 + fortyGigE0/4 + + false + 0 + 0 + 25000 + + + DeviceInterface + + true + true + 1 + fortyGigE0/8 + + false + 0 + 0 + 40000 + Interface description + + + DeviceInterface + + true + true + 1 + fortyGigE0/12 + + false + 0 + 0 + 100000 + Interface description + + + true + 0 + Force10-S6000 + + + switch-T0 + Force10-S6000 +
diff --git a/src/sonic-config-engine/tests/test_minigraph_case.py b/src/sonic-config-engine/tests/test_minigraph_case.py new file mode 100644 index 000000000000..754bdae799f4 --- /dev/null +++ b/src/sonic-config-engine/tests/test_minigraph_case.py @@ -0,0 +1,111 @@ +from unittest import TestCase +import subprocess +import os + +class TestCfgGenCaseInsensitive(TestCase): + + def setUp(self): + self.test_dir = os.path.dirname(os.path.realpath(__file__)) + self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.sample_graph = os.path.join(self.test_dir, 'simple-sample-graph-case.xml') + self.port_config = os.path.join(self.test_dir, 't0-sample-port-config.ini') + + def run_script(self, argument, check_stderr=False): + print '\n Running sonic-cfggen ' + argument + if check_stderr: + output = subprocess.check_output(self.script_file + ' ' + argument, stderr=subprocess.STDOUT, shell=True) + else: + output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + + linecount = output.strip().count('\n') + if linecount <= 0: + print ' Output: ' + output.strip() + else: + print ' Output: ({0} lines, {1} bytes)'.format(linecount + 1, len(output)) + return output + + def test_dummy_run(self): + argument = '' + output = self.run_script(argument) + self.assertEqual(output, '') + + def test_minigraph_sku(self): + argument = '-v "DEVICE_METADATA[\'localhost\'][\'hwsku\']" -m "' + self.sample_graph + '"' + output = self.run_script(argument) + self.assertEqual(output.strip(), 'Force10-S6000') + + def test_print_data(self): + argument = '-m "' + self.sample_graph + '" --print-data' + output = self.run_script(argument) + self.assertTrue(len(output.strip()) > 0) + + def test_jinja_expression(self): + argument = '-m "' + self.sample_graph + '" -v "DEVICE_METADATA[\'localhost\'][\'type\']"' + output = self.run_script(argument) + self.assertEqual(output.strip(), 'ToRRouter') + + def test_additional_json_data(self): + argument = '-a \'{"key1":"value1"}\' -v key1' + output = self.run_script(argument) + self.assertEqual(output.strip(), 'value1') + + def test_read_yaml(self): + argument = '-v yml_item -y ' + os.path.join(self.test_dir, 'test.yml') + output = self.run_script(argument) + self.assertEqual(output.strip(), '[\'value1\', \'value2\']') + + def test_render_template(self): + argument = '-y ' + os.path.join(self.test_dir, 'test.yml') + ' -t ' + os.path.join(self.test_dir, 'test.j2') + output = self.run_script(argument) + self.assertEqual(output.strip(), 'value1\nvalue2') + + def test_minigraph_everflow(self): + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v MIRROR_SESSION' + output = self.run_script(argument) + self.assertEqual(output.strip(), "{'everflow0': {'src_ip': '10.1.0.32', 'dst_ip': '10.0.100.1'}}") + + def test_minigraph_interfaces(self): + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v \'INTERFACE.keys()\'' + output = self.run_script(argument) + self.assertEqual(output.strip(), "[('Ethernet0', '10.0.0.58/31'), ('Ethernet0', 'FC00::75/126')]") + + def test_minigraph_vlans(self): + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v VLAN' + output = self.run_script(argument) + self.assertEqual(output.strip(), "{'Vlan1000': {'alias': 'ab1', 'dhcp_servers': ['192.0.0.1', '192.0.0.2'], 'vlanid': '1000'}}") + + def test_minigraph_vlan_members(self): + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v VLAN_MEMBER' + output = self.run_script(argument) + self.assertEqual(output.strip(), "{'Vlan1000|Ethernet8': {'tagging_mode': 'untagged'}}") + + def test_minigraph_vlan_interfaces(self): + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "VLAN_INTERFACE.keys()"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "[('Vlan1000', '192.168.0.1/27')]") + + def test_minigraph_portchannels(self): + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v PORTCHANNEL' + output = self.run_script(argument) + self.assertEqual(output.strip(), "{'PortChannel01': {'members': ['Ethernet4']}}") + + def test_minigraph_deployment_id(self): + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "DEVICE_METADATA[\'localhost\'][\'deployment_id\']"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "1") + + def test_metadata_everflow(self): + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "MIRROR_SESSION"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "{'everflow0': {'src_ip': '10.1.0.32', 'dst_ip': '10.0.100.1'}}") + + def test_metadata_tacacs(self): + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "TACPLUS_SERVER"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "{'10.0.10.7': {'priority': '1', 'tcp_port': '49'}, '10.0.10.8': {'priority': '1', 'tcp_port': '49'}}") + + def test_metadata_ntp(self): + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "NTP_SERVER"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "{'10.0.10.1': {}, '10.0.10.2': {}}") + From dcdcf404de07be2fd1b1009bb4e5c00a92fae91b Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Thu, 19 Apr 2018 03:50:36 +0000 Subject: [PATCH 028/219] [bugfix]: pass correct port name to led_control.py in ledd Signed-off-by: Guohan Lu --- src/sonic-platform-daemons | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-daemons b/src/sonic-platform-daemons index 31c007e260ba..64ec0ca4c184 160000 --- a/src/sonic-platform-daemons +++ b/src/sonic-platform-daemons @@ -1 +1 @@ -Subproject commit 31c007e260ba081bc73cbf467eb27cd8747c2177 +Subproject commit 64ec0ca4c18418acf1a852b28313ce904481643c From 9fad33c41108f38f20eec5aa75209dbb10b5a32d Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Mon, 23 Apr 2018 00:09:26 -0700 Subject: [PATCH 029/219] [cfggen]: Fix build by fixing pyangbind version (#1633) Signed-off-by: Qi Luo --- src/sonic-config-engine/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-config-engine/setup.py b/src/sonic-config-engine/setup.py index 296b7a03a6b9..e1530d0d3d32 100755 --- a/src/sonic-config-engine/setup.py +++ b/src/sonic-config-engine/setup.py @@ -17,6 +17,6 @@ def get_test_suite(): url='https://github.com/Azure/sonic-buildimage', py_modules=['portconfig', 'minigraph', 'openconfig_acl', 'sonic_platform'], scripts=['sonic-cfggen'], - install_requires=['lxml', 'jinja2', 'netaddr', 'ipaddr', 'pyyaml', 'pyangbind'], + install_requires=['lxml', 'jinja2', 'netaddr', 'ipaddr', 'pyyaml', 'pyangbind==0.6.0'], test_suite='setup.get_test_suite', ) From a84ca2d5a2dfe6b6b82cb1ebb178e6661b181857 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Tue, 24 Apr 2018 17:44:21 +0000 Subject: [PATCH 030/219] [swss]: update sonic-swss submodule * ea34b92 2018-04-24 | Fix tables handling race condition in buffermgr (#484) (HEAD -> 201803, origin/201803) [Andriy Moroz] * 53831be 2018-04-19 | [pfcwd]: create PFCWD acl instead of L3 ACL (#479) [sihuihan88] Signed-off-by: Guohan Lu --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index d711d2cf5783..ea34b92b37c4 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit d711d2cf57839589aa7d6653b252305c31f8c2b0 +Subproject commit ea34b92b37c46b45b7aeba3efe1da605ff2c95d8 From f46e87391620b56f0acd70b03e93aaf9c4d54315 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 24 Apr 2018 15:13:51 -0700 Subject: [PATCH 031/219] [radvd] Ensure at least one interface is specified in radvd.conf before starting radvd (#1636) --- dockers/docker-router-advertiser/start.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dockers/docker-router-advertiser/start.sh b/dockers/docker-router-advertiser/start.sh index 7fcaf65a79c9..159006a176bd 100755 --- a/dockers/docker-router-advertiser/start.sh +++ b/dockers/docker-router-advertiser/start.sh @@ -14,5 +14,12 @@ fi # Generate /etc/radvd.conf config file sonic-cfggen -d -t /usr/share/sonic/templates/radvd.conf.j2 > /etc/radvd.conf +# Enusre at least one interface is specified in radvd.conf +NUM_IFACES=$(grep -c "^interface " /etc/radvd.conf) +if [ $NUM_IFACES -eq 0 ]; then + echo "No interfaces specified in radvd.conf. Not starting router advertiser process." + exit 0 +fi + # Start the router advertiser supervisorctl start radvd From 90c94334e5568592c201b825ab1999a05946c830 Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Thu, 26 Apr 2018 15:27:20 -0700 Subject: [PATCH 032/219] [updategraph]: Keep updategraph service active after start (#1651) --- files/image_config/updategraph/updategraph.service | 1 + 1 file changed, 1 insertion(+) diff --git a/files/image_config/updategraph/updategraph.service b/files/image_config/updategraph/updategraph.service index 4599f56bdc64..ec478d93a132 100644 --- a/files/image_config/updategraph/updategraph.service +++ b/files/image_config/updategraph/updategraph.service @@ -7,6 +7,7 @@ Requires=database.service [Service] Type=oneshot ExecStart=/usr/bin/updategraph +RemainAfterExit=yes [Install] WantedBy=multi-user.target From 018b8405b4450c3a9709a5dbdcf7f3b25fd1eff3 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Thu, 26 Apr 2018 19:01:33 -0700 Subject: [PATCH 033/219] [docker-lldpd]: Various fixes (#1650) * We don't need configure anything until we have interfaces created * Don't run lldpcli for a port, until a port is up and running * Remove lldpd socket before starting lldpd * Fix sample files for lldpd configuration * Another attempt to make the test working * Quick fix for lldpd paused after start bug --- dockers/docker-lldp-sv2/lldpd.conf.j2 | 3 --- dockers/docker-lldp-sv2/lldpmgrd | 19 +++++++++++++++ dockers/docker-lldp-sv2/start.sh | 24 +++++++++++++++++++ .../tests/sample_output/lldpd.conf | 4 ---- 4 files changed, 43 insertions(+), 7 deletions(-) diff --git a/dockers/docker-lldp-sv2/lldpd.conf.j2 b/dockers/docker-lldp-sv2/lldpd.conf.j2 index ea8be54b097d..94a04596699f 100644 --- a/dockers/docker-lldp-sv2/lldpd.conf.j2 +++ b/dockers/docker-lldp-sv2/lldpd.conf.j2 @@ -1,6 +1,3 @@ {% if MGMT_INTERFACE %} configure ports eth0 lldp portidsubtype local {{ MGMT_INTERFACE.keys()[0][0] }} {% endif %} -{% for local_port in DEVICE_NEIGHBOR %} -configure ports {{ local_port }} lldp portidsubtype local {{ PORT[local_port]['alias'] }} description {{ DEVICE_NEIGHBOR[local_port]['name'] }}:{{ DEVICE_NEIGHBOR[local_port]['port'] }} -{% endfor %} diff --git a/dockers/docker-lldp-sv2/lldpmgrd b/dockers/docker-lldp-sv2/lldpmgrd index 1d13b1aaafd4..65f624dfd1dc 100755 --- a/dockers/docker-lldp-sv2/lldpmgrd +++ b/dockers/docker-lldp-sv2/lldpmgrd @@ -20,6 +20,7 @@ try: import subprocess import sys import syslog + import os.path from swsscommon import swsscommon except ImportError as err: raise ImportError("%s - required module not found" % str(err)) @@ -70,6 +71,19 @@ def signal_handler(sig, frame): else: log_warning("Caught unhandled signal '" + sig + "'") +# ========================== Helpers ================================== + +def is_port_up(port_name): + filename = "/sys/class/net/%s/operstate" % port_name + if not os.path.exists(filename): + return False + + with open(filename) as fp: + state = fp.read() + if 'up' in state: + return True + else: + return False # ============================== Classes ============================== @@ -161,6 +175,11 @@ class LldpManager(object): to_delete = [] for (port_name, cmd) in self.pending_cmds.iteritems(): + if not is_port_up(port_name): + # it doesn't make any sense to configure lldpd if the target port is unavailable + # let's postpone the command for the next iteration + continue + log_debug("Running command: '{}'".format(cmd)) proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) diff --git a/dockers/docker-lldp-sv2/start.sh b/dockers/docker-lldp-sv2/start.sh index 26337fb0667d..adc322979813 100755 --- a/dockers/docker-lldp-sv2/start.sh +++ b/dockers/docker-lldp-sv2/start.sh @@ -6,8 +6,32 @@ mkdir -p /var/sonic echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status rm -f /var/run/rsyslogd.pid +rm -f /var/run/lldpd.socket supervisorctl start rsyslogd supervisorctl start lldpd supervisorctl start lldp-syncd supervisorctl start lldpmgrd + +# Current lldpd version has a bug. +# When lldpd starts it is in the pause state by default +# But then it execute 'lldpcli resume' to configure and unpause itself. +# When lldpd execute lldpcli, it doesn't check the return code +# Sometimes lldpcli returns failure, but lldpd doesn't catch it +# and keeps working paused and unconfigured +# +# The fix below addresses the issue. +# + +# wait until lldpd started +until [[ -e /var/run/lldpd.socket ]]; +do + sleep 1; +done + +# Manually try to resume lldpd, until it's successful +while /bin/true; +do + lldpcli -u /var/run/lldpd.socket -c /etc/lldpd.conf -c /etc/lldpd.d resume > /dev/null && break + sleep 1 +done diff --git a/src/sonic-config-engine/tests/sample_output/lldpd.conf b/src/sonic-config-engine/tests/sample_output/lldpd.conf index d906f909bc7d..29739cb890d0 100644 --- a/src/sonic-config-engine/tests/sample_output/lldpd.conf +++ b/src/sonic-config-engine/tests/sample_output/lldpd.conf @@ -1,6 +1,2 @@ configure ports eth0 lldp portidsubtype local eth0 -configure ports Ethernet116 lldp portidsubtype local fortyGigE0/116 description ARISTA02T1:Ethernet1/1 -configure ports Ethernet124 lldp portidsubtype local fortyGigE0/124 description ARISTA04T1:Ethernet1/1 -configure ports Ethernet112 lldp portidsubtype local fortyGigE0/112 description ARISTA01T1:Ethernet1/1 -configure ports Ethernet120 lldp portidsubtype local fortyGigE0/120 description ARISTA03T1:Ethernet1/1 From ae1484637901b5c80b4390072bdd3f4d14fe3d1f Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Fri, 27 Apr 2018 02:06:51 +0000 Subject: [PATCH 034/219] [submodules]: update swss and utilities modules swss: * e34104e 2018-04-13 | [pfcwd]: support BIG_RED_SWITCH mode (#467) (HEAD, origin/201803) [sihuihan88] * 1f857d5 2018-04-25 | [buffermgr]: remove the item from consumer queue if invalid (#489) [sihuihan88] utilities: * 0b9bb2b 2018-04-26 | Stop services before pushing new config during "load_minigraph" (#247) (HEAD, origin/201803) [Prince Sunny] * dc119c9 2018-04-18 | [show logging] For following, change 'tail -f' to 'tail -F' in order to retry in the case log is rotated (#240) [Joe LeVeque] * 08da428 2018-04-16 | [pfcwd]: add cli to enable/disable BIG_RED_SWITCH mode (#237) [sihuihan88] Signed-off-by: Guohan Lu --- src/sonic-swss | 2 +- src/sonic-utilities | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sonic-swss b/src/sonic-swss index ea34b92b37c4..e34104eea161 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit ea34b92b37c46b45b7aeba3efe1da605ff2c95d8 +Subproject commit e34104eea161a63eea8230e63b306c884380449a diff --git a/src/sonic-utilities b/src/sonic-utilities index ca11c1533fce..0b9bb2b12c3c 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit ca11c1533fce57365824902c9bc382cb0b269554 +Subproject commit 0b9bb2b12c3c68aab273bc11488f21ca7395e455 From de3e8cc5633592f2e6ea8aaec9aad7c87afa1019 Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Fri, 20 Apr 2018 22:19:01 -0700 Subject: [PATCH 035/219] [snmp]: Fix a race between snmpd-config-updater and snmpd (#1628) There is a small window in which snmpd might not have registered a callback for SIGHUP and which will result in its death if snmpd-config-updater send this signal meant for a config reload. --- dockers/docker-snmp-sv2/snmpd-config-updater | 63 +++++++++++++++++++- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/dockers/docker-snmp-sv2/snmpd-config-updater b/dockers/docker-snmp-sv2/snmpd-config-updater index ea837e5a787f..487160ba6425 100755 --- a/dockers/docker-snmp-sv2/snmpd-config-updater +++ b/dockers/docker-snmp-sv2/snmpd-config-updater @@ -11,6 +11,7 @@ import os import re +import signal import subprocess import sys import syslog @@ -24,6 +25,62 @@ SYSLOG_IDENTIFIER = "snmpd-config-updater" # ============================== Classes ============================== +class Process(object): + def __init__(self, pid): + self.pid = pid + self.path = '/proc/%d/status' % pid + self.status = None + + def read_proc_status(self): + data = {} + with open(self.path) as f: + for line in f.readlines(): + key, value = line.split(':', 1) + data[ key ] = value.strip() + self.status = data + + def get_proc_signals(self): + assert self.status + sigBlk = int(self.status[ 'SigBlk' ], 16) + sigIgn = int(self.status[ 'SigIgn' ], 16) + sigCgt = int(self.status[ 'SigCgt' ], 16) + return (sigBlk, sigIgn, sigCgt) + + def handle_signal(self, sig): + sigBlk, sigIgn, sigCgt = self.get_proc_signals() + mask = 1 << ( sig - 1 ) + if mask & sigBlk: + return True + if mask & sigIgn: + return True + if mask & sigCgt: + return True + return False + + def send_signal(self, sig): + log_info('Sending signal %s to %d' % (sig, self.pid)) + os.kill(self.pid, sig) + + def safe_send_signal(self, sig): + self.read_proc_status() + if not self.handle_signal(sig): + return False + self.send_signal(sig) + return True + + def wait_send_signal(self, sig, interval=0.1): + while not self.safe_send_signal(sig): + log_info('Process %s has not yet registered %s' % (self.pid, sig)) + time.sleep(interval) + + @staticmethod + def by_name(name): + try: + pid = subprocess.check_output([ 'pidof', '-s', name ]) + except subprocess.CalledProcessError: + return None + return Process(int(pid.rstrip())) + class ConfigUpdater(object): SERVICE = "snmpd" CONFIG_FILE_PATH = "/etc/snmp" @@ -125,8 +182,10 @@ class ConfigUpdater(object): os.rename(filename_tmp, filename) - # Force snmpd to reload its configuration - os.system("kill -HUP $(pgrep snmpd) > /dev/null 2> /dev/null || :") + # Force snmpd process to reload its configuration if it is running + proc = Process.by_name(self.SERVICE) + if proc: + proc.wait_send_signal(signal.SIGHUP) def notification_handler(self, key, data): log_info("ACL configuration changed. Updating {} config accordingly...".format(self.SERVICE)) From 0a70626c650a5acee93137436d3e1a1272d0e071 Mon Sep 17 00:00:00 2001 From: yurypm Date: Mon, 23 Apr 2018 16:52:21 +0100 Subject: [PATCH 036/219] [snmpd]: Fix typo in is_platform_arista (#1634) --- dockers/docker-snmp-sv2/snmpd-config-updater | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockers/docker-snmp-sv2/snmpd-config-updater b/dockers/docker-snmp-sv2/snmpd-config-updater index 487160ba6425..19702451495c 100755 --- a/dockers/docker-snmp-sv2/snmpd-config-updater +++ b/dockers/docker-snmp-sv2/snmpd-config-updater @@ -238,7 +238,7 @@ def is_platform_arista(): if proc.returncode != 0: log_error("Failed to retrieve platform string") - return false + return False return "arista" in stdout From 93d14725eca0b33324b03202d34b3f8dc1096bfd Mon Sep 17 00:00:00 2001 From: Andriy Moroz Date: Sat, 28 Apr 2018 08:48:44 +0300 Subject: [PATCH 037/219] [mellanox]: Update SAI version to 1.11.4 and SDK to 4.2.7303 (#1655) Signed-off-by: Andriy Moroz --- platform/mellanox/mlnx-sai.mk | 4 ++-- platform/mellanox/sdk.mk | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index 23ef8c60458b..9432b596428c 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,7 +1,7 @@ # Mellanox SAI -MLNX_SAI_VERSION = SAIRel1.11.4-master -MLNX_SAI_REVISION = 1a44c29b22e1f36f4856f4aee92ad513c963c2b8 +MLNX_SAI_VERSION = SAIRel1.11.5-master +MLNX_SAI_REVISION = 15f8f0f0a3d5e33e62a404bae829f1d6b378b0f7 export MLNX_SAI_VERSION MLNX_SAI_REVISION diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index 2ebb7d23f9c6..2ae9e43ac52a 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,5 +1,5 @@ -MLNX_SDK_BASE_URL = https://github.com/Mellanox/SAI-Implementation/raw/6367854b48b73470a6e093f6fbbd45b3341edaba/sdk -MLNX_SDK_VERSION = 4.2.7201 +MLNX_SDK_BASE_URL = https://github.com/Mellanox/SAI-Implementation/raw/56130a854a3b0f4e46d6d84749a5d758e7d1f297/sdk +MLNX_SDK_VERSION = 4.2.7303 MLNX_SDK_RDEBS += $(APPLIBS) $(IPROUTE2_MLNX) $(SX_ACL_RM) $(SX_COMPLIB) \ $(SX_EXAMPLES) $(SX_GEN_UTILS) $(SX_SCEW) $(SX_SDN_HAL) \ $(SXD_LIBS) $(TESTX) From 2a3092e37eb640a12207f892824092f5db6c970f Mon Sep 17 00:00:00 2001 From: zhenggen-xu Date: Sun, 29 Apr 2018 20:19:06 -0700 Subject: [PATCH 038/219] [docker-dhcp]: Fix the sonic build issue (#1659) Install the built version of isc-dhcp-client in docker-dhcp-relay --- rules/docker-dhcp-relay.mk | 2 +- rules/isc-dhcp.mk | 6 +++++- src/isc-dhcp/Makefile | 3 ++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/rules/docker-dhcp-relay.mk b/rules/docker-dhcp-relay.mk index 44d3904d7394..53406ad1e15f 100644 --- a/rules/docker-dhcp-relay.mk +++ b/rules/docker-dhcp-relay.mk @@ -2,7 +2,7 @@ DOCKER_DHCP_RELAY = docker-dhcp-relay.gz $(DOCKER_DHCP_RELAY)_PATH = $(DOCKERS_PATH)/docker-dhcp-relay -$(DOCKER_DHCP_RELAY)_DEPENDS += $(ISC_DHCP_COMMON) $(ISC_DHCP_RELAY) +$(DOCKER_DHCP_RELAY)_DEPENDS += $(ISC_DHCP_COMMON) $(ISC_DHCP_RELAY) $(ISC_DHCP_CLIENT) $(DOCKER_DHCP_RELAY)_LOAD_DOCKERS = $(DOCKER_CONFIG_ENGINE) SONIC_DOCKER_IMAGES += $(DOCKER_DHCP_RELAY) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_DHCP_RELAY) diff --git a/rules/isc-dhcp.mk b/rules/isc-dhcp.mk index 7b7f69c6cfc6..37c775da017a 100644 --- a/rules/isc-dhcp.mk +++ b/rules/isc-dhcp.mk @@ -8,5 +8,9 @@ ISC_DHCP_COMMON = isc-dhcp-common_$(ISC_DHCP_VERSION)_amd64.deb $(ISC_DHCP_COMMON)_SRC_PATH = $(SRC_PATH)/isc-dhcp SONIC_MAKE_DEBS += $(ISC_DHCP_COMMON) +ISC_DHCP_CLIENT = isc-dhcp-client_$(ISC_DHCP_VERSION)_amd64.deb +$(ISC_DHCP_CLIENT)_SRC_PATH = $(SRC_PATH)/isc-dhcp +SONIC_MAKE_DEBS += $(ISC_DHCP_CLIENT) + ISC_DHCP_RELAY = isc-dhcp-relay_$(ISC_DHCP_VERSION)_amd64.deb -$(eval $(call add_derived_package,$(ISC_DHCP_COMMON),$(ISC_DHCP_RELAY))) +$(eval $(call add_derived_package,$(ISC_DHCP_COMMON),$(ISC_DHCP_RELAY),$(ISC_DHCP_CLIENT))) diff --git a/src/isc-dhcp/Makefile b/src/isc-dhcp/Makefile index 5b1cb8407005..b439ec7c1ee6 100644 --- a/src/isc-dhcp/Makefile +++ b/src/isc-dhcp/Makefile @@ -3,7 +3,8 @@ SHELL = /bin/bash .SHELLFLAGS += -e MAIN_TARGET = isc-dhcp-common_$(ISC_DHCP_VERSION)_amd64.deb -DERIVED_TARGETS = isc-dhcp-relay_$(ISC_DHCP_VERSION)_amd64.deb +DERIVED_TARGETS = isc-dhcp-relay_$(ISC_DHCP_VERSION)_amd64.deb \ + isc-dhcp-client_$(ISC_DHCP_VERSION)_amd64.deb $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # Remove any stale files From d3e958a1aef81cae3e4aae7c0e79b25ad7de19b6 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Tue, 1 May 2018 09:52:17 +0000 Subject: [PATCH 039/219] [swss]: update swss 118b3f0 2018-05-01 | Populate existing interface cache, bring down before configDone Signed-off-by: Guohan Lu --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index e34104eea161..118b3f02c170 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit e34104eea161a63eea8230e63b306c884380449a +Subproject commit 118b3f02c170d5c8a8abd94381283bfd779fe55f From 2d8ed10139be46d6f1cf93be365f02091da1e0cc Mon Sep 17 00:00:00 2001 From: Taoyu Li Date: Tue, 1 May 2018 20:53:47 -0700 Subject: [PATCH 040/219] [zebra.conf] Fix template issue with multiple lo addresses (#1662) * [zebra.conf] Fix template issue with multiple lo addresses * Add unitest for Loopback1 --- dockers/docker-fpm-quagga/zebra.conf.j2 | 12 ++- dockers/docker-orchagent/ipinip.json.j2 | 2 +- .../tests/sample_output/bgpd.conf | 91 +++++++++++++++++++ .../tests/sample_output/interfaces | 4 + .../tests/sample_output/zebra.conf | 44 +++++++++ .../tests/t0-sample-graph.xml | 10 +- src/sonic-config-engine/tests/test_j2files.py | 16 +++- 7 files changed, 171 insertions(+), 8 deletions(-) create mode 100644 src/sonic-config-engine/tests/sample_output/bgpd.conf create mode 100644 src/sonic-config-engine/tests/sample_output/zebra.conf diff --git a/dockers/docker-fpm-quagga/zebra.conf.j2 b/dockers/docker-fpm-quagga/zebra.conf.j2 index 8b967f98671c..e4586e72dd62 100644 --- a/dockers/docker-fpm-quagga/zebra.conf.j2 +++ b/dockers/docker-fpm-quagga/zebra.conf.j2 @@ -40,11 +40,13 @@ ip route 0.0.0.0/0 {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} 200 {% set lo_ipv6_addrs = [] %} {% if LOOPBACK_INTERFACE %} {% for (name, prefix) in LOOPBACK_INTERFACE %} -{% if prefix | ipv6 %} -{% if lo_ipv6_addrs.append(prefix) %} -{% endif %} -{% else %} -{% if lo_ipv4_addrs.append(prefix) %} +{% if name == 'Loopback0' %} +{% if prefix | ipv6 %} +{% if lo_ipv6_addrs.append(prefix) %} +{% endif %} +{% else %} +{% if lo_ipv4_addrs.append(prefix) %} +{% endif %} {% endif %} {% endif %} {% endfor %} diff --git a/dockers/docker-orchagent/ipinip.json.j2 b/dockers/docker-orchagent/ipinip.json.j2 index bee97f45b8ae..36fccddc237a 100644 --- a/dockers/docker-orchagent/ipinip.json.j2 +++ b/dockers/docker-orchagent/ipinip.json.j2 @@ -1,7 +1,7 @@ {# only IPv4 decapsulation is supported #} {% set ipv4_loopback_addresses = [] %} {% for (name, prefix) in LOOPBACK_INTERFACE %} - {%- if prefix | ipv4 %} + {%- if prefix | ipv4 and name == 'Loopback0' %} {%- set ipv4_loopback_addresses = ipv4_loopback_addresses.append(prefix) %} {%- endif %} {% endfor %} diff --git a/src/sonic-config-engine/tests/sample_output/bgpd.conf b/src/sonic-config-engine/tests/sample_output/bgpd.conf new file mode 100644 index 000000000000..4416b4628569 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/bgpd.conf @@ -0,0 +1,91 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/quagga/bgpd.conf.j2 with config DB data +! file: bgpd.conf +! +! +hostname switch-t0 +password zebra +log syslog informational +log facility local4 +! enable password ! +! +! bgp multiple-instance +! +route-map FROM_BGP_SPEAKER_V4 permit 10 +! +route-map TO_BGP_SPEAKER_V4 deny 10 +! +router bgp 65100 + bgp log-neighbor-changes + bgp bestpath as-path multipath-relax + no bgp default ipv4-unicast + bgp graceful-restart + bgp router-id 10.1.0.32 + network 10.1.0.32/32 + address-family ipv6 + network fc00:1::32/64 + exit-address-family + network 192.168.0.1/27 + neighbor 10.0.0.57 remote-as 64600 + neighbor 10.0.0.57 description ARISTA01T1 + address-family ipv4 + neighbor 10.0.0.57 allowas-in 1 + neighbor 10.0.0.57 activate + maximum-paths 64 + exit-address-family + neighbor 10.0.0.59 remote-as 64600 + neighbor 10.0.0.59 description ARISTA02T1 + address-family ipv4 + neighbor 10.0.0.59 allowas-in 1 + neighbor 10.0.0.59 activate + maximum-paths 64 + exit-address-family + neighbor 10.0.0.61 remote-as 64600 + neighbor 10.0.0.61 description ARISTA03T1 + address-family ipv4 + neighbor 10.0.0.61 allowas-in 1 + neighbor 10.0.0.61 activate + maximum-paths 64 + exit-address-family + neighbor 10.0.0.63 remote-as 64600 + neighbor 10.0.0.63 description ARISTA04T1 + address-family ipv4 + neighbor 10.0.0.63 allowas-in 1 + neighbor 10.0.0.63 activate + maximum-paths 64 + exit-address-family + neighbor fc00::7a remote-as 64600 + neighbor fc00::7a description ARISTA03T1 + address-family ipv6 + neighbor fc00::7a allowas-in 1 + neighbor fc00::7a activate + maximum-paths 64 + exit-address-family + neighbor fc00::7e remote-as 64600 + neighbor fc00::7e description ARISTA04T1 + address-family ipv6 + neighbor fc00::7e allowas-in 1 + neighbor fc00::7e activate + maximum-paths 64 + exit-address-family + neighbor fc00::72 remote-as 64600 + neighbor fc00::72 description ARISTA01T1 + address-family ipv6 + neighbor fc00::72 allowas-in 1 + neighbor fc00::72 activate + maximum-paths 64 + exit-address-family + neighbor fc00::76 remote-as 64600 + neighbor fc00::76 description ARISTA02T1 + address-family ipv6 + neighbor fc00::76 allowas-in 1 + neighbor fc00::76 activate + maximum-paths 64 + exit-address-family +! +maximum-paths 64 +! +route-map ISOLATE permit 10 +set as-path prepend 65100 +! diff --git a/src/sonic-config-engine/tests/sample_output/interfaces b/src/sonic-config-engine/tests/sample_output/interfaces index c8da2fee8f76..96dc577ffe8b 100644 --- a/src/sonic-config-engine/tests/sample_output/interfaces +++ b/src/sonic-config-engine/tests/sample_output/interfaces @@ -15,6 +15,10 @@ iface lo inet6 static address fc00:1::32 netmask 128 # +iface lo inet static + address 10.10.0.99 + netmask 255.255.255.255 +# # The management network interface auto eth0 iface eth0 inet static diff --git a/src/sonic-config-engine/tests/sample_output/zebra.conf b/src/sonic-config-engine/tests/sample_output/zebra.conf new file mode 100644 index 000000000000..aa3486b0163a --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/zebra.conf @@ -0,0 +1,44 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/quagga/zebra.conf.j2 using config DB data +! file: zebra.conf +! +! +hostname switch-t0 +password zebra +enable password zebra +! +! Enable link-detect (default disabled) +interface PortChannel01 +link-detect +! +interface PortChannel02 +link-detect +! +interface PortChannel03 +link-detect +! +interface PortChannel04 +link-detect +! +! +! set static default route to mgmt gateway as a backup to learned default +ip route 0.0.0.0/0 10.0.0.1 200 +! +! Set ip source to loopback for bgp learned routes +route-map RM_SET_SRC permit 10 + set src 10.1.0.32 +! + +route-map RM_SET_SRC6 permit 10 + set src fc00:1::32 +! +ip protocol bgp route-map RM_SET_SRC +! +ipv6 protocol bgp route-map RM_SET_SRC6 +! +! +log syslog informational +log facility local4 +! + diff --git a/src/sonic-config-engine/tests/t0-sample-graph.xml b/src/sonic-config-engine/tests/t0-sample-graph.xml index bda5517771e5..ce0177d4c158 100644 --- a/src/sonic-config-engine/tests/t0-sample-graph.xml +++ b/src/sonic-config-engine/tests/t0-sample-graph.xml @@ -153,7 +153,15 @@ FC00:1::32/128 - + + LoopbackIP1 + Loopback1 + + 10.10.0.99/32 + + 10.10.0.99/32 + + HostIP diff --git a/src/sonic-config-engine/tests/test_j2files.py b/src/sonic-config-engine/tests/test_j2files.py index 129c3973d7b5..67266b0d9517 100644 --- a/src/sonic-config-engine/tests/test_j2files.py +++ b/src/sonic-config-engine/tests/test_j2files.py @@ -20,6 +20,9 @@ def setUp(self): def run_script(self, argument): print 'CMD: sonic-cfggen ' + argument return subprocess.check_output(self.script_file + ' ' + argument, shell=True) + + def run_diff(self, file1, file2, diff): + return subprocess.check_output('diff {} {} >{}'.format(file1, file2, diff), shell=True) def test_interfaces(self): interfaces_template = os.path.join(self.test_dir, '..', '..', '..', 'files', 'image_config', 'interfaces', 'interfaces.j2') @@ -59,6 +62,18 @@ def test_lldp(self): self.run_script(argument) self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'lldpd.conf'), self.output_file)) + def test_bgpd(self): + conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-quagga', 'bgpd.conf.j2') + argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + conf_template + ' > ' + self.output_file + self.run_script(argument) + self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'bgpd.conf'), self.output_file)) + + def test_zebra(self): + conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-fpm-quagga', 'zebra.conf.j2') + argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + conf_template + ' > ' + self.output_file + self.run_script(argument) + self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'zebra.conf'), self.output_file)) + def test_teamd(self): def test_render_teamd(self, pc, minigraph, sample_output): @@ -94,7 +109,6 @@ def test_ipinip(self): self.run_script(argument) sample_output_file = os.path.join(self.test_dir, 'sample_output', 'ipinip.json') - assert filecmp.cmp(sample_output_file, self.output_file) def test_msn27xx_32ports_buffers(self): From 8088f2b6008f06dc17a1a0d79eaf58407bb50922 Mon Sep 17 00:00:00 2001 From: Shuotian Cheng Date: Tue, 1 May 2018 21:58:33 -0700 Subject: [PATCH 041/219] [swss]: Change the hash seed to 0 for ToR and 10 for Leaf routers (#1667) Due to some ASIC platform limitations, the hash seed range is from 0 to 15. Thus the switch.json.j2 template is updated so that ToRRouter is using hash seed 0 and LeafRouter is using hash seed 10. Signed-off-by: Shu0T1an ChenG --- dockers/docker-orchagent/switch.json.j2 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dockers/docker-orchagent/switch.json.j2 b/dockers/docker-orchagent/switch.json.j2 index 7a8c3522ecee..7aaada1b1e40 100644 --- a/dockers/docker-orchagent/switch.json.j2 +++ b/dockers/docker-orchagent/switch.json.j2 @@ -1,10 +1,11 @@ +{# the range of hash_seed is 0-15 #} {# set default hash seed to 0 #} {% set hash_seed = 0 %} {% if DEVICE_METADATA.localhost.type %} {% if DEVICE_METADATA.localhost.type == "ToRRouter" %} -{% set hash_seed = 10 %} +{% set hash_seed = 0 %} {% elif DEVICE_METADATA.localhost.type == "LeafRouter" %} -{% set hash_seed = 20 %} +{% set hash_seed = 10 %} {% endif %} {% endif %} [ From f1cf5b24178a2ad6c3f05070aa5e502caff96499 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Tue, 1 May 2018 22:41:58 -0700 Subject: [PATCH 042/219] [snmp]: Stop spamming logs with statfs permission denied log message (#1668) --- src/snmpd/Makefile | 1 + src/snmpd/statfs_error.patch | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 src/snmpd/statfs_error.patch diff --git a/src/snmpd/Makefile b/src/snmpd/Makefile index 457cd2ef05da..b372f0d22458 100644 --- a/src/snmpd/Makefile +++ b/src/snmpd/Makefile @@ -23,6 +23,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : dpkg-source -x net-snmp_$(SNMPD_VERSION_FULL).dsc pushd net-snmp-$(SNMPD_VERSION) + patch -p0 < ../statfs_error.patch fakeroot debian/rules -j$(SONIC_CONFIG_MAKE_JOBS) binary popd diff --git a/src/snmpd/statfs_error.patch b/src/snmpd/statfs_error.patch new file mode 100644 index 000000000000..a07b59bc9175 --- /dev/null +++ b/src/snmpd/statfs_error.patch @@ -0,0 +1,22 @@ +--- agent/mibgroup/hardware/fsys/fsys_mntctl.c.old 2018-04-30 23:26:58.097636453 +0000 ++++ agent/mibgroup/hardware/fsys/fsys_mntctl.c 2018-04-30 23:27:36.189499479 +0000 +@@ -163,8 +163,6 @@ + continue; + + if ( statfs( entry->path, &stat_buf ) < 0 ) { +- snprintf( tmpbuf, sizeof(tmpbuf), "Cannot statfs %s", entry->path ); +- snmp_log_perror( tmpbuf ); + continue; + } + entry->units = stat_buf.f_bsize; +--- agent/mibgroup/hardware/fsys/fsys_mntent.c.old 2018-04-30 23:26:54.569649140 +0000 ++++ agent/mibgroup/hardware/fsys/fsys_mntent.c 2018-04-30 23:27:22.001550497 +0000 +@@ -238,8 +238,6 @@ + if ( NSFS_STATFS( entry->path, &stat_buf ) < 0 ) + #endif + { +- snprintf( tmpbuf, sizeof(tmpbuf), "Cannot statfs %s", entry->path ); +- snmp_log_perror( tmpbuf ); + continue; + } + entry->units = stat_buf.NSFS_SIZE; From 8a5013bb5af5717116c5e1edad48afcd191bba4c Mon Sep 17 00:00:00 2001 From: lguohan Date: Wed, 2 May 2018 02:36:12 -0700 Subject: [PATCH 043/219] [broadcom]: update broadcom SAI to 3.1.3.4-11 (#1670) Provide better ECMP load-balancing via hash seed Signed-off-by: Guohan Lu --- platform/broadcom/sai.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 5120b1518f6e..572ad5271f10 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,9 +1,9 @@ -BRCM_SAI = libsaibcm_3.1.3.4-10_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm_3.1.3.4-10_amd64.deb?sv=2015-04-05&sr=b&sig=72n19AElVmbqo3ahrEFVBwMgR%2FoQ7fhUj4tcadx8pVE%3D&se=2031-12-20T20%3A27%3A14Z&sp=r" +BRCM_SAI = libsaibcm_3.1.3.4-11_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm_3.1.3.4-11_amd64.deb?sv=2015-04-05&sr=b&sig=0pctCvAKfSqT8O%2FWSMxw532XAXFsxXdKljQqWfOX8xA%3D&se=2155-03-25T07%3A23%3A41Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.1.3.4-10_amd64.deb +BRCM_SAI_DEV = libsaibcm-dev_3.1.3.4-11_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm-dev_3.1.3.4-10_amd64.deb?sv=2015-04-05&sr=b&sig=cN4qsWX8XW04ZObBDonwh5Uzgmp5A0iRBkpZA9N5Zb8%3D&se=2031-12-20T20%3A26%3A45Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm-dev_3.1.3.4-11_amd64.deb?sv=2015-04-05&sr=b&sig=IO1g%2FdcObkureizN8ZMPqISP6opZXu%2FrHostog6aIrU%3D&se=2155-03-25T08%3A13%3A34Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) From b29d8350c484ea49e242e4af9d721f4364818ae6 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Wed, 2 May 2018 22:01:59 +0000 Subject: [PATCH 044/219] [sonic-cfggen]: fix bgpd and zebra template for sonic-cfggen test I took the original patch (bebb7a0) into 201803 branch need to also adapt the patch since we do not have commit (d423841) in 201803 branch. Signed-off-by: Guohan Lu --- .../tests/sample_output/bgpd.conf | 36 +++++++++---------- .../tests/sample_output/zebra.conf | 4 +-- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/sonic-config-engine/tests/sample_output/bgpd.conf b/src/sonic-config-engine/tests/sample_output/bgpd.conf index 4416b4628569..1722d28fcf5b 100644 --- a/src/sonic-config-engine/tests/sample_output/bgpd.conf +++ b/src/sonic-config-engine/tests/sample_output/bgpd.conf @@ -27,13 +27,6 @@ router bgp 65100 network fc00:1::32/64 exit-address-family network 192.168.0.1/27 - neighbor 10.0.0.57 remote-as 64600 - neighbor 10.0.0.57 description ARISTA01T1 - address-family ipv4 - neighbor 10.0.0.57 allowas-in 1 - neighbor 10.0.0.57 activate - maximum-paths 64 - exit-address-family neighbor 10.0.0.59 remote-as 64600 neighbor 10.0.0.59 description ARISTA02T1 address-family ipv4 @@ -55,13 +48,6 @@ router bgp 65100 neighbor 10.0.0.63 activate maximum-paths 64 exit-address-family - neighbor fc00::7a remote-as 64600 - neighbor fc00::7a description ARISTA03T1 - address-family ipv6 - neighbor fc00::7a allowas-in 1 - neighbor fc00::7a activate - maximum-paths 64 - exit-address-family neighbor fc00::7e remote-as 64600 neighbor fc00::7e description ARISTA04T1 address-family ipv6 @@ -69,11 +55,18 @@ router bgp 65100 neighbor fc00::7e activate maximum-paths 64 exit-address-family - neighbor fc00::72 remote-as 64600 - neighbor fc00::72 description ARISTA01T1 + neighbor fc00::7a remote-as 64600 + neighbor fc00::7a description ARISTA03T1 address-family ipv6 - neighbor fc00::72 allowas-in 1 - neighbor fc00::72 activate + neighbor fc00::7a allowas-in 1 + neighbor fc00::7a activate + maximum-paths 64 + exit-address-family + neighbor 10.0.0.57 remote-as 64600 + neighbor 10.0.0.57 description ARISTA01T1 + address-family ipv4 + neighbor 10.0.0.57 allowas-in 1 + neighbor 10.0.0.57 activate maximum-paths 64 exit-address-family neighbor fc00::76 remote-as 64600 @@ -83,6 +76,13 @@ router bgp 65100 neighbor fc00::76 activate maximum-paths 64 exit-address-family + neighbor fc00::72 remote-as 64600 + neighbor fc00::72 description ARISTA01T1 + address-family ipv6 + neighbor fc00::72 allowas-in 1 + neighbor fc00::72 activate + maximum-paths 64 + exit-address-family ! maximum-paths 64 ! diff --git a/src/sonic-config-engine/tests/sample_output/zebra.conf b/src/sonic-config-engine/tests/sample_output/zebra.conf index aa3486b0163a..b1b791b252e8 100644 --- a/src/sonic-config-engine/tests/sample_output/zebra.conf +++ b/src/sonic-config-engine/tests/sample_output/zebra.conf @@ -9,13 +9,13 @@ password zebra enable password zebra ! ! Enable link-detect (default disabled) -interface PortChannel01 +interface PortChannel03 link-detect ! interface PortChannel02 link-detect ! -interface PortChannel03 +interface PortChannel01 link-detect ! interface PortChannel04 From 3e3a56ee705dd086a3cd79796e86f759d46705b0 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Wed, 2 May 2018 22:02:56 +0000 Subject: [PATCH 045/219] [swss]: update sonic-swss module [201803 d57f9a1] [lua]: use not to check whether the field exists (#492) Signed-off-by: Guohan Lu --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 118b3f02c170..d57f9a16b142 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 118b3f02c170d5c8a8abd94381283bfd779fe55f +Subproject commit d57f9a16b1428fab216e5f3e2ec1e2f8c1f9aefc From 4cf791398720de70a3bdde154887dc1e3fbca1bb Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Thu, 3 May 2018 22:26:50 -0700 Subject: [PATCH 046/219] [device] Update arista driver submodule (#1674) --- platform/broadcom/sonic-platform-modules-arista | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index 86221d907f27..a35c7eddaf94 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 86221d907f27e7f6df40393a5bfe217bf22b19af +Subproject commit a35c7eddaf945a1ff09ea71b47f69b6ddba5e892 From f734033550c0178448730b6d276604d5cf9dae66 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Wed, 25 Apr 2018 14:28:20 -0700 Subject: [PATCH 047/219] [submodule]: Update submodule sonic-snmpagent (#1642) Signed-off-by: Qi Luo --- src/sonic-snmpagent | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-snmpagent b/src/sonic-snmpagent index 12bc0e0c9843..a03f7794d6b2 160000 --- a/src/sonic-snmpagent +++ b/src/sonic-snmpagent @@ -1 +1 @@ -Subproject commit 12bc0e0c98432eb21add3b547e13bcf10e77ab51 +Subproject commit a03f7794d6b2faec23088ba064cb6ce7e7d2122a From 532953eaaec6e5459bed2ffd950b899ed68377a5 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Tue, 24 Apr 2018 16:01:17 -0700 Subject: [PATCH 048/219] sonic-cfggen supports hwsku parameter (#1631) *Note*: tuned test data during cherry-pick --- sonic-slave/Dockerfile | 18 +-- src/sonic-config-engine/data/l2switch.j2 | 21 ++++ src/sonic-config-engine/setup.py | 6 +- src/sonic-config-engine/sonic-cfggen | 31 +++-- .../tests/sample_output/l2switch.json | 107 ++++++++++++++++++ src/sonic-config-engine/tests/test_j2files.py | 8 ++ 6 files changed, 172 insertions(+), 19 deletions(-) create mode 100644 src/sonic-config-engine/data/l2switch.j2 create mode 100644 src/sonic-config-engine/tests/sample_output/l2switch.json diff --git a/sonic-slave/Dockerfile b/sonic-slave/Dockerfile index ed85b0ca436a..213daf1a8e47 100644 --- a/sonic-slave/Dockerfile +++ b/sonic-slave/Dockerfile @@ -184,16 +184,12 @@ RUN apt-get update && apt-get install -y \ libjs-sphinxdoc \ libjs-underscore \ python-docutils \ - python-jinja2 \ python-markupsafe \ python-pygments \ python-roman \ - python-sphinx \ sphinx-common \ - python3-sphinx \ # For sonic config engine testing python-lxml \ - python-jinja2 \ python-netaddr \ python-ipaddr \ python-yaml \ @@ -229,16 +225,22 @@ RUN export VERSION=1.8.3 \ && echo 'export GOROOT=/usr/local/go' >> /etc/bash.bashrc \ && echo 'export PATH=$PATH:$GOROOT/bin' >> /etc/bash.bashrc +# Upgrade pip2 +# Note: use pip2 specific version so jinja2 2.10 will install +RUN python2 -m pip install -U pip==9.0.3 + # For p4 build RUN pip install \ ctypesgen \ crc16 -# For templating -RUN pip install j2cli - # For sonic config engine testing -RUN pip install pyangbind==0.5.10 +RUN pip install pyangbind==0.6.0 +# Note: force upgrade debian packaged jinja2, if installed +RUN pip install --force-reinstall --upgrade jinja2>=2.10 + +# For templating (requiring jinja2) +RUN pip install j2cli # For sonic utilities testing RUN pip install click-default-group click natsort tabulate diff --git a/src/sonic-config-engine/data/l2switch.j2 b/src/sonic-config-engine/data/l2switch.j2 new file mode 100644 index 000000000000..ee24f5ebd19d --- /dev/null +++ b/src/sonic-config-engine/data/l2switch.j2 @@ -0,0 +1,21 @@ +{ + "DEVICE_METADATA": {{ DEVICE_METADATA | tojson }}, + "PORT": {{ PORT | tojson }}, + "VLAN": { + "Vlan1000": { + "vlanid": "1000" + } + }, + {% set ns = {'firstPrinted': False} -%} + "VLAN_MEMBER": { + {%- for port in PORT -%} + {%- if ns.firstPrinted %},{% endif %} + + "Vlan1000|{{ port }}": { + "tagging_mode": "untagged" + } + {%- if ns.update({'firstPrinted': True}) %}{% endif -%} + {%- endfor %} + + } +} diff --git a/src/sonic-config-engine/setup.py b/src/sonic-config-engine/setup.py index e1530d0d3d32..1d0c7f99fa41 100755 --- a/src/sonic-config-engine/setup.py +++ b/src/sonic-config-engine/setup.py @@ -3,6 +3,7 @@ from setuptools import setup import os.path import unittest +import glob def get_test_suite(): test_loader = unittest.TestLoader() @@ -17,6 +18,9 @@ def get_test_suite(): url='https://github.com/Azure/sonic-buildimage', py_modules=['portconfig', 'minigraph', 'openconfig_acl', 'sonic_platform'], scripts=['sonic-cfggen'], - install_requires=['lxml', 'jinja2', 'netaddr', 'ipaddr', 'pyyaml', 'pyangbind==0.6.0'], + install_requires=['lxml', 'jinja2>=2.10', 'netaddr', 'ipaddr', 'pyyaml', 'pyangbind==0.6.0'], test_suite='setup.get_test_suite', + data_files=[ + ('/usr/share/sonic/templates', glob.glob('data/*')), + ], ) diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index b11385ab8c8b..42f64884200d 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -15,6 +15,7 @@ Examples: See usage string for detail description for arguments. """ +from __future__ import print_function import sys import os.path import argparse @@ -26,6 +27,7 @@ from functools import partial from minigraph import minigraph_encoder from minigraph import parse_xml from minigraph import parse_device_desc_xml +from portconfig import get_port_config from sonic_platform import get_machine_info from sonic_platform import get_platform_info from sonic_platform import get_system_mac @@ -134,7 +136,8 @@ def main(): group = parser.add_mutually_exclusive_group() group.add_argument("-m", "--minigraph", help="minigraph xml file", nargs='?', const='/etc/sonic/minigraph.xml') group.add_argument("-M", "--device-description", help="device description xml file") - parser.add_argument("-p", "--port-config", help="port config file, used with -m") + group.add_argument("-k", "--hwsku", help="HwSKU") + parser.add_argument("-p", "--port-config", help="port config file, used with -m or -k", nargs='?', const=None) parser.add_argument("-y", "--yaml", help="yaml file that contains additional variables", action='append', default=[]) parser.add_argument("-j", "--json", help="json file that contains additional variables", action='append', default=[]) parser.add_argument("-a", "--additional-data", help="addition data, in json string") @@ -156,7 +159,18 @@ def main(): db_kwargs['unix_socket_path'] = args.redis_unix_sock_file data = {} + hwsku = args.hwsku + if hwsku is not None: + hardware_data = {'DEVICE_METADATA': {'localhost': { + 'hwsku': hwsku + }}} + deep_update(data, hardware_data) + (ports, _) = get_port_config(hwsku, platform, args.port_config) + if not ports: + print('Failed to get port config', file=sys.stderr) + sys.exit(1) + deep_update(data, {'PORT': ports}) if args.minigraph != None: minigraph = args.minigraph @@ -166,10 +180,7 @@ def main(): else: deep_update(data, parse_xml(minigraph, platform)) else: - if args.port_config != None: - deep_update(data, parse_xml(minigraph, port_config_file=args.port_config)) - else: - deep_update(data, parse_xml(minigraph)) + deep_update(data, parse_xml(minigraph, port_config_file=args.port_config)) if args.device_description != None: deep_update(data, parse_device_desc_xml(args.device_description)) @@ -210,14 +221,14 @@ def main(): for attr in ['ip', 'network', 'prefixlen', 'netmask']: env.filters[attr] = partial(prefix_attr, attr) template = env.get_template(template_file) - print template.render(data) - + print(template.render(data)) + if args.var != None: template = jinja2.Template('{{' + args.var + '}}') - print template.render(data) + print(template.render(data)) if args.var_json != None: - print json.dumps(FormatConverter.to_serialized(data[args.var_json]), indent=4, cls=minigraph_encoder) + print(json.dumps(FormatConverter.to_serialized(data[args.var_json]), indent=4, cls=minigraph_encoder)) if args.write_to_db: configdb = ConfigDBConnector(**db_kwargs) @@ -225,7 +236,7 @@ def main(): configdb.mod_config(FormatConverter.output_to_db(data)) if args.print_data: - print json.dumps(FormatConverter.to_serialized(data), indent=4, cls=minigraph_encoder) + print(json.dumps(FormatConverter.to_serialized(data), indent=4, cls=minigraph_encoder)) if __name__ == "__main__": diff --git a/src/sonic-config-engine/tests/sample_output/l2switch.json b/src/sonic-config-engine/tests/sample_output/l2switch.json new file mode 100644 index 000000000000..7288b1c38cbd --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/l2switch.json @@ -0,0 +1,107 @@ +{ + "DEVICE_METADATA": {"localhost": {"hwsku": "Mellanox-SN2700"}}, + "PORT": {"Ethernet0": {"alias": "fortyGigE0/0", "lanes": "29,30,31,32"}, "Ethernet100": {"alias": "fortyGigE0/100", "lanes": "125,126,127,128"}, "Ethernet104": {"alias": "fortyGigE0/104", "lanes": "85,86,87,88"}, "Ethernet108": {"alias": "fortyGigE0/108", "lanes": "81,82,83,84"}, "Ethernet112": {"alias": "fortyGigE0/112", "lanes": "89,90,91,92"}, "Ethernet116": {"alias": "fortyGigE0/116", "lanes": "93,94,95,96"}, "Ethernet12": {"alias": "fortyGigE0/12", "lanes": "33,34,35,36"}, "Ethernet120": {"alias": "fortyGigE0/120", "lanes": "97,98,99,100"}, "Ethernet124": {"alias": "fortyGigE0/124", "lanes": "101,102,103,104"}, "Ethernet16": {"alias": "fortyGigE0/16", "lanes": "41,42,43,44"}, "Ethernet20": {"alias": "fortyGigE0/20", "lanes": "45,46,47,48"}, "Ethernet24": {"alias": "fortyGigE0/24", "lanes": "5,6,7,8"}, "Ethernet28": {"alias": "fortyGigE0/28", "lanes": "1,2,3,4"}, "Ethernet32": {"alias": "fortyGigE0/32", "lanes": "9,10,11,12"}, "Ethernet36": {"alias": "fortyGigE0/36", "lanes": "13,14,15,16"}, "Ethernet4": {"alias": "fortyGigE0/4", "lanes": "25,26,27,28"}, "Ethernet40": {"alias": "fortyGigE0/40", "lanes": "21,22,23,24"}, "Ethernet44": {"alias": "fortyGigE0/44", "lanes": "17,18,19,20"}, "Ethernet48": {"alias": "fortyGigE0/48", "lanes": "49,50,51,52"}, "Ethernet52": {"alias": "fortyGigE0/52", "lanes": "53,54,55,56"}, "Ethernet56": {"alias": "fortyGigE0/56", "lanes": "61,62,63,64"}, "Ethernet60": {"alias": "fortyGigE0/60", "lanes": "57,58,59,60"}, "Ethernet64": {"alias": "fortyGigE0/64", "lanes": "65,66,67,68"}, "Ethernet68": {"alias": "fortyGigE0/68", "lanes": "69,70,71,72"}, "Ethernet72": {"alias": "fortyGigE0/72", "lanes": "77,78,79,80"}, "Ethernet76": {"alias": "fortyGigE0/76", "lanes": "73,74,75,76"}, "Ethernet8": {"alias": "fortyGigE0/8", "lanes": "37,38,39,40"}, "Ethernet80": {"alias": "fortyGigE0/80", "lanes": "105,106,107,108"}, "Ethernet84": {"alias": "fortyGigE0/84", "lanes": "109,110,111,112"}, "Ethernet88": {"alias": "fortyGigE0/88", "lanes": "117,118,119,120"}, "Ethernet92": {"alias": "fortyGigE0/92", "lanes": "113,114,115,116"}, "Ethernet96": {"alias": "fortyGigE0/96", "lanes": "121,122,123,124"}}, + "VLAN": { + "Vlan1000": { + "vlanid": "1000" + } + }, + "VLAN_MEMBER": { + "Vlan1000|Ethernet8": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet0": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet4": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet108": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet100": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet104": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet68": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet96": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet124": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet92": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet120": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet52": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet56": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet76": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet72": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet64": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet32": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet16": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet36": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet12": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet88": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet116": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet80": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet112": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet84": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet48": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet44": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet40": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet28": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet60": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet20": { + "tagging_mode": "untagged" + }, + "Vlan1000|Ethernet24": { + "tagging_mode": "untagged" + } + } +} diff --git a/src/sonic-config-engine/tests/test_j2files.py b/src/sonic-config-engine/tests/test_j2files.py index 67266b0d9517..bda3a20dbdfb 100644 --- a/src/sonic-config-engine/tests/test_j2files.py +++ b/src/sonic-config-engine/tests/test_j2files.py @@ -120,6 +120,14 @@ def test_msn27xx_32ports_buffers(self): self.assertTrue(filecmp.cmp(sample_output_file, self.output_file)) + def test_sku_render_template(self): + argument = '-k Mellanox-SN2700 -t ' + os.path.join(self.test_dir, '../data/l2switch.j2') + ' -p ' + self.t0_port_config + ' > ' + self.output_file + self.run_script(argument) + + sample_output_file = os.path.join(self.test_dir, 'sample_output', 'l2switch.json') + + self.assertTrue(filecmp.cmp(sample_output_file, self.output_file)) + def tearDown(self): try: os.remove(self.output_file) From 04ca35bdeb213222adde929b309618bacf9efd8a Mon Sep 17 00:00:00 2001 From: stanepc1 <35956037+stanepc1@users.noreply.github.com> Date: Tue, 8 May 2018 04:51:40 +0800 Subject: [PATCH 049/219] [device] Add PSU utility for platform ly1200 of MiTAC (#1673) [platform/broadcom/sonic-platform-modules-mitac] Install acpi package for daemon and adjust i2c sequence Signed-off-by: Eddy Weng --- .../plugins/psuutil.py | 72 +++++++++++++++++++ .../broadcom/sonic-platform-modules-mitac | 2 +- 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/plugins/psuutil.py diff --git a/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/plugins/psuutil.py b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/plugins/psuutil.py new file mode 100644 index 000000000000..8fd9d3b1f349 --- /dev/null +++ b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/plugins/psuutil.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python + +############################################################################# +# MiTAC +# +# Module contains an implementation of SONiC PSU Base API and +# provides the PSUs status which are available in the platform +# +############################################################################# + +import os.path + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + + self.psu_nums = 2 + self.psu_path = "/sys/bus/i2c/devices/1-0032/" + self.psu_presence = "ps{}_ps" + self.psu_oper_status = "ps{}_pg" + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + :return: An integer, the number of PSUs available on the device + """ + return self.psu_nums + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by 1-based index + :param index: An integer, 1-based index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is faulty + """ + if index is None: + return False + + status = 1 + try: + with open(self.psu_path + self.psu_oper_status.format(index), 'r') as power_status: + status = int(power_status.read(), 0) + except IOError: + return False + + return status == 0 + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by 1-based index + :param index: An integer, 1-based index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + if index is None: + return False + + status = 1 + try: + with open(self.psu_path + self.psu_presence.format(index), 'r') as presence_status: + status = int(presence_status.read(), 0) + except IOError: + return False + + return status == 0 diff --git a/platform/broadcom/sonic-platform-modules-mitac b/platform/broadcom/sonic-platform-modules-mitac index ed807feb6f8e..db8e7de1b41a 160000 --- a/platform/broadcom/sonic-platform-modules-mitac +++ b/platform/broadcom/sonic-platform-modules-mitac @@ -1 +1 @@ -Subproject commit ed807feb6f8efc612ae57dea3123256d972506c5 +Subproject commit db8e7de1b41a407028ee2c4361177bd7b52f9431 From 1dd26fe7cd1edc969ca2a0463d8ba2daecbd96bb Mon Sep 17 00:00:00 2001 From: Volodymyr Samotiy Date: Wed, 9 May 2018 00:46:18 +0300 Subject: [PATCH 050/219] [mellanox]: Update MLNX SAI pointer (#1684) Signed-off-by: Volodymyr Samotiy --- platform/mellanox/mlnx-sai.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index 9432b596428c..53e74021bb84 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,7 +1,7 @@ # Mellanox SAI MLNX_SAI_VERSION = SAIRel1.11.5-master -MLNX_SAI_REVISION = 15f8f0f0a3d5e33e62a404bae829f1d6b378b0f7 +MLNX_SAI_REVISION = 957f61820e441e490081cb3724f702ed507f7477 export MLNX_SAI_VERSION MLNX_SAI_REVISION From 621c250312cadab5199c64a826ad90629f08637d Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Mon, 7 May 2018 11:02:30 -0700 Subject: [PATCH 051/219] 40G profile for Arista 7060 (#1677) --- .../Arista-7060CX-32S-Q32/buffers.json.j2 | 2 + .../buffers_defaults_t0.j2 | 47 +++++ .../buffers_defaults_t1.j2 | 47 +++++ .../pg_profile_lookup.ini | 17 ++ .../Arista-7060CX-32S-Q32/port_config.ini | 33 ++++ .../Arista-7060CX-32S-Q32/qos.json | 167 ++++++++++++++++++ .../Arista-7060CX-32S-Q32/sai.profile.j2 | 13 ++ 7 files changed, 326 insertions(+) create mode 100644 device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers.json.j2 create mode 100644 device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t0.j2 create mode 100644 device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t1.j2 create mode 100644 device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/pg_profile_lookup.ini create mode 100644 device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/port_config.ini create mode 100644 device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/qos.json create mode 100644 device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/sai.profile.j2 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers.json.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers.json.j2 new file mode 100644 index 000000000000..0b1cb2c541b6 --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..3e39d411e8bf --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t0.j2 @@ -0,0 +1,47 @@ + +{%- set default_cable = '5m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0,128,4) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11213696", + "type": "ingress", + "mode": "dynamic", + "xoff": "3855488" + }, + "egress_lossy_pool": { + "size": "9532224", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "15982720", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "static_th":"3995680" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t1.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..d9f562f95624 --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t1.j2 @@ -0,0 +1,47 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0,128,4) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "10443264", + "type": "ingress", + "mode": "dynamic", + "xoff": "4625920" + }, + "egress_lossy_pool": { + "size": "8877440", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "15982720", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "static_th":"3995680" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/pg_profile_lookup.ini b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/pg_profile_lookup.ini new file mode 100644 index 000000000000..3b2a417cebcd --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 1248 2288 35776 -4 2288 + 25000 5m 1248 2288 53248 -4 2288 + 40000 5m 1248 2288 66560 -4 2288 + 50000 5m 1248 2288 90272 -4 2288 + 100000 5m 1248 2288 165568 -4 2288 + 10000 40m 1248 2288 37024 -4 2288 + 25000 40m 1248 2288 53248 -4 2288 + 40000 40m 1248 2288 71552 -4 2288 + 50000 40m 1248 2288 96096 -4 2288 + 100000 40m 1248 2288 177632 -4 2288 + 10000 300m 1248 2288 46176 -4 2288 + 25000 300m 1248 2288 79040 -4 2288 + 40000 300m 1248 2288 108160 -4 2288 + 50000 300m 1248 2288 141856 -4 2288 + 100000 300m 1248 2288 268736 -4 2288 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/port_config.ini b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/port_config.ini new file mode 100644 index 000000000000..bfe4a721141d --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index +Ethernet0 33,34,35,36 Ethernet1/1 1 +Ethernet4 37,38,39,40 Ethernet2/1 2 +Ethernet8 41,42,43,44 Ethernet3/1 3 +Ethernet12 45,46,47,48 Ethernet4/1 4 +Ethernet16 49,50,51,52 Ethernet5/1 5 +Ethernet20 53,54,55,56 Ethernet6/1 6 +Ethernet24 57,58,59,60 Ethernet7/1 7 +Ethernet28 61,62,63,64 Ethernet8/1 8 +Ethernet32 65,66,67,68 Ethernet9/1 9 +Ethernet36 69,70,71,72 Ethernet10/1 10 +Ethernet40 73,74,75,76 Ethernet11/1 11 +Ethernet44 77,78,79,80 Ethernet12/1 12 +Ethernet48 81,82,83,84 Ethernet13/1 13 +Ethernet52 85,86,87,88 Ethernet14/1 14 +Ethernet56 89,90,91,92 Ethernet15/1 15 +Ethernet60 93,94,95,96 Ethernet16/1 16 +Ethernet64 97,98,99,100 Ethernet17/1 17 +Ethernet68 101,102,103,104 Ethernet18/1 18 +Ethernet72 105,106,107,108 Ethernet19/1 19 +Ethernet76 109,110,111,112 Ethernet20/1 20 +Ethernet80 113,114,115,116 Ethernet21/1 21 +Ethernet84 117,118,119,120 Ethernet22/1 22 +Ethernet88 121,122,123,124 Ethernet23/1 23 +Ethernet92 125,126,127,128 Ethernet24/1 24 +Ethernet96 1,2,3,4 Ethernet25/1 25 +Ethernet100 5,6,7,8 Ethernet26/1 26 +Ethernet104 9,10,11,12 Ethernet27/1 27 +Ethernet108 13,14,15,16 Ethernet28/1 28 +Ethernet112 17,18,19,20 Ethernet29/1 29 +Ethernet116 21,22,23,24 Ethernet30/1 30 +Ethernet120 25,26,27,28 Ethernet31/1 31 +Ethernet124 29,30,31,32 Ethernet32/1 32 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/qos.json b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/qos.json new file mode 100644 index 000000000000..b724b48c2c23 --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/qos.json @@ -0,0 +1,167 @@ +{ + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "MAP_PFC_PRIORITY_TO_QUEUE": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"3", + "4":"4", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "SCHEDULER": { + "scheduler.0" : { + "type":"DWRR", + "weight": "25" + }, + "scheduler.1" : { + "type":"DWRR", + "weight": "30" + }, + "scheduler.2" : { + "type":"DWRR", + "weight": "20" + } + }, + "PORT_QOS_MAP": { + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable": "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSY" : { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"512000", + "red_min_threshold":"512000", + "yellow_max_threshold":"512000", + "yellow_min_threshold":"512000", + "green_max_threshold": "184320", + "green_min_threshold": "184320" + }, + "AZURE_LOSSLESS" : { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"512000", + "red_min_threshold":"512000", + "yellow_max_threshold":"512000", + "yellow_min_threshold":"512000", + "green_max_threshold": "184320", + "green_min_threshold": "184320" + } + }, + "QUEUE": { + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0-1" : { + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3-4" : { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0" : { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|1" : { + "scheduler" : "[SCHEDULER|scheduler.2]" + } + } +} diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/sai.profile.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/sai.profile.j2 new file mode 100644 index 000000000000..bef6932f1eac --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/sai.profile.j2 @@ -0,0 +1,13 @@ +{# Get sai.profile based on switch_role #} +{%- if DEVICE_METADATA is defined -%} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] -%} +{%- if switch_role.lower() == 'torrouter' %} +{% set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/etc/bcm/th-a7060-cx32s-32x40G.config.bcm' -%} +{%- else %} +{%- set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/etc/bcm/th-a7060-cx32s-32x40G-t1.config.bcm' -%} +{%- endif %} +{%- else %} +{%- set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/etc/bcm/th-a7060-cx32s-32x40G-t1.config.bcm' -%} +{%- endif %} +{# Write the contents of sai_ profile_filename to sai.profile file #} +{{ sai_profile_contents }} From 323cafd7d9af0d13b69dab5c6816d021f0b85bf9 Mon Sep 17 00:00:00 2001 From: Andriy Moroz Date: Tue, 8 May 2018 18:37:35 +0300 Subject: [PATCH 052/219] Update buffers config for Mellanox 27xx devices (#1649) * Update buffers config for Mellanox 27xx devices Signed-off-by: Andriy Moroz * Remove buffers template test for msn27xx Signed-off-by: Andriy Moroz --- .../LS-SN2700/buffers.json.j2 | 163 +---------------- .../LS-SN2700/buffers_defaults_t0.j2 | 1 + .../LS-SN2700/buffers_defaults_t1.j2 | 1 + .../ACS-MSN2700/buffers.json.j2 | 164 +----------------- .../ACS-MSN2700/buffers_defaults_t0.j2 | 90 ++++++++++ .../ACS-MSN2700/buffers_defaults_t1.j2 | 90 ++++++++++ .../ACS-MSN2740/buffers.json.j2 | 163 +---------------- .../ACS-MSN2740/buffers_defaults_t0.j2 | 1 + .../ACS-MSN2740/buffers_defaults_t1.j2 | 1 + files/build_templates/buffers_config.j2 | 26 ++- src/sonic-config-engine/tests/test_j2files.py | 9 - 11 files changed, 209 insertions(+), 500 deletions(-) mode change 100644 => 120000 device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/buffers.json.j2 create mode 120000 device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/buffers_defaults_t0.j2 create mode 120000 device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/buffers_defaults_t1.j2 create mode 100644 device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 create mode 100644 device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 mode change 100644 => 120000 device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/buffers.json.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/buffers_defaults_t0.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/buffers_defaults_t1.j2 diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/buffers.json.j2 b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/buffers.json.j2 deleted file mode 100644 index da9c764db92b..000000000000 --- a/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/buffers.json.j2 +++ /dev/null @@ -1,162 +0,0 @@ -{# Default values which will be used if no actual configura available #} -{% set default_cable = '300m' %} -{% set default_ports_num = 32 -%} - -{# 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(0,default_ports_num) %} - {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% 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 %} - } - }, -{%if switch_role == 'ToRRouter' %} -{% set ingress_lossless_pool_size = '4194304' %} -{% set ingress_lossy_pool_size = '7340032' %} -{% set egress_lossless_pool_size = '16777152' %} -{% set egress_lossy_pool_size = '7340032' %} -{% else %} -{% set ingress_lossless_pool_size = '2097152' %} -{% set ingress_lossy_pool_size = '5242880' %} -{% set egress_lossless_pool_size = '16777152' %} -{% set egress_lossy_pool_size = '5242880' %} -{%endif %} - "BUFFER_POOL": { - "ingress_lossless_pool": { - "size": "{{ ingress_lossless_pool_size }}", - "type": "ingress", - "mode": "dynamic" - }, - "ingress_lossy_pool": { - "size": "{{ ingress_lossy_pool_size }}", - "type": "ingress", - "mode": "dynamic" - }, - "egress_lossless_pool": { - "size": "{{ egress_lossless_pool_size }}", - "type": "egress", - "mode": "dynamic" - }, - "egress_lossy_pool": { - "size": "{{ egress_lossy_pool_size }}", - "type": "egress", - "mode": "dynamic" - } - }, - "BUFFER_PROFILE": { - "ingress_lossless_profile": { - "pool":"[BUFFER_POOL|ingress_lossless_pool]", - "size":"0", - "dynamic_th":"0" - }, - "ingress_lossy_profile": { - "pool":"[BUFFER_POOL|ingress_lossy_pool]", - "size":"0", - "dynamic_th":"3" - }, - "egress_lossless_profile": { - "pool":"[BUFFER_POOL|egress_lossless_pool]", - "size":"0", - "dynamic_th":"7" - }, - "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", - "size":"4096", - "dynamic_th":"3" - }, - "pg_lossy_profile": { - "pool":"[BUFFER_POOL|ingress_lossy_pool]", - "size":"0", - "dynamic_th":"3" - }, - "q_lossless_profile": { - "pool":"[BUFFER_POOL|egress_lossless_pool]", - "size":"0", - "dynamic_th":"7" - }, - "q_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", - "size":"0", - "dynamic_th":"3" - } - }, - "BUFFER_PORT_INGRESS_PROFILE_LIST": { - "{{ port_names }}": { - "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" - } - }, - "BUFFER_PORT_EGRESS_PROFILE_LIST": { - "{{ port_names }}": { - "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" - } - }, - "BUFFER_PG": { - "{{ port_names }}|0-1": { - "profile" : "[BUFFER_PROFILE|pg_lossy_profile]" - } - }, - "BUFFER_QUEUE": { - "{{ port_names }}|3-4": { - "profile" : "[BUFFER_PROFILE|q_lossless_profile]" - }, - "{{ port_names }}|0-1": { - "profile" : "[BUFFER_PROFILE|q_lossy_profile]" - } - } -} diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/buffers.json.j2 b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/buffers.json.j2 new file mode 120000 index 000000000000..add8bf8bb7c2 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/buffers.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/buffers_defaults_t0.j2 new file mode 120000 index 000000000000..7bcae62336f6 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/buffers_defaults_t0.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/buffers_defaults_t1.j2 new file mode 120000 index 000000000000..a437d613434d --- /dev/null +++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/buffers_defaults_t1.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers.json.j2 index da9c764db92b..1083a6210fc9 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers.json.j2 +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers.json.j2 @@ -1,162 +1,2 @@ -{# Default values which will be used if no actual configura available #} -{% set default_cable = '300m' %} -{% set default_ports_num = 32 -%} - -{# 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(0,default_ports_num) %} - {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% 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 %} - } - }, -{%if switch_role == 'ToRRouter' %} -{% set ingress_lossless_pool_size = '4194304' %} -{% set ingress_lossy_pool_size = '7340032' %} -{% set egress_lossless_pool_size = '16777152' %} -{% set egress_lossy_pool_size = '7340032' %} -{% else %} -{% set ingress_lossless_pool_size = '2097152' %} -{% set ingress_lossy_pool_size = '5242880' %} -{% set egress_lossless_pool_size = '16777152' %} -{% set egress_lossy_pool_size = '5242880' %} -{%endif %} - "BUFFER_POOL": { - "ingress_lossless_pool": { - "size": "{{ ingress_lossless_pool_size }}", - "type": "ingress", - "mode": "dynamic" - }, - "ingress_lossy_pool": { - "size": "{{ ingress_lossy_pool_size }}", - "type": "ingress", - "mode": "dynamic" - }, - "egress_lossless_pool": { - "size": "{{ egress_lossless_pool_size }}", - "type": "egress", - "mode": "dynamic" - }, - "egress_lossy_pool": { - "size": "{{ egress_lossy_pool_size }}", - "type": "egress", - "mode": "dynamic" - } - }, - "BUFFER_PROFILE": { - "ingress_lossless_profile": { - "pool":"[BUFFER_POOL|ingress_lossless_pool]", - "size":"0", - "dynamic_th":"0" - }, - "ingress_lossy_profile": { - "pool":"[BUFFER_POOL|ingress_lossy_pool]", - "size":"0", - "dynamic_th":"3" - }, - "egress_lossless_profile": { - "pool":"[BUFFER_POOL|egress_lossless_pool]", - "size":"0", - "dynamic_th":"7" - }, - "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", - "size":"4096", - "dynamic_th":"3" - }, - "pg_lossy_profile": { - "pool":"[BUFFER_POOL|ingress_lossy_pool]", - "size":"0", - "dynamic_th":"3" - }, - "q_lossless_profile": { - "pool":"[BUFFER_POOL|egress_lossless_pool]", - "size":"0", - "dynamic_th":"7" - }, - "q_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", - "size":"0", - "dynamic_th":"3" - } - }, - "BUFFER_PORT_INGRESS_PROFILE_LIST": { - "{{ port_names }}": { - "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" - } - }, - "BUFFER_PORT_EGRESS_PROFILE_LIST": { - "{{ port_names }}": { - "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" - } - }, - "BUFFER_PG": { - "{{ port_names }}|0-1": { - "profile" : "[BUFFER_PROFILE|pg_lossy_profile]" - } - }, - "BUFFER_QUEUE": { - "{{ port_names }}|3-4": { - "profile" : "[BUFFER_PROFILE|q_lossless_profile]" - }, - "{{ port_names }}|0-1": { - "profile" : "[BUFFER_PROFILE|q_lossy_profile]" - } - } -} +{%- set default_topo = 't0' %} +{%- include 'buffers_config.j2' %} diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..475a0227143c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 @@ -0,0 +1,90 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '4194304' %} +{% set ingress_lossy_pool_size = '7340032' %} +{% set egress_lossless_pool_size = '16777152' %} +{% set egress_lossy_pool_size = '7340032' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"0" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { + "{{ port_names }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { + "{{ port_names }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + } + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-1": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + } + } +{%- endmacro %} + + diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..c292ecc2f21a --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 @@ -0,0 +1,90 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '2097152' %} +{% set ingress_lossy_pool_size = '5242880' %} +{% set egress_lossless_pool_size = '16777152' %} +{% set egress_lossy_pool_size = '5242880' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"0" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { + "{{ port_names }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { + "{{ port_names }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + } + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-1": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + } + } +{%- endmacro %} + + diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/buffers.json.j2 deleted file mode 100644 index da9c764db92b..000000000000 --- a/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/buffers.json.j2 +++ /dev/null @@ -1,162 +0,0 @@ -{# Default values which will be used if no actual configura available #} -{% set default_cable = '300m' %} -{% set default_ports_num = 32 -%} - -{# 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(0,default_ports_num) %} - {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% 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 %} - } - }, -{%if switch_role == 'ToRRouter' %} -{% set ingress_lossless_pool_size = '4194304' %} -{% set ingress_lossy_pool_size = '7340032' %} -{% set egress_lossless_pool_size = '16777152' %} -{% set egress_lossy_pool_size = '7340032' %} -{% else %} -{% set ingress_lossless_pool_size = '2097152' %} -{% set ingress_lossy_pool_size = '5242880' %} -{% set egress_lossless_pool_size = '16777152' %} -{% set egress_lossy_pool_size = '5242880' %} -{%endif %} - "BUFFER_POOL": { - "ingress_lossless_pool": { - "size": "{{ ingress_lossless_pool_size }}", - "type": "ingress", - "mode": "dynamic" - }, - "ingress_lossy_pool": { - "size": "{{ ingress_lossy_pool_size }}", - "type": "ingress", - "mode": "dynamic" - }, - "egress_lossless_pool": { - "size": "{{ egress_lossless_pool_size }}", - "type": "egress", - "mode": "dynamic" - }, - "egress_lossy_pool": { - "size": "{{ egress_lossy_pool_size }}", - "type": "egress", - "mode": "dynamic" - } - }, - "BUFFER_PROFILE": { - "ingress_lossless_profile": { - "pool":"[BUFFER_POOL|ingress_lossless_pool]", - "size":"0", - "dynamic_th":"0" - }, - "ingress_lossy_profile": { - "pool":"[BUFFER_POOL|ingress_lossy_pool]", - "size":"0", - "dynamic_th":"3" - }, - "egress_lossless_profile": { - "pool":"[BUFFER_POOL|egress_lossless_pool]", - "size":"0", - "dynamic_th":"7" - }, - "egress_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", - "size":"4096", - "dynamic_th":"3" - }, - "pg_lossy_profile": { - "pool":"[BUFFER_POOL|ingress_lossy_pool]", - "size":"0", - "dynamic_th":"3" - }, - "q_lossless_profile": { - "pool":"[BUFFER_POOL|egress_lossless_pool]", - "size":"0", - "dynamic_th":"7" - }, - "q_lossy_profile": { - "pool":"[BUFFER_POOL|egress_lossy_pool]", - "size":"0", - "dynamic_th":"3" - } - }, - "BUFFER_PORT_INGRESS_PROFILE_LIST": { - "{{ port_names }}": { - "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" - } - }, - "BUFFER_PORT_EGRESS_PROFILE_LIST": { - "{{ port_names }}": { - "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" - } - }, - "BUFFER_PG": { - "{{ port_names }}|0-1": { - "profile" : "[BUFFER_PROFILE|pg_lossy_profile]" - } - }, - "BUFFER_QUEUE": { - "{{ port_names }}|3-4": { - "profile" : "[BUFFER_PROFILE|q_lossless_profile]" - }, - "{{ port_names }}|0-1": { - "profile" : "[BUFFER_PROFILE|q_lossy_profile]" - } - } -} diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/buffers.json.j2 new file mode 120000 index 000000000000..add8bf8bb7c2 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/buffers.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/buffers_defaults_t0.j2 new file mode 120000 index 000000000000..7bcae62336f6 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/buffers_defaults_t0.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/buffers_defaults_t1.j2 new file mode 120000 index 000000000000..a437d613434d --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/buffers_defaults_t1.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 \ No newline at end of file diff --git a/files/build_templates/buffers_config.j2 b/files/build_templates/buffers_config.j2 index 6c55b257342e..20019d20afae 100644 --- a/files/build_templates/buffers_config.j2 +++ b/files/build_templates/buffers_config.j2 @@ -4,7 +4,7 @@ {%- else %} def {%- endif %} -{%- endmacro %} +{%- endmacro -%} {# Determine device topology and filename postfix #} {%- if DEVICE_METADATA is defined %} @@ -19,12 +19,12 @@ def {%- else %} {%- set filename_postfix = set_default_topology() %} {%- set switch_role = '' %} -{%- endif %} +{%- endif -%} {# Import default values from device HWSKU folder #} {%- import 'buffers_defaults_%s.j2' % filename_postfix as defs %} -{%- set default_cable = defs.default_cable %} +{%- set default_cable = defs.default_cable -%} {# Port configuration to cable length look-up table #} {# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} @@ -106,13 +106,28 @@ def {% endfor %} } }, -{% set bufs = defs.generate_buffer_pool_and_profiles() %} -{{ bufs }} + +{% if defs.generate_buffer_pool_and_profiles is defined %} +{{ defs.generate_buffer_pool_and_profiles() }} +{% endif %} + +{%- if defs.generate_profile_lists is defined %} +{{ defs.generate_profile_lists(port_names_all) }}, +{% endif %} + +{%- if defs.generate_pg_profils is defined %} +{{ defs.generate_pg_profils }}, +{% else %} "BUFFER_PG": { "{{ port_names_all }}|0-1": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" } }, +{% endif %} + +{% if defs.generate_queue_buffers is defined %} +{{ defs.generate_queue_buffers(port_names_all) }} +{% else %} "BUFFER_QUEUE": { "{{ port_names_all }}|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" @@ -121,4 +136,5 @@ def "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" } } +{% endif %} } diff --git a/src/sonic-config-engine/tests/test_j2files.py b/src/sonic-config-engine/tests/test_j2files.py index bda3a20dbdfb..aba7feb194ad 100644 --- a/src/sonic-config-engine/tests/test_j2files.py +++ b/src/sonic-config-engine/tests/test_j2files.py @@ -111,15 +111,6 @@ def test_ipinip(self): sample_output_file = os.path.join(self.test_dir, 'sample_output', 'ipinip.json') assert filecmp.cmp(sample_output_file, self.output_file) - def test_msn27xx_32ports_buffers(self): - buffer_file = os.path.join(self.test_dir, '..', '..', '..', 'device', 'mellanox', 'x86_64-mlnx_msn2700-r0', 'ACS-MSN2700', 'buffers.json.j2') - argument = '-m ' + self.t1_mlnx_minigraph + ' -p ' + self.mlnx_port_config + ' -t ' + buffer_file + ' > ' + self.output_file - self.run_script(argument) - - sample_output_file = os.path.join(self.test_dir, 'sample_output', 'msn27.32ports.json') - - self.assertTrue(filecmp.cmp(sample_output_file, self.output_file)) - def test_sku_render_template(self): argument = '-k Mellanox-SN2700 -t ' + os.path.join(self.test_dir, '../data/l2switch.j2') + ' -p ' + self.t0_port_config + ' > ' + self.output_file self.run_script(argument) From 1139cd740245b178ec89b011cc177600ba9cc548 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Wed, 9 May 2018 19:18:35 -0700 Subject: [PATCH 053/219] [submodule]: Update submodule sonic-snmpagent: Improve mib fundamental classes (#1689) Signed-off-by: Qi Luo --- src/sonic-snmpagent | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-snmpagent b/src/sonic-snmpagent index a03f7794d6b2..b6bf4a77e07a 160000 --- a/src/sonic-snmpagent +++ b/src/sonic-snmpagent @@ -1 +1 @@ -Subproject commit a03f7794d6b2faec23088ba064cb6ce7e7d2122a +Subproject commit b6bf4a77e07a1d70d750aad69125532df33276dc From d826055c29f088adb5e86d7e71599b6df681ed00 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Thu, 10 May 2018 09:03:21 +0000 Subject: [PATCH 054/219] [sonic-utilities]: update sonic utilities submodule * 951633b 2018-05-04 | [generate_dump]: fix a saidump file copy bug (#248) (HEAD, origin/201803) [Kebo Liu] * 69baff7 2018-05-03 | [acl_loader]: Missing one colon (#252) [Shuotian Cheng] * 557248d 2018-05-02 | [acl-loader]: Add --table_name option to update full operation (#249) [Shuotian Cheng] * a8aadee 2018-04-30 | [acl-loader]: Change the header from Rule ID to Table (#250) [Shuotian Cheng] Signed-off-by: Guohan Lu --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 0b9bb2b12c3c..951633b02606 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 0b9bb2b12c3c68aab273bc11488f21ca7395e455 +Subproject commit 951633b02606768b458b7dc88f6c6f8ca736db4e From d26d9fb061f0cf7b6259bd13f07a165775e1033a Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Thu, 10 May 2018 09:05:13 +0000 Subject: [PATCH 055/219] [swss]: update sonic-swss * b57c376 2018-05-10 | [teamsyncd]: Add team_ifindex2ifname return value check (#500) (HEAD, origin/201803) [Shuotian Cheng] * 236843f 2018-05-07 | Fix Crm Acl used counter update (#496) [Nadiya] Signed-off-by: Guohan Lu --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index d57f9a16b142..b57c37603324 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit d57f9a16b1428fab216e5f3e2ec1e2f8c1f9aefc +Subproject commit b57c376033244605b39291f101874ea2ac032b35 From 1c5403977e2cae9b49f10dc4fab17e65cbe8248d Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Thu, 10 May 2018 09:43:10 +0000 Subject: [PATCH 056/219] [swss]: update sonic-swss c374357 2018-04-23 | Fix ZeroBufferProfile parameters (#485) (HEAD -> 201803) [Andriy Moroz] Signed-off-by: Guohan Lu --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index b57c37603324..c374357b25df 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit b57c376033244605b39291f101874ea2ac032b35 +Subproject commit c374357b25df9b222c3b898f916463f8a74df40c From 30a08a18e9bdff239d845c70cb980ea9690a5140 Mon Sep 17 00:00:00 2001 From: Hnydyn Nazar Date: Sat, 12 May 2018 02:39:20 +0300 Subject: [PATCH 057/219] [platform]: Fixed Cavium platform modules build. (#1694) --- platform/cavium/cavm-platform-modules.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/cavium/cavm-platform-modules.mk b/platform/cavium/cavm-platform-modules.mk index 4ac72a4c4aab..500043d131e1 100644 --- a/platform/cavium/cavm-platform-modules.mk +++ b/platform/cavium/cavm-platform-modules.mk @@ -1,3 +1,4 @@ CAVM_PLATFORM_DEB = cavm_platform_modules.deb $(CAVM_PLATFORM_DEB)_SRC_PATH = $(PLATFORM_PATH)/cavm_platform_modules +$(CAVM_PLATFORM_DEB)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) SONIC_MAKE_DEBS += $(CAVM_PLATFORM_DEB) From 5836ec7768e3d4c6499dcaddd3d8c564bd8bd2dc Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Fri, 11 May 2018 21:23:01 -0700 Subject: [PATCH 058/219] [submodule]: Update submodule sonic-snmpagent: Improve mib fundamental classes: retry after reinit_data() throws (#1700) --- src/sonic-snmpagent | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-snmpagent b/src/sonic-snmpagent index b6bf4a77e07a..f28315252698 160000 --- a/src/sonic-snmpagent +++ b/src/sonic-snmpagent @@ -1 +1 @@ -Subproject commit b6bf4a77e07a1d70d750aad69125532df33276dc +Subproject commit f28315252698aabc927eca84b836493385fcf4a1 From 0dca56395d43b5433652febfbd95d8d6e53b3295 Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Sat, 12 May 2018 01:31:17 -0700 Subject: [PATCH 059/219] [baseimage]: Disable DAD for eth0 explicitly (#1701) --- build_debian.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/build_debian.sh b/build_debian.sh index 2b2294194d7b..b1026c7bf3c2 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -300,6 +300,7 @@ set /files/etc/sysctl.conf/net.ipv6.conf.eth0.forwarding 0 set /files/etc/sysctl.conf/net.ipv6.conf.default.accept_dad 0 set /files/etc/sysctl.conf/net.ipv6.conf.all.accept_dad 0 +set /files/etc/sysctl.conf/net.ipv6.conf.eth0.accept_dad 0 set /files/etc/sysctl.conf/net.ipv6.conf.eth0.accept_ra_defrtr 0 From 1d03df43c0b908f63ceab6cfd17467d5106df8d5 Mon Sep 17 00:00:00 2001 From: lguohan Date: Fri, 11 May 2018 14:02:10 -0700 Subject: [PATCH 060/219] [quagga]: update quagga submodule (#1698) * [quagga]: update quagga submodule 0bc6bd6 2018-05-11 | ignore nexthop attribute when NLRI is present (#18) (HEAD, origin/debian/0.99.24.1, origin/HEAD) [lguohan] Signed-off-by: Guohan Lu * add vs bgp test Signed-off-by: Guohan Lu --- platform/vs/README.md | 2 +- platform/vs/tests/README.md | 4 + platform/vs/tests/bgp/files/bgpd.conf | 7 + .../vs/tests/bgp/files/invalid_nexthop.conf | 19 ++ platform/vs/tests/bgp/test_invalid_nexthop.py | 32 +++ platform/vs/tests/conftest.py | 231 ++++++++++++++++++ src/sonic-quagga | 2 +- 7 files changed, 295 insertions(+), 2 deletions(-) create mode 100644 platform/vs/tests/README.md create mode 100644 platform/vs/tests/bgp/files/bgpd.conf create mode 100644 platform/vs/tests/bgp/files/invalid_nexthop.conf create mode 100644 platform/vs/tests/bgp/test_invalid_nexthop.py create mode 100644 platform/vs/tests/conftest.py diff --git a/platform/vs/README.md b/platform/vs/README.md index 52f3f30eac6d..30d29b371b6e 100644 --- a/platform/vs/README.md +++ b/platform/vs/README.md @@ -44,7 +44,7 @@ sw-srv0 (id: 5) 2. Start sonic virtual switch docker ``` -$ docker run --privileged --network container:sw -d docker-sonic-vs +$ docker run --privileged --network container:sw --name vs -d docker-sonic-vs ``` 3. Setup IP in the virtual switch docker diff --git a/platform/vs/tests/README.md b/platform/vs/tests/README.md new file mode 100644 index 000000000000..29ba27db62fc --- /dev/null +++ b/platform/vs/tests/README.md @@ -0,0 +1,4 @@ +Requirements: + +- Enable IPv6 for docker engine +- pip install exabgp diff --git a/platform/vs/tests/bgp/files/bgpd.conf b/platform/vs/tests/bgp/files/bgpd.conf new file mode 100644 index 000000000000..b22bf17f92e3 --- /dev/null +++ b/platform/vs/tests/bgp/files/bgpd.conf @@ -0,0 +1,7 @@ +router bgp 65501 + bgp router-id 1.1.1.1 + no bgp default ipv4-unicast + neighbor fc00::2 remote-as 65502 + address-family ipv6 + neighbor fc00::2 activate + exit-address-family diff --git a/platform/vs/tests/bgp/files/invalid_nexthop.conf b/platform/vs/tests/bgp/files/invalid_nexthop.conf new file mode 100644 index 000000000000..60a327d7121d --- /dev/null +++ b/platform/vs/tests/bgp/files/invalid_nexthop.conf @@ -0,0 +1,19 @@ +neighbor fc00::1 { + router-id 1.2.3.4; + local-address fc00::2; + local-as 65502; + peer-as 65501; + group-updates false; + + family { + ipv4 unicast; + ipv6 unicast; + } + + static { + route 3333::0/64 { + next-hop 0.0.0.0; + next-hop fc00::2; + } + } +} diff --git a/platform/vs/tests/bgp/test_invalid_nexthop.py b/platform/vs/tests/bgp/test_invalid_nexthop.py new file mode 100644 index 000000000000..cdb67337b896 --- /dev/null +++ b/platform/vs/tests/bgp/test_invalid_nexthop.py @@ -0,0 +1,32 @@ +from swsscommon import swsscommon +import os +import re +import time +import json + +def test_InvalidNexthop(dvs): + + dvs.copy_file("/etc/quagga/", "bgp/files/bgpd.conf") + dvs.runcmd("supervisorctl start bgpd") + dvs.runcmd("ip addr add fc00::1/126 dev Ethernet0") + dvs.runcmd("ifconfig Ethernet0 up") + + dvs.servers[0].runcmd("ip addr add fc00::2/126 dev eth0") + dvs.servers[0].runcmd("ifconfig eth0 up") + + time.sleep(5) + + print dvs.runcmd("supervisorctl status") + + p = dvs.servers[0].runcmd_async("exabgp -d bgp/files/invalid_nexthop.conf") + + time.sleep(10) + + output = dvs.runcmd(["vtysh", "-c", "show ipv6 bgp"]) + + p.terminate() + p = p.wait() + + print output + + assert "3333::/64" in output diff --git a/platform/vs/tests/conftest.py b/platform/vs/tests/conftest.py new file mode 100644 index 000000000000..98b6b2a2e1a6 --- /dev/null +++ b/platform/vs/tests/conftest.py @@ -0,0 +1,231 @@ +import os +import os.path +import re +import time +import docker +import pytest +import commands +import tarfile +import StringIO +import subprocess +from swsscommon import swsscommon + +def pytest_addoption(parser): + parser.addoption("--dvsname", action="store", default=None, + help="dvs name") + +class AsicDbValidator(object): + def __init__(self, dvs): + self.adb = swsscommon.DBConnector(1, dvs.redis_sock, 0) + + # get default dot1q vlan id + atbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN") + + keys = atbl.getKeys() + assert len(keys) == 1 + self.default_vlan_id = keys[0] + + # build port oid to front port name mapping + self.portoidmap = {} + self.portnamemap = {} + self.hostifoidmap = {} + self.hostifnamemap = {} + atbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_HOSTIF") + keys = atbl.getKeys() + + assert len(keys) == 32 + for k in keys: + (status, fvs) = atbl.get(k) + + assert status == True + + for fv in fvs: + if fv[0] == "SAI_HOSTIF_ATTR_OBJ_ID": + port_oid = fv[1] + elif fv[0] == "SAI_HOSTIF_ATTR_NAME": + port_name = fv[1] + + self.portoidmap[port_oid] = port_name + self.portnamemap[port_name] = port_oid + self.hostifoidmap[k] = port_name + self.hostifnamemap[port_name] = k + + # get default acl table and acl rules + atbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_TABLE") + keys = atbl.getKeys() + + assert len(keys) == 1 + self.default_acl_table = keys[0] + + atbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_ENTRY") + keys = atbl.getKeys() + + assert len(keys) == 2 + self.default_acl_entries = keys + +class VirtualServer(object): + def __init__(self, ctn_name, pid, i): + self.nsname = "%s-srv%d" % (ctn_name, i) + self.vifname = "vEthernet%d" % (i * 4) + self.cleanup = True + + # create netns + if os.path.exists("/var/run/netns/%s" % self.nsname): + self.cleanup = False + else: + os.system("ip netns add %s" % self.nsname) + + # create vpeer link + os.system("ip link add %s type veth peer name %s" % (self.nsname[0:12], self.vifname)) + os.system("ip link set %s netns %s" % (self.nsname[0:12], self.nsname)) + os.system("ip link set %s netns %d" % (self.vifname, pid)) + + # bring up link in the virtual server + os.system("ip netns exec %s ip link set dev %s name eth0" % (self.nsname, self.nsname[0:12])) + os.system("ip netns exec %s ip link set dev eth0 up" % (self.nsname)) + os.system("ip netns exec %s ethtool -K eth0 tx off" % (self.nsname)) + + # bring up link in the virtual switch + os.system("nsenter -t %d -n ip link set dev %s up" % (pid, self.vifname)) + + def __del__(self): + if self.cleanup: + os.system("ip netns delete %s" % self.nsname) + + def runcmd(self, cmd): + os.system("ip netns exec %s %s" % (self.nsname, cmd)) + + def runcmd_async(self, cmd): + return subprocess.Popen("ip netns exec %s %s" % (self.nsname, cmd), shell=True) + +class DockerVirtualSwitch(object): + def __init__(self, name=None): + self.pnames = ['fpmsyncd', + 'intfmgrd', + 'intfsyncd', + 'neighsyncd', + 'orchagent', + 'portsyncd', + 'redis-server', + 'rsyslogd', + 'syncd', + 'teamsyncd', + 'vlanmgrd', + 'zebra'] + self.mount = "/var/run/redis-vs" + self.redis_sock = self.mount + '/' + "redis.sock" + self.client = docker.from_env() + + self.ctn = None + self.cleanup = True + if name != None: + # get virtual switch container + for ctn in self.client.containers.list(): + if ctn.name == name: + self.ctn = ctn + (status, output) = commands.getstatusoutput("docker inspect --format '{{.HostConfig.NetworkMode}}' %s" % name) + ctn_sw_id = output.split(':')[1] + self.cleanup = False + if self.ctn == None: + raise NameError("cannot find container %s" % name) + + # get base container + for ctn in self.client.containers.list(): + if ctn.id == ctn_sw_id or ctn.name == ctn_sw_id: + ctn_sw_name = ctn.name + + (status, output) = commands.getstatusoutput("docker inspect --format '{{.State.Pid}}' %s" % ctn_sw_name) + self.ctn_sw_pid = int(output) + + # create virtual servers + self.servers = [] + for i in range(32): + server = VirtualServer(ctn_sw_name, self.ctn_sw_pid, i) + self.servers.append(server) + + self.restart() + else: + self.ctn_sw = self.client.containers.run('debian:jessie', privileged=True, detach=True, + command="bash", stdin_open=True) + (status, output) = commands.getstatusoutput("docker inspect --format '{{.State.Pid}}' %s" % self.ctn_sw.name) + self.ctn_sw_pid = int(output) + + # create virtual server + self.servers = [] + for i in range(32): + server = VirtualServer(self.ctn_sw.name, self.ctn_sw_pid, i) + self.servers.append(server) + + # create virtual switch container + self.ctn = self.client.containers.run('docker-sonic-vs', privileged=True, detach=True, + network_mode="container:%s" % self.ctn_sw.name, + volumes={ self.mount: { 'bind': '/var/run/redis', 'mode': 'rw' } }) + + self.ctn.exec_run("sysctl -w net.ipv6.conf.all.disable_ipv6=0") + self.check_ready() + self.init_asicdb_validator() + + def destroy(self): + if self.cleanup: + self.ctn.remove(force=True) + self.ctn_sw.remove(force=True) + for s in self.servers: + del(s) + + def check_ready(self, timeout=30): + '''check if all processes in the dvs is ready''' + + re_space = re.compile('\s+') + process_status = {} + ready = False + started = 0 + while True: + # get process status + out = self.ctn.exec_run("supervisorctl status") + for l in out.split('\n'): + fds = re_space.split(l) + if len(fds) < 2: + continue + process_status[fds[0]] = fds[1] + + # check if all processes are running + ready = True + for pname in self.pnames: + try: + if process_status[pname] != "RUNNING": + ready = False + except KeyError: + ready = False + + if ready == True: + break + + started += 1 + if started > timeout: + raise ValueError(out) + + time.sleep(1) + + def restart(self): + self.ctn.restart() + + def init_asicdb_validator(self): + self.asicdb = AsicDbValidator(self) + + def runcmd(self, cmd): + return self.ctn.exec_run(cmd) + + def copy_file(self, path, filename): + tarstr = StringIO.StringIO() + tar = tarfile.open(fileobj=tarstr, mode="w") + tar.add(filename, os.path.basename(filename)) + tar.close() + self.ctn.put_archive(path, tarstr.getvalue()) + tarstr.close() + +@pytest.yield_fixture(scope="module") +def dvs(request): + name = request.config.getoption("--dvsname") + dvs = DockerVirtualSwitch(name) + yield dvs + dvs.destroy() diff --git a/src/sonic-quagga b/src/sonic-quagga index e1217a526999..0bc6bd6b208e 160000 --- a/src/sonic-quagga +++ b/src/sonic-quagga @@ -1 +1 @@ -Subproject commit e1217a5269990926dff30624063975673b1da065 +Subproject commit 0bc6bd6b208e3701df89c3e231c48f3bdb3d046f From 20d0531e42a1a78b231c2db68f41046f396c84b5 Mon Sep 17 00:00:00 2001 From: Volodymyr Samotiy Date: Thu, 17 May 2018 21:13:32 +0300 Subject: [PATCH 061/219] [mellanox]: Update FW pointer (#1722) Signed-off-by: Volodymyr Samotiy --- platform/mellanox/fw.mk | 2 +- platform/mellanox/sdk.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index 0ac9dd9b7aa6..73d1236f5a9a 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -1,6 +1,6 @@ # mellanox firmware -MLNX_FW_VERSION = 13.1620.0208 +MLNX_FW_VERSION = 13.1620.0222 MLNX_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_FW_VERSION))-EVB.mfa $(MLNX_FW_FILE)_URL = $(MLNX_SDK_BASE_URL)/$(MLNX_FW_FILE) SONIC_ONLINE_FILES += $(MLNX_FW_FILE) diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index 2ae9e43ac52a..f301032846c3 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,4 +1,4 @@ -MLNX_SDK_BASE_URL = https://github.com/Mellanox/SAI-Implementation/raw/56130a854a3b0f4e46d6d84749a5d758e7d1f297/sdk +MLNX_SDK_BASE_URL = https://github.com/Mellanox/SAI-Implementation/raw/957f61820e441e490081cb3724f702ed507f7477/sdk MLNX_SDK_VERSION = 4.2.7303 MLNX_SDK_RDEBS += $(APPLIBS) $(IPROUTE2_MLNX) $(SX_ACL_RM) $(SX_COMPLIB) \ $(SX_EXAMPLES) $(SX_GEN_UTILS) $(SX_SCEW) $(SX_SDN_HAL) \ From 4faf96f68851718d2ceb712180dd2ae49f3e5a43 Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Tue, 15 May 2018 05:27:10 -0700 Subject: [PATCH 062/219] [Arista]: Add a reboot script for all remaining platforms. (#1706) Adds a platform_reboot script for 7050QX-32, 7050QX-32S and 7060CX-32S. This allow a proper cold reboot to happen. --- .../x86_64-arista_7050_qx32/platform_reboot | 87 +++++++++++++++++++ .../x86_64-arista_7050_qx32s/platform_reboot | 87 +++++++++++++++++++ .../x86_64-arista_7060_cx32s/platform_reboot | 18 ++++ 3 files changed, 192 insertions(+) create mode 100755 device/arista/x86_64-arista_7050_qx32/platform_reboot create mode 100755 device/arista/x86_64-arista_7050_qx32s/platform_reboot create mode 100755 device/arista/x86_64-arista_7060_cx32s/platform_reboot diff --git a/device/arista/x86_64-arista_7050_qx32/platform_reboot b/device/arista/x86_64-arista_7050_qx32/platform_reboot new file mode 100755 index 000000000000..da438b8fe52b --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32/platform_reboot @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# Copyright (c) 2018 Arista Networks, Inc. All rights reserved. +# Arista Networks, Inc. Confidential and Proprietary. + +# Reboot script for 7050QX-32 + +from __future__ import print_function +import sys +import mmap, os +import subprocess +from struct import pack, unpack + +class MmapResource( object ): + """Resource implementation for a directly-mapped memory region.""" + + def __init__( self, path ): + try: + fd = os.open( path, os.O_RDWR ) + except EnvironmentError: + print( "FAIL can not open scd memory-map resource file" ) + print( "FAIL are you running on the proper platform?" ) + sys.exit( 1 ) + try: + size = os.fstat( fd ).st_size + except EnvironmentError: + print( "FAIL can not fstat scd memory-map resource file" ) + print( "FAIL are you running on the proper platform?" ) + sys.exit( 1 ) + try: + self.mmap_ = mmap.mmap( fd, size, mmap.MAP_SHARED, + mmap.PROT_READ | mmap.PROT_WRITE ) + except EnvironmentError: + print( "FAIL can not map scd memory-map file" ) + print( "FAIL are you running on the proper platform?" ) + sys.exit( 1 ) + finally: + try: + # Note that closing the file descriptor has no effect on the memory map + os.close( fd ) + except EnvironmentError: + print( "FAIL failed to close scd memory-map file" ) + sys.exit( 1 ) + + def read32( self, addr ): + return unpack( ' Date: Wed, 16 May 2018 10:04:17 -0700 Subject: [PATCH 063/219] [fast-reboot]: support encoded & gzipped minigraph in fast reboot (#1716) * [fast-reboot]: support encoded & gzipped minigraph in fast reboot Signed-off-by: Guohan Lu * add acl.json and snmp.yml into fast-reboot Signed-off-by: Guohan Lu --- files/image_config/platform/rc.local | 34 ++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/files/image_config/platform/rc.local b/files/image_config/platform/rc.local index a931efb5b469..de54d141ef7e 100755 --- a/files/image_config/platform/rc.local +++ b/files/image_config/platform/rc.local @@ -126,19 +126,31 @@ if [ ! -e /host/machine.conf ]; then if [ -n "$nos_dev" ]; then # Mount the previous NOS's partition - mkdir -p /mnt/nos_migration - mount $nos_dev /mnt/nos_migration + NOS_DIR=/mnt/nos_migration + MG_GZFILE=$NOS_DIR/minigraph.xml.gz.base64.txt + MG_FILE=$NOS_DIR/minigraph.xml + ACL_GZFILE=$NOS_DIR/acl.json.gz.base64.txt + ACL_FILE=$NOS_DIR/acl.json + SNMP_FILE=$NOS_DIR/snmp.yml + mkdir -p $NOS_DIR + mount $nos_dev $NOS_DIR mkdir -p /host/fast-reboot + # decode & unzip minigraph.xml.gz.base64.txt + [ -f $MG_GZFILE ] && /usr/bin/base64 -d $MG_GZFILE | /bin/gunzip > $MG_FILE + [ -f $ACL_GZFILE ] && /usr/bin/base64 -d $ACL_GZFILE | /bin/gunzip > $ACL_FILE + # Copy relevant files - nos_migration_import /mnt/nos_migration/mgmt_interface.cfg /host/migration - nos_migration_import /mnt/nos_migration/minigraph.xml /host/migration - nos_migration_import /mnt/nos_migration/arp.json /host/fast-reboot - nos_migration_import /mnt/nos_migration/fdb.json /host/fast-reboot - nos_migration_import /mnt/nos_migration/default_routes.json /host/fast-reboot - - umount /mnt/nos_migration - rmdir /mnt/nos_migration + nos_migration_import $NOS_DIR/mgmt_interface.cfg /host/migration + nos_migration_import $MG_FILE /host/migration + nos_migration_import $ACL_FILE /host/migration + nos_migration_import $SNMP_FILE /host/migration + nos_migration_import $NOS_DIR/arp.json /host/fast-reboot + nos_migration_import $NOS_DIR/fdb.json /host/fast-reboot + nos_migration_import $NOS_DIR/default_routes.json /host/fast-reboot + + umount $NOS_DIR + rmdir $NOS_DIR fi update_mgmt_interface_macaddr /host/migration/mgmt_interface.cfg @@ -196,6 +208,8 @@ if [ -f /host/image-$sonic_version/platform/firsttime ]; then elif [ -n "$migration" ] && [ -f /host/migration/minigraph.xml ]; then mkdir -p /etc/sonic/old_config mv /host/migration/minigraph.xml /etc/sonic/old_config/ + [ -f /host/migration/acl.json ] && mv /host/migration/acl.json /etc/sonic/old_config/ + [ -f /host/migration/snmp.yml ] && mv /host/migration/snmp.yml /etc/sonic/old_config/ touch /tmp/pending_config_migration [ -f /etc/sonic/updategraph.conf ] && sed -i -e "s/enabled=false/enabled=true/g" /etc/sonic/updategraph.conf else From 35bc68d65241dd973be8ff8d44c6b2db0da0b629 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 16 May 2018 14:32:42 -0700 Subject: [PATCH 064/219] [dhcp_relay] Only attempt to start 'isc-dhcp-relay' group if it is not empty (#1713) --- dockers/docker-dhcp-relay/start.sh | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/dockers/docker-dhcp-relay/start.sh b/dockers/docker-dhcp-relay/start.sh index 2ee80c4e3388..0ac5ea1a10ec 100755 --- a/dockers/docker-dhcp-relay/start.sh +++ b/dockers/docker-dhcp-relay/start.sh @@ -6,13 +6,16 @@ rm -f /var/run/rsyslogd.pid # Start rsyslog supervisorctl start rsyslogd -# Wait for all interfaces to come up and be assigned IPv4 addresses before -# starting the DHCP relay agent(s). If an interface the relay should listen -# on is down, the relay agent will not start. If an interface the relay should -# listen on is up but does not have an IP address assigned when the relay -# agent starts, it will not listen or send on that interface for the lifetime -# of the process. -/usr/bin/wait_for_intf.sh +# If our supervisor config has entries in the "isc-dhcp-relay" group... +if [ $(supervisorctl status | grep -c "^isc-dhcp-relay:") -gt 0 ]; then + # Wait for all interfaces to come up and be assigned IPv4 addresses before + # starting the DHCP relay agent(s). If an interface the relay should listen + # on is down, the relay agent will not start. If an interface the relay + # should listen on is up but does not have an IP address assigned when the + # relay agent starts, it will not listen or send on that interface for the + # lifetime of the process. + /usr/bin/wait_for_intf.sh -# Start the DHCP relay agent(s) -supervisorctl start isc-dhcp-relay:* + # Start all DHCP relay agent(s) + supervisorctl start isc-dhcp-relay:* +fi From da27cd80dad900d7b1de2aa4fe888b95cbf8ad60 Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Thu, 17 May 2018 17:41:43 -0700 Subject: [PATCH 065/219] [devices]: Reverting the xoff value for Arista 7060 t0 topology (#1726) --- .../Arista-7060CX-32S-D48C8/buffers_defaults_t0.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers_defaults_t0.j2 index 2b7215243f12..7463e20afabe 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers_defaults_t0.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers_defaults_t0.j2 @@ -28,7 +28,7 @@ "size": "11213696", "type": "ingress", "mode": "dynamic", - "xoff": "8356608" + "xoff": "3855488" }, "egress_lossy_pool": { "size": "9532224", From 341075054e69ca3a2302b3a3ae54bda99badd19c Mon Sep 17 00:00:00 2001 From: lguohan Date: Fri, 18 May 2018 16:32:49 -0700 Subject: [PATCH 066/219] [devices]: add Mellanox-SN2700-D48C8 hwsku (#1717) Signed-off-by: Guohan Lu --- .../Mellanox-SN2700-D48C8/buffers.json.j2 | 2 + .../buffers_defaults_t0.j2 | 90 ++++++ .../buffers_defaults_t1.j2 | 90 ++++++ .../pg_profile_lookup.ini | 17 ++ .../Mellanox-SN2700-D48C8/port_config.ini | 57 ++++ .../Mellanox-SN2700-D48C8/qos.json | 166 +++++++++++ .../Mellanox-SN2700-D48C8/sai.profile | 1 + .../sai_2700_48x50g_8x100g.xml | 267 ++++++++++++++++++ 8 files changed, 690 insertions(+) create mode 100644 device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers.json.j2 create mode 100644 device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_defaults_t0.j2 create mode 100644 device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_defaults_t1.j2 create mode 100644 device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/pg_profile_lookup.ini create mode 100644 device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini create mode 100644 device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/qos.json create mode 100644 device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/sai.profile create mode 100644 device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/sai_2700_48x50g_8x100g.xml diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers.json.j2 new file mode 100644 index 000000000000..1083a6210fc9 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't0' %} +{%- include 'buffers_config.j2' %} diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..475a0227143c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_defaults_t0.j2 @@ -0,0 +1,90 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '4194304' %} +{% set ingress_lossy_pool_size = '7340032' %} +{% set egress_lossless_pool_size = '16777152' %} +{% set egress_lossy_pool_size = '7340032' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"0" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { + "{{ port_names }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { + "{{ port_names }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + } + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-1": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + } + } +{%- endmacro %} + + diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..c292ecc2f21a --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/buffers_defaults_t1.j2 @@ -0,0 +1,90 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '2097152' %} +{% set ingress_lossy_pool_size = '5242880' %} +{% set egress_lossless_pool_size = '16777152' %} +{% set egress_lossy_pool_size = '5242880' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"0" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { + "{{ port_names }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { + "{{ port_names }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + } + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-1": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + } + } +{%- endmacro %} + + diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/pg_profile_lookup.ini new file mode 100644 index 000000000000..b66b129fe43f --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 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 + 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 + 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/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini new file mode 100644 index 000000000000..d54a31851614 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini @@ -0,0 +1,57 @@ +# name lanes speed +Ethernet0 0,1 50000 +Ethernet2 2,3 50000 +Ethernet4 4,5 50000 +Ethernet6 6,7 50000 +Ethernet8 8,9 50000 +Ethernet10 10,11 50000 +Ethernet12 12,13 50000 +Ethernet14 14,15 50000 +Ethernet16 16,17 50000 +Ethernet18 18,19 50000 +Ethernet20 20,21 50000 +Ethernet22 22,23 50000 +Ethernet24 24,25,26,27 100000 +Ethernet28 28,29,30,31 100000 +Ethernet32 32,33,34,35 100000 +Ethernet36 36,37,38,39 100000 +Ethernet40 40,41 50000 +Ethernet42 42,43 50000 +Ethernet44 44,45 50000 +Ethernet46 46,47 50000 +Ethernet48 48,49 50000 +Ethernet50 50,51 50000 +Ethernet52 52,53 50000 +Ethernet54 54,55 50000 +Ethernet56 56,57 50000 +Ethernet58 58,59 50000 +Ethernet60 60,61 50000 +Ethernet62 62,63 50000 +Ethernet64 64,65 50000 +Ethernet66 66,67 50000 +Ethernet68 68,69 50000 +Ethernet70 70,71 50000 +Ethernet72 72,73 50000 +Ethernet74 74,75 50000 +Ethernet76 76,77 50000 +Ethernet78 78,79 50000 +Ethernet80 80,81 50000 +Ethernet82 82,83 50000 +Ethernet84 84,85 50000 +Ethernet86 86,87 50000 +Ethernet88 88,89,90,91 100000 +Ethernet92 92,93,94,95 100000 +Ethernet96 96,97,98,99 100000 +Ethernet100 100,101,102,103 100000 +Ethernet104 104,105 50000 +Ethernet106 106,107 50000 +Ethernet108 108,109 50000 +Ethernet110 110,111 50000 +Ethernet112 112,113 50000 +Ethernet114 114,115 50000 +Ethernet116 116,117 50000 +Ethernet118 118,119 50000 +Ethernet120 120,121 50000 +Ethernet122 122,123 50000 +Ethernet124 124,125 50000 +Ethernet126 126,127 50000 diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/qos.json b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/qos.json new file mode 100644 index 000000000000..d35f614de635 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/qos.json @@ -0,0 +1,166 @@ +{ + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4" + } + }, + "MAP_PFC_PRIORITY_TO_QUEUE": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4" + } + }, + "TC_TO_QUEUE_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"3", + "4":"4", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type":"DWRR", + "weight": "25" + }, + "scheduler.1": { + "type":"DWRR", + "weight": "30" + }, + "scheduler.2": { + "type":"DWRR", + "weight": "20" + } + }, + "PFC_PRIORITY_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4" + } + }, + "PORT_QOS_MAP": { + "Ethernet8,Ethernet2,Ethernet0,Ethernet6,Ethernet4,Ethernet108,Ethernet100,Ethernet104,Ethernet106,Ethernet58,Ethernet126,Ethernet96,Ethernet124,Ethernet122,Ethernet92,Ethernet120,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet76,Ethernet74,Ethernet18,Ethernet70,Ethernet32,Ethernet72,Ethernet16,Ethernet36,Ethernet78,Ethernet60,Ethernet28,Ethernet62,Ethernet14,Ethernet88,Ethernet118,Ethernet24,Ethernet116,Ethernet82,Ethernet114,Ethernet80,Ethernet112,Ethernet86,Ethernet110,Ethernet84,Ethernet48,Ethernet10,Ethernet44,Ethernet42,Ethernet40,Ethernet64,Ethernet66,Ethernet12,Ethernet46,Ethernet20,Ethernet22,Ethernet68": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_to_pg_map" : "[PFC_PRIORITY_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_enable": "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSY": { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"516096", + "red_min_threshold":"516096", + "yellow_max_threshold":"516096", + "yellow_min_threshold":"516096", + "green_max_threshold": "184320", + "green_min_threshold": "184320" + }, + "AZURE_LOSSLESS": { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"516096", + "red_min_threshold":"516096", + "yellow_max_threshold":"516096", + "yellow_min_threshold":"516096", + "green_max_threshold": "184320", + "green_min_threshold": "184320" + } + }, + "QUEUE": { + "Ethernet8,Ethernet2,Ethernet0,Ethernet6,Ethernet4,Ethernet108,Ethernet100,Ethernet104,Ethernet106,Ethernet58,Ethernet126,Ethernet96,Ethernet124,Ethernet122,Ethernet92,Ethernet120,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet76,Ethernet74,Ethernet18,Ethernet70,Ethernet32,Ethernet72,Ethernet16,Ethernet36,Ethernet78,Ethernet60,Ethernet28,Ethernet62,Ethernet14,Ethernet88,Ethernet118,Ethernet24,Ethernet116,Ethernet82,Ethernet114,Ethernet80,Ethernet112,Ethernet86,Ethernet110,Ethernet84,Ethernet48,Ethernet10,Ethernet44,Ethernet42,Ethernet40,Ethernet64,Ethernet66,Ethernet12,Ethernet46,Ethernet20,Ethernet22,Ethernet68|0": { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, + "Ethernet8,Ethernet2,Ethernet0,Ethernet6,Ethernet4,Ethernet108,Ethernet100,Ethernet104,Ethernet106,Ethernet58,Ethernet126,Ethernet96,Ethernet124,Ethernet122,Ethernet92,Ethernet120,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet76,Ethernet74,Ethernet18,Ethernet70,Ethernet32,Ethernet72,Ethernet16,Ethernet36,Ethernet78,Ethernet60,Ethernet28,Ethernet62,Ethernet14,Ethernet88,Ethernet118,Ethernet24,Ethernet116,Ethernet82,Ethernet114,Ethernet80,Ethernet112,Ethernet86,Ethernet110,Ethernet84,Ethernet48,Ethernet10,Ethernet44,Ethernet42,Ethernet40,Ethernet64,Ethernet66,Ethernet12,Ethernet46,Ethernet20,Ethernet22,Ethernet68|1": { + "scheduler" : "[SCHEDULER|scheduler.2]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0-1": { + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]" + }, + "Ethernet8,Ethernet2,Ethernet0,Ethernet6,Ethernet4,Ethernet108,Ethernet100,Ethernet104,Ethernet106,Ethernet58,Ethernet126,Ethernet96,Ethernet124,Ethernet122,Ethernet92,Ethernet120,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet76,Ethernet74,Ethernet18,Ethernet70,Ethernet32,Ethernet72,Ethernet16,Ethernet36,Ethernet78,Ethernet60,Ethernet28,Ethernet62,Ethernet14,Ethernet88,Ethernet118,Ethernet24,Ethernet116,Ethernet82,Ethernet114,Ethernet80,Ethernet112,Ethernet86,Ethernet110,Ethernet84,Ethernet48,Ethernet10,Ethernet44,Ethernet42,Ethernet40,Ethernet64,Ethernet66,Ethernet12,Ethernet46,Ethernet20,Ethernet22,Ethernet68|3-4": { + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" + } + } +} + diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/sai.profile b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/sai.profile new file mode 100644 index 000000000000..bfbcb1e78f47 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_2700_48x50g_8x100g.xml diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/sai_2700_48x50g_8x100g.xml b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/sai_2700_48x50g_8x100g.xml new file mode 100644 index 000000000000..bda7a3e1cc17 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/sai_2700_48x50g_8x100g.xml @@ -0,0 +1,267 @@ + + + + + + 00:02:03:04:05:00 + + + 32 + + + + + 1 + 4 + 16 + + + 3 + + + 3221225472 + 2 + + + 3 + 4 + 17 + 1 + 3221225472 + 2 + + + 5 + 4 + 18 + 3 + 3221225472 + 2 + + + 7 + 4 + 19 + 1 + 3221225472 + 2 + + + 9 + 4 + 20 + 3 + 3221225472 + 2 + + + 11 + 4 + 21 + 1 + 3221225472 + 2 + + + 13 + 4 + 22 + 3 + 11534336 + + + 15 + 4 + 23 + 1 + 11534336 + + + 17 + 4 + 24 + 3 + 11534336 + + + 19 + 4 + 25 + 1 + 11534336 + + + 21 + 4 + 26 + 3 + 3221225472 + 2 + + + 23 + 4 + 27 + 1 + 3221225472 + 2> + + + 25 + 4 + 28 + 3 + 3221225472 + 2 + + + 27 + 4 + 29 + 1 + 3221225472 + 2 + + + 29 + 4 + 30 + 3 + 3221225472 + 2 + + + 31 + 4 + 31 + 1 + 3221225472 + 2 + + + 33 + 4 + 14 + 3 + 3221225472 + 2 + + + 35 + 4 + 15 + 1 + 3221225472 + 2 + + + 37 + 4 + 12 + 3 + 3221225472 + 2 + + + 39 + 4 + 13 + 1 + 3221225472 + 2 + + + 41 + 4 + 10 + 3 + 3221225472 + 2 + + + 43 + 4 + 11 + 1 + 3221225472 + 2 + + + 45 + 4 + 8 + 3 + 11534336 + + + 47 + 4 + 9 + 1 + 11534336 + + + 49 + 4 + 6 + 3 + 11534336 + + + 51 + 4 + 7 + 1 + 11534336 + + + 53 + 4 + 4 + 3 + 3221225472 + 2 + + + 55 + 4 + 5 + 1 + 3221225472 + 2 + + + 57 + 4 + 2 + 3 + 3221225472 + 2 + + + 59 + 4 + 3 + 1 + 3221225472 + 2 + + + 61 + 4 + 0 + 3 + 3221225472 + 2 + + + 63 + 4 + 1 + 1 + 3221225472 + 2 + + + + From bf2be4afa9cc4e43287749debd3f2384da2218cb Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 19 May 2018 09:40:40 +0000 Subject: [PATCH 067/219] [swss]: update swss submodule * a1b6fa3 2018-04-16 | [vlanmgr]: Fix the incorrect ip link del command for vlan remove (#474) (HEAD, origin/201803) [Jipan Yang] * 66287cf 2018-05-18 | fix SAI_BUFFER_PROFILE_ATTR_SHARED_DYNAMIC_TH value type mismatch bug (#502) [yangbashuang] * 43365f3 2018-05-14 | [crmorch]: neighbor used counter increased twice (#472) (#501) [MaxPolovyi] Signed-off-by: Guohan Lu --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index c374357b25df..a1b6fa323c69 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit c374357b25df9b222c3b898f916463f8a74df40c +Subproject commit a1b6fa323c693fe3e21cc0aebf2e29fce18aa5b3 From 6ed14b3f4afbf01a90725e4cae1a1e529d377eef Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Tue, 22 May 2018 14:53:35 -0700 Subject: [PATCH 068/219] [submodule]: Update submodule sonic-snmpagent: power_status_handler handles missing PSU (#1732) --- src/sonic-snmpagent | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-snmpagent b/src/sonic-snmpagent index f28315252698..bf1b165458e4 160000 --- a/src/sonic-snmpagent +++ b/src/sonic-snmpagent @@ -1 +1 @@ -Subproject commit f28315252698aabc927eca84b836493385fcf4a1 +Subproject commit bf1b165458e4e19286d245a3398921057f4df21c From 1e7508d3f3b777950f5cd5767f24da914124fb13 Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Wed, 23 May 2018 16:55:29 +0700 Subject: [PATCH 069/219] [devices]: update dx010 fan configuration (#1735) --- .../celestica/x86_64-cel_seastone-r0/sensors.conf | 14 ++++++++++++++ platform/broadcom/sonic-platform-modules-cel | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/device/celestica/x86_64-cel_seastone-r0/sensors.conf b/device/celestica/x86_64-cel_seastone-r0/sensors.conf index e25717ac589f..11461a0afef9 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sensors.conf +++ b/device/celestica/x86_64-cel_seastone-r0/sensors.conf @@ -62,3 +62,17 @@ chip "dx010_lm75b-i2c-*-4e" label temp1 "Rear-panel temp sensor 2" set temp1_max 43 set temp1_max_hyst 28 + +chip "emc2305-i2c-*-2e" + label fan2 "fan1" + label fan1 "fan2" + label fan4 "fan3" + label fan5 "fan4" + label fan3 "fan5" + +chip "emc2305-i2c-*-4d" + label fan2 "fan1" + label fan4 "fan2" + label fan5 "fan3" + label fan3 "fan4" + label fan1 "fan5" diff --git a/platform/broadcom/sonic-platform-modules-cel b/platform/broadcom/sonic-platform-modules-cel index 190d0b71ac19..7875e46964fc 160000 --- a/platform/broadcom/sonic-platform-modules-cel +++ b/platform/broadcom/sonic-platform-modules-cel @@ -1 +1 @@ -Subproject commit 190d0b71ac1902679e2d720368e100d78eb09f3e +Subproject commit 7875e46964fcc329ff92a80c379c026da530221f From 1a4123a92351903fc7d7f7bfbdcdea9a997ae36e Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 23 May 2018 17:57:38 -0700 Subject: [PATCH 070/219] Remove fan LED initialization from led_control plugins for Arista 7050-QX32, 7050-QX-32S (#1733) --- .../x86_64-arista_7050_qx32/plugins/led_control.py | 10 ---------- .../x86_64-arista_7050_qx32s/plugins/led_control.py | 11 ----------- 2 files changed, 21 deletions(-) diff --git a/device/arista/x86_64-arista_7050_qx32/plugins/led_control.py b/device/arista/x86_64-arista_7050_qx32/plugins/led_control.py index 1f6034e2e2eb..31effbaf11c6 100644 --- a/device/arista/x86_64-arista_7050_qx32/plugins/led_control.py +++ b/device/arista/x86_64-arista_7050_qx32/plugins/led_control.py @@ -85,16 +85,6 @@ def __init__(self): with open("/sys/class/leds/psu2/brightness", "w") as f: f.write("1") - # Initialize all fan LEDs to green - with open("/sys/devices/platform/sb800-fans/hwmon/hwmon1/fan1_led", "w") as f: - f.write("3") - with open("/sys/devices/platform/sb800-fans/hwmon/hwmon1/fan2_led", "w") as f: - f.write("3") - with open("/sys/devices/platform/sb800-fans/hwmon/hwmon1/fan3_led", "w") as f: - f.write("3") - with open("/sys/devices/platform/sb800-fans/hwmon/hwmon1/fan4_led", "w") as f: - f.write("3") - # Initialize: Turn all front panel QSFP LEDs off for qsfp_index in range(self.QSFP_BREAKOUT_START_IDX, self.QSFP_BREAKOUT_END_IDX + 1): for lane in range(1, 5): diff --git a/device/arista/x86_64-arista_7050_qx32s/plugins/led_control.py b/device/arista/x86_64-arista_7050_qx32s/plugins/led_control.py index 8fa0c63a473a..6424516a59d9 100644 --- a/device/arista/x86_64-arista_7050_qx32s/plugins/led_control.py +++ b/device/arista/x86_64-arista_7050_qx32s/plugins/led_control.py @@ -80,17 +80,6 @@ def __init__(self): with open("/sys/class/leds/psu2/brightness", "w") as f: f.write("1") - # Initialize all fan LEDs to green - with open("/sys/devices/pci0000:00/0000:00:02.2/0000:02:00.0/i2c-3/3-0060/hwmon/hwmon4/fan1_led", "w") as f: - f.write("1") - with open("/sys/devices/pci0000:00/0000:00:02.2/0000:02:00.0/i2c-3/3-0060/hwmon/hwmon4/fan2_led", "w") as f: - f.write("1") - with open("/sys/devices/pci0000:00/0000:00:02.2/0000:02:00.0/i2c-3/3-0060/hwmon/hwmon4/fan3_led", "w") as f: - f.write("1") - with open("/sys/devices/pci0000:00/0000:00:02.2/0000:02:00.0/i2c-3/3-0060/hwmon/hwmon4/fan4_led", "w") as f: - f.write("1") - - # Initialize: Turn all front panel QSFP LEDs off for qsfp_index in range(self.QSFP_BREAKOUT_START_IDX, self.QSFP_BREAKOUT_END_IDX + 1): for lane in range(1, 5): From 989000c741046b15f24f41b3babdb18da6d5c250 Mon Sep 17 00:00:00 2001 From: Wenda Ni Date: Thu, 24 May 2018 11:05:38 -0700 Subject: [PATCH 071/219] [sonic-cfggen]: Protect config_db.json from minigraph misconfig (#1727) * Add noise config for PortChannel & EthernetInterface in simple-sample-graph.xml * Add noise config for PORTCHANNEL_INTERFACE in simple-sample-graph.xml Signed-off-by: Wenda * Add noice config for DEVICE_NEIGHBOR in t0-sample-graph.xml Add unit test against introducing ports not existing in port_config.ini into DEVICE_NEIGHBOR Signed-off-by: Wenda * DeviceInterfaceLink in minigraph.xml can contain port not existing in port_config.ini but contraining non-zero Bandwidth attribute Add noice config in simple-sample-graph.xml to capture the case that such a port is leaked into config_db.json Signed-off-by: Wenda * Protect PORTCHANNEL from ports not existing in port_config.ini Signed-off-by: Wenda * Protect PORTCHANNEL_INTERFACE from portchannels containing ports not existing in port_config.ini Signed-off-by: Wenda * Protect DEVICE_NEIGHBOR from ports not existing in port_config.ini Signed-off-by: Wenda * Add noise config Ethernet1 in DeviceInterfaceLinks in simple-sample-graph.xml as it is in PortChannel1001 Signed-off-by: Wenda * Add noise config Ethernet1 in DeviceInterfaceLinks in simple-sample-graph.xml as it is in PortChannel1001 Signed-off-by: Wenda * Protect PORTCHANNEL from ports not existing in port_config.ini Signed-off-by: Wenda * Protect PORTCHANNEL_INTERFACE from portchannels containing ports not existing in port_config.ini Signed-off-by: Wenda * Protect DEVICE_NEIGHBOR from ports not existing in port_config.ini Signed-off-by: Wenda * Correct space in minigraph.py Signed-off-by: Wenda * Does not allow non-port_config.ini port to get into the port list Signed-off-by: Wenda * Check PORTCHANNEL against PORT list only if port_config_file exists Signed-off-by: Wenda * Correct format Signed-off-by: Wenda * print warning when a port coming from DeviceInterfaceLink is not in port_config.ini Signed-off-by: Wenda * Change Ethernet1 and 2 to fortyGigE0/1 and 2,respectively Signed-off-by: Wenda * Change Ethernet1 and 2 to fortyGigE0/1 and 2,respectively Signed-off-by: Wenda * print warning when ignoring ports, portchannels, portchannel interfaces, and device neighbors Update t0-sample-graph.xml with interface name 'fortyGigE0/2' and the ACL_TABLE output Signed-off-by: Wenda --- src/sonic-config-engine/minigraph.py | 37 +++++++++++-- .../tests/simple-sample-graph.xml | 52 ++++++++++++++++++- .../tests/t0-sample-graph.xml | 11 ++++ src/sonic-config-engine/tests/test_cfggen.py | 11 ++++ 4 files changed, 105 insertions(+), 6 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index dba1a6516cf4..14bf34a34b05 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -412,7 +412,7 @@ def parse_xml(filename, platform=None, port_config_file=None): (port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku) current_device = [devices[key] for key in devices if key.lower() == hostname.lower()][0] - results = {} + results = {} results['DEVICE_METADATA'] = {'localhost': { 'bgp_asn': bgp_asn, 'deployment_id': deployment_id, @@ -445,7 +445,6 @@ def parse_xml(filename, platform=None, port_config_file=None): results['INTERFACE'] = phyport_intfs results['VLAN_INTERFACE'] = vlan_intfs - results['PORTCHANNEL_INTERFACE'] = pc_intfs for port_name in port_speeds_default: # ignore port not in port_config.ini @@ -455,9 +454,11 @@ def parse_xml(filename, platform=None, port_config_file=None): ports.setdefault(port_name, {})['speed'] = port_speeds_default[port_name] for port_name in port_speed_png: - # if port_name is not in port_config.ini, still consider it. - # and later swss will pick up and behave on-demand port break-up. - # if on-deman port break-up is not supported on a specific platform, swss will return error. + # not consider port not in port_config.ini + if port_name not in ports: + print >> sys.stderr, "Warning: ignore interface '%s' as it is not in the port_config.ini" % port_name + continue + ports.setdefault(port_name, {})['speed'] = port_speed_png[port_name] for port_name, port in ports.items(): @@ -472,10 +473,36 @@ def parse_xml(filename, platform=None, port_config_file=None): ports.setdefault(port_name, {})['description'] = port_descriptions[port_name] results['PORT'] = ports + + if port_config_file: + port_set = set(ports.keys()) + for (pc_name, mbr_map) in pcs.items(): + # remove portchannels that contain ports not existing in port_config.ini + # when port_config.ini exists + if not set(mbr_map['members']).issubset(port_set): + print >> sys.stderr, "Warning: ignore '%s' as part of its member interfaces is not in the port_config.ini" % pc_name + del pcs[pc_name] + results['PORTCHANNEL'] = pcs + + + for pc_intf in pc_intfs.keys(): + # remove portchannels not in PORTCHANNEL dictionary + if pc_intf[0] not in pcs: + print >> sys.stderr, "Warning: ignore '%s' interface '%s' as '%s' is not in the valid PortChannel list" % (pc_intf[0], pc_intf[1], pc_intf[0]) + del pc_intfs[pc_intf] + + results['PORTCHANNEL_INTERFACE'] = pc_intfs + results['VLAN'] = vlans results['VLAN_MEMBER'] = vlan_members + for nghbr in neighbors.keys(): + # remove port not in port_config.ini + if nghbr not in ports: + print >> sys.stderr, "Warning: ignore interface '%s' in DEVICE_NEIGHBOR as it is not in the port_config.ini" % nghbr + del neighbors[nghbr] + results['DEVICE_NEIGHBOR'] = neighbors results['DEVICE_NEIGHBOR_METADATA'] = { key:devices[key] for key in devices if key.lower() != hostname.lower() } results['SYSLOG_SERVER'] = dict((item, {}) for item in syslog_servers) diff --git a/src/sonic-config-engine/tests/simple-sample-graph.xml b/src/sonic-config-engine/tests/simple-sample-graph.xml index 6e351e1cd003..f5054bb084d3 100644 --- a/src/sonic-config-engine/tests/simple-sample-graph.xml +++ b/src/sonic-config-engine/tests/simple-sample-graph.xml @@ -125,6 +125,11 @@ fortyGigE0/4 + + PortChannel1001 + fortyGigE0/1;fortyGigE0/2 + + @@ -147,6 +152,16 @@ PortChannel01 FC00::71/126 + + + PortChannel1001 + 10.0.0.57/31 + + + + PortChannel1001 + FC00::72/126 + fortyGigE0/0 @@ -193,6 +208,28 @@ fortyGigE0/8 true + + DeviceInterfaceLink + true + 10000 + switch-t0 + fortyGigE0/1 + true + ARISTA05T1 + Ethernet1/32 + true + + + DeviceInterfaceLink + true + 10000 + switch-t0 + fortyGigE0/2 + true + ARISTA06T1 + Ethernet1/33 + true +
@@ -240,7 +277,20 @@ true true 1 - fortyGigE0/1 + Ethernet1 + + false + 0 + 0 + 10000 +
+ + DeviceInterface + + true + true + 1 + Ethernet2 false 0 diff --git a/src/sonic-config-engine/tests/t0-sample-graph.xml b/src/sonic-config-engine/tests/t0-sample-graph.xml index ce0177d4c158..5eace767c468 100644 --- a/src/sonic-config-engine/tests/t0-sample-graph.xml +++ b/src/sonic-config-engine/tests/t0-sample-graph.xml @@ -338,6 +338,17 @@ switch-t0 fortyGigE0/124 + + DeviceInterfaceLink + true + 10000 + switch-t0 + fortyGigE0/2 + true + ARISTA05T1 + Ethernet1/33 + true + diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 901b882f7048..37b66a27b4c4 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -79,6 +79,8 @@ def test_minigraph_acl(self): argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v ACL_TABLE' output = self.run_script(argument, True) self.assertEqual(output.strip(), "Warning: Ignoring Control Plane ACL NTP_ACL without type\n" + "Warning: ignore interface 'fortyGigE0/2' as it is not in the port_config.ini\n" + "Warning: ignore interface 'fortyGigE0/2' in DEVICE_NEIGHBOR as it is not in the port_config.ini\n" "{'SSH_ACL': {'services': ['SSH'], 'type': 'CTRLPLANE', 'policy_desc': 'SSH_ACL'}," " 'SNMP_ACL': {'services': ['SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'SNMP_ACL'}," " 'DATAACL': {'type': 'L3', 'policy_desc': 'DATAACL', 'ports': ['Ethernet112', 'Ethernet116', 'Ethernet120', 'Ethernet124']}," @@ -130,6 +132,15 @@ def test_minigraph_neighbors(self): output = self.run_script(argument) self.assertEqual(output.strip(), "{'name': 'ARISTA04T1', 'port': 'Ethernet1/1'}") + def test_minigraph_extra_neighbors(self): + argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v DEVICE_NEIGHBOR' + output = self.run_script(argument) + self.assertEqual(output.strip(), \ + "{'Ethernet116': {'name': 'ARISTA02T1', 'port': 'Ethernet1/1'}, " + "'Ethernet124': {'name': 'ARISTA04T1', 'port': 'Ethernet1/1'}, " + "'Ethernet112': {'name': 'ARISTA01T1', 'port': 'Ethernet1/1'}, " + "'Ethernet120': {'name': 'ARISTA03T1', 'port': 'Ethernet1/1'}}") + def test_minigraph_bgp(self): argument = '-m "' + self.sample_graph_bgp_speaker + '" -p "' + self.port_config + '" -v "BGP_NEIGHBOR[\'10.0.0.59\']"' output = self.run_script(argument) From 2aa1de5d0c39c2f888cb0ba01fb861ca8a6659bf Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Fri, 25 May 2018 10:52:35 -0700 Subject: [PATCH 072/219] [service] introducing serial port watchdog service (#1743) * [rc.local] refactor platform identification code to separate function Signed-off-by: Ying Xie * [rc.local] infrastructure to take action according to installer.conf * [serial port watchdog] add service to watch serial port processes Monitor serial port processes. Kill ones stuck for too long. Signed-off-by: Ying Xie * [rc.local] start watchdog on serial port specified by installer.conf Signed-off-by: Ying Xie --- .../build_templates/sonic_debian_extension.j2 | 5 + files/image_config/platform/rc.local | 44 ++- .../serial-port-watchdog.py | 328 ++++++++++++++++++ .../serial-port-watchdog.service | 12 + 4 files changed, 385 insertions(+), 4 deletions(-) create mode 100755 files/image_config/serial-port-watchdog/serial-port-watchdog.py create mode 100644 files/image_config/serial-port-watchdog/serial-port-watchdog.service diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 0849118b83a4..301ae938a882 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -154,6 +154,11 @@ sudo cp $IMAGE_CONFIGS/hostname/hostname-config.service $FILESYSTEM_ROOT/etc/sy sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable hostname-config.service sudo cp $IMAGE_CONFIGS/hostname/hostname-config.sh $FILESYSTEM_ROOT/usr/bin/ +# Copy serial-port-watchdog configuration scripts +sudo cp $IMAGE_CONFIGS/serial-port-watchdog/serial-port-watchdog.service $FILESYSTEM_ROOT/etc/systemd/system/ +sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable serial-port-watchdog.service +sudo cp $IMAGE_CONFIGS/serial-port-watchdog/serial-port-watchdog.py $FILESYSTEM_ROOT/usr/bin/ + # Copy updategraph script and service file sudo cp $IMAGE_CONFIGS/updategraph/updategraph.service $FILESYSTEM_ROOT/etc/systemd/system/ sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable updategraph.service diff --git a/files/image_config/platform/rc.local b/files/image_config/platform/rc.local index de54d141ef7e..ab88b7a3f5b4 100755 --- a/files/image_config/platform/rc.local +++ b/files/image_config/platform/rc.local @@ -183,15 +183,51 @@ for x in "$@"; do done } -eval sonic_version=$(cat /etc/sonic/sonic_version.yml | grep build_version | cut -f2 -d" ") - -if [ -f /host/image-$sonic_version/platform/firsttime ]; then - +setup_platform() +{ if [ -n "$aboot_platform" ]; then platform=$aboot_platform elif [ -n "$onie_platform" ]; then platform=$onie_platform else + platform='' + fi +} + +# Setup default values in this function before reading installer.conf +# installer.conf could override the value set in this function. +setup_platform_defaults() +{ + # Default serial port: ttyS0 + CONSOLE_DEV=0 +} + +load_platform_installer_config() +{ + INSTALLER_CFG=/usr/share/sonic/device/$platform/installer.conf + if [ -f $INSTALLER_CFG ]; then + . $INSTALLER_CFG + fi +} + +program_serial_port() +{ + sed -i "s|ttyS.|ttyS$CONSOLE_DEV|g" /etc/systemd/system/serial-port-watchdog.service + systemctl daemon-reload + systemctl restart serial-port-watchdog.service +} + +eval sonic_version=$(cat /etc/sonic/sonic_version.yml | grep build_version | cut -f2 -d" ") + +setup_platform +setup_platform_defaults +load_platform_installer_config + +program_serial_port + +if [ -f /host/image-$sonic_version/platform/firsttime ]; then + + if [ -z "$platform" ]; then echo "Unknown sonic platform" firsttime_exit fi diff --git a/files/image_config/serial-port-watchdog/serial-port-watchdog.py b/files/image_config/serial-port-watchdog/serial-port-watchdog.py new file mode 100755 index 000000000000..15c57556d065 --- /dev/null +++ b/files/image_config/serial-port-watchdog/serial-port-watchdog.py @@ -0,0 +1,328 @@ +#!/usr/bin/env python + +from __future__ import print_function, with_statement + +import argparse +import logging +import logging.handlers +import os +import time +import signal +import socket +import sys + +from collections import namedtuple + +PRGNAME = 'serial-port-watchdog' + +DEVFS_PATH = '/dev' +PROCFS_PATH = '/proc' + +# According to procfs(5) +ProcStat = namedtuple( 'ProcStat', [ + 'pid', 'comm', 'state', 'ppid', 'pgrp', 'session', 'tty_nr', 'tpgid', + 'flags', 'minflt', 'cminflt', 'majflt', 'cmajflt', 'utime', 'stime', + 'cutime', 'cstime', 'priority', 'nice', 'num_threads', 'itrealvalue', + 'starttime', 'vsize', 'rss', 'rsslim', 'startcode', 'endcode', + 'startstack', 'kstkesp', 'kstkeip', 'signal', 'blocked', 'sigignore', + 'sigcatch', 'wchan', 'nswap', 'cnswap', 'exit_signal', 'processor', + 'rt_priority', 'policy', 'delayacct_blkio_ticks', 'guest_time', + 'cguest_time', 'start_data', 'end_data', 'start_brk', 'arg_start', + 'arg_end', 'env_start', 'env_end', 'exit_code' +] ) + +# According to procfs(5) +ProcIo = namedtuple( 'ProcIo', [ + 'rchar', 'wchar', 'syscr', 'syscw', 'read_bytes', 'write_bytes', + 'cancelled_write_bytes' +] ) + +class Process( object ): + def __init__( self, pid, path=PROCFS_PATH ): + self.pid = pid + self.path = os.path.join( path, str( pid ) ) + self.childs = [] + self.parent = None + + self.stat = None + + self.io = None + self.stack = None + self.stackStartTime = None + + def refresh( self ): + with open( os.path.join( self.path, 'stat' ) ) as f: + data = f.read().rstrip().split() + self.stat = ProcStat( *data ) + + def getStat( self, key=None ): + self.refresh() + return self.stat + + def uid( self ): + return '%s/%s' % ( self.pid, self.stat.starttime ) + + def ppid( self ): + return self.stat.ppid + + def name( self ): + with open( os.path.join( self.path, 'comm' ) ) as f: + return f.read().rstrip() + + def getTtyForFd( self, fd ): + path = os.path.join( self.path, 'fd', str( fd ) ) + if not os.path.exists( path ): + return '' + return os.readlink( path ) + + def getStack( self ): + with open( os.path.join( self.path, 'stack' ) ) as f: + return f.read() + + def getIo( self ): + with open( os.path.join( self.path, 'io' ) ) as f: + data = [ int( l.split( ': ' )[ 1 ] ) for l in f.readlines() ] + return ProcIo( *data ) + + def isUsingTty( self, tty ): + return self.getTtyForFd( 0 ).endswith( tty ) + + def checkStuck( self, content ): + stack = self.getStack() + + found = False + for match in content: + if match in stack: + found = True + break + + if not found: + self.io = None + self.stack = None + self.stackStartTime = None + return 0 + + io = self.getIo() + + if self.stack != stack or self.io != io: + self.io = io + self.stack = stack + self.stackStartTime = time.time() + return 0 + + return time.time() - self.stackStartTime + + def __repr__( self ): + return '' % self.uid() + +class ProcessMonitor( object ): + def __init__( self, path=PROCFS_PATH ): + self.path = path + self.procs = {} + self.filters = [] + self.checkers = [] + self.whitelist = [] + + def addProcessFilter( self, func, *args ): + self.filters.append( ( func, args ) ) + + def addStuckChecker( self, func, *args ): + self.checkers.append( ( func, args ) ) + + def setWhitelist( self, whitelist ): + self.whitelist = whitelist + + def shouldHandleProcess( self, proc ): + matched = False + for func, args in self.filters: + if func( proc, *args ): + matched = True + break + + if not matched: + return False + + name = proc.name() + for item in self.whitelist: + if item in name: + return False + + return True + + def getRunningPids( self ): + pids = [] + for entry in os.listdir( self.path ): + if not entry.isdigit(): + continue + pids.append( int( entry ) ) + return pids + + def killStuckProcess( self, proc, elapsed, kill, timeout ): + if not elapsed: + return + + if elapsed < timeout: + if elapsed > timeout / 2: + logging.info( 'process %d seems stuck, idle for %ds, waiting ' + 'some more time', proc.pid, elapsed ) + return + + logging.warning( 'process %d has been stuck for %d seconds, killing...', + proc.pid, elapsed ) + logging.info( 'process %d kernel stack\n%s', proc.pid, proc.stack ) + if kill: + # XXX: SIGTERM sleep then if alive SIGKILL ? + os.kill( proc.pid, signal.SIGKILL ) + + def killStuckProcesses( self, kill, timeout ): + for proc in self.procs.values(): + for checker, args in self.checkers: + elapsed = checker( proc, *args ) + self.killStuckProcess( proc, elapsed, kill, timeout ) + + def updatePid( self, pid ): + p = Process( pid ) + + # if the process is already monitored (previously running) + r = self.procs.get( pid, None ) + if r: + p.refresh() + # if the process is still running + if p.uid() == r.uid(): + logging.debug( 'process %d still running', pid ) + return + # or the pid was reused but the process is different + logging.debug( 'pid %d reused for another process', pid ) + del self.procs[ pid ] + + # check if the process is relevant for monitoring + if not self.shouldHandleProcess( p ): + return + + logging.debug( 'watching process %d', pid ) + p.refresh() + self.procs[ pid ] = p + + def updateParenting( self ): + # clear parent and childs for monitored processes + for proc in self.procs.values(): + del proc.childs[:] + proc.parent = None + + # set parent and childs for monitored processes + for proc in self.procs.values(): + ppid = proc.ppid() + parent = self.procs.get( ppid, None ) + if parent: + proc.parent = parent + parent.childs.append( proc ) + + def update( self ): + pids = self.getRunningPids() + + # remove defunct processes + for pid in list(self.procs.keys()): + if pid not in pids: + logging.debug( 'process %d is defunct', pid ) + del self.procs[ pid ] + + # create or update running processes information + for pid in pids: + try: + self.updatePid( pid ) + except: + logging.warning( 'An issue occured whileupdating process %s', + pid ) + raise + + #self.updateParenting() + +def checkRootPermissions(): + if os.geteuid() != 0: + logging.error( 'You must be root to use this feature' ) + sys.exit( 1 ) + +def getHostname(): + try: + return socket.gethostname() + except: + return 'localhost' + +def setupLogging( verbose=False ): + loglevel = logging.DEBUG if verbose else logging.INFO + dateFmt = '%Y-%m-%d %H:%M:%S' + + log = logging.getLogger() + log.setLevel( logging.DEBUG ) + + logOut = logging.StreamHandler( sys.stdout ) + logOut.setFormatter( logging.Formatter( '%(levelname)s: %(message)s' ) ) + logOut.setLevel( loglevel ) + log.addHandler( logOut ) + + logSys = logging.handlers.SysLogHandler() + # format to rfc5424 format + fmt = '{} {}: %(message)s'.format( getHostname(), PRGNAME ) + logSys.setFormatter( logging.Formatter( fmt ) ) + logSys.setLevel( logging.WARNING ) + log.addHandler( logSys ) + try: + # the connection to the syslog socket happens with the first message + log.info( 'Attaching to syslog' ) + except: + log.warning( 'Failed open syslog' ) + +def listParser( value ): + if not value.strip(): + return [] + return value.split( ',' ) + +def ttyParser( dev, path=DEVFS_PATH ): + if not dev.startswith( DEVFS_PATH ): + dev = os.path.join( DEVFS_PATH, dev ) + if not os.path.exists( dev ): + raise argparse.ArgumentTypeError( '%s is not a device' % dev ) + return dev + +def parseArgs( args ): + parser = argparse.ArgumentParser() + + parser.add_argument( '-d', '--dry-run', action='store_true', + help='only print processes that would be killed' ) + parser.add_argument( '-f', '--funcs', default=[ 'tty_' ], type=listParser, + help='functions to look for in the stack trace' ) + parser.add_argument( '-i', '--interval', default=60, type=float, + help='interval at which to check the procfs' ) + parser.add_argument( '-k', '--timeout', default=3600, type=float, + help='timeout for which a process gets killed' ) + parser.add_argument( '-t', '--tty', default='ttyS0', type=ttyParser, + help='tty to check for stuck process' ) + parser.add_argument( '-v', '--verbose', action='store_true', + help='print all debug messages' ) + parser.add_argument( '-w', '--whitelist', default=[ 'agetty' ], type=listParser, + help='whitelist programs that should never be killed' ) + + return parser.parse_args( args ) + +def main( args ): + args = parseArgs( args ) + + setupLogging( args.verbose ) + checkRootPermissions() + + m = ProcessMonitor() + m.addProcessFilter( Process.isUsingTty, args.tty ) + m.addStuckChecker( Process.checkStuck, args.funcs ) + m.setWhitelist( args.whitelist ) + + while True: + logging.debug( 'updating processes' ) + m.update() + m.killStuckProcesses( kill=( not args.dry_run ), timeout=args.timeout ) + time.sleep( args.interval ) + + return 0 + +if __name__ == '__main__': + sys.exit( main( sys.argv[ 1: ] ) ) + diff --git a/files/image_config/serial-port-watchdog/serial-port-watchdog.service b/files/image_config/serial-port-watchdog/serial-port-watchdog.service new file mode 100644 index 000000000000..b86580ec2767 --- /dev/null +++ b/files/image_config/serial-port-watchdog/serial-port-watchdog.service @@ -0,0 +1,12 @@ +[Unit] +Description=Monitor serial port processes, kill stuck ones +Requires= +After=rc.local.Service + +[Service] +ExecStart=/usr/bin/serial-port-watchdog.py -t ttyS0 +Restart=always +RestartSec=0 + +[Install] +WantedBy=multi-user.target From 188afc1e09361365bdc18e22597d5b5ff1a34adb Mon Sep 17 00:00:00 2001 From: Shuotian Cheng Date: Fri, 25 May 2018 20:04:08 -0700 Subject: [PATCH 073/219] [docker_image_ctl]: Add --force while removing obsolete dockers (#1744) --- files/build_templates/docker_image_ctl.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 6592e9ed173d..352d1c763673 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -52,7 +52,7 @@ start() { # docker created with a different HWSKU, remove and recreate echo "Removing obsolete {{docker_container_name}} container with HWSKU $DOCKERMOUNT" - docker rm {{docker_container_name}} + docker rm -f {{docker_container_name}} fi {%- if docker_container_name == "database" %} From 6e162be8588db267b955691df097af72b5b5c093 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Wed, 30 May 2018 05:32:26 +0000 Subject: [PATCH 074/219] [sairedis]: update sonic-sairedis submodule * 524685a 2018-05-14 | Ignore bridge port id in fdb consolidated event if value is NULL (#319) (origin/201803) [Kamil Cudnik] * be0d9c3 2018-05-23 | Merge pull request #321 from yxieca/syncd [Ying Xie] Signed-off-by: Guohan Lu --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index c860472a3d8c..524685a2b5a1 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit c860472a3d8c16cad8a44fd7f76e848c39651f2e +Subproject commit 524685a2b5a129986887c9808834f853e1a478b9 From d7ed6388b667387b142452dea0eb676db189fbe6 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Sun, 27 May 2018 00:43:36 +0800 Subject: [PATCH 075/219] [minigraph parser] Fix minigraph parser issue when handling LAG related ACL table configuration (#1712) * Fix minigraph parser issue when handling LAG related ACL table configuration * rephrase the warning message. * pick up swss change in https://github.com/Azure/sonic-swss/pull/494 --- src/sonic-config-engine/minigraph.py | 20 +++++++++++++++++--- src/sonic-config-engine/tests/test_cfggen.py | 2 +- src/sonic-swss | 2 +- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 14bf34a34b05..58d5960857d6 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -149,12 +149,15 @@ def parse_dpg(dpg, hname): pcintfs = child.find(str(QName(ns, "PortChannelInterfaces"))) pc_intfs = [] pcs = {} + intfs_inpc = [] # List to hold all the LAG member interfaces for pcintf in pcintfs.findall(str(QName(ns, "PortChannel"))): pcintfname = pcintf.find(str(QName(ns, "Name"))).text pcintfmbr = pcintf.find(str(QName(ns, "AttachTo"))).text pcmbr_list = pcintfmbr.split(';') + pc_intfs.append(pcintfname) for i, member in enumerate(pcmbr_list): pcmbr_list[i] = port_alias_map.get(member, member) + intfs_inpc.append(pcmbr_list[i]) if pcintf.find(str(QName(ns, "Fallback"))) != None: pcs[pcintfname] = {'members': pcmbr_list, 'fallback': pcintf.find(str(QName(ns, "Fallback"))).text} else: @@ -202,15 +205,26 @@ def parse_dpg(dpg, hname): for member in aclattach: member = member.strip() if pcs.has_key(member): - acl_intfs.extend(pcs[member]['members']) # For ACL attaching to port channels, we break them into port channel members + # If try to attach ACL to a LAG interface then we shall add the LAG to + # to acl_intfs directly instead of break it into member ports, ACL attach + # to LAG will be applied to all the LAG members internally by SAI/SDK + acl_intfs.append(member) elif vlans.has_key(member): print >> sys.stderr, "Warning: ACL " + aclname + " is attached to a Vlan interface, which is currently not supported" elif port_alias_map.has_key(member): acl_intfs.append(port_alias_map[member]) + # Give a warning if trying to attach ACL to a LAG member interface, correct way is to attach ACL to the LAG interface + if port_alias_map[member] in intfs_inpc: + print >> sys.stderr, "Warning: ACL " + aclname + " is attached to a LAG member interface " + port_alias_map[member] + ", instead of LAG interface" elif member.lower() == 'erspan': is_mirror = True; - # Erspan session will be attached to all front panel ports - acl_intfs = port_alias_map.values() + # Erspan session will be attached to all front panel ports, + # if panel ports is a member port of LAG, should add the LAG + # to acl table instead of the panel ports + acl_intfs = pc_intfs + for panel_port in port_alias_map.values(): + if panel_port not in intfs_inpc: + acl_intfs.append(panel_port) break; if acl_intfs: acls[aclname] = {'policy_desc': aclname, diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 37b66a27b4c4..d88f0525d546 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -83,7 +83,7 @@ def test_minigraph_acl(self): "Warning: ignore interface 'fortyGigE0/2' in DEVICE_NEIGHBOR as it is not in the port_config.ini\n" "{'SSH_ACL': {'services': ['SSH'], 'type': 'CTRLPLANE', 'policy_desc': 'SSH_ACL'}," " 'SNMP_ACL': {'services': ['SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'SNMP_ACL'}," - " 'DATAACL': {'type': 'L3', 'policy_desc': 'DATAACL', 'ports': ['Ethernet112', 'Ethernet116', 'Ethernet120', 'Ethernet124']}," + " 'DATAACL': {'type': 'L3', 'policy_desc': 'DATAACL', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04']}," " 'NTP_ACL': {'services': ['NTP'], 'type': 'CTRLPLANE', 'policy_desc': 'NTP_ACL'}," " 'ROUTER_PROTECT': {'services': ['SSH', 'SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'ROUTER_PROTECT'}}") diff --git a/src/sonic-swss b/src/sonic-swss index a1b6fa323c69..0f433515d1dc 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit a1b6fa323c693fe3e21cc0aebf2e29fce18aa5b3 +Subproject commit 0f433515d1dc585848cfa58b38f2da65397f27bb From 6d09e0e5967e50e00b4c0ae779e5ed5598018a6e Mon Sep 17 00:00:00 2001 From: Andriy Moroz Date: Wed, 30 May 2018 09:24:05 +0300 Subject: [PATCH 076/219] Add QoS and Buffers configs for Mellanox MSN2100 and MSN2410 (#1739) * Add QoS and Buffers config for Mellanox MSN2410 Signed-off-by: Andriy Moroz * Add QoS and Buffers config for Mellanox MSN2100 Signed-off-by: Andriy Moroz --- .../ACS-MSN2100/buffers.json.j2 | 1 + .../ACS-MSN2100/buffers_defaults_t0.j2 | 1 + .../ACS-MSN2100/buffers_defaults_t1.j2 | 1 + .../ACS-MSN2100/pg_profile_lookup.ini | 17 ++ .../ACS-MSN2100/qos.json | 165 ++++++++++++++++++ .../ACS-MSN2410/buffers.json.j2 | 1 + .../ACS-MSN2410/buffers_defaults_t0.j2 | 1 + .../ACS-MSN2410/buffers_defaults_t1.j2 | 1 + .../ACS-MSN2410/pg_profile_lookup.ini | 17 ++ .../ACS-MSN2410/qos.json | 165 ++++++++++++++++++ 10 files changed, 370 insertions(+) create mode 120000 device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/buffers.json.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/buffers_defaults_t0.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/buffers_defaults_t1.j2 create mode 100644 device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/pg_profile_lookup.ini create mode 100644 device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/qos.json create mode 120000 device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/buffers.json.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/buffers_defaults_t0.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/buffers_defaults_t1.j2 create mode 100644 device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/pg_profile_lookup.ini create mode 100644 device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/qos.json diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/buffers.json.j2 new file mode 120000 index 000000000000..add8bf8bb7c2 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/buffers.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/buffers_defaults_t0.j2 new file mode 120000 index 000000000000..7bcae62336f6 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/buffers_defaults_t0.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/buffers_defaults_t1.j2 new file mode 120000 index 000000000000..a437d613434d --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/buffers_defaults_t1.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/pg_profile_lookup.ini new file mode 100644 index 000000000000..b66b129fe43f --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 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 + 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 + 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/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/qos.json b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/qos.json new file mode 100644 index 000000000000..74045469dbfd --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/qos.json @@ -0,0 +1,165 @@ +{ + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4" + } + }, + "MAP_PFC_PRIORITY_TO_QUEUE": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4" + } + }, + "TC_TO_QUEUE_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"3", + "4":"4", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type":"DWRR", + "weight": "25" + }, + "scheduler.1": { + "type":"DWRR", + "weight": "30" + }, + "scheduler.2": { + "type":"DWRR", + "weight": "20" + } + }, + "PFC_PRIORITY_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4" + } + }, + "PORT_QOS_MAP": { + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_to_pg_map" : "[PFC_PRIORITY_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_enable": "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSY": { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"516096", + "red_min_threshold":"516096", + "yellow_max_threshold":"516096", + "yellow_min_threshold":"516096", + "green_max_threshold": "184320", + "green_min_threshold": "184320" + }, + "AZURE_LOSSLESS": { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"516096", + "red_min_threshold":"516096", + "yellow_max_threshold":"516096", + "yellow_min_threshold":"516096", + "green_max_threshold": "184320", + "green_min_threshold": "184320" + } + }, + "QUEUE": { + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60|0": { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60|1": { + "scheduler" : "[SCHEDULER|scheduler.2]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60|0-1": { + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60|3-4": { + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/buffers.json.j2 new file mode 120000 index 000000000000..add8bf8bb7c2 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/buffers.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/buffers_defaults_t0.j2 new file mode 120000 index 000000000000..7bcae62336f6 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/buffers_defaults_t0.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/buffers_defaults_t1.j2 new file mode 120000 index 000000000000..a437d613434d --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/buffers_defaults_t1.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/pg_profile_lookup.ini new file mode 100644 index 000000000000..b66b129fe43f --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 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 + 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 + 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/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/qos.json b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/qos.json new file mode 100644 index 000000000000..95652cf96f4e --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/qos.json @@ -0,0 +1,165 @@ +{ + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4" + } + }, + "MAP_PFC_PRIORITY_TO_QUEUE": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4" + } + }, + "TC_TO_QUEUE_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"3", + "4":"4", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type":"DWRR", + "weight": "25" + }, + "scheduler.1": { + "type":"DWRR", + "weight": "30" + }, + "scheduler.2": { + "type":"DWRR", + "weight": "20" + } + }, + "PFC_PRIORITY_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4" + } + }, + "PORT_QOS_MAP": { + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124,Ethernet128,Ethernet132,Ethernet136,Ethernet140,Ethernet144,Ethernet148,Ethernet152,Ethernet156,Ethernet160,Ethernet164,Ethernet168,Ethernet172,Ethernet176,Ethernet180,Ethernet184,Ethernet188,Ethernet192,Ethernet196,Ethernet200,Ethernet204,Ethernet208,Ethernet212,Ethernet216,Ethernet220": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_to_pg_map" : "[PFC_PRIORITY_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_enable": "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSY": { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"516096", + "red_min_threshold":"516096", + "yellow_max_threshold":"516096", + "yellow_min_threshold":"516096", + "green_max_threshold": "184320", + "green_min_threshold": "184320" + }, + "AZURE_LOSSLESS": { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"516096", + "red_min_threshold":"516096", + "yellow_max_threshold":"516096", + "yellow_min_threshold":"516096", + "green_max_threshold": "184320", + "green_min_threshold": "184320" + } + }, + "QUEUE": { + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124,Ethernet128,Ethernet132,Ethernet136,Ethernet140,Ethernet144,Ethernet148,Ethernet152,Ethernet156,Ethernet160,Ethernet164,Ethernet168,Ethernet172,Ethernet176,Ethernet180,Ethernet184,Ethernet188,Ethernet192,Ethernet196,Ethernet200,Ethernet204,Ethernet208,Ethernet212,Ethernet216,Ethernet220|0": { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124,Ethernet128,Ethernet132,Ethernet136,Ethernet140,Ethernet144,Ethernet148,Ethernet152,Ethernet156,Ethernet160,Ethernet164,Ethernet168,Ethernet172,Ethernet176,Ethernet180,Ethernet184,Ethernet188,Ethernet192,Ethernet196,Ethernet200,Ethernet204,Ethernet208,Ethernet212,Ethernet216,Ethernet220|1": { + "scheduler" : "[SCHEDULER|scheduler.2]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124,Ethernet128,Ethernet132,Ethernet136,Ethernet140,Ethernet144,Ethernet148,Ethernet152,Ethernet156,Ethernet160,Ethernet164,Ethernet168,Ethernet172,Ethernet176,Ethernet180,Ethernet184,Ethernet188,Ethernet192,Ethernet196,Ethernet200,Ethernet204,Ethernet208,Ethernet212,Ethernet216,Ethernet220|0-1": { + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124,Ethernet128,Ethernet132,Ethernet136,Ethernet140,Ethernet144,Ethernet148,Ethernet152,Ethernet156,Ethernet160,Ethernet164,Ethernet168,Ethernet172,Ethernet176,Ethernet180,Ethernet184,Ethernet188,Ethernet192,Ethernet196,Ethernet200,Ethernet204,Ethernet208,Ethernet212,Ethernet216,Ethernet220|3-4": { + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" + } + } +} From 85c45818c4a69179f989db18504e56c06147aa26 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Wed, 30 May 2018 18:29:43 -0700 Subject: [PATCH 077/219] [serial watchdog] remove serial watchdog service dependency to rc.local (#1752) * [serial watchdog] remove serial watchdog service dependency to rc.local When restarting this service in rc.local, the dependency causes an error in syslog. Removing the dependency to mute the error log entry. * remove lines with empty inputs --- .../serial-port-watchdog/serial-port-watchdog.service | 2 -- 1 file changed, 2 deletions(-) diff --git a/files/image_config/serial-port-watchdog/serial-port-watchdog.service b/files/image_config/serial-port-watchdog/serial-port-watchdog.service index b86580ec2767..1fcb15a103a5 100644 --- a/files/image_config/serial-port-watchdog/serial-port-watchdog.service +++ b/files/image_config/serial-port-watchdog/serial-port-watchdog.service @@ -1,7 +1,5 @@ [Unit] Description=Monitor serial port processes, kill stuck ones -Requires= -After=rc.local.Service [Service] ExecStart=/usr/bin/serial-port-watchdog.py -t ttyS0 From 2ad793c83683ba2c3dfb52e3e63551e19e133010 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Thu, 31 May 2018 18:38:12 -0700 Subject: [PATCH 078/219] Fix links of debian git server (#1755) --- src/initramfs-tools/Makefile | 2 +- src/isc-dhcp/Makefile | 2 +- src/libnl3/Makefile | 2 +- src/libteam/Makefile | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/initramfs-tools/Makefile b/src/initramfs-tools/Makefile index 95d5c24d1185..c5010e876d8b 100644 --- a/src/initramfs-tools/Makefile +++ b/src/initramfs-tools/Makefile @@ -7,7 +7,7 @@ MAIN_TARGET = initramfs-tools_$(INITRAMFS_TOOLS_VERSION)_all.deb $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # Obtaining the initramfs-tools rm -rf ./initramfs-tools - git clone --branch v0.120 https://anonscm.debian.org/git/kernel/initramfs-tools.git ./initramfs-tools + git clone --branch v0.120 https://salsa.debian.org/kernel-team/initramfs-tools.git ./initramfs-tools # Patch pushd ./initramfs-tools diff --git a/src/isc-dhcp/Makefile b/src/isc-dhcp/Makefile index b439ec7c1ee6..482abc58dd01 100644 --- a/src/isc-dhcp/Makefile +++ b/src/isc-dhcp/Makefile @@ -11,7 +11,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : rm -rf ./isc-dhcp # Clone isc-dhcp repo - git clone https://anonscm.debian.org/cgit/pkg-dhcp/isc-dhcp.git + git clone https://salsa.debian.org/berni/isc-dhcp.git pushd ./isc-dhcp # Reset HEAD to the commit of the proper tag diff --git a/src/libnl3/Makefile b/src/libnl3/Makefile index efd234424dff..6f50e4e389fa 100644 --- a/src/libnl3/Makefile +++ b/src/libnl3/Makefile @@ -16,7 +16,7 @@ DERIVED_TARGETS = libnl-3-dev_$(LIBNL3_VERSION)_amd64.deb \ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # Obtaining the libnl3 rm -rf ./libnl3 - git clone https://anonscm.debian.org/git/collab-maint/libnl3.git + git clone https://github.com/qiluo-msft/libnl3.git pushd ./libnl3 git checkout -f b77c0e49cb diff --git a/src/libteam/Makefile b/src/libteam/Makefile index c96266a5c7fd..a20f8dbd35b0 100644 --- a/src/libteam/Makefile +++ b/src/libteam/Makefile @@ -22,7 +22,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : popd # Obtain debian packaging - git clone https://anonscm.debian.org/git/collab-maint/libteam.git tmp + git clone https://salsa.debian.org/debian/libteam.git tmp pushd ./tmp git checkout -f da006f2 # v1.26 popd From 36fc74d42039c74e2d39e70f865e292652990d82 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Thu, 24 May 2018 16:49:24 -0700 Subject: [PATCH 079/219] [broadcom sai] upgrade Broadcom SAI to version 3.1.3.4-12 (#1740) Signed-off-by: Ying Xie --- platform/broadcom/sai.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 572ad5271f10..62181597e7b3 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,9 +1,9 @@ -BRCM_SAI = libsaibcm_3.1.3.4-11_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm_3.1.3.4-11_amd64.deb?sv=2015-04-05&sr=b&sig=0pctCvAKfSqT8O%2FWSMxw532XAXFsxXdKljQqWfOX8xA%3D&se=2155-03-25T07%3A23%3A41Z&sp=r" +BRCM_SAI = libsaibcm_3.1.3.4-12_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm_3.1.3.4-12_amd64.deb?sv=2015-04-05&sr=b&sig=iK79gjz8GQnPLU8OSxgzw35MzqmxwAXQg2N%2BalLUos0%3D&se=2032-01-31T20%3A36%3A51Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.1.3.4-11_amd64.deb +BRCM_SAI_DEV = libsaibcm-dev_3.1.3.4-12_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm-dev_3.1.3.4-11_amd64.deb?sv=2015-04-05&sr=b&sig=IO1g%2FdcObkureizN8ZMPqISP6opZXu%2FrHostog6aIrU%3D&se=2155-03-25T08%3A13%3A34Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm-dev_3.1.3.4-12_amd64.deb?sv=2015-04-05&sr=b&sig=tSBPnK%2BK9axdPbkWP19r5ngM0ggRTWWijUIKTl8WNW0%3D&se=2032-01-31T20%3A36%3A11Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) From 9943dba2db6806bb8d80ca576249521008ac164d Mon Sep 17 00:00:00 2001 From: lguohan Date: Fri, 1 Jun 2018 08:13:58 -0700 Subject: [PATCH 080/219] [broadcom]: update brcm sai to 3.1.3.4-13 (#1760) Signed-off-by: Guohan Lu --- platform/broadcom/sai.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 62181597e7b3..0012e8a8106a 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,9 +1,9 @@ -BRCM_SAI = libsaibcm_3.1.3.4-12_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm_3.1.3.4-12_amd64.deb?sv=2015-04-05&sr=b&sig=iK79gjz8GQnPLU8OSxgzw35MzqmxwAXQg2N%2BalLUos0%3D&se=2032-01-31T20%3A36%3A51Z&sp=r" +BRCM_SAI = libsaibcm_3.1.3.4-13_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm_3.1.3.4-13_amd64.deb?sv=2015-04-05&sr=b&sig=Y7mQMOnQEzwb%2FG%2BY9dcEX0Y9tQBDCK2UmF4TjIz3Zn8%3D&se=2155-04-24T09%3A52%3A42Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.1.3.4-12_amd64.deb +BRCM_SAI_DEV = libsaibcm-dev_3.1.3.4-13_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm-dev_3.1.3.4-12_amd64.deb?sv=2015-04-05&sr=b&sig=tSBPnK%2BK9axdPbkWP19r5ngM0ggRTWWijUIKTl8WNW0%3D&se=2032-01-31T20%3A36%3A11Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm-dev_3.1.3.4-13_amd64.deb?sv=2015-04-05&sr=b&sig=YYjwAt47PlCYJgW0RtEsdcmGAc52UdAzHEd5qVKImxc%3D&se=2155-04-24T09%3A53%3A45Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) From c464ded594c4ab1db0a957a5f747af18d1ef82b2 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Mon, 4 Jun 2018 19:03:07 -0700 Subject: [PATCH 081/219] Revert "[minigraph parser] Fix minigraph parser issue when handling LAG related ACL table configuration (#1712)" (#1764) This reverts commit d7ed6388b667387b142452dea0eb676db189fbe6. --- src/sonic-config-engine/minigraph.py | 20 +++----------------- src/sonic-config-engine/tests/test_cfggen.py | 2 +- src/sonic-swss | 2 +- 3 files changed, 5 insertions(+), 19 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 58d5960857d6..14bf34a34b05 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -149,15 +149,12 @@ def parse_dpg(dpg, hname): pcintfs = child.find(str(QName(ns, "PortChannelInterfaces"))) pc_intfs = [] pcs = {} - intfs_inpc = [] # List to hold all the LAG member interfaces for pcintf in pcintfs.findall(str(QName(ns, "PortChannel"))): pcintfname = pcintf.find(str(QName(ns, "Name"))).text pcintfmbr = pcintf.find(str(QName(ns, "AttachTo"))).text pcmbr_list = pcintfmbr.split(';') - pc_intfs.append(pcintfname) for i, member in enumerate(pcmbr_list): pcmbr_list[i] = port_alias_map.get(member, member) - intfs_inpc.append(pcmbr_list[i]) if pcintf.find(str(QName(ns, "Fallback"))) != None: pcs[pcintfname] = {'members': pcmbr_list, 'fallback': pcintf.find(str(QName(ns, "Fallback"))).text} else: @@ -205,26 +202,15 @@ def parse_dpg(dpg, hname): for member in aclattach: member = member.strip() if pcs.has_key(member): - # If try to attach ACL to a LAG interface then we shall add the LAG to - # to acl_intfs directly instead of break it into member ports, ACL attach - # to LAG will be applied to all the LAG members internally by SAI/SDK - acl_intfs.append(member) + acl_intfs.extend(pcs[member]['members']) # For ACL attaching to port channels, we break them into port channel members elif vlans.has_key(member): print >> sys.stderr, "Warning: ACL " + aclname + " is attached to a Vlan interface, which is currently not supported" elif port_alias_map.has_key(member): acl_intfs.append(port_alias_map[member]) - # Give a warning if trying to attach ACL to a LAG member interface, correct way is to attach ACL to the LAG interface - if port_alias_map[member] in intfs_inpc: - print >> sys.stderr, "Warning: ACL " + aclname + " is attached to a LAG member interface " + port_alias_map[member] + ", instead of LAG interface" elif member.lower() == 'erspan': is_mirror = True; - # Erspan session will be attached to all front panel ports, - # if panel ports is a member port of LAG, should add the LAG - # to acl table instead of the panel ports - acl_intfs = pc_intfs - for panel_port in port_alias_map.values(): - if panel_port not in intfs_inpc: - acl_intfs.append(panel_port) + # Erspan session will be attached to all front panel ports + acl_intfs = port_alias_map.values() break; if acl_intfs: acls[aclname] = {'policy_desc': aclname, diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index d88f0525d546..37b66a27b4c4 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -83,7 +83,7 @@ def test_minigraph_acl(self): "Warning: ignore interface 'fortyGigE0/2' in DEVICE_NEIGHBOR as it is not in the port_config.ini\n" "{'SSH_ACL': {'services': ['SSH'], 'type': 'CTRLPLANE', 'policy_desc': 'SSH_ACL'}," " 'SNMP_ACL': {'services': ['SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'SNMP_ACL'}," - " 'DATAACL': {'type': 'L3', 'policy_desc': 'DATAACL', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04']}," + " 'DATAACL': {'type': 'L3', 'policy_desc': 'DATAACL', 'ports': ['Ethernet112', 'Ethernet116', 'Ethernet120', 'Ethernet124']}," " 'NTP_ACL': {'services': ['NTP'], 'type': 'CTRLPLANE', 'policy_desc': 'NTP_ACL'}," " 'ROUTER_PROTECT': {'services': ['SSH', 'SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'ROUTER_PROTECT'}}") diff --git a/src/sonic-swss b/src/sonic-swss index 0f433515d1dc..a1b6fa323c69 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 0f433515d1dc585848cfa58b38f2da65397f27bb +Subproject commit a1b6fa323c693fe3e21cc0aebf2e29fce18aa5b3 From 53373b63830d71518419826b38bf2044e089eb10 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Mon, 4 Jun 2018 21:06:58 -0700 Subject: [PATCH 082/219] Revert the feature: serial port watchdog service (#1766) * Revert "[serial watchdog] remove serial watchdog service dependency to rc.local (#1752)" * Revert "[service] introducing serial port watchdog service (#1743)" --- .../build_templates/sonic_debian_extension.j2 | 5 - files/image_config/platform/rc.local | 44 +-- .../serial-port-watchdog.py | 328 ------------------ .../serial-port-watchdog.service | 10 - 4 files changed, 4 insertions(+), 383 deletions(-) delete mode 100755 files/image_config/serial-port-watchdog/serial-port-watchdog.py delete mode 100644 files/image_config/serial-port-watchdog/serial-port-watchdog.service diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 301ae938a882..0849118b83a4 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -154,11 +154,6 @@ sudo cp $IMAGE_CONFIGS/hostname/hostname-config.service $FILESYSTEM_ROOT/etc/sy sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable hostname-config.service sudo cp $IMAGE_CONFIGS/hostname/hostname-config.sh $FILESYSTEM_ROOT/usr/bin/ -# Copy serial-port-watchdog configuration scripts -sudo cp $IMAGE_CONFIGS/serial-port-watchdog/serial-port-watchdog.service $FILESYSTEM_ROOT/etc/systemd/system/ -sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable serial-port-watchdog.service -sudo cp $IMAGE_CONFIGS/serial-port-watchdog/serial-port-watchdog.py $FILESYSTEM_ROOT/usr/bin/ - # Copy updategraph script and service file sudo cp $IMAGE_CONFIGS/updategraph/updategraph.service $FILESYSTEM_ROOT/etc/systemd/system/ sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable updategraph.service diff --git a/files/image_config/platform/rc.local b/files/image_config/platform/rc.local index ab88b7a3f5b4..de54d141ef7e 100755 --- a/files/image_config/platform/rc.local +++ b/files/image_config/platform/rc.local @@ -183,51 +183,15 @@ for x in "$@"; do done } -setup_platform() -{ +eval sonic_version=$(cat /etc/sonic/sonic_version.yml | grep build_version | cut -f2 -d" ") + +if [ -f /host/image-$sonic_version/platform/firsttime ]; then + if [ -n "$aboot_platform" ]; then platform=$aboot_platform elif [ -n "$onie_platform" ]; then platform=$onie_platform else - platform='' - fi -} - -# Setup default values in this function before reading installer.conf -# installer.conf could override the value set in this function. -setup_platform_defaults() -{ - # Default serial port: ttyS0 - CONSOLE_DEV=0 -} - -load_platform_installer_config() -{ - INSTALLER_CFG=/usr/share/sonic/device/$platform/installer.conf - if [ -f $INSTALLER_CFG ]; then - . $INSTALLER_CFG - fi -} - -program_serial_port() -{ - sed -i "s|ttyS.|ttyS$CONSOLE_DEV|g" /etc/systemd/system/serial-port-watchdog.service - systemctl daemon-reload - systemctl restart serial-port-watchdog.service -} - -eval sonic_version=$(cat /etc/sonic/sonic_version.yml | grep build_version | cut -f2 -d" ") - -setup_platform -setup_platform_defaults -load_platform_installer_config - -program_serial_port - -if [ -f /host/image-$sonic_version/platform/firsttime ]; then - - if [ -z "$platform" ]; then echo "Unknown sonic platform" firsttime_exit fi diff --git a/files/image_config/serial-port-watchdog/serial-port-watchdog.py b/files/image_config/serial-port-watchdog/serial-port-watchdog.py deleted file mode 100755 index 15c57556d065..000000000000 --- a/files/image_config/serial-port-watchdog/serial-port-watchdog.py +++ /dev/null @@ -1,328 +0,0 @@ -#!/usr/bin/env python - -from __future__ import print_function, with_statement - -import argparse -import logging -import logging.handlers -import os -import time -import signal -import socket -import sys - -from collections import namedtuple - -PRGNAME = 'serial-port-watchdog' - -DEVFS_PATH = '/dev' -PROCFS_PATH = '/proc' - -# According to procfs(5) -ProcStat = namedtuple( 'ProcStat', [ - 'pid', 'comm', 'state', 'ppid', 'pgrp', 'session', 'tty_nr', 'tpgid', - 'flags', 'minflt', 'cminflt', 'majflt', 'cmajflt', 'utime', 'stime', - 'cutime', 'cstime', 'priority', 'nice', 'num_threads', 'itrealvalue', - 'starttime', 'vsize', 'rss', 'rsslim', 'startcode', 'endcode', - 'startstack', 'kstkesp', 'kstkeip', 'signal', 'blocked', 'sigignore', - 'sigcatch', 'wchan', 'nswap', 'cnswap', 'exit_signal', 'processor', - 'rt_priority', 'policy', 'delayacct_blkio_ticks', 'guest_time', - 'cguest_time', 'start_data', 'end_data', 'start_brk', 'arg_start', - 'arg_end', 'env_start', 'env_end', 'exit_code' -] ) - -# According to procfs(5) -ProcIo = namedtuple( 'ProcIo', [ - 'rchar', 'wchar', 'syscr', 'syscw', 'read_bytes', 'write_bytes', - 'cancelled_write_bytes' -] ) - -class Process( object ): - def __init__( self, pid, path=PROCFS_PATH ): - self.pid = pid - self.path = os.path.join( path, str( pid ) ) - self.childs = [] - self.parent = None - - self.stat = None - - self.io = None - self.stack = None - self.stackStartTime = None - - def refresh( self ): - with open( os.path.join( self.path, 'stat' ) ) as f: - data = f.read().rstrip().split() - self.stat = ProcStat( *data ) - - def getStat( self, key=None ): - self.refresh() - return self.stat - - def uid( self ): - return '%s/%s' % ( self.pid, self.stat.starttime ) - - def ppid( self ): - return self.stat.ppid - - def name( self ): - with open( os.path.join( self.path, 'comm' ) ) as f: - return f.read().rstrip() - - def getTtyForFd( self, fd ): - path = os.path.join( self.path, 'fd', str( fd ) ) - if not os.path.exists( path ): - return '' - return os.readlink( path ) - - def getStack( self ): - with open( os.path.join( self.path, 'stack' ) ) as f: - return f.read() - - def getIo( self ): - with open( os.path.join( self.path, 'io' ) ) as f: - data = [ int( l.split( ': ' )[ 1 ] ) for l in f.readlines() ] - return ProcIo( *data ) - - def isUsingTty( self, tty ): - return self.getTtyForFd( 0 ).endswith( tty ) - - def checkStuck( self, content ): - stack = self.getStack() - - found = False - for match in content: - if match in stack: - found = True - break - - if not found: - self.io = None - self.stack = None - self.stackStartTime = None - return 0 - - io = self.getIo() - - if self.stack != stack or self.io != io: - self.io = io - self.stack = stack - self.stackStartTime = time.time() - return 0 - - return time.time() - self.stackStartTime - - def __repr__( self ): - return '' % self.uid() - -class ProcessMonitor( object ): - def __init__( self, path=PROCFS_PATH ): - self.path = path - self.procs = {} - self.filters = [] - self.checkers = [] - self.whitelist = [] - - def addProcessFilter( self, func, *args ): - self.filters.append( ( func, args ) ) - - def addStuckChecker( self, func, *args ): - self.checkers.append( ( func, args ) ) - - def setWhitelist( self, whitelist ): - self.whitelist = whitelist - - def shouldHandleProcess( self, proc ): - matched = False - for func, args in self.filters: - if func( proc, *args ): - matched = True - break - - if not matched: - return False - - name = proc.name() - for item in self.whitelist: - if item in name: - return False - - return True - - def getRunningPids( self ): - pids = [] - for entry in os.listdir( self.path ): - if not entry.isdigit(): - continue - pids.append( int( entry ) ) - return pids - - def killStuckProcess( self, proc, elapsed, kill, timeout ): - if not elapsed: - return - - if elapsed < timeout: - if elapsed > timeout / 2: - logging.info( 'process %d seems stuck, idle for %ds, waiting ' - 'some more time', proc.pid, elapsed ) - return - - logging.warning( 'process %d has been stuck for %d seconds, killing...', - proc.pid, elapsed ) - logging.info( 'process %d kernel stack\n%s', proc.pid, proc.stack ) - if kill: - # XXX: SIGTERM sleep then if alive SIGKILL ? - os.kill( proc.pid, signal.SIGKILL ) - - def killStuckProcesses( self, kill, timeout ): - for proc in self.procs.values(): - for checker, args in self.checkers: - elapsed = checker( proc, *args ) - self.killStuckProcess( proc, elapsed, kill, timeout ) - - def updatePid( self, pid ): - p = Process( pid ) - - # if the process is already monitored (previously running) - r = self.procs.get( pid, None ) - if r: - p.refresh() - # if the process is still running - if p.uid() == r.uid(): - logging.debug( 'process %d still running', pid ) - return - # or the pid was reused but the process is different - logging.debug( 'pid %d reused for another process', pid ) - del self.procs[ pid ] - - # check if the process is relevant for monitoring - if not self.shouldHandleProcess( p ): - return - - logging.debug( 'watching process %d', pid ) - p.refresh() - self.procs[ pid ] = p - - def updateParenting( self ): - # clear parent and childs for monitored processes - for proc in self.procs.values(): - del proc.childs[:] - proc.parent = None - - # set parent and childs for monitored processes - for proc in self.procs.values(): - ppid = proc.ppid() - parent = self.procs.get( ppid, None ) - if parent: - proc.parent = parent - parent.childs.append( proc ) - - def update( self ): - pids = self.getRunningPids() - - # remove defunct processes - for pid in list(self.procs.keys()): - if pid not in pids: - logging.debug( 'process %d is defunct', pid ) - del self.procs[ pid ] - - # create or update running processes information - for pid in pids: - try: - self.updatePid( pid ) - except: - logging.warning( 'An issue occured whileupdating process %s', - pid ) - raise - - #self.updateParenting() - -def checkRootPermissions(): - if os.geteuid() != 0: - logging.error( 'You must be root to use this feature' ) - sys.exit( 1 ) - -def getHostname(): - try: - return socket.gethostname() - except: - return 'localhost' - -def setupLogging( verbose=False ): - loglevel = logging.DEBUG if verbose else logging.INFO - dateFmt = '%Y-%m-%d %H:%M:%S' - - log = logging.getLogger() - log.setLevel( logging.DEBUG ) - - logOut = logging.StreamHandler( sys.stdout ) - logOut.setFormatter( logging.Formatter( '%(levelname)s: %(message)s' ) ) - logOut.setLevel( loglevel ) - log.addHandler( logOut ) - - logSys = logging.handlers.SysLogHandler() - # format to rfc5424 format - fmt = '{} {}: %(message)s'.format( getHostname(), PRGNAME ) - logSys.setFormatter( logging.Formatter( fmt ) ) - logSys.setLevel( logging.WARNING ) - log.addHandler( logSys ) - try: - # the connection to the syslog socket happens with the first message - log.info( 'Attaching to syslog' ) - except: - log.warning( 'Failed open syslog' ) - -def listParser( value ): - if not value.strip(): - return [] - return value.split( ',' ) - -def ttyParser( dev, path=DEVFS_PATH ): - if not dev.startswith( DEVFS_PATH ): - dev = os.path.join( DEVFS_PATH, dev ) - if not os.path.exists( dev ): - raise argparse.ArgumentTypeError( '%s is not a device' % dev ) - return dev - -def parseArgs( args ): - parser = argparse.ArgumentParser() - - parser.add_argument( '-d', '--dry-run', action='store_true', - help='only print processes that would be killed' ) - parser.add_argument( '-f', '--funcs', default=[ 'tty_' ], type=listParser, - help='functions to look for in the stack trace' ) - parser.add_argument( '-i', '--interval', default=60, type=float, - help='interval at which to check the procfs' ) - parser.add_argument( '-k', '--timeout', default=3600, type=float, - help='timeout for which a process gets killed' ) - parser.add_argument( '-t', '--tty', default='ttyS0', type=ttyParser, - help='tty to check for stuck process' ) - parser.add_argument( '-v', '--verbose', action='store_true', - help='print all debug messages' ) - parser.add_argument( '-w', '--whitelist', default=[ 'agetty' ], type=listParser, - help='whitelist programs that should never be killed' ) - - return parser.parse_args( args ) - -def main( args ): - args = parseArgs( args ) - - setupLogging( args.verbose ) - checkRootPermissions() - - m = ProcessMonitor() - m.addProcessFilter( Process.isUsingTty, args.tty ) - m.addStuckChecker( Process.checkStuck, args.funcs ) - m.setWhitelist( args.whitelist ) - - while True: - logging.debug( 'updating processes' ) - m.update() - m.killStuckProcesses( kill=( not args.dry_run ), timeout=args.timeout ) - time.sleep( args.interval ) - - return 0 - -if __name__ == '__main__': - sys.exit( main( sys.argv[ 1: ] ) ) - diff --git a/files/image_config/serial-port-watchdog/serial-port-watchdog.service b/files/image_config/serial-port-watchdog/serial-port-watchdog.service deleted file mode 100644 index 1fcb15a103a5..000000000000 --- a/files/image_config/serial-port-watchdog/serial-port-watchdog.service +++ /dev/null @@ -1,10 +0,0 @@ -[Unit] -Description=Monitor serial port processes, kill stuck ones - -[Service] -ExecStart=/usr/bin/serial-port-watchdog.py -t ttyS0 -Restart=always -RestartSec=0 - -[Install] -WantedBy=multi-user.target From 704f2fa6dfb03940fc05223815ba65403c5db219 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 5 Jun 2018 03:24:30 -0700 Subject: [PATCH 083/219] [caclmgrd] Heuristically determine whether ACL is IPv4 or IPv6, use iptables/ip6tables accordingly (#1767) * [caclmgrd] Heuristically determine whether ACL is IPv4 or IPv6, use iptables/ip6tables accordingly * Check all rules in table until we find one with a SRC_IP --- files/image_config/caclmgrd/caclmgrd | 31 +++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index dee85d2e26ed..0dc59766b3d5 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -11,6 +11,7 @@ # try: + import ipaddr as ipaddress import os import subprocess import sys @@ -113,12 +114,22 @@ class ControlPlaneAclManager(object): # Add iptables command to delete all non-default chains iptables_cmds.append("iptables -X") + # Add same set of commands for ip6tables + iptables_cmds.append("ip6tables -P INPUT ACCEPT") + iptables_cmds.append("ip6tables -P FORWARD ACCEPT") + iptables_cmds.append("ip6tables -P OUTPUT ACCEPT") + iptables_cmds.append("ip6tables -F") + iptables_cmds.append("ip6tables -X") + # Get current ACL tables and rules from Config DB self._tables_db_info = self.config_db.get_table(self.ACL_TABLE) self._rules_db_info = self.config_db.get_table(self.ACL_RULE) # Walk the ACL tables for (table_name, table_data) in self._tables_db_info.iteritems(): + + table_ip_version = None + # Ignore non-control-plane ACL tables if table_data["type"] != self.ACL_TABLE_TYPE_CTRLPLANE: continue @@ -144,6 +155,23 @@ class ControlPlaneAclManager(object): if rule_table_name == table_name: acl_rules[rule_props["PRIORITY"]] = rule_props + # If we haven't determined the IP version for this ACL table yet, + # try to do it now. We determine heuristically based on whether the + # src IP is an IPv4 or IPv6 address. + if not table_ip_version and "SRC_IP" in rule_props and rule_props["SRC_IP"]: + ip_addr = ipaddress.IPAddress(rule_props["SRC_IP"].split("/")[0]) + if isinstance(ip_addr, ipaddress.IPv6Address): + table_ip_version = 6 + elif isinstance(ip_addr, ipaddress.IPv4Address): + table_ip_version = 4 + + # If we were unable to determine whether this ACL table contains + # IPv4 or IPv6 rules, log a message and skip processing this table. + if not table_ip_version: + log_warning("Unable to determine if ACL table '{}' contains IPv4 or IPv6 rules. Skipping table..." + .format(table_name)) + continue + # For each ACL rule in this table (in descending order of priority) for priority in sorted(acl_rules.iterkeys(), reverse=True): rule_props = acl_rules[priority] @@ -155,7 +183,8 @@ class ControlPlaneAclManager(object): # Apply the rule to the default protocol(s) for this ACL service for ip_protocol in ip_protocols: for dst_port in dst_ports: - rule_cmd = "iptables -A INPUT -p {}".format(ip_protocol) + rule_cmd = "ip6tables" if table_ip_version == 6 else "iptables" + rule_cmd += " -A INPUT -p {}".format(ip_protocol) if "SRC_IP" in rule_props and rule_props["SRC_IP"]: rule_cmd += " -s {}".format(rule_props["SRC_IP"]) From a3385b3fe8e2c40ac21e5eb6a26c77c66306ee94 Mon Sep 17 00:00:00 2001 From: Andriy Moroz Date: Sat, 9 Jun 2018 00:34:52 +0300 Subject: [PATCH 084/219] [platform]: Update Mellanox SDK/SAI pointers (new firmware) (#1777) Signed-off-by: Andriy Moroz --- platform/mellanox/fw.mk | 2 +- platform/mellanox/mlnx-sai.mk | 2 +- platform/mellanox/sdk.mk | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index 73d1236f5a9a..ca8e4f988bd8 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -1,6 +1,6 @@ # mellanox firmware -MLNX_FW_VERSION = 13.1620.0222 +MLNX_FW_VERSION = 13.1620.0234 MLNX_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_FW_VERSION))-EVB.mfa $(MLNX_FW_FILE)_URL = $(MLNX_SDK_BASE_URL)/$(MLNX_FW_FILE) SONIC_ONLINE_FILES += $(MLNX_FW_FILE) diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index 53e74021bb84..648ee3eca5b7 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,7 +1,7 @@ # Mellanox SAI MLNX_SAI_VERSION = SAIRel1.11.5-master -MLNX_SAI_REVISION = 957f61820e441e490081cb3724f702ed507f7477 +MLNX_SAI_REVISION = 5675ef1037813992cd234d3afcee43959e1ca4f6 export MLNX_SAI_VERSION MLNX_SAI_REVISION diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index f301032846c3..83d5dad7af8a 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,4 +1,4 @@ -MLNX_SDK_BASE_URL = https://github.com/Mellanox/SAI-Implementation/raw/957f61820e441e490081cb3724f702ed507f7477/sdk +MLNX_SDK_BASE_URL = https://github.com/Mellanox/SAI-Implementation/raw/5675ef1037813992cd234d3afcee43959e1ca4f6/sdk MLNX_SDK_VERSION = 4.2.7303 MLNX_SDK_RDEBS += $(APPLIBS) $(IPROUTE2_MLNX) $(SX_ACL_RM) $(SX_COMPLIB) \ $(SX_EXAMPLES) $(SX_GEN_UTILS) $(SX_SCEW) $(SX_SDN_HAL) \ From 8fb23130665c3123d200bc0494bc3c15c7ef2aa9 Mon Sep 17 00:00:00 2001 From: Hnydyn Nazar Date: Sat, 9 Jun 2018 00:35:44 +0300 Subject: [PATCH 085/219] [devices]: Updated AS7512-32X ini config files. (#1685) --- .../accton/x86_64-accton_as7512_32x-r0/AS7512-C32/sai.profile | 2 ++ .../accton/x86_64-accton_as7512_32x-r0/AS7512-S128/sai.profile | 2 ++ device/accton/x86_64-accton_as7512_32x-r0/AS7512/sai.profile | 2 ++ 3 files changed, 6 insertions(+) diff --git a/device/accton/x86_64-accton_as7512_32x-r0/AS7512-C32/sai.profile b/device/accton/x86_64-accton_as7512_32x-r0/AS7512-C32/sai.profile index 457c339c58ab..211383b00640 100644 --- a/device/accton/x86_64-accton_as7512_32x-r0/AS7512-C32/sai.profile +++ b/device/accton/x86_64-accton_as7512_32x-r0/AS7512-C32/sai.profile @@ -1,2 +1,4 @@ mode=3 hwId=as7512 +netdevMode=1 +aclEntryMaxPrio=1024 diff --git a/device/accton/x86_64-accton_as7512_32x-r0/AS7512-S128/sai.profile b/device/accton/x86_64-accton_as7512_32x-r0/AS7512-S128/sai.profile index 471c4395758f..07c7ce4d6b2e 100644 --- a/device/accton/x86_64-accton_as7512_32x-r0/AS7512-S128/sai.profile +++ b/device/accton/x86_64-accton_as7512_32x-r0/AS7512-S128/sai.profile @@ -1,2 +1,4 @@ mode=0 hwId=as7512 +netdevMode=1 +aclEntryMaxPrio=1024 diff --git a/device/accton/x86_64-accton_as7512_32x-r0/AS7512/sai.profile b/device/accton/x86_64-accton_as7512_32x-r0/AS7512/sai.profile index 017996f7d7cc..381a440f988b 100644 --- a/device/accton/x86_64-accton_as7512_32x-r0/AS7512/sai.profile +++ b/device/accton/x86_64-accton_as7512_32x-r0/AS7512/sai.profile @@ -1,2 +1,4 @@ mode=1 hwId=as7512 +netdevMode=1 +aclEntryMaxPrio=1024 From fd7392f3fba59d761d8da7e901c47ca50c9f4e5b Mon Sep 17 00:00:00 2001 From: Nadiya Date: Sat, 9 Jun 2018 00:36:08 +0300 Subject: [PATCH 086/219] [platform]: Add Cavium packages for 201803 revision (#1773) Signed-off-by: Nadiya Stetskovych --- platform/cavium/cavm-sai.mk | 2 +- platform/cavium/cavm-xpnet.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/cavium/cavm-sai.mk b/platform/cavium/cavm-sai.mk index 0008135729c5..6064d8d7561a 100644 --- a/platform/cavium/cavm-sai.mk +++ b/platform/cavium/cavm-sai.mk @@ -1,6 +1,6 @@ # Cavium SAI -CAVM_SAI_GITHUB = https://github.com/XPliant/OpenXPS/raw/13a7eaf10f523e7887964ca235f19095fcc88537/SAI/cavm-sai/ +CAVM_SAI_GITHUB = https://github.com/XPliant/OpenXPS/raw/d37a606cdf7d2bdc9d6ee025b758f64572f8ddbe/SAI/cavm-sai/ CAVM_LIBSAI = libsai.deb CAVM_SAI = sai.deb diff --git a/platform/cavium/cavm-xpnet.mk b/platform/cavium/cavm-xpnet.mk index ed86558a36ae..a4c43cb334bd 100644 --- a/platform/cavium/cavm-xpnet.mk +++ b/platform/cavium/cavm-xpnet.mk @@ -1,4 +1,4 @@ -CAVM_SAI_URL = https://github.com/XPliant/OpenXPS/raw/c26aea6a7098936ab3692e148238d73fa8962585/SAI +CAVM_SAI_URL = https://github.com/XPliant/OpenXPS/raw/d37a606cdf7d2bdc9d6ee025b758f64572f8ddbe/SAI CAVM_XPNET_DEB = xp80-Pcie-Endpoint.deb $(CAVM_XPNET_DEB)_URL = $(CAVM_SAI_URL)/netdev/$(CAVM_XPNET_DEB) From 552826413c1eecd863e227c61bcb9e6a86491aff Mon Sep 17 00:00:00 2001 From: Pradchaya P Date: Tue, 12 Jun 2018 00:40:58 +0700 Subject: [PATCH 087/219] Add Celestica seastone dx010 psuutil.py plugins (#1781) --- .../x86_64-cel_seastone-r0/plugins/psuutil.py | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 device/celestica/x86_64-cel_seastone-r0/plugins/psuutil.py diff --git a/device/celestica/x86_64-cel_seastone-r0/plugins/psuutil.py b/device/celestica/x86_64-cel_seastone-r0/plugins/psuutil.py new file mode 100644 index 000000000000..9e8f99e7a7f2 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/plugins/psuutil.py @@ -0,0 +1,102 @@ +# +# psuutil.py +# Platform-specific PSU status interface for SONiC +# + +import os.path + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + # DX010 PSU pin mapping + self.psu = [ + {'base':216}, # Reserved + {'abs':27, 'power':22}, + {'abs':28, 'power':25} + ] + + def init_psu_gpio(self, pinnum): + # export pin, input as default + gpio_base = self.psu[0]['base'] + export_file = "/sys/class/gpio/export" + direction_file = '/sys/class/gpio/gpio' + str(gpio_base+pinnum) + '/direction' + + try: + with open(export_file, 'w') as fd: + fd.write(str(gpio_base+pinnum)) + except Exception as error: + logging.error("Unable to export gpio ", pinnum) + + + # Get a psu status and presence + def read_psu_statuses(self, pinnum): + sys_gpio_dir = "/sys/class/gpio" + retval = 'ERR' + gpio_base = self.psu[0]['base'] + + gpio_dir = sys_gpio_dir + '/gpio' + str(gpio_base+pinnum) + gpio_file = gpio_dir + "/value" + + # init gpio + if (not os.path.isdir(gpio_dir)): + self.init_psu_gpio(pinnum) + + try: + with open(gpio_file, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", gpio_file, "file !") + + retval = retval.rstrip('\r\n') + return retval + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + :return: An integer, the number of PSUs available on the device + """ + DX010_MAX_PSUS = 2 + return DX010_MAX_PSUS + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is\ + faulty + """ + status = 0 + psu_status = self.read_psu_statuses(self.psu[index]['power']) + if (psu_status != 'ERR'): + psu_status = int(psu_status, 10) + # Check for PSU status + if (psu_status == 1): + status = 1 + + return status + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + status = 0 + psu_absence = self.read_psu_statuses(self.psu[index]['abs']) + if (psu_absence != 'ERR'): + psu_absence = (int(psu_absence, 10)) + # Check for PSU presence + if (psu_absence == 0): + status = 1 + + return status From 9d5913d199337b8694c3e38309c37bda4bebca3e Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Mon, 11 Jun 2018 13:54:02 -0700 Subject: [PATCH 088/219] [devices]: Add Broadcom config files for Arista 7050 SKUs; Remove 'serdes_firmware_mode_xe=0x1' line (#1779) * Add Broadcom config files for Arista-7050-QX32 and Arista-7050-Q16S64 SKUs under respective directories * Remove 'serdes_firmware_mode_xe=0x1' line from Arista 7050 Broadcom config files --- .../Arista-7050-Q16S64/sai.profile | 2 +- ...-a7050-qx32-16x40G+32x10G+8x40G.config.bcm | 707 ++++++++++++++ .../Arista-7050-QX32/sai.profile | 2 +- .../td2-a7050-qx32-32x40G.config.bcm | 873 ++++++++++++++++++ 4 files changed, 1582 insertions(+), 2 deletions(-) create mode 100644 device/arista/x86_64-arista_7050_qx32/Arista-7050-Q16S64/td2-a7050-qx32-16x40G+32x10G+8x40G.config.bcm create mode 100644 device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/td2-a7050-qx32-32x40G.config.bcm diff --git a/device/arista/x86_64-arista_7050_qx32/Arista-7050-Q16S64/sai.profile b/device/arista/x86_64-arista_7050_qx32/Arista-7050-Q16S64/sai.profile index 0175b59a5da3..5c613675c37f 100644 --- a/device/arista/x86_64-arista_7050_qx32/Arista-7050-Q16S64/sai.profile +++ b/device/arista/x86_64-arista_7050_qx32/Arista-7050-Q16S64/sai.profile @@ -1,2 +1,2 @@ -SAI_INIT_CONFIG_FILE=/etc/bcm/td2-a7050-qx32-16x40G+32x10G+8x40G.config.bcm +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-a7050-qx32-16x40G+32x10G+8x40G.config.bcm SAI_NUM_ECMP_MEMBERS=32 diff --git a/device/arista/x86_64-arista_7050_qx32/Arista-7050-Q16S64/td2-a7050-qx32-16x40G+32x10G+8x40G.config.bcm b/device/arista/x86_64-arista_7050_qx32/Arista-7050-Q16S64/td2-a7050-qx32-16x40G+32x10G+8x40G.config.bcm new file mode 100644 index 000000000000..6d72e20b2104 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32/Arista-7050-Q16S64/td2-a7050-qx32-16x40G+32x10G+8x40G.config.bcm @@ -0,0 +1,707 @@ +#/****************************************************************************** +# * +# * File: config.bcm.cloverdales (7050-QX32) +# * Name: +# * +# * Description: This file contains SDK properties for an Arista +# * Cloverdales platform. +# * +# *----------------------------------------------------------------------------- +# ******************************************************************************/ +#################################################################### +# BCM Config file for Cloverdale platform +# - 16x40g + 32x10g + 8x40G Portmode + +# Old LPM only configuration +# l2_mem_entries=163840 +# l3_mem_entries=90112 +# l3_alpm_enable=0 +# ipv6_lpm_128b_enable=0 +# +# ALPM enable +l3_alpm_enable=2 +ipv6_lpm_128b_enable=1 +l2_mem_entries=32768 +l3_mem_entries=16384 + +# From old config file +os=unix +higig2_hdr_mode=1 + +# Parity +parity_correction=1 +parity_enable=1 +stat_if_parity_enable=0 + +# l2 thread related config vars +l2xmsg_hostbuf_size=8192 +l2xmsg_mode=1 + +bcm_num_cos=8 +bcm_stat_interval=2000000 +lls_num_l2uc=12 +max_vp_lags=0 +miim_intr_enable=0 +mmu_lossless=0 +module_64ports=0 +scache_filename=/tmp/scache +schan_intr_enable=0 +stable_size=0x2000000 +tdma_timeout_usec=5000000 + +# for GLC transceiver +phy_an_c73=0x0 +phy_an_c37=0x3 + +########################### +#port_init_speed_xe=40000 +#port_init_speed_xe.0=40000 + +#load_firmware=0x0102 +load_firmware.0=2 + +######################### +# All ports are in oversubscription mode +pbmp_oversubscribe=0x1fffffffffffffffffffffffffe +pbmp_xport_xe.0=0x1fffffffffffffffffffffffffe + +########################################## +#skip_L2_USER_ENTRY=0 +phy_aux_voltage_enable=1 +############################### +serdes_fiber_pref=1 +############################### +mdio_output_delay.0=0x0d +############################### +serdes_sgmii_m=0 +xgxs_lcpll_xtal_refclk=1 +xgxs_lcpll_xtal_refclk.0=1 +xgxs_lcpll_xtal_refclk.1=1 +xgxs_lcpll_xtal_refclk.2=1 +xgxs_lcpll_xtal_refclk.3=1 +tdma_intr_enable=1 +tslam_intr_enable=1 +tslam_dma_enable.2=1 +tslam_dma_enable.3=1 +#dport_map_port=0 +#pci2eb_overrid=0 +#bcm_xlate_port_enable.0=0 +#xgxs_pdetect_1=0 +table_dma_enable.0=1 +table_dma_enable.1=1 +table_dma_enable.2=1 +table_dma_enable.3=1 + + +phy_84328_1.0=1 +phy_84328_5.0=1 +phy_84328_9.0=1 +phy_84328_13.0=1 +phy_84328_101.0=1 +phy_84328_102.0=1 +phy_84328_103.0=1 +phy_84328_104.0=1 + +phy_an_c37_1.0=0 +phy_an_c37_5.0=0 +phy_an_c37_9.0=0 +phy_an_c37_13.0=0 +phy_an_c37_17.0=0 +phy_an_c37_21.0=0 +phy_an_c37_25.0=0 +phy_an_c37_29.0=0 +phy_an_c37_33.0=0 +phy_an_c37_37.0=0 +phy_an_c37_41.0=0 +phy_an_c37_45.0=0 +phy_an_c37_49.0=0 +phy_an_c37_53.0=0 +phy_an_c37_57.0=0 +phy_an_c37_61.0=0 +phy_an_c37_65.0=3 +phy_an_c37_66.0=3 +phy_an_c37_67.0=3 +phy_an_c37_68.0=3 +phy_an_c37_69.0=3 +phy_an_c37_70.0=3 +phy_an_c37_71.0=3 +phy_an_c37_72.0=3 +phy_an_c37_73.0=3 +phy_an_c37_74.0=3 +phy_an_c37_75.0=3 +phy_an_c37_76.0=3 +phy_an_c37_77.0=3 +phy_an_c37_78.0=3 +phy_an_c37_79.0=3 +phy_an_c37_80.0=3 +phy_an_c37_81.0=3 +phy_an_c37_82.0=3 +phy_an_c37_83.0=3 +phy_an_c37_84.0=3 +phy_an_c37_85.0=3 +phy_an_c37_86.0=3 +phy_an_c37_87.0=3 +phy_an_c37_88.0=3 +phy_an_c37_89.0=3 +phy_an_c37_90.0=3 +phy_an_c37_91.0=3 +phy_an_c37_92.0=3 +phy_an_c37_93.0=3 +phy_an_c37_94.0=3 +phy_an_c37_95.0=3 +phy_an_c37_96.0=3 +phy_an_c37_97.0=0 +phy_an_c37_98.0=0 +phy_an_c37_99.0=0 +phy_an_c37_100.0=0 +phy_an_c37_101.0=0 +phy_an_c37_102.0=0 +phy_an_c37_103.0=0 +phy_an_c37_104.0=0 + +phy_an_c73_1.0=2 +phy_an_c73_5.0=2 +phy_an_c73_9.0=2 +phy_an_c73_13.0=2 +phy_an_c73_17.0=2 +phy_an_c73_21.0=2 +phy_an_c73_25.0=2 +phy_an_c73_29.0=2 +phy_an_c73_33.0=2 +phy_an_c73_37.0=2 +phy_an_c73_41.0=2 +phy_an_c73_45.0=2 +phy_an_c73_49.0=2 +phy_an_c73_53.0=2 +phy_an_c73_57.0=2 +phy_an_c73_61.0=2 +phy_an_c73_65.0=0 +phy_an_c73_66.0=0 +phy_an_c73_67.0=0 +phy_an_c73_68.0=0 +phy_an_c73_69.0=0 +phy_an_c73_70.0=0 +phy_an_c73_71.0=0 +phy_an_c73_72.0=0 +phy_an_c73_73.0=0 +phy_an_c73_74.0=0 +phy_an_c73_75.0=0 +phy_an_c73_76.0=0 +phy_an_c73_77.0=0 +phy_an_c73_78.0=0 +phy_an_c73_79.0=0 +phy_an_c73_80.0=0 +phy_an_c73_81.0=0 +phy_an_c73_82.0=0 +phy_an_c73_83.0=0 +phy_an_c73_84.0=0 +phy_an_c73_85.0=0 +phy_an_c73_86.0=0 +phy_an_c73_87.0=0 +phy_an_c73_88.0=0 +phy_an_c73_89.0=0 +phy_an_c73_90.0=0 +phy_an_c73_91.0=0 +phy_an_c73_92.0=0 +phy_an_c73_93.0=0 +phy_an_c73_94.0=0 +phy_an_c73_95.0=0 +phy_an_c73_96.0=0 +phy_an_c73_97.0=2 +phy_an_c73_98.0=2 +phy_an_c73_99.0=2 +phy_an_c73_100.0=2 +phy_an_c73_101.0=2 +phy_an_c73_102.0=2 +phy_an_c73_103.0=2 +phy_an_c73_104.0=2 + +phy_aux_voltage_enable_1.0=0x1 +phy_aux_voltage_enable_5.0=0x1 +phy_aux_voltage_enable_9.0=0x1 +phy_aux_voltage_enable_13.0=0x1 +phy_aux_voltage_enable_101.0=0x1 +phy_aux_voltage_enable_102.0=0x1 +phy_aux_voltage_enable_103.0=0x1 +phy_aux_voltage_enable_104.0=0x1 + +phy_ext_rom_boot.0=0 + +phy_ext_rom_boot_1.0=0x0 +phy_ext_rom_boot_5.0=0x0 +phy_ext_rom_boot_9.0=0x0 +phy_ext_rom_boot_13.0=0x0 +phy_ext_rom_boot_101.0=0x0 +phy_ext_rom_boot_102.0=0x0 +phy_ext_rom_boot_103.0=0x0 +phy_ext_rom_boot_104.0=0x0 + + +phy_line_tx_mode_1.0=1 +phy_line_tx_mode_5.0=1 +phy_line_tx_mode_9.0=1 +phy_line_tx_mode_13.0=1 +phy_line_tx_mode_101.0=1 +phy_line_tx_mode_102.0=1 +phy_line_tx_mode_103.0=1 +phy_line_tx_mode_104.0=1 + + +phy_rx_polarity_flip_1.0=0x0 +phy_rx_polarity_flip_5.0=0x0 +phy_rx_polarity_flip_9.0=0x0 +phy_rx_polarity_flip_13.0=0x0 +phy_rx_polarity_flip_101.0=0x0 +phy_rx_polarity_flip_102.0=0x0 +phy_rx_polarity_flip_103.0=0x0 +phy_rx_polarity_flip_104.0=0x0 + +phy_system_tx_mode_1.0=0 +phy_system_tx_mode_5.0=0 +phy_system_tx_mode_9.0=0 +phy_system_tx_mode_13.0=0 +phy_system_tx_mode_101.0=0 +phy_system_tx_mode_102.0=0 +phy_system_tx_mode_103.0=0 +phy_system_tx_mode_104.0=0 + + +phy_tx_polarity_flip_1.0=0x0 +phy_tx_polarity_flip_5.0=0x0 +phy_tx_polarity_flip_9.0=0x0 +phy_tx_polarity_flip_13.0=0x0 +phy_tx_polarity_flip_101.0=0x0 +phy_tx_polarity_flip_102.0=0x0 +phy_tx_polarity_flip_103.0=0x0 +phy_tx_polarity_flip_104.0=0x0 + + +phy_xaui_rx_polarity_flip_1.0=0x0 +phy_xaui_rx_polarity_flip_5.0=0x0 +phy_xaui_rx_polarity_flip_9.0=0x0 +phy_xaui_rx_polarity_flip_13.0=0x0 +phy_xaui_rx_polarity_flip_17.0=0x0 +phy_xaui_rx_polarity_flip_21.0=0x0 +phy_xaui_rx_polarity_flip_25.0=0x0 +phy_xaui_rx_polarity_flip_29.0=0x0 +phy_xaui_rx_polarity_flip_33.0=0x0 +phy_xaui_rx_polarity_flip_37.0=0x0 +phy_xaui_rx_polarity_flip_41.0=0x0 +phy_xaui_rx_polarity_flip_45.0=0x0 +phy_xaui_rx_polarity_flip_49.0=0x0 +phy_xaui_rx_polarity_flip_53.0=0x0 +phy_xaui_rx_polarity_flip_57.0=0x0 +phy_xaui_rx_polarity_flip_61.0=0x0 +phy_xaui_rx_polarity_flip_65.0=0x0 +phy_xaui_rx_polarity_flip_66.0=0x0 +phy_xaui_rx_polarity_flip_67.0=0x0 +phy_xaui_rx_polarity_flip_68.0=0x0 +phy_xaui_rx_polarity_flip_69.0=0x0 +phy_xaui_rx_polarity_flip_70.0=0x0 +phy_xaui_rx_polarity_flip_71.0=0x0 +phy_xaui_rx_polarity_flip_72.0=0x0 +phy_xaui_rx_polarity_flip_73.0=0x0 +phy_xaui_rx_polarity_flip_74.0=0x0 +phy_xaui_rx_polarity_flip_75.0=0x0 +phy_xaui_rx_polarity_flip_76.0=0x0 +phy_xaui_rx_polarity_flip_77.0=0x0 +phy_xaui_rx_polarity_flip_78.0=0x0 +phy_xaui_rx_polarity_flip_79.0=0x0 +phy_xaui_rx_polarity_flip_80.0=0x0 +phy_xaui_rx_polarity_flip_81.0=0x0 +phy_xaui_rx_polarity_flip_82.0=0x0 +phy_xaui_rx_polarity_flip_83.0=0x0 +phy_xaui_rx_polarity_flip_84.0=0x0 +phy_xaui_rx_polarity_flip_85.0=0x0 +phy_xaui_rx_polarity_flip_86.0=0x0 +phy_xaui_rx_polarity_flip_87.0=0x0 +phy_xaui_rx_polarity_flip_88.0=0x0 +phy_xaui_rx_polarity_flip_89.0=0x0 +phy_xaui_rx_polarity_flip_90.0=0x0 +phy_xaui_rx_polarity_flip_91.0=0x0 +phy_xaui_rx_polarity_flip_92.0=0x0 +phy_xaui_rx_polarity_flip_93.0=0x0 +phy_xaui_rx_polarity_flip_94.0=0x0 +phy_xaui_rx_polarity_flip_95.0=0x0 +phy_xaui_rx_polarity_flip_96.0=0x0 +phy_xaui_rx_polarity_flip_97.0=0x0 +phy_xaui_rx_polarity_flip_98.0=0x0 +phy_xaui_rx_polarity_flip_99.0=0x0 +phy_xaui_rx_polarity_flip_100.0=0x0 +phy_xaui_rx_polarity_flip_101.0=0x0 +phy_xaui_rx_polarity_flip_102.0=0x0 +phy_xaui_rx_polarity_flip_103.0=0x0 +phy_xaui_rx_polarity_flip_104.0=0x0 + +phy_xaui_tx_polarity_flip_1.0=0x0 +phy_xaui_tx_polarity_flip_5.0=0x0 +phy_xaui_tx_polarity_flip_9.0=0x0 +phy_xaui_tx_polarity_flip_13.0=0x0 +phy_xaui_tx_polarity_flip_17.0=0x0 +phy_xaui_tx_polarity_flip_21.0=0x0 +phy_xaui_tx_polarity_flip_25.0=0x0 +phy_xaui_tx_polarity_flip_29.0=0x0 +phy_xaui_tx_polarity_flip_33.0=0x0 +phy_xaui_tx_polarity_flip_37.0=0x0 +phy_xaui_tx_polarity_flip_41.0=0x0 +phy_xaui_tx_polarity_flip_45.0=0x0 +phy_xaui_tx_polarity_flip_49.0=0x0 +phy_xaui_tx_polarity_flip_53.0=0x0 +phy_xaui_tx_polarity_flip_57.0=0x0 +phy_xaui_tx_polarity_flip_61.0=0x0 +phy_xaui_tx_polarity_flip_65.0=0x0 +phy_xaui_tx_polarity_flip_66.0=0x0 +phy_xaui_tx_polarity_flip_67.0=0x0 +phy_xaui_tx_polarity_flip_68.0=0x0 +phy_xaui_tx_polarity_flip_69.0=0x0 +phy_xaui_tx_polarity_flip_70.0=0x0 +phy_xaui_tx_polarity_flip_71.0=0x0 +phy_xaui_tx_polarity_flip_72.0=0x0 +phy_xaui_tx_polarity_flip_73.0=0x0 +phy_xaui_tx_polarity_flip_74.0=0x0 +phy_xaui_tx_polarity_flip_75.0=0x0 +phy_xaui_tx_polarity_flip_76.0=0x0 +phy_xaui_tx_polarity_flip_77.0=0x0 +phy_xaui_tx_polarity_flip_78.0=0x0 +phy_xaui_tx_polarity_flip_79.0=0x0 +phy_xaui_tx_polarity_flip_80.0=0x0 +phy_xaui_tx_polarity_flip_81.0=0x0 +phy_xaui_tx_polarity_flip_82.0=0x0 +phy_xaui_tx_polarity_flip_83.0=0x0 +phy_xaui_tx_polarity_flip_84.0=0x0 +phy_xaui_tx_polarity_flip_85.0=0x0 +phy_xaui_tx_polarity_flip_86.0=0x0 +phy_xaui_tx_polarity_flip_87.0=0x0 +phy_xaui_tx_polarity_flip_88.0=0x0 +phy_xaui_tx_polarity_flip_89.0=0x0 +phy_xaui_tx_polarity_flip_90.0=0x0 +phy_xaui_tx_polarity_flip_91.0=0x0 +phy_xaui_tx_polarity_flip_92.0=0x0 +phy_xaui_tx_polarity_flip_93.0=0x0 +phy_xaui_tx_polarity_flip_94.0=0x0 +phy_xaui_tx_polarity_flip_95.0=0x0 +phy_xaui_tx_polarity_flip_96.0=0x0 +phy_xaui_tx_polarity_flip_97.0=0x0 +phy_xaui_tx_polarity_flip_98.0=0x0 +phy_xaui_tx_polarity_flip_99.0=0x0 +phy_xaui_tx_polarity_flip_100.0=0x0 +phy_xaui_tx_polarity_flip_101.0=0x0 +phy_xaui_tx_polarity_flip_102.0=0x0 +phy_xaui_tx_polarity_flip_103.0=0x0 +phy_xaui_tx_polarity_flip_104.0=0x0 + +port_init_autoneg_17.0=0 +port_init_autoneg_21.0=0 +port_init_autoneg_25.0=0 +port_init_autoneg_29.0=0 +port_init_autoneg_33.0=0 +port_init_autoneg_37.0=0 +port_init_autoneg_41.0=0 +port_init_autoneg_45.0=0 +port_init_autoneg_49.0=0 +port_init_autoneg_53.0=0 +port_init_autoneg_57.0=0 +port_init_autoneg_61.0=0 +port_init_autoneg_65.0=0 +port_init_autoneg_66.0=0 +port_init_autoneg_67.0=0 +port_init_autoneg_68.0=0 +port_init_autoneg_69.0=0 +port_init_autoneg_70.0=0 +port_init_autoneg_71.0=0 +port_init_autoneg_72.0=0 +port_init_autoneg_73.0=0 +port_init_autoneg_74.0=0 +port_init_autoneg_75.0=0 +port_init_autoneg_76.0=0 +port_init_autoneg_77.0=0 +port_init_autoneg_78.0=0 +port_init_autoneg_79.0=0 +port_init_autoneg_80.0=0 +port_init_autoneg_81.0=0 +port_init_autoneg_82.0=0 +port_init_autoneg_83.0=0 +port_init_autoneg_84.0=0 +port_init_autoneg_85.0=0 +port_init_autoneg_86.0=0 +port_init_autoneg_87.0=0 +port_init_autoneg_88.0=0 +port_init_autoneg_89.0=0 +port_init_autoneg_90.0=0 +port_init_autoneg_91.0=0 +port_init_autoneg_92.0=0 +port_init_autoneg_93.0=0 +port_init_autoneg_94.0=0 +port_init_autoneg_95.0=0 +port_init_autoneg_96.0=0 +port_init_autoneg_97.0=0 +port_init_autoneg_98.0=0 +port_init_autoneg_99.0=0 +port_init_autoneg_100.0=0 + +port_init_cl72_hg.0=0x11 + + +portmap_1.0=125:40 +portmap_5.0=121:40 +portmap_9.0=13:40 +portmap_13.0=9:40 +portmap_17.0=17:40 +portmap_21.0=21:40 +portmap_25.0=25:40 +portmap_29.0=29:40 +portmap_33.0=37:40 +portmap_37.0=33:40 +portmap_41.0=45:40 +portmap_45.0=41:40 +portmap_49.0=53:40 +portmap_53.0=49:40 +portmap_57.0=69:40 +portmap_61.0=65:40 +portmap_65.0=77:10 +portmap_66.0=78:10 +portmap_67.0=79:10 +portmap_68.0=80:10 +portmap_69.0=73:10 +portmap_70.0=74:10 +portmap_71.0=75:10 +portmap_72.0=76:10 +portmap_73.0=93:10 +portmap_74.0=94:10 +portmap_75.0=95:10 +portmap_76.0=96:10 +portmap_77.0=89:10 +portmap_78.0=90:10 +portmap_79.0=91:10 +portmap_80.0=92:10 +portmap_81.0=101:10 +portmap_82.0=102:10 +portmap_83.0=103:10 +portmap_84.0=104:10 +portmap_85.0=97:10 +portmap_86.0=98:10 +portmap_87.0=99:10 +portmap_88.0=100:10 +portmap_89.0=109:10 +portmap_90.0=110:10 +portmap_91.0=111:10 +portmap_92.0=112:10 +portmap_93.0=105:10 +portmap_94.0=106:10 +portmap_95.0=107:10 +portmap_96.0=108:10 +portmap_97.0=61:40 +portmap_98.0=57:40 +portmap_99.0=81:40 +portmap_100.0=85:40 +portmap_101.0=117:40 +portmap_102.0=113:40 +portmap_103.0=5:40 +portmap_104.0=1:40 + +port_phy_addr_1.0=0x4 +port_phy_addr_5.0=0x0 +port_phy_addr_9.0=0x2c +port_phy_addr_13.0=0x28 +port_phy_addr_17.0=0x7f +port_phy_addr_21.0=0x7f +port_phy_addr_25.0=0x7f +port_phy_addr_29.0=0x7f +port_phy_addr_33.0=0x7f +port_phy_addr_37.0=0x7f +port_phy_addr_41.0=0x7f +port_phy_addr_45.0=0x7f +port_phy_addr_49.0=0x7f +port_phy_addr_53.0=0x7f +port_phy_addr_57.0=0x7f +port_phy_addr_61.0=0x7f +port_phy_addr_65.0=0x7f +port_phy_addr_66.0=0x7f +port_phy_addr_67.0=0x7f +port_phy_addr_68.0=0x7f +port_phy_addr_69.0=0x7f +port_phy_addr_70.0=0x7f +port_phy_addr_71.0=0x7f +port_phy_addr_72.0=0x7f +port_phy_addr_73.0=0x7f +port_phy_addr_74.0=0x7f +port_phy_addr_75.0=0x7f +port_phy_addr_76.0=0x7f +port_phy_addr_77.0=0x7f +port_phy_addr_78.0=0x7f +port_phy_addr_79.0=0x7f +port_phy_addr_80.0=0x7f +port_phy_addr_81.0=0x7f +port_phy_addr_82.0=0x7f +port_phy_addr_83.0=0x7f +port_phy_addr_84.0=0x7f +port_phy_addr_85.0=0x7f +port_phy_addr_86.0=0x7f +port_phy_addr_87.0=0x7f +port_phy_addr_88.0=0x7f +port_phy_addr_89.0=0x7f +port_phy_addr_90.0=0x7f +port_phy_addr_91.0=0x7f +port_phy_addr_92.0=0x7f +port_phy_addr_93.0=0x7f +port_phy_addr_94.0=0x7f +port_phy_addr_95.0=0x7f +port_phy_addr_96.0=0x7f +port_phy_addr_97.0=0x7f +port_phy_addr_98.0=0x7f +port_phy_addr_99.0=0x7f +port_phy_addr_100.0=0x7f +port_phy_addr_101.0=0x54 +port_phy_addr_102.0=0x50 +port_phy_addr_103.0=0x7c +port_phy_addr_104.0=0x78 + +port_phy_clause_1.0=0x2d +port_phy_clause_5.0=0x2d +port_phy_clause_9.0=0x2d +port_phy_clause_13.0=0x2d +port_phy_clause_101.0=0x2d +port_phy_clause_102.0=0x2d +port_phy_clause_103.0=0x2d +port_phy_clause_104.0=0x2d + +port_phy_id0_1.0=0x600d +port_phy_id0_5.0=0x600d +port_phy_id0_9.0=0x600d +port_phy_id0_13.0=0x600d +port_phy_id0_101.0=0x600d +port_phy_id0_102.0=0x600d +port_phy_id0_103.0=0x600d +port_phy_id0_104.0=0x600d + +port_phy_id1_1.0=0x8500 +port_phy_id1_5.0=0x8500 +port_phy_id1_9.0=0x8500 +port_phy_id1_13.0=0x8500 +port_phy_id1_101.0=0x8500 +port_phy_id1_102.0=0x8500 +port_phy_id1_103.0=0x8500 +port_phy_id1_104.0=0x8500 + +xgxs_rx_lane_map_1.0=0x0123 +xgxs_rx_lane_map_5.0=0x0123 +xgxs_rx_lane_map_9.0=0x0123 +xgxs_rx_lane_map_13.0=0x0123 +xgxs_rx_lane_map_17.0=0x2031 +xgxs_rx_lane_map_21.0=0x2031 +xgxs_rx_lane_map_25.0=0x2031 +xgxs_rx_lane_map_29.0=0x2031 +xgxs_rx_lane_map_33.0=0x3120 +xgxs_rx_lane_map_37.0=0x3120 +xgxs_rx_lane_map_41.0=0x3120 +xgxs_rx_lane_map_45.0=0x3120 +xgxs_rx_lane_map_49.0=0x3120 +xgxs_rx_lane_map_53.0=0x3120 +xgxs_rx_lane_map_57.0=0x3120 +xgxs_rx_lane_map_61.0=0x3120 +xgxs_rx_lane_map_65.0=0x3120 +xgxs_rx_lane_map_69.0=0x3120 +xgxs_rx_lane_map_73.0=0x3120 +xgxs_rx_lane_map_77.0=0x3120 +xgxs_rx_lane_map_81.0=0x3120 +xgxs_rx_lane_map_85.0=0x3120 +xgxs_rx_lane_map_89.0=0x3120 +xgxs_rx_lane_map_93.0=0x3120 +xgxs_rx_lane_map_97.0=0x1302 +xgxs_rx_lane_map_98.0=0x1302 +xgxs_rx_lane_map_99.0=0x0213 +xgxs_tx_lane_map_100.0=0x0213 +xgxs_tx_lane_map_101.0=0x0123 +xgxs_tx_lane_map_102.0=0x0123 +xgxs_tx_lane_map_103.0=0x0123 +xgxs_tx_lane_map_104.0=0x0123 + +xgxs_tx_lane_map_1.0=0x0123 +xgxs_tx_lane_map_5.0=0x0123 +xgxs_tx_lane_map_9.0=0x0123 +xgxs_tx_lane_map_13.0=0x0123 +xgxs_tx_lane_map_17.0=0x1302 +xgxs_tx_lane_map_21.0=0x1302 +xgxs_tx_lane_map_25.0=0x1302 +xgxs_tx_lane_map_29.0=0x1302 +xgxs_tx_lane_map_33.0=0x3120 +xgxs_tx_lane_map_37.0=0x3120 +xgxs_tx_lane_map_41.0=0x3120 +xgxs_tx_lane_map_45.0=0x3120 +xgxs_tx_lane_map_49.0=0x3120 +xgxs_tx_lane_map_53.0=0x3120 +xgxs_tx_lane_map_57.0=0x3120 +xgxs_tx_lane_map_61.0=0x3120 +xgxs_tx_lane_map_65.0=0x3120 +xgxs_tx_lane_map_69.0=0x3120 +xgxs_tx_lane_map_73.0=0x3120 +xgxs_tx_lane_map_77.0=0x3120 +xgxs_tx_lane_map_81.0=0x3120 +xgxs_tx_lane_map_85.0=0x3120 +xgxs_tx_lane_map_89.0=0x3120 +xgxs_tx_lane_map_93.0=0x3120 +xgxs_tx_lane_map_97.0=0x2031 +xgxs_tx_lane_map_98.0=0x2031 +xgxs_tx_lane_map_99.0=0x0213 +xgxs_rx_lane_map_100.0=0x0213 +xgxs_rx_lane_map_101.0=0x0123 +xgxs_rx_lane_map_102.0=0x0123 +xgxs_rx_lane_map_103.0=0x0123 +xgxs_rx_lane_map_104.0=0x0123 + +serdes_firmware_mode_1.0=1 +serdes_firmware_mode_5.0=1 +serdes_firmware_mode_9.0=1 +serdes_firmware_mode_13.0=1 +serdes_firmware_mode_17.0=2 +serdes_firmware_mode_21.0=2 +serdes_firmware_mode_25.0=2 +serdes_firmware_mode_29.0=2 +serdes_firmware_mode_33.0=2 +serdes_firmware_mode_37.0=2 +serdes_firmware_mode_41.0=2 +serdes_firmware_mode_45.0=2 +serdes_firmware_mode_49.0=2 +serdes_firmware_mode_53.0=2 +serdes_firmware_mode_57.0=2 +serdes_firmware_mode_61.0=2 +serdes_firmware_mode_65.0=2 +serdes_firmware_mode_66.0=2 +serdes_firmware_mode_67.0=2 +serdes_firmware_mode_68.0=2 +serdes_firmware_mode_69.0=2 +serdes_firmware_mode_70.0=2 +serdes_firmware_mode_71.0=2 +serdes_firmware_mode_72.0=2 +serdes_firmware_mode_73.0=2 +serdes_firmware_mode_74.0=2 +serdes_firmware_mode_75.0=2 +serdes_firmware_mode_76.0=2 +serdes_firmware_mode_77.0=2 +serdes_firmware_mode_78.0=2 +serdes_firmware_mode_79.0=2 +serdes_firmware_mode_80.0=2 +serdes_firmware_mode_81.0=2 +serdes_firmware_mode_82.0=2 +serdes_firmware_mode_83.0=2 +serdes_firmware_mode_84.0=2 +serdes_firmware_mode_85.0=2 +serdes_firmware_mode_86.0=2 +serdes_firmware_mode_87.0=2 +serdes_firmware_mode_88.0=2 +serdes_firmware_mode_89.0=2 +serdes_firmware_mode_90.0=2 +serdes_firmware_mode_91.0=2 +serdes_firmware_mode_92.0=2 +serdes_firmware_mode_93.0=2 +serdes_firmware_mode_94.0=2 +serdes_firmware_mode_95.0=2 +serdes_firmware_mode_96.0=2 +serdes_firmware_mode_97.0=2 +serdes_firmware_mode_98.0=2 +serdes_firmware_mode_99.0=2 +serdes_firmware_mode_100.0=2 +serdes_firmware_mode_101.0=1 +serdes_firmware_mode_102.0=1 +serdes_firmware_mode_103.0=1 +serdes_firmware_mode_104.0=1 diff --git a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/sai.profile b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/sai.profile index 938d37180676..27d83fcc20e9 100644 --- a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/sai.profile +++ b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/sai.profile @@ -1,2 +1,2 @@ -SAI_INIT_CONFIG_FILE=/etc/bcm/td2-a7050-qx32-32x40G.config.bcm +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-a7050-qx32-32x40G.config.bcm SAI_NUM_ECMP_MEMBERS=32 diff --git a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/td2-a7050-qx32-32x40G.config.bcm b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/td2-a7050-qx32-32x40G.config.bcm new file mode 100644 index 000000000000..701a8480dcb3 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/td2-a7050-qx32-32x40G.config.bcm @@ -0,0 +1,873 @@ +#/****************************************************************************** +# * +# * File: config.bcm.cloverdales (7050-QX32) +# * Name: +# * +# * Description: This file contains SDK properties for an Arista +# * Cloverdales platform. +# * +# *----------------------------------------------------------------------------- +# ******************************************************************************/ +#################################################################### +# BCM Config file for Cloverdale platform +# - 32x40g Portmode + +# Old LPM only configuration +# l2_mem_entries=163840 +# l3_mem_entries=90112 +# l3_alpm_enable=0 +# ipv6_lpm_128b_enable=0 +# +# ALPM enable +l3_alpm_enable=2 +ipv6_lpm_128b_enable=1 +l2_mem_entries=32768 +l3_mem_entries=16384 + +# From old config file +os=unix +higig2_hdr_mode=1 + +# Parity +parity_correction=1 +parity_enable=1 +stat_if_parity_enable=0 + +# l2 thread related config vars +l2xmsg_hostbuf_size=8192 +l2xmsg_mode=1 + +bcm_num_cos=8 +bcm_stat_interval=2000000 +lls_num_l2uc=12 +max_vp_lags=0 +miim_intr_enable=0 +mmu_lossless=0 +module_64ports=0 +scache_filename=/tmp/scache +schan_intr_enable=0 +stable_size=0x2000000 +tdma_timeout_usec=5000000 + +# for GLC transceiver +phy_an_c73=0x0 +phy_an_c37=0x3 + +########################### +#port_init_speed_xe=40000 +#port_init_speed_xe.0=40000 + +#load_firmware=0x0102 +load_firmware.0=2 + +######################### +# All ports are in oversubscription mode +pbmp_oversubscribe=0x1fffffffffffffffffffffffffe +pbmp_xport_xe.0=0x1fffffffe + +phy_84328_1.0=1 +phy_84328_2.0=1 +phy_84328_29.0=1 +phy_84328_3.0=1 +phy_84328_30.0=1 +phy_84328_31.0=1 +phy_84328_32.0=1 +phy_84328_4.0=1 +phy_an_c37_1.0=3 +phy_an_c37_10.0=3 +phy_an_c37_11.0=3 +phy_an_c37_12.0=3 +phy_an_c37_13.0=3 +phy_an_c37_14.0=3 +phy_an_c37_15.0=3 +phy_an_c37_16.0=3 +phy_an_c37_17.0=3 +phy_an_c37_18.0=3 +phy_an_c37_19.0=3 +phy_an_c37_2.0=3 +phy_an_c37_20.0=3 +phy_an_c37_21.0=3 +phy_an_c37_22.0=3 +phy_an_c37_23.0=3 +phy_an_c37_24.0=3 +phy_an_c37_25.0=3 +phy_an_c37_26.0=3 +phy_an_c37_27.0=3 +phy_an_c37_28.0=3 +phy_an_c37_29.0=3 +phy_an_c37_3.0=3 +phy_an_c37_30.0=3 +phy_an_c37_31.0=3 +phy_an_c37_32.0=3 +phy_an_c37_4.0=3 +phy_an_c37_5.0=3 +phy_an_c37_6.0=3 +phy_an_c37_7.0=3 +phy_an_c37_8.0=3 +phy_an_c37_9.0=3 +phy_an_c73_1.0=1 +phy_an_c73_10.0=1 +phy_an_c73_11.0=1 +phy_an_c73_12.0=1 +phy_an_c73_13.0=1 +phy_an_c73_14.0=1 +phy_an_c73_15.0=1 +phy_an_c73_16.0=1 +phy_an_c73_17.0=1 +phy_an_c73_18.0=1 +phy_an_c73_19.0=1 +phy_an_c73_2.0=1 +phy_an_c73_20.0=1 +phy_an_c73_21.0=1 +phy_an_c73_22.0=1 +phy_an_c73_23.0=1 +phy_an_c73_24.0=1 +phy_an_c73_25.0=1 +phy_an_c73_26.0=1 +phy_an_c73_27.0=1 +phy_an_c73_28.0=1 +phy_an_c73_29.0=1 +phy_an_c73_3.0=1 +phy_an_c73_30.0=1 +phy_an_c73_31.0=1 +phy_an_c73_32.0=1 +phy_an_c73_4.0=1 +phy_an_c73_5.0=1 +phy_an_c73_6.0=1 +phy_an_c73_7.0=1 +phy_an_c73_8.0=1 +phy_an_c73_9.0=1 +phy_aux_voltage_enable_1.0=0x1 +phy_aux_voltage_enable_2.0=0x1 +phy_aux_voltage_enable_29.0=0x1 +phy_aux_voltage_enable_3.0=0x1 +phy_aux_voltage_enable_30.0=0x1 +phy_aux_voltage_enable_31.0=0x1 +phy_aux_voltage_enable_32.0=0x1 +phy_aux_voltage_enable_4.0=0x1 +phy_ext_rom_boot.0=0 +phy_ext_rom_boot_1.0=0x0 +phy_ext_rom_boot_2.0=0x0 +phy_ext_rom_boot_29.0=0x0 +phy_ext_rom_boot_3.0=0x0 +phy_ext_rom_boot_30.0=0x0 +phy_ext_rom_boot_31.0=0x0 +phy_ext_rom_boot_32.0=0x0 +phy_ext_rom_boot_4.0=0x0 +phy_line_tx_mode_1.0=1 +phy_line_tx_mode_2.0=1 +phy_line_tx_mode_29.0=1 +phy_line_tx_mode_3.0=1 +phy_line_tx_mode_30.0=1 +phy_line_tx_mode_31.0=1 +phy_line_tx_mode_32.0=1 +phy_line_tx_mode_4.0=1 +phy_rx_polarity_flip_1.0=0x0 +phy_rx_polarity_flip_2.0=0x0 +phy_rx_polarity_flip_29.0=0x0 +phy_rx_polarity_flip_3.0=0x0 +phy_rx_polarity_flip_30.0=0x0 +phy_rx_polarity_flip_31.0=0x0 +phy_rx_polarity_flip_32.0=0x0 +phy_rx_polarity_flip_4.0=0x0 +phy_system_tx_mode_1.0=0 +phy_system_tx_mode_2.0=0 +phy_system_tx_mode_29.0=0 +phy_system_tx_mode_3.0=0 +phy_system_tx_mode_30.0=0 +phy_system_tx_mode_31.0=0 +phy_system_tx_mode_32.0=0 +phy_system_tx_mode_4.0=0 +phy_tx_polarity_flip_1.0=0x0 +phy_tx_polarity_flip_2.0=0x0 +phy_tx_polarity_flip_29.0=0x0 +phy_tx_polarity_flip_3.0=0x0 +phy_tx_polarity_flip_30.0=0x0 +phy_tx_polarity_flip_31.0=0x0 +phy_tx_polarity_flip_32.0=0x0 +phy_tx_polarity_flip_4.0=0x0 +phy_xaui_rx_polarity_flip_1.0=0x0 +phy_xaui_rx_polarity_flip_10.0=0x0 +phy_xaui_rx_polarity_flip_11.0=0x0 +phy_xaui_rx_polarity_flip_12.0=0x0 +phy_xaui_rx_polarity_flip_13.0=0x0 +phy_xaui_rx_polarity_flip_14.0=0x0 +phy_xaui_rx_polarity_flip_15.0=0x0 +phy_xaui_rx_polarity_flip_16.0=0x0 +phy_xaui_rx_polarity_flip_17.0=0x0 +phy_xaui_rx_polarity_flip_18.0=0x0 +phy_xaui_rx_polarity_flip_19.0=0x0 +phy_xaui_rx_polarity_flip_2.0=0x0 +phy_xaui_rx_polarity_flip_20.0=0x0 +phy_xaui_rx_polarity_flip_21.0=0x0 +phy_xaui_rx_polarity_flip_22.0=0x0 +phy_xaui_rx_polarity_flip_23.0=0x0 +phy_xaui_rx_polarity_flip_24.0=0x0 +phy_xaui_rx_polarity_flip_25.0=0x0 +phy_xaui_rx_polarity_flip_26.0=0x0 +phy_xaui_rx_polarity_flip_27.0=0x0 +phy_xaui_rx_polarity_flip_28.0=0x0 +phy_xaui_rx_polarity_flip_29.0=0x0 +phy_xaui_rx_polarity_flip_3.0=0x0 +phy_xaui_rx_polarity_flip_30.0=0x0 +phy_xaui_rx_polarity_flip_31.0=0x0 +phy_xaui_rx_polarity_flip_32.0=0x0 +phy_xaui_rx_polarity_flip_4.0=0x0 +phy_xaui_rx_polarity_flip_5.0=0x0 +phy_xaui_rx_polarity_flip_6.0=0x0 +phy_xaui_rx_polarity_flip_7.0=0x0 +phy_xaui_rx_polarity_flip_8.0=0x0 +phy_xaui_rx_polarity_flip_9.0=0x0 +phy_xaui_tx_polarity_flip_1.0=0x0 +phy_xaui_tx_polarity_flip_10.0=0x0 +phy_xaui_tx_polarity_flip_11.0=0x0 +phy_xaui_tx_polarity_flip_12.0=0x0 +phy_xaui_tx_polarity_flip_13.0=0x0 +phy_xaui_tx_polarity_flip_14.0=0x0 +phy_xaui_tx_polarity_flip_15.0=0x0 +phy_xaui_tx_polarity_flip_16.0=0x0 +phy_xaui_tx_polarity_flip_17.0=0x0 +phy_xaui_tx_polarity_flip_18.0=0x0 +phy_xaui_tx_polarity_flip_19.0=0x0 +phy_xaui_tx_polarity_flip_2.0=0x0 +phy_xaui_tx_polarity_flip_20.0=0x0 +phy_xaui_tx_polarity_flip_21.0=0x0 +phy_xaui_tx_polarity_flip_22.0=0x0 +phy_xaui_tx_polarity_flip_23.0=0x0 +phy_xaui_tx_polarity_flip_24.0=0x0 +phy_xaui_tx_polarity_flip_25.0=0x0 +phy_xaui_tx_polarity_flip_26.0=0x0 +phy_xaui_tx_polarity_flip_27.0=0x0 +phy_xaui_tx_polarity_flip_28.0=0x0 +phy_xaui_tx_polarity_flip_29.0=0x0 +phy_xaui_tx_polarity_flip_3.0=0x0 +phy_xaui_tx_polarity_flip_30.0=0x0 +phy_xaui_tx_polarity_flip_31.0=0x0 +phy_xaui_tx_polarity_flip_32.0=0x0 +phy_xaui_tx_polarity_flip_4.0=0x0 +phy_xaui_tx_polarity_flip_5.0=0x0 +phy_xaui_tx_polarity_flip_6.0=0x0 +phy_xaui_tx_polarity_flip_7.0=0x0 +phy_xaui_tx_polarity_flip_8.0=0x0 +phy_xaui_tx_polarity_flip_9.0=0x0 +port_init_autoneg_10.0=0 +port_init_autoneg_11.0=0 +port_init_autoneg_12.0=0 +port_init_autoneg_13.0=0 +port_init_autoneg_14.0=0 +port_init_autoneg_15.0=0 +port_init_autoneg_16.0=0 +port_init_autoneg_17.0=0 +port_init_autoneg_18.0=0 +port_init_autoneg_19.0=0 +port_init_autoneg_20.0=0 +port_init_autoneg_21.0=0 +port_init_autoneg_22.0=0 +port_init_autoneg_23.0=0 +port_init_autoneg_24.0=0 +port_init_autoneg_25.0=0 +port_init_autoneg_26.0=0 +port_init_autoneg_27.0=0 +port_init_autoneg_28.0=0 +port_init_autoneg_5.0=0 +port_init_autoneg_6.0=0 +port_init_autoneg_7.0=0 +port_init_autoneg_8.0=0 +port_init_autoneg_9.0=0 +port_init_cl72_hg.0=0x11 +port_phy_addr_1.0=0x4 +port_phy_addr_10.0=0x7f +port_phy_addr_11.0=0x7f +port_phy_addr_12.0=0x7f +port_phy_addr_13.0=0x7f +port_phy_addr_14.0=0x7f +port_phy_addr_15.0=0x7f +port_phy_addr_16.0=0x7f +port_phy_addr_17.0=0x7f +port_phy_addr_18.0=0x7f +port_phy_addr_19.0=0x7f +port_phy_addr_2.0=0x0 +port_phy_addr_20.0=0x7f +port_phy_addr_21.0=0x7f +port_phy_addr_22.0=0x7f +port_phy_addr_23.0=0x7f +port_phy_addr_24.0=0x7f +port_phy_addr_25.0=0x7f +port_phy_addr_26.0=0x7f +port_phy_addr_27.0=0x7f +port_phy_addr_28.0=0x7f +port_phy_addr_29.0=0x54 +port_phy_addr_3.0=0x2c +port_phy_addr_30.0=0x50 +port_phy_addr_31.0=0x7c +port_phy_addr_32.0=0x78 +port_phy_addr_4.0=0x28 +port_phy_addr_5.0=0x7f +port_phy_addr_6.0=0x7f +port_phy_addr_7.0=0x7f +port_phy_addr_8.0=0x7f +port_phy_addr_9.0=0x7f +port_phy_clause_1.0=0x2d +port_phy_clause_2.0=0x2d +port_phy_clause_29.0=0x2d +port_phy_clause_3.0=0x2d +port_phy_clause_30.0=0x2d +port_phy_clause_31.0=0x2d +port_phy_clause_32.0=0x2d +port_phy_clause_4.0=0x2d +port_phy_id0_1.0=0x600d +port_phy_id0_2.0=0x600d +port_phy_id0_29.0=0x600d +port_phy_id0_3.0=0x600d +port_phy_id0_30.0=0x600d +port_phy_id0_31.0=0x600d +port_phy_id0_32.0=0x600d +port_phy_id0_4.0=0x600d +port_phy_id1_1.0=0x8500 +port_phy_id1_2.0=0x8500 +port_phy_id1_29.0=0x8500 +port_phy_id1_3.0=0x8500 +port_phy_id1_30.0=0x8500 +port_phy_id1_31.0=0x8500 +port_phy_id1_32.0=0x8500 +port_phy_id1_4.0=0x8500 +portmap_1.0=125:40 +portmap_10.0=33:40 +portmap_11.0=45:40 +portmap_12.0=41:40 +portmap_13.0=53:40 +portmap_14.0=49:40 +portmap_15.0=69:40 +portmap_16.0=65:40 +portmap_17.0=77:40 +portmap_18.0=73:40 +portmap_19.0=93:40 +portmap_2.0=121:40 +portmap_20.0=89:40 +portmap_21.0=101:40 +portmap_22.0=97:40 +portmap_23.0=109:40 +portmap_24.0=105:40 +portmap_25.0=61:40 +portmap_26.0=57:40 +portmap_27.0=81:40 +portmap_28.0=85:40 +portmap_29.0=117:40 +portmap_3.0=13:40 +portmap_30.0=113:40 +portmap_31.0=5:40 +portmap_32.0=1:40 +portmap_4.0=9:40 +portmap_5.0=17:40 +portmap_6.0=21:40 +portmap_7.0=25:40 +portmap_8.0=29:40 +portmap_9.0=37:40 +serdes_firmware_mode_1.0=1 +serdes_firmware_mode_10.0=2 +serdes_firmware_mode_11.0=2 +serdes_firmware_mode_12.0=2 +serdes_firmware_mode_13.0=2 +serdes_firmware_mode_14.0=2 +serdes_firmware_mode_15.0=2 +serdes_firmware_mode_16.0=2 +serdes_firmware_mode_17.0=2 +serdes_firmware_mode_18.0=2 +serdes_firmware_mode_19.0=2 +serdes_firmware_mode_2.0=1 +serdes_firmware_mode_20.0=2 +serdes_firmware_mode_21.0=2 +serdes_firmware_mode_22.0=2 +serdes_firmware_mode_23.0=2 +serdes_firmware_mode_24.0=2 +serdes_firmware_mode_25.0=2 +serdes_firmware_mode_26.0=2 +serdes_firmware_mode_27.0=2 +serdes_firmware_mode_28.0=2 +serdes_firmware_mode_29.0=1 +serdes_firmware_mode_3.0=1 +serdes_firmware_mode_30.0=1 +serdes_firmware_mode_31.0=1 +serdes_firmware_mode_32.0=1 +serdes_firmware_mode_4.0=1 +serdes_firmware_mode_5.0=2 +serdes_firmware_mode_6.0=2 +serdes_firmware_mode_7.0=2 +serdes_firmware_mode_8.0=2 +serdes_firmware_mode_9.0=2 +xgxs_lcpll_xtal_refclk.0=1 +xgxs_rx_lane_map_1.0=0x0123 +xgxs_rx_lane_map_10.0=0x3120 +xgxs_rx_lane_map_11.0=0x3120 +xgxs_rx_lane_map_12.0=0x3120 +xgxs_rx_lane_map_13.0=0x3120 +xgxs_rx_lane_map_14.0=0x3120 +xgxs_rx_lane_map_15.0=0x3120 +xgxs_rx_lane_map_16.0=0x3120 +xgxs_rx_lane_map_17.0=0x3120 +xgxs_rx_lane_map_18.0=0x3120 +xgxs_rx_lane_map_19.0=0x3120 +xgxs_rx_lane_map_2.0=0x0123 +xgxs_rx_lane_map_20.0=0x3120 +xgxs_rx_lane_map_21.0=0x3120 +xgxs_rx_lane_map_22.0=0x3120 +xgxs_rx_lane_map_23.0=0x3120 +xgxs_rx_lane_map_24.0=0x3120 +xgxs_rx_lane_map_25.0=0x2031 +xgxs_rx_lane_map_26.0=0x2031 +xgxs_rx_lane_map_27.0=0x0213 +xgxs_rx_lane_map_28.0=0x0213 +xgxs_rx_lane_map_29.0=0x0123 +xgxs_rx_lane_map_3.0=0x0123 +xgxs_rx_lane_map_30.0=0x0123 +xgxs_rx_lane_map_31.0=0x0123 +xgxs_rx_lane_map_32.0=0x0123 +xgxs_rx_lane_map_4.0=0x0123 +xgxs_rx_lane_map_5.0=0x2031 +xgxs_rx_lane_map_6.0=0x2031 +xgxs_rx_lane_map_7.0=0x2031 +xgxs_rx_lane_map_8.0=0x2031 +xgxs_rx_lane_map_9.0=0x3120 +xgxs_tx_lane_map_1.0=0x0123 +xgxs_tx_lane_map_10.0=0x3120 +xgxs_tx_lane_map_11.0=0x3120 +xgxs_tx_lane_map_12.0=0x3120 +xgxs_tx_lane_map_13.0=0x3120 +xgxs_tx_lane_map_14.0=0x3120 +xgxs_tx_lane_map_15.0=0x3120 +xgxs_tx_lane_map_16.0=0x3120 +xgxs_tx_lane_map_17.0=0x3120 +xgxs_tx_lane_map_18.0=0x3120 +xgxs_tx_lane_map_19.0=0x3120 +xgxs_tx_lane_map_2.0=0x0123 +xgxs_tx_lane_map_20.0=0x3120 +xgxs_tx_lane_map_21.0=0x3120 +xgxs_tx_lane_map_22.0=0x3120 +xgxs_tx_lane_map_23.0=0x3120 +xgxs_tx_lane_map_24.0=0x3120 +xgxs_tx_lane_map_25.0=0x2031 +xgxs_tx_lane_map_26.0=0x2031 +xgxs_tx_lane_map_27.0=0x0213 +xgxs_tx_lane_map_28.0=0x0213 +xgxs_tx_lane_map_29.0=0x0123 +xgxs_tx_lane_map_3.0=0x0123 +xgxs_tx_lane_map_30.0=0x0123 +xgxs_tx_lane_map_31.0=0x0123 +xgxs_tx_lane_map_32.0=0x0123 +xgxs_tx_lane_map_4.0=0x0123 +xgxs_tx_lane_map_5.0=0x1302 +xgxs_tx_lane_map_6.0=0x1302 +xgxs_tx_lane_map_7.0=0x1302 +xgxs_tx_lane_map_8.0=0x1302 +xgxs_tx_lane_map_9.0=0x3120 + +########################################## +#skip_L2_USER_ENTRY=0 +phy_aux_voltage_enable=1 +############################### +serdes_fiber_pref=1 +############################### +mdio_output_delay.0=0x0d +############################### +serdes_sgmii_m=0 +xgxs_lcpll_xtal_refclk=1 +xgxs_lcpll_xtal_refclk.1=1 +xgxs_lcpll_xtal_refclk.2=1 +xgxs_lcpll_xtal_refclk.3=1 +tdma_intr_enable=1 +tslam_intr_enable=1 +tslam_dma_enable.2=1 +tslam_dma_enable.3=1 +#dport_map_port=0 +#dport_map_enable=0 +#dport_map_indexed=0 +#bcm_xlate_port_enable.0=0 +#xgxs_pdetect_1=0 +table_dma_enable.0=1 +table_dma_enable.1=1 +table_dma_enable.2=1 +table_dma_enable.3=1 +serdes_driver_current_lane0_1=2 +serdes_pre_driver_current_lane0_1=2 +serdes_preemphasis_lane0_1=0x8fc0 +serdes_driver_current_lane1_1=2 +serdes_pre_driver_current_lane1_1=2 +serdes_preemphasis_lane1_1=0x8fc0 +serdes_driver_current_lane2_1=2 +serdes_pre_driver_current_lane2_1=2 +serdes_preemphasis_lane2_1=0x8fc0 +serdes_driver_current_lane3_1=2 +serdes_pre_driver_current_lane3_1=2 +serdes_preemphasis_lane3_1=0x8fc0 +serdes_driver_current_lane0_2=3 +serdes_pre_driver_current_lane0_2=2 +serdes_preemphasis_lane0_2=0x8fc0 +serdes_driver_current_lane1_2=3 +serdes_pre_driver_current_lane1_2=2 +serdes_preemphasis_lane1_2=0x8fc0 +serdes_driver_current_lane2_2=3 +serdes_pre_driver_current_lane2_2=2 +serdes_preemphasis_lane2_2=0x8fc0 +serdes_driver_current_lane3_2=3 +serdes_pre_driver_current_lane3_2=2 +serdes_preemphasis_lane3_2=0x8fc0 +serdes_driver_current_lane0_3=2 +serdes_pre_driver_current_lane0_3=2 +serdes_preemphasis_lane0_3=0x8fc0 +serdes_driver_current_lane1_3=2 +serdes_pre_driver_current_lane1_3=2 +serdes_preemphasis_lane1_3=0x8fc0 +serdes_driver_current_lane2_3=2 +serdes_pre_driver_current_lane2_3=2 +serdes_preemphasis_lane2_3=0x8fc0 +serdes_driver_current_lane3_3=2 +serdes_pre_driver_current_lane3_3=2 +serdes_preemphasis_lane3_3=0x8fc0 +serdes_driver_current_lane0_4=2 +serdes_pre_driver_current_lane0_4=2 +serdes_preemphasis_lane0_4=0x8fc0 +serdes_driver_current_lane1_4=2 +serdes_pre_driver_current_lane1_4=2 +serdes_preemphasis_lane1_4=0x8fc0 +serdes_driver_current_lane2_4=2 +serdes_pre_driver_current_lane2_4=2 +serdes_preemphasis_lane2_4=0x8fc0 +serdes_driver_current_lane3_4=2 +serdes_pre_driver_current_lane3_4=2 +serdes_preemphasis_lane3_4=0x8fc0 +serdes_driver_current_lane0_5=4 +serdes_pre_driver_current_lane0_5=4 +serdes_preemphasis_lane0_5=0xbf00 +serdes_driver_current_lane1_5=4 +serdes_pre_driver_current_lane1_5=4 +serdes_preemphasis_lane1_5=0xbf00 +serdes_driver_current_lane2_5=4 +serdes_pre_driver_current_lane2_5=4 +serdes_preemphasis_lane2_5=0xbf00 +serdes_driver_current_lane3_5=4 +serdes_pre_driver_current_lane3_5=4 +serdes_preemphasis_lane3_5=0xbf00 +serdes_driver_current_lane0_6=4 +serdes_pre_driver_current_lane0_6=4 +serdes_preemphasis_lane0_6=0xbb10 +serdes_driver_current_lane1_6=4 +serdes_pre_driver_current_lane1_6=4 +serdes_preemphasis_lane1_6=0xbb10 +serdes_driver_current_lane2_6=4 +serdes_pre_driver_current_lane2_6=4 +serdes_preemphasis_lane2_6=0xbb10 +serdes_driver_current_lane3_6=4 +serdes_pre_driver_current_lane3_6=4 +serdes_preemphasis_lane3_6=0xbb10 +serdes_driver_current_lane0_7=3 +serdes_pre_driver_current_lane0_7=3 +serdes_preemphasis_lane0_7=0xcad0 +serdes_driver_current_lane1_7=3 +serdes_pre_driver_current_lane1_7=3 +serdes_preemphasis_lane1_7=0xcad0 +serdes_driver_current_lane2_7=3 +serdes_pre_driver_current_lane2_7=3 +serdes_preemphasis_lane2_7=0xcad0 +serdes_driver_current_lane3_7=3 +serdes_pre_driver_current_lane3_7=3 +serdes_preemphasis_lane3_7=0xcad0 +serdes_driver_current_lane0_8=3 +serdes_pre_driver_current_lane0_8=3 +serdes_preemphasis_lane0_8=0xcad0 +serdes_driver_current_lane1_8=3 +serdes_pre_driver_current_lane1_8=3 +serdes_preemphasis_lane1_8=0xcad0 +serdes_driver_current_lane2_8=3 +serdes_pre_driver_current_lane2_8=3 +serdes_preemphasis_lane2_8=0xcad0 +serdes_driver_current_lane3_8=3 +serdes_pre_driver_current_lane3_8=3 +serdes_preemphasis_lane3_8=0xcad0 +serdes_driver_current_lane0_9=3 +serdes_pre_driver_current_lane0_9=3 +serdes_preemphasis_lane0_9=0xc2f0 +serdes_driver_current_lane1_9=3 +serdes_pre_driver_current_lane1_9=3 +serdes_preemphasis_lane1_9=0xc2f0 +serdes_driver_current_lane2_9=3 +serdes_pre_driver_current_lane2_9=3 +serdes_preemphasis_lane2_9=0xc2f0 +serdes_driver_current_lane3_9=3 +serdes_pre_driver_current_lane3_9=3 +serdes_preemphasis_lane3_9=0xc2f0 +serdes_driver_current_lane0_10=3 +serdes_pre_driver_current_lane0_10=3 +serdes_preemphasis_lane0_10=0xc6e0 +serdes_driver_current_lane1_10=3 +serdes_pre_driver_current_lane1_10=3 +serdes_preemphasis_lane1_10=0xc6e0 +serdes_driver_current_lane2_10=3 +serdes_pre_driver_current_lane2_10=3 +serdes_preemphasis_lane2_10=0xc6e0 +serdes_driver_current_lane3_10=3 +serdes_pre_driver_current_lane3_10=3 +serdes_preemphasis_lane3_10=0xc6e0 +serdes_driver_current_lane0_11=3 +serdes_pre_driver_current_lane0_11=3 +serdes_preemphasis_lane0_11=0xc2f0 +serdes_driver_current_lane1_11=3 +serdes_pre_driver_current_lane1_11=3 +serdes_preemphasis_lane1_11=0xc2f0 +serdes_driver_current_lane2_11=3 +serdes_pre_driver_current_lane2_11=3 +serdes_preemphasis_lane2_11=0xc2f0 +serdes_driver_current_lane3_11=3 +serdes_pre_driver_current_lane3_11=3 +serdes_preemphasis_lane3_11=0xc2f0 +serdes_driver_current_lane0_12=3 +serdes_pre_driver_current_lane0_12=3 +serdes_preemphasis_lane0_12=0xc2f0 +serdes_driver_current_lane1_12=3 +serdes_pre_driver_current_lane1_12=3 +serdes_preemphasis_lane1_12=0xc2f0 +serdes_driver_current_lane2_12=3 +serdes_pre_driver_current_lane2_12=3 +serdes_preemphasis_lane2_12=0xc2f0 +serdes_driver_current_lane3_12=3 +serdes_pre_driver_current_lane3_12=3 +serdes_preemphasis_lane3_12=0xc2f0 +serdes_driver_current_lane0_13=3 +serdes_pre_driver_current_lane0_13=3 +serdes_preemphasis_lane0_13=0xc2f0 +serdes_driver_current_lane1_13=3 +serdes_pre_driver_current_lane1_13=3 +serdes_preemphasis_lane1_13=0xc2f0 +serdes_driver_current_lane2_13=3 +serdes_pre_driver_current_lane2_13=3 +serdes_preemphasis_lane2_13=0xc2f0 +serdes_driver_current_lane3_13=3 +serdes_pre_driver_current_lane3_13=3 +serdes_preemphasis_lane3_13=0xc2f0 +serdes_driver_current_lane0_14=3 +serdes_pre_driver_current_lane0_14=3 +serdes_preemphasis_lane0_14=0xc2f0 +serdes_driver_current_lane1_14=3 +serdes_pre_driver_current_lane1_14=3 +serdes_preemphasis_lane1_14=0xc2f0 +serdes_driver_current_lane2_14=3 +serdes_pre_driver_current_lane2_14=3 +serdes_preemphasis_lane2_14=0xc2f0 +serdes_driver_current_lane3_14=3 +serdes_pre_driver_current_lane3_14=3 +serdes_preemphasis_lane3_14=0xc2f0 +serdes_driver_current_lane0_15=3 +serdes_pre_driver_current_lane0_15=3 +serdes_preemphasis_lane0_15=0xc2f0 +serdes_driver_current_lane1_15=3 +serdes_pre_driver_current_lane1_15=3 +serdes_preemphasis_lane1_15=0xc2f0 +serdes_driver_current_lane2_15=3 +serdes_pre_driver_current_lane2_15=3 +serdes_preemphasis_lane2_15=0xc2f0 +serdes_driver_current_lane3_15=3 +serdes_pre_driver_current_lane3_15=3 +serdes_preemphasis_lane3_15=0xc2f0 +serdes_driver_current_lane0_16=3 +serdes_pre_driver_current_lane0_16=3 +serdes_preemphasis_lane0_16=0xc2f0 +serdes_driver_current_lane1_16=3 +serdes_pre_driver_current_lane1_16=3 +serdes_preemphasis_lane1_16=0xc2f0 +serdes_driver_current_lane2_16=3 +serdes_pre_driver_current_lane2_16=3 +serdes_preemphasis_lane2_16=0xc2f0 +serdes_driver_current_lane3_16=3 +serdes_pre_driver_current_lane3_16=3 +serdes_preemphasis_lane3_16=0xc2f0 +serdes_driver_current_lane0_17=3 +serdes_pre_driver_current_lane0_17=3 +serdes_preemphasis_lane0_17=0xc2f0 +serdes_driver_current_lane1_17=3 +serdes_pre_driver_current_lane1_17=3 +serdes_preemphasis_lane1_17=0xc2f0 +serdes_driver_current_lane2_17=3 +serdes_pre_driver_current_lane2_17=3 +serdes_preemphasis_lane2_17=0xc2f0 +serdes_driver_current_lane3_17=3 +serdes_pre_driver_current_lane3_17=3 +serdes_preemphasis_lane3_17=0xc2f0 +serdes_driver_current_lane0_18=3 +serdes_pre_driver_current_lane0_18=3 +serdes_preemphasis_lane0_18=0xc2f0 +serdes_driver_current_lane1_18=3 +serdes_pre_driver_current_lane1_18=3 +serdes_preemphasis_lane1_18=0xc2f0 +serdes_driver_current_lane2_18=3 +serdes_pre_driver_current_lane2_18=3 +serdes_preemphasis_lane2_18=0xc2f0 +serdes_driver_current_lane3_18=3 +serdes_pre_driver_current_lane3_18=3 +serdes_preemphasis_lane3_18=0xc2f0 +serdes_driver_current_lane0_19=3 +serdes_pre_driver_current_lane0_19=3 +serdes_preemphasis_lane0_19=0xc2f0 +serdes_driver_current_lane1_19=3 +serdes_pre_driver_current_lane1_19=3 +serdes_preemphasis_lane1_19=0xc2f0 +serdes_driver_current_lane2_19=3 +serdes_pre_driver_current_lane2_19=3 +serdes_preemphasis_lane2_19=0xc2f0 +serdes_driver_current_lane3_19=3 +serdes_pre_driver_current_lane3_19=3 +serdes_preemphasis_lane3_19=0xc2f0 +serdes_driver_current_lane0_20=3 +serdes_pre_driver_current_lane0_20=3 +serdes_preemphasis_lane0_20=0xc2f0 +serdes_driver_current_lane1_20=3 +serdes_pre_driver_current_lane1_20=3 +serdes_preemphasis_lane1_20=0xc2f0 +serdes_driver_current_lane2_20=3 +serdes_pre_driver_current_lane2_20=3 +serdes_preemphasis_lane2_20=0xc2f0 +serdes_driver_current_lane3_20=3 +serdes_pre_driver_current_lane3_20=3 +serdes_preemphasis_lane3_20=0xc2f0 +serdes_driver_current_lane0_21=3 +serdes_pre_driver_current_lane0_21=3 +serdes_preemphasis_lane0_21=0xc6e0 +serdes_driver_current_lane1_21=3 +serdes_pre_driver_current_lane1_21=3 +serdes_preemphasis_lane1_21=0xc6e0 +serdes_driver_current_lane2_21=3 +serdes_pre_driver_current_lane2_21=3 +serdes_preemphasis_lane2_21=0xc6e0 +serdes_driver_current_lane3_21=3 +serdes_pre_driver_current_lane3_21=3 +serdes_preemphasis_lane3_21=0xc6e0 +serdes_driver_current_lane0_22=3 +serdes_pre_driver_current_lane0_22=3 +serdes_preemphasis_lane0_22=0xc6e0 +serdes_driver_current_lane1_22=3 +serdes_pre_driver_current_lane1_22=3 +serdes_preemphasis_lane1_22=0xc6e0 +serdes_driver_current_lane2_22=3 +serdes_pre_driver_current_lane2_22=3 +serdes_preemphasis_lane2_22=0xc6e0 +serdes_driver_current_lane3_22=3 +serdes_pre_driver_current_lane3_22=3 +serdes_preemphasis_lane3_22=0xc6e0 +serdes_driver_current_lane0_23=3 +serdes_pre_driver_current_lane0_23=3 +serdes_preemphasis_lane0_23=0xcad0 +serdes_driver_current_lane1_23=3 +serdes_pre_driver_current_lane1_23=3 +serdes_preemphasis_lane1_23=0xcad0 +serdes_driver_current_lane2_23=3 +serdes_pre_driver_current_lane2_23=3 +serdes_preemphasis_lane2_23=0xcad0 +serdes_driver_current_lane3_23=3 +serdes_pre_driver_current_lane3_23=3 +serdes_preemphasis_lane3_23=0xcad0 +serdes_driver_current_lane0_24=3 +serdes_pre_driver_current_lane0_24=3 +serdes_preemphasis_lane0_24=0xcad0 +serdes_driver_current_lane1_24=3 +serdes_pre_driver_current_lane1_24=3 +serdes_preemphasis_lane1_24=0xcad0 +serdes_driver_current_lane2_24=3 +serdes_pre_driver_current_lane2_24=3 +serdes_preemphasis_lane2_24=0xcad0 +serdes_driver_current_lane3_24=3 +serdes_pre_driver_current_lane3_24=3 +serdes_preemphasis_lane3_24=0xcad0 +serdes_driver_current_lane0_25=5 +serdes_pre_driver_current_lane0_25=5 +serdes_preemphasis_lane0_25=0xc2f0 +serdes_driver_current_lane1_25=5 +serdes_pre_driver_current_lane1_25=5 +serdes_preemphasis_lane1_25=0xc2f0 +serdes_driver_current_lane2_25=5 +serdes_pre_driver_current_lane2_25=5 +serdes_preemphasis_lane2_25=0xc2f0 +serdes_driver_current_lane3_25=5 +serdes_pre_driver_current_lane3_25=5 +serdes_preemphasis_lane3_25=0xc2f0 +serdes_driver_current_lane0_26=5 +serdes_pre_driver_current_lane0_26=5 +serdes_preemphasis_lane0_26=0xc2f0 +serdes_driver_current_lane1_26=5 +serdes_pre_driver_current_lane1_26=5 +serdes_preemphasis_lane1_26=0xc2f0 +serdes_driver_current_lane2_26=5 +serdes_pre_driver_current_lane2_26=5 +serdes_preemphasis_lane2_26=0xc2f0 +serdes_driver_current_lane3_26=5 +serdes_pre_driver_current_lane3_26=5 +serdes_preemphasis_lane3_26=0xc2f0 +serdes_driver_current_lane0_27=5 +serdes_pre_driver_current_lane0_27=5 +serdes_preemphasis_lane0_27=0xc2f0 +serdes_driver_current_lane1_27=5 +serdes_pre_driver_current_lane1_27=5 +serdes_preemphasis_lane1_27=0xc2f0 +serdes_driver_current_lane2_27=5 +serdes_pre_driver_current_lane2_27=5 +serdes_preemphasis_lane2_27=0xc2f0 +serdes_driver_current_lane3_27=5 +serdes_pre_driver_current_lane3_27=5 +serdes_preemphasis_lane3_27=0xc2f0 +serdes_driver_current_lane0_28=8 +serdes_pre_driver_current_lane0_28=6 +serdes_preemphasis_lane0_28=0xc2f0 +serdes_driver_current_lane1_28=8 +serdes_pre_driver_current_lane1_28=6 +serdes_preemphasis_lane1_28=0xc2f0 +serdes_driver_current_lane2_28=8 +serdes_pre_driver_current_lane2_28=6 +serdes_preemphasis_lane2_28=0xc2f0 +serdes_driver_current_lane3_28=8 +serdes_pre_driver_current_lane3_28=6 +serdes_preemphasis_lane3_28=0xc2f0 +serdes_driver_current_lane0_29=2 +serdes_pre_driver_current_lane0_29=2 +serdes_preemphasis_lane0_29=0x8fc0 +serdes_driver_current_lane1_29=2 +serdes_pre_driver_current_lane1_29=2 +serdes_preemphasis_lane1_29=0x8fc0 +serdes_driver_current_lane2_29=2 +serdes_pre_driver_current_lane2_29=2 +serdes_preemphasis_lane2_29=0x8fc0 +serdes_driver_current_lane3_29=2 +serdes_pre_driver_current_lane3_29=2 +serdes_preemphasis_lane3_29=0x8fc0 +serdes_driver_current_lane0_30=2 +serdes_pre_driver_current_lane0_30=2 +serdes_preemphasis_lane0_30=0x8fc0 +serdes_driver_current_lane1_30=2 +serdes_pre_driver_current_lane1_30=2 +serdes_preemphasis_lane1_30=0x8fc0 +serdes_driver_current_lane2_30=2 +serdes_pre_driver_current_lane2_30=2 +serdes_preemphasis_lane2_30=0x8fc0 +serdes_driver_current_lane3_30=2 +serdes_pre_driver_current_lane3_30=2 +serdes_preemphasis_lane3_30=0x8fc0 +serdes_driver_current_lane0_31=2 +serdes_pre_driver_current_lane0_31=2 +serdes_preemphasis_lane0_31=0x8fc0 +serdes_driver_current_lane1_31=2 +serdes_pre_driver_current_lane1_31=2 +serdes_preemphasis_lane1_31=0x8fc0 +serdes_driver_current_lane2_31=2 +serdes_pre_driver_current_lane2_31=2 +serdes_preemphasis_lane2_31=0x8fc0 +serdes_driver_current_lane3_31=2 +serdes_pre_driver_current_lane3_31=2 +serdes_preemphasis_lane3_31=0x8fc0 +serdes_driver_current_lane0_32=2 +serdes_pre_driver_current_lane0_32=2 +serdes_preemphasis_lane0_32=0x8fc0 +serdes_driver_current_lane1_32=2 +serdes_pre_driver_current_lane1_32=2 +serdes_preemphasis_lane1_32=0x8fc0 +serdes_driver_current_lane2_32=2 +serdes_pre_driver_current_lane2_32=2 +serdes_preemphasis_lane2_32=0x8fc0 +serdes_driver_current_lane3_32=2 +serdes_pre_driver_current_lane3_32=2 +serdes_preemphasis_lane3_32=0x8fc0 From 4d795ec99534fd5f86b4f8562807b3f41b046149 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Fri, 15 Jun 2018 11:49:10 -0700 Subject: [PATCH 089/219] Update 201803 branch with masters of sonic-swss, sonic-sairedis, sonic-swss-common, and sonic-utilities (#1791) --- .../Force10-S6100/sai.profile.j2 | 10 ++++++++++ dockers/docker-lldp-sv2/lldpmgrd | 6 +++--- files/image_config/cron.d/s6100-fast-reboot | 2 ++ platform/broadcom/docker-syncd-brcm/start.sh | 2 +- src/sonic-config-engine/sonic-cfggen | 4 +++- src/sonic-config-engine/sonic_platform.py | 3 +++ src/sonic-sairedis | 2 +- src/sonic-swss | 2 +- src/sonic-swss-common | 2 +- src/sonic-utilities | 2 +- 10 files changed, 26 insertions(+), 9 deletions(-) create mode 100644 files/image_config/cron.d/s6100-fast-reboot diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/sai.profile.j2 b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/sai.profile.j2 index 92cda77668f6..265d93a5aaca 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/sai.profile.j2 +++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/sai.profile.j2 @@ -11,3 +11,13 @@ {%- endif %} {# Write the contents of sai_ profile_filename to sai.profile file #} {{ sai_profile_contents }} +{# make linkscan interval time equal to 2.0 sec to make Fast-Reboot faster #} +{%- if DEVICE_METADATA is defined and DEVICE_METADATA['localhost'] is defined and DEVICE_METADATA['localhost']['fast_reboot'] is defined -%} +{%- set fast_reboot = DEVICE_METADATA['localhost']['fast_reboot'] -%} +{%- if fast_reboot %} +{%- set sai_profile_contents = 'SAI_BCM_LINKSCAN_INTERVAL=2000000' -%} +{%- else %} +{%- set sai_profile_contents = '' -%} +{%- endif %} +{{ sai_profile_contents }} +{%- endif %} \ No newline at end of file diff --git a/dockers/docker-lldp-sv2/lldpmgrd b/dockers/docker-lldp-sv2/lldpmgrd index 65f624dfd1dc..c572967d3e48 100755 --- a/dockers/docker-lldp-sv2/lldpmgrd +++ b/dockers/docker-lldp-sv2/lldpmgrd @@ -126,7 +126,7 @@ class LldpManager(object): TABLE_SEPARATOR = "|" # Retrieve all entires for this port from the Port table - port_table = swsscommon.Table(self.config_db, swsscommon.CFG_PORT_TABLE_NAME, TABLE_SEPARATOR) + port_table = swsscommon.Table(self.config_db, swsscommon.CFG_PORT_TABLE_NAME) (status, fvp) = port_table.get(port_name) if status: # Convert list of tuples to a dictionary @@ -144,7 +144,7 @@ class LldpManager(object): lldpcli_cmd = "lldpcli configure ports {0} lldp portidsubtype local {1}".format(port_name, port_alias) # Retrieve all entires for this port from the Device Neighbor table - device_neighbor_table = swsscommon.Table(self.config_db, swsscommon.CFG_DEVICE_NEIGHBOR_TABLE_NAME, TABLE_SEPARATOR) + device_neighbor_table = swsscommon.Table(self.config_db, swsscommon.CFG_DEVICE_NEIGHBOR_TABLE_NAME) (status, fvp) = device_neighbor_table.get(port_name) if status: # Convert list of tuples to a dictionary @@ -216,7 +216,7 @@ class LldpManager(object): # Listen indefinitely for changes to the PORT table in the State DB while True: - (state, c, fd) = sel.select(SELECT_TIMEOUT_MS) + (state, c) = sel.select(SELECT_TIMEOUT_MS) if state == swsscommon.Select.OBJECT: (key, op, fvp) = sst.pop() diff --git a/files/image_config/cron.d/s6100-fast-reboot b/files/image_config/cron.d/s6100-fast-reboot new file mode 100644 index 000000000000..aa3217e61fd0 --- /dev/null +++ b/files/image_config/cron.d/s6100-fast-reboot @@ -0,0 +1,2 @@ +# Change linkscan interval to 0.25 sec after 3 minutes after start on Dell S6100 +@reboot root sleep 180 && [ $(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) = 'x86_64-dell_s6100_c2538-r0' ] && [ $(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.fast_reboot) = 'True' ] && /usr/bin/docker exec -i syncd bcmcmd 'linkscan i=250000' > /dev/null 2>&1 diff --git a/platform/broadcom/docker-syncd-brcm/start.sh b/platform/broadcom/docker-syncd-brcm/start.sh index d2180bce1ed7..3ed445ded691 100755 --- a/platform/broadcom/docker-syncd-brcm/start.sh +++ b/platform/broadcom/docker-syncd-brcm/start.sh @@ -11,7 +11,7 @@ mkdir -p /etc/sai.d/ # Create/Copy the sai.profile to /etc/sai.d/sai.profile if [ -f $HWSKU_DIR/sai.profile.j2 ]; then - sonic-cfggen -d -t $HWSKU_DIR/sai.profile.j2 > /etc/sai.d/sai.profile + sonic-cfggen -H -d -t $HWSKU_DIR/sai.profile.j2 > /etc/sai.d/sai.profile else if [ -f $HWSKU_DIR/sai.profile ]; then cp $HWSKU_DIR/sai.profile /etc/sai.d/sai.profile diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index 42f64884200d..11399926bc11 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -31,6 +31,7 @@ from portconfig import get_port_config from sonic_platform import get_machine_info from sonic_platform import get_platform_info from sonic_platform import get_system_mac +from sonic_platform import get_fast_reboot_status from swsssdk import ConfigDBConnector from collections import OrderedDict from natsort import natsorted @@ -205,7 +206,8 @@ def main(): if args.platform_info: hardware_data = {'DEVICE_METADATA': {'localhost': { 'platform': platform, - 'mac': get_system_mac() + 'mac': get_system_mac(), + 'fast_reboot': get_fast_reboot_status() }}} deep_update(data, hardware_data) diff --git a/src/sonic-config-engine/sonic_platform.py b/src/sonic-config-engine/sonic_platform.py index f573d6a6575d..9715b4b3e0e3 100644 --- a/src/sonic-config-engine/sonic_platform.py +++ b/src/sonic-config-engine/sonic_platform.py @@ -53,3 +53,6 @@ def get_system_mac(): mac = mac[:-2] + aligned_last_byte return mac +def get_fast_reboot_status(): + with open('/proc/cmdline') as fp: + return 'fast-reboot' in fp.read() diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 524685a2b5a1..ce6abfa3acc4 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 524685a2b5a129986887c9808834f853e1a478b9 +Subproject commit ce6abfa3acc4ffc376844d46d051a1e5647945e0 diff --git a/src/sonic-swss b/src/sonic-swss index a1b6fa323c69..7a9f49b7be2d 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit a1b6fa323c693fe3e21cc0aebf2e29fce18aa5b3 +Subproject commit 7a9f49b7be2d2ecfa971c38ec0c5ff5da8187893 diff --git a/src/sonic-swss-common b/src/sonic-swss-common index 14ca39fa0670..f907e9463bd9 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit 14ca39fa0670b0e9b34d0ab63b12348bcba652ac +Subproject commit f907e9463bd9eb81d5cfb6d632774de41a100f93 diff --git a/src/sonic-utilities b/src/sonic-utilities index 951633b02606..c641d2b3eec5 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 951633b02606768b458b7dc88f6c6f8ca736db4e +Subproject commit c641d2b3eec5684182eb56ee71ac3843dbf3b0d0 From c8753d037caef9c50ac4a5ae91651de9d1cfe462 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Tue, 3 Apr 2018 11:24:59 +0800 Subject: [PATCH 090/219] [build templates] Add environment variables for mellanox syncd container to support mellanox sdk and prm sniffer. (#1551) modified: files/build_templates/docker_image_ctl.j2 Signed-off-by: Kebo Liu kebol@mellanox.com --- files/build_templates/docker_image_ctl.j2 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 352d1c763673..1216013e63c2 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -63,6 +63,13 @@ start() { docker run -d {{docker_image_run_opt}} \ {%- if '--log-driver=json-file' in docker_image_run_opt or '--log-driver' not in docker_image_run_opt %} --log-opt max-size=2M --log-opt max-file=5 \ +{%- endif %} +{%- if docker_container_name == "syncd" and sonic_asic_platform == "mellanox" %} + -e SX_SNIFFER_ENABLE \ + -e SX_SNIFFER_TARGET \ + -e PRM_SNIFFER \ + -e PRM_SNIFFER_FILE_PATH \ + -v /var/log/mellanox/sniffer:/var/log/mellanox/sniffer:rw \ {%- endif %} -v /var/run/redis:/var/run/redis:rw \ -v /usr/share/sonic/device/$PLATFORM:/usr/share/sonic/platform:ro \ From 45206594a855defca46953f70a373178161262f4 Mon Sep 17 00:00:00 2001 From: Shuotian Cheng Date: Tue, 19 Jun 2018 17:52:09 -0700 Subject: [PATCH 091/219] [Broadcom]: update Broadcom SAI to 3.1.3.4-14 (#1797) Fix mirror session destination update bug causing no resources issue Signed-off-by: Shu0T1an ChenG --- platform/broadcom/sai.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 0012e8a8106a..52214493edd0 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,9 +1,9 @@ -BRCM_SAI = libsaibcm_3.1.3.4-13_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm_3.1.3.4-13_amd64.deb?sv=2015-04-05&sr=b&sig=Y7mQMOnQEzwb%2FG%2BY9dcEX0Y9tQBDCK2UmF4TjIz3Zn8%3D&se=2155-04-24T09%3A52%3A42Z&sp=r" +BRCM_SAI = libsaibcm_3.1.3.4-14_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm_3.1.3.4-14_amd64.deb?sv=2015-04-05&sr=b&sig=RUib2nzuTwstNgT9OJ6DGv5OraWc6oyOmMtaRh6pDdw%3D&se=2032-02-25T17%3A38%3A41Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.1.3.4-13_amd64.deb +BRCM_SAI_DEV = libsaibcm-dev_3.1.3.4-14_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm-dev_3.1.3.4-13_amd64.deb?sv=2015-04-05&sr=b&sig=YYjwAt47PlCYJgW0RtEsdcmGAc52UdAzHEd5qVKImxc%3D&se=2155-04-24T09%3A53%3A45Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm-dev_3.1.3.4-14_amd64.deb?sv=2015-04-05&sr=b&sig=GRdByGTrNZbZoQmXhsVC%2BL7ZeDwzstl4Vq6vGssrmyo%3D&se=2032-02-25T17%3A39%3A09Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) From 3779c5824aea232c7f4f49a079b8564e79329796 Mon Sep 17 00:00:00 2001 From: Taoyu Li Date: Thu, 21 Jun 2018 10:40:28 -0700 Subject: [PATCH 092/219] [interface-config] Force eth0 before reconfiguration (#1802) --- files/image_config/interfaces/interfaces-config.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/image_config/interfaces/interfaces-config.sh b/files/image_config/interfaces/interfaces-config.sh index 75660e713e7f..a702917419ca 100755 --- a/files/image_config/interfaces/interfaces-config.sh +++ b/files/image_config/interfaces/interfaces-config.sh @@ -1,6 +1,6 @@ #!/bin/bash -ifdown eth0 +ifdown --force eth0 sonic-cfggen -d -t /usr/share/sonic/templates/interfaces.j2 > /etc/network/interfaces From 310c3f9ff62c0d3876d4962cceb6cc6eeec88869 Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Fri, 22 Jun 2018 00:57:32 +0700 Subject: [PATCH 093/219] [device]: Fix a bug that psuutil cannot access gpio sysfs to get PSU status (#1789) --- .../x86_64-cel_seastone-r0/plugins/psuutil.py | 49 +++++++------------ 1 file changed, 19 insertions(+), 30 deletions(-) diff --git a/device/celestica/x86_64-cel_seastone-r0/plugins/psuutil.py b/device/celestica/x86_64-cel_seastone-r0/plugins/psuutil.py index 9e8f99e7a7f2..510c03a43ff1 100644 --- a/device/celestica/x86_64-cel_seastone-r0/plugins/psuutil.py +++ b/device/celestica/x86_64-cel_seastone-r0/plugins/psuutil.py @@ -3,7 +3,8 @@ # Platform-specific PSU status interface for SONiC # -import os.path +import os + try: from sonic_psu.psu_base import PsuBase @@ -18,42 +19,32 @@ def __init__(self): PsuBase.__init__(self) # DX010 PSU pin mapping self.psu = [ - {'base':216}, # Reserved + {'base': self.get_gpio_base()}, {'abs':27, 'power':22}, {'abs':28, 'power':25} ] - def init_psu_gpio(self, pinnum): - # export pin, input as default - gpio_base = self.psu[0]['base'] - export_file = "/sys/class/gpio/export" - direction_file = '/sys/class/gpio/gpio' + str(gpio_base+pinnum) + '/direction' - - try: - with open(export_file, 'w') as fd: - fd.write(str(gpio_base+pinnum)) - except Exception as error: - logging.error("Unable to export gpio ", pinnum) + def get_gpio_base(self): + sys_gpio_dir = "/sys/class/gpio" + for r in os.listdir(sys_gpio_dir): + if "gpiochip" in r: + return int(r[8:],10) + return 216 #Reserve # Get a psu status and presence def read_psu_statuses(self, pinnum): sys_gpio_dir = "/sys/class/gpio" - retval = 'ERR' gpio_base = self.psu[0]['base'] gpio_dir = sys_gpio_dir + '/gpio' + str(gpio_base+pinnum) gpio_file = gpio_dir + "/value" - - # init gpio - if (not os.path.isdir(gpio_dir)): - self.init_psu_gpio(pinnum) try: with open(gpio_file, 'r') as fd: retval = fd.read() - except Exception as error: - logging.error("Unable to open ", gpio_file, "file !") + except IOError: + raise IOError("Unable to open " + gpio_file + "file !") retval = retval.rstrip('\r\n') return retval @@ -76,11 +67,10 @@ def get_psu_status(self, index): """ status = 0 psu_status = self.read_psu_statuses(self.psu[index]['power']) - if (psu_status != 'ERR'): - psu_status = int(psu_status, 10) - # Check for PSU status - if (psu_status == 1): - status = 1 + psu_status = int(psu_status, 10) + # Check for PSU status + if (psu_status == 1): + status = 1 return status @@ -93,10 +83,9 @@ def get_psu_presence(self, index): """ status = 0 psu_absence = self.read_psu_statuses(self.psu[index]['abs']) - if (psu_absence != 'ERR'): - psu_absence = (int(psu_absence, 10)) - # Check for PSU presence - if (psu_absence == 0): - status = 1 + psu_absence = (int(psu_absence, 10)) + # Check for PSU presence + if (psu_absence == 0): + status = 1 return status From 7457c0086348d7d1945b06bb896c89104d02325b Mon Sep 17 00:00:00 2001 From: Pradchaya P Date: Sat, 23 Jun 2018 01:56:22 +0700 Subject: [PATCH 094/219] [platform] Celestica: dx010 init gpio sysfs (#1807) --- platform/broadcom/platform-modules-cel.mk | 2 +- platform/broadcom/sonic-platform-modules-cel | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/broadcom/platform-modules-cel.mk b/platform/broadcom/platform-modules-cel.mk index 09e8b374e861..551ff37e3b37 100644 --- a/platform/broadcom/platform-modules-cel.mk +++ b/platform/broadcom/platform-modules-cel.mk @@ -1,6 +1,6 @@ # Celestica DX010 Platform modules -CEL_DX010_PLATFORM_MODULE_VERSION = 0.6 +CEL_DX010_PLATFORM_MODULE_VERSION = 0.7 export CEL_DX010_PLATFORM_MODULE_VERSION diff --git a/platform/broadcom/sonic-platform-modules-cel b/platform/broadcom/sonic-platform-modules-cel index 7875e46964fc..4c8bcd1584e5 160000 --- a/platform/broadcom/sonic-platform-modules-cel +++ b/platform/broadcom/sonic-platform-modules-cel @@ -1 +1 @@ -Subproject commit 7875e46964fcc329ff92a80c379c026da530221f +Subproject commit 4c8bcd1584e5afb05476a67e0ed82ca02fba6da0 From c6d43c4be2e9e239d454b840cd59286f416e9551 Mon Sep 17 00:00:00 2001 From: Taoyu Li Date: Fri, 22 Jun 2018 11:57:44 -0700 Subject: [PATCH 095/219] [tacacs] To modify local user permission according to priv lvl (#1804) --- ...able-modifying-local-user-permission.patch | 71 +++++++++++++++++++ src/tacacs/nss/Makefile | 3 +- 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 src/tacacs/nss/0002-Enable-modifying-local-user-permission.patch diff --git a/src/tacacs/nss/0002-Enable-modifying-local-user-permission.patch b/src/tacacs/nss/0002-Enable-modifying-local-user-permission.patch new file mode 100644 index 000000000000..2c476354705a --- /dev/null +++ b/src/tacacs/nss/0002-Enable-modifying-local-user-permission.patch @@ -0,0 +1,71 @@ +From 7045acb8f530331d3fbabef20bcf2787d3430c55 Mon Sep 17 00:00:00 2001 +From: Taoyu Li +Date: Thu, 21 Jun 2018 19:21:01 +0000 +Subject: [PATCH] Do authorization and modify user permission even if local + user exists + +--- + nss_tacplus.c | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +diff --git a/nss_tacplus.c b/nss_tacplus.c +index 63f01d4..a13c278 100644 +--- a/nss_tacplus.c ++++ b/nss_tacplus.c +@@ -408,7 +408,7 @@ static int delete_conf_line(const char *name) + * conf, it will be written in conf and created by command 'useradd'. When + * useradd command use getpwnam(), it will return when username found in conf. + */ +-static int create_local_user(const char *name, int level) ++static int create_or_modify_local_user(const char *name, int level, bool existing_user) + { + FILE *fp; + useradd_info_t *user; +@@ -416,6 +416,7 @@ static int create_local_user(const char *name, int level) + int len = 512; + int lvl, cnt; + bool found = false; ++ const char* command = existing_user ? "/usr/sbin/usermod": "/usr/sbin/useradd"; + + fp = fopen(user_conf, "ab+"); + if(!fp) { +@@ -458,17 +459,18 @@ static int create_local_user(const char *name, int level) + while(lvl >= MIN_TACACS_USER_PRIV) { + user = &useradd_grp_list[lvl]; + if(user->info && user->secondary_grp && user->shell) { +- snprintf(buf, len, "useradd -G %s \"%s\" -g %d -c \"%s\" -d /home/%s -m -s %s", +- user->secondary_grp, name, user->gid, user->info, name, user->shell); ++ snprintf(buf, len, "%s -G %s \"%s\" -g %d -c \"%s\" -d /home/%s -m -s %s", ++ command, user->secondary_grp, name, user->gid, user->info, name, user->shell); ++ if(debug) syslog(LOG_DEBUG, "%s", buf); + fp = popen(buf, "r"); + if(!fp || -1 == pclose(fp)) { +- syslog(LOG_ERR, "%s: useradd popen failed errno=%d %s", +- nssname, errno, strerror(errno)); ++ syslog(LOG_ERR, "%s: %s popen failed errno=%d %s", ++ nssname, command, errno, strerror(errno)); + delete_conf_line(name); + return -1; + } + if(debug) +- syslog(LOG_DEBUG, "%s: create local user %s success", nssname, name); ++ syslog(LOG_DEBUG, "%s: %s %s success", nssname, command, name); + delete_conf_line(name); + return 0; + } +@@ -558,10 +560,10 @@ static int lookup_user_pw(struct pwbuf *pb, int level) + if(debug) + syslog(LOG_DEBUG, "%s: %s passwd %s found in local", nssname, username, + found ? "is" : "isn't"); +- if(0 != ret || found) ++ if(0 != ret) + return ret; + +- if(0 != create_local_user(username, level)) ++ if(0 != create_or_modify_local_user(username, level, found)) + return -1; + + ret = lookup_pw_local(username, pb, &found); +-- +2.9.3 + diff --git a/src/tacacs/nss/Makefile b/src/tacacs/nss/Makefile index 4f1a337b34b4..259e9b281389 100644 --- a/src/tacacs/nss/Makefile +++ b/src/tacacs/nss/Makefile @@ -12,7 +12,8 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : git checkout -f 19008ab # Apply patch - git apply ../0001-Modify-user-map-profile.patch + git am ../0001-Modify-user-map-profile.patch + git am ../0002-Enable-modifying-local-user-permission.patch dpkg-buildpackage -rfakeroot -b -us -uc popd From 4eb866c615693093a2602b6120ccf9285a057c23 Mon Sep 17 00:00:00 2001 From: sihuihan88 Date: Fri, 22 Jun 2018 18:03:27 -0700 Subject: [PATCH 096/219] [sai]: update SAI version to 3.1.3.4-15 (#1808) Signed-off-by: Sihui Han --- platform/broadcom/sai.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 52214493edd0..5cda170b3391 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,9 +1,9 @@ -BRCM_SAI = libsaibcm_3.1.3.4-14_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm_3.1.3.4-14_amd64.deb?sv=2015-04-05&sr=b&sig=RUib2nzuTwstNgT9OJ6DGv5OraWc6oyOmMtaRh6pDdw%3D&se=2032-02-25T17%3A38%3A41Z&sp=r" +BRCM_SAI = libsaibcm_3.1.3.4-15_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm_3.1.3.4-15_amd64.deb?sv=2015-04-05&sr=b&sig=7CIkdlBB%2BY6Xjae0vc1QBnlAVedRkreJRhWM93SyHOI%3D&se=2032-02-29T18%3A31%3A54Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.1.3.4-14_amd64.deb +BRCM_SAI_DEV = libsaibcm-dev_3.1.3.4-15_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm-dev_3.1.3.4-14_amd64.deb?sv=2015-04-05&sr=b&sig=GRdByGTrNZbZoQmXhsVC%2BL7ZeDwzstl4Vq6vGssrmyo%3D&se=2032-02-25T17%3A39%3A09Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm-dev_3.1.3.4-15_amd64.deb?sv=2015-04-05&sr=b&sig=rBOT802o1o%2BAcogaXq%2FgqyuTAmSlFKhtPzYM%2BtXlIdM%3D&se=2032-02-29T18%3A34%3A10Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) From 6568203c15c9a35343ba402ce330e363ef18de28 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Tue, 26 Jun 2018 12:17:51 -0700 Subject: [PATCH 097/219] Enable sairedis counter thread in 3 minutes after SONiC was started (#1813) * Enable sairedis counter thread in 3 minutes after SONiC was started * Enable all counters --- files/build_templates/enable_counters.service | 7 +++++++ files/build_templates/enable_counters.timer | 9 +++++++++ files/build_templates/snmp.service.j2 | 7 ++----- files/build_templates/snmp.timer | 9 +++++++++ files/build_templates/sonic_debian_extension.j2 | 8 ++++++++ src/sonic-sairedis | 2 +- src/sonic-swss | 2 +- src/sonic-utilities | 2 +- 8 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 files/build_templates/enable_counters.service create mode 100644 files/build_templates/enable_counters.timer create mode 100644 files/build_templates/snmp.timer diff --git a/files/build_templates/enable_counters.service b/files/build_templates/enable_counters.service new file mode 100644 index 000000000000..f19249369f87 --- /dev/null +++ b/files/build_templates/enable_counters.service @@ -0,0 +1,7 @@ +[Unit] +Description=Enable SONiC counters + +[Service] +Type=oneshot +ExecStart=/bin/bash -c '/usr/bin/counterpoll queue enable ; /usr/bin/counterpoll port enable ; /usr/bin/pfcwd counter_poll enable' +RemainAfterExit=yes diff --git a/files/build_templates/enable_counters.timer b/files/build_templates/enable_counters.timer new file mode 100644 index 000000000000..7382a1658c1b --- /dev/null +++ b/files/build_templates/enable_counters.timer @@ -0,0 +1,9 @@ +[Unit] +Description=Delays the SONiC counters gathering until SONiC has started + +[Timer] +OnBootSec=3min +Unit=enable_counters.service + +[Install] +WantedBy=timers.target diff --git a/files/build_templates/snmp.service.j2 b/files/build_templates/snmp.service.j2 index f0612a9cfcb6..93ef869b86e1 100644 --- a/files/build_templates/snmp.service.j2 +++ b/files/build_templates/snmp.service.j2 @@ -1,12 +1,9 @@ [Unit] Description=SNMP container -Requires=updategraph.service swss.service -After=updategraph.service swss.service +Requires=updategraph.service swss.service enable_counters.service +After=updategraph.service swss.service enable_counters.service [Service] ExecStartPre=/usr/bin/{{docker_container_name}}.sh start ExecStart=/usr/bin/{{docker_container_name}}.sh attach ExecStop=/usr/bin/{{docker_container_name}}.sh stop - -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/snmp.timer b/files/build_templates/snmp.timer new file mode 100644 index 000000000000..464cf01459ba --- /dev/null +++ b/files/build_templates/snmp.timer @@ -0,0 +1,9 @@ +[Unit] +Description=Delays snmp container until SONiC has started + +[Timer] +OnBootSec=3min 30 sec +Unit=snmp.service + +[Install] +WantedBy=timers.target diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 0849118b83a4..4898bdb294cf 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -272,6 +272,14 @@ sudo LANG=C chroot $FILESYSTEM_ROOT fuser -km /sys || true sudo LANG=C chroot $FILESYSTEM_ROOT umount -lf /sys {% endif %} +# Copy systemd timer configuration +# It implements delayed start of services +sudo cp $BUILD_TEMPLATES/enable_counters.timer $FILESYSTEM_ROOT/etc/systemd/system/ +sudo cp $BUILD_TEMPLATES/enable_counters.service $FILESYSTEM_ROOT/etc/systemd/system/ +sudo cp $BUILD_TEMPLATES/snmp.timer $FILESYSTEM_ROOT/etc/systemd/system/ +sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable enable_counters.timer +sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable snmp.timer + sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get remove -y python-dev sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get clean -y sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get autoremove -y diff --git a/src/sonic-sairedis b/src/sonic-sairedis index ce6abfa3acc4..17fd36e2e115 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit ce6abfa3acc4ffc376844d46d051a1e5647945e0 +Subproject commit 17fd36e2e115af90dea491f71689147fc06f7d30 diff --git a/src/sonic-swss b/src/sonic-swss index 7a9f49b7be2d..06718ad33eae 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 7a9f49b7be2d2ecfa971c38ec0c5ff5da8187893 +Subproject commit 06718ad33eae0f14659dbe6401d9f63088dd263f diff --git a/src/sonic-utilities b/src/sonic-utilities index c641d2b3eec5..27bea61072d0 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit c641d2b3eec5684182eb56ee71ac3843dbf3b0d0 +Subproject commit 27bea61072d0a4c8756b4be89b4b349f72918889 From 71ede53d86ab0b6ccdb58f421296ce08b37e3b00 Mon Sep 17 00:00:00 2001 From: Hnydyn Nazar Date: Thu, 28 Jun 2018 23:43:30 +0300 Subject: [PATCH 098/219] Updated Cavium SAI headers. (#1822) --- platform/cavium/cavm-sai.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/cavium/cavm-sai.mk b/platform/cavium/cavm-sai.mk index 6064d8d7561a..600bb4f1de31 100644 --- a/platform/cavium/cavm-sai.mk +++ b/platform/cavium/cavm-sai.mk @@ -1,6 +1,6 @@ # Cavium SAI -CAVM_SAI_GITHUB = https://github.com/XPliant/OpenXPS/raw/d37a606cdf7d2bdc9d6ee025b758f64572f8ddbe/SAI/cavm-sai/ +CAVM_SAI_GITHUB = https://github.com/XPliant/OpenXPS/raw/d4e8e80da546a6e53490a71dc73e26216bb40125/SAI/cavm-sai/ CAVM_LIBSAI = libsai.deb CAVM_SAI = sai.deb From 868b867f2582ba754b05cd2c383b70e33069a41e Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Sat, 30 Jun 2018 09:41:18 -0700 Subject: [PATCH 099/219] Update sonic-swss for 201803 branch. Postpone init of the queue maps (#1831) --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 06718ad33eae..ed9c1c8b59de 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 06718ad33eae0f14659dbe6401d9f63088dd263f +Subproject commit ed9c1c8b59ded974bd3ab7d0db6266d222689dfa From 4012e3d74a66550f1f37be276f4d214fc12dd4f6 Mon Sep 17 00:00:00 2001 From: tiantianlv <38775940+tiantianlv@users.noreply.github.com> Date: Wed, 4 Jul 2018 10:22:21 +0800 Subject: [PATCH 100/219] Add pre-emphasis for 100G optical mocule (#1838) --- .../Seastone-DX010/sai.profile | 2 +- .../th-seastone-dx010-32x100G.config.bcm | 694 ++++++++++++++++++ 2 files changed, 695 insertions(+), 1 deletion(-) create mode 100644 device/celestica/x86_64-cel_seastone-r0/Seastone-DX010/th-seastone-dx010-32x100G.config.bcm diff --git a/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010/sai.profile b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010/sai.profile index 8db218c89a52..072467af3e9a 100644 --- a/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010/sai.profile +++ b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010/sai.profile @@ -1 +1 @@ -SAI_INIT_CONFIG_FILE=/etc/bcm/th-seastone-dx010-32x100G.config.bcm +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-seastone-dx010-32x100G.config.bcm diff --git a/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010/th-seastone-dx010-32x100G.config.bcm b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010/th-seastone-dx010-32x100G.config.bcm new file mode 100644 index 000000000000..cff5e4f1b232 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010/th-seastone-dx010-32x100G.config.bcm @@ -0,0 +1,694 @@ +# Define default OS / SAL +os=unix + +# all XPORTs to XE ports +#pbmp_xport_xe=0x1fffffffe +pbmp_xport_xe=0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe +pbmp_oversubscribe=0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe + +# Mode control to select L2 Table DMA mode aka L2MODE_POLL (0) or +# L2MOD_FIFO mechanism aka L2MODE_FIFO (1) for L2 table change notification. +l2xmsg_mode=1 + +# Memory table size configs +l2_mem_entries=8192 +l3_mem_entries=8192 +l3_alpm_enable=2 +ipv6_lpm_128b_enable=1 +mmu_lossless=0 + +################################################################################### +# Celestica Customize for SeaStone +################################################################################### + +#ext mdio frequency to 495/0x80/2(1.933Mhz) or 415/0x80/2(1.62MHz) +# default is 40 +# Set external MDIO freq to 6.19MHz (495MHz) or 5.19MHz (415MHz) +#* target_freq is core_clock_freq * DIVIDEND / DIVISOR / 2 +# +rate_ext_mdio_divisor=0x80 + +# use internal rom boot +phy_ext_rom_boot=0 + +#fpem_mem_entries=32768 +oversubscribe_mode=1 +#pbmp_xport_xe=0x3fd000000ff4000003fc000001fe + + +dport_map_enable=1 + +dport_map_port_68=1 +dport_map_port_72=5 +dport_map_port_76=9 +dport_map_port_80=13 +dport_map_port_34=17 +dport_map_port_38=21 +dport_map_port_42=25 +dport_map_port_46=29 +dport_map_port_50=33 +dport_map_port_54=37 +dport_map_port_58=41 +dport_map_port_62=45 +dport_map_port_84=49 +dport_map_port_88=53 +dport_map_port_92=57 +dport_map_port_96=61 +dport_map_port_102=65 +dport_map_port_106=69 +dport_map_port_110=73 +dport_map_port_114=77 +dport_map_port_1=81 +dport_map_port_5=85 +dport_map_port_9=89 +dport_map_port_13=93 +dport_map_port_17=97 +dport_map_port_21=101 +dport_map_port_25=105 +dport_map_port_29=109 +dport_map_port_118=113 +dport_map_port_122=117 +dport_map_port_126=121 +dport_map_port_130=125 + + +# port mapping +portmap_68=65:100:4 +portmap_72=69:100:4 +portmap_76=73:100:4 +portmap_80=77:100:4 +portmap_34=33:100:4 +portmap_38=37:100:4 +portmap_42=41:100:4 +portmap_46=45:100:4 +portmap_50=49:100:4 +portmap_54=53:100:4 +portmap_58=57:100:4 +portmap_62=61:100:4 +portmap_84=81:100:4 +portmap_88=85:100:4 +portmap_92=89:100:4 +portmap_96=93:100:4 +portmap_102=97:100:4 +portmap_106=101:100:4 +portmap_110=105:100:4 +portmap_114=109:100:4 +portmap_1=1:100:4 +portmap_5=5:100:4 +portmap_9=9:100:4 +portmap_13=13:100:4 +portmap_17=17:100:4 +portmap_21=21:100:4 +portmap_25=25:100:4 +portmap_29=29:100:4 +portmap_118=113:100:4 +portmap_122=117:100:4 +portmap_126=121:100:4 +portmap_130=125:100:4 +#portmap_66=129:10 +#portmap_100=131:10 + +#WC16 +xgxs_tx_lane_map_68=0x3201 +xgxs_rx_lane_map_68=0x2310 + + +#WC17 +xgxs_tx_lane_map_72=0x3201 +xgxs_rx_lane_map_72=0x2301 + +#WC18 +xgxs_tx_lane_map_76=0x0132 +xgxs_rx_lane_map_76=0x0123 + +#WC19 +xgxs_tx_lane_map_80=0x2031 +xgxs_rx_lane_map_80=0x1320 + +#WC8 +xgxs_tx_lane_map_34=0x3021 +xgxs_rx_lane_map_34=0x0213 + +#WC9 +xgxs_tx_lane_map_38=0x3210 +xgxs_rx_lane_map_38=0x1023 + +#WC10 +xgxs_tx_lane_map_42=0x2310 +xgxs_rx_lane_map_42=0x3210 + +#WC11 +xgxs_tx_lane_map_46=0x1032 +xgxs_rx_lane_map_46=0x1302 + +#WC12 +xgxs_tx_lane_map_50=0x3201 +xgxs_rx_lane_map_50=0x0213 + + +#WC13 +xgxs_tx_lane_map_54=0x2301 +xgxs_rx_lane_map_54=0x2310 + +#WC14 +xgxs_tx_lane_map_58=0x3201 +xgxs_rx_lane_map_58=0x0213 + +#WC15 +xgxs_tx_lane_map_62=0x1302 +xgxs_rx_lane_map_62=0x2310 + +#WC20 +xgxs_tx_lane_map_84=0x0213 +xgxs_rx_lane_map_84=0x2301 + +#WC21 +xgxs_tx_lane_map_88=0x0132 +xgxs_rx_lane_map_88=0x3210 + +#WC22 +xgxs_tx_lane_map_92=0x0132 +xgxs_rx_lane_map_92=0x2031 + +#WC23 +xgxs_tx_lane_map_96=0x2031 +xgxs_rx_lane_map_96=0x3201 + +#WC24 +xgxs_tx_lane_map_102=0x0132 +xgxs_rx_lane_map_102=0x2301 + +#WC25 +xgxs_tx_lane_map_106=0x0132 +xgxs_rx_lane_map_106=0x3201 + +#WC26 +xgxs_tx_lane_map_110=0x0132 +xgxs_rx_lane_map_110=0x2031 + +#WC27 +xgxs_tx_lane_map_114=0x2031 +xgxs_rx_lane_map_114=0x2301 + + +#WC0 +xgxs_tx_lane_map_1=0x3210 +xgxs_rx_lane_map_1=0x3120 + +#WC1 +xgxs_tx_lane_map_5=0x0132 +xgxs_rx_lane_map_5=0x1023 + +#WC2 +xgxs_tx_lane_map_9=0x3201 +xgxs_rx_lane_map_9=0x3120 + +#WC3 +xgxs_tx_lane_map_13=0x2031 +xgxs_rx_lane_map_13=0x1032 + +#WC4 +xgxs_tx_lane_map_17=0x2310 +xgxs_rx_lane_map_17=0x3210 + +#WC5 +xgxs_tx_lane_map_21=0x2301 +xgxs_rx_lane_map_21=0x3120 + +#WC6 +xgxs_tx_lane_map_25=0x3201 +xgxs_rx_lane_map_25=0x0213 + +#WC7 +xgxs_tx_lane_map_29=0x1302 +xgxs_rx_lane_map_29=0x1023 + +#WC28 +xgxs_tx_lane_map_118=0x1320 +xgxs_rx_lane_map_118=0x1302 + +#WC29 +xgxs_tx_lane_map_122=0x1032 +xgxs_rx_lane_map_122=0x1023 + +#WC30 +xgxs_tx_lane_map_126=0x3120 +xgxs_rx_lane_map_126=0x3120 + +#WC31 +xgxs_tx_lane_map_130=0x1302 +xgxs_rx_lane_map_130=0x2310 + +#PN + +#WC16 +phy_xaui_tx_polarity_flip_68=0x0000 +phy_xaui_rx_polarity_flip_68=0x0000 + +#WC17 +phy_xaui_tx_polarity_flip_72=0x000D +phy_xaui_rx_polarity_flip_72=0x0002 + + +#WC18 +phy_xaui_tx_polarity_flip_76=0x000F +phy_xaui_rx_polarity_flip_76=0x0000 + +#WC19 +phy_xaui_tx_polarity_flip_80=0x000F +phy_xaui_rx_polarity_flip_80=0x000F + + +#WC8 +phy_xaui_tx_polarity_flip_34=0x000E +phy_xaui_rx_polarity_flip_34=0x0000 + +#WC9 +phy_xaui_tx_polarity_flip_38=0x0008 +phy_xaui_rx_polarity_flip_38=0x0000 + +#WC10 +phy_xaui_tx_polarity_flip_42=0x000D +phy_xaui_rx_polarity_flip_42=0x0000 + +#WC11 +phy_xaui_tx_polarity_flip_46=0x0000 +phy_xaui_rx_polarity_flip_46=0x0000 + + +#WC12 +phy_xaui_tx_polarity_flip_50=0x0002 +phy_xaui_rx_polarity_flip_50=0x0000 + +#WC13 +phy_xaui_tx_polarity_flip_54=0x0002 +phy_xaui_rx_polarity_flip_54=0x0000 + +#WC14 +phy_xaui_tx_polarity_flip_58=0x0000 +phy_xaui_rx_polarity_flip_58=0x0000 + +#WC15 +phy_xaui_tx_polarity_flip_62=0x000A +phy_xaui_rx_polarity_flip_62=0x000F + + +#WC20 + phy_xaui_tx_polarity_flip_84=0x0007 + phy_xaui_rx_polarity_flip_84=0x000E + +#WC21 +phy_xaui_tx_polarity_flip_88=0x000D +phy_xaui_rx_polarity_flip_88=0x000D + +#WC22 +phy_xaui_tx_polarity_flip_92=0x000F +phy_xaui_rx_polarity_flip_92=0x0008 + +#WC23 +phy_xaui_tx_polarity_flip_96=0x0005 +phy_xaui_rx_polarity_flip_96=0x0000 + +#WC24 +phy_xaui_tx_polarity_flip_102=0x0000 +phy_xaui_rx_polarity_flip_102=0x000F + +#WC25 +phy_xaui_tx_polarity_flip_106=0x000F +phy_xaui_rx_polarity_flip_106=0x0000 + +#WC26 +phy_xaui_tx_polarity_flip_110=0x000F +phy_xaui_rx_polarity_flip_110=0x000F + +#WC27 +phy_xaui_tx_polarity_flip_114=0x000F +phy_xaui_rx_polarity_flip_114=0x0007 + +#WC0 +phy_xaui_tx_polarity_flip_1=0x0003 +phy_xaui_rx_polarity_flip_1=0x000F + +#WC1 +phy_xaui_tx_polarity_flip_5=0x0007 +phy_xaui_rx_polarity_flip_5=0x0000 + +#WC2 +phy_xaui_tx_polarity_flip_9=0x0002 +phy_xaui_rx_polarity_flip_9=0x0008 + +#WC3 +phy_xaui_tx_polarity_flip_13=0x000F +phy_xaui_rx_polarity_flip_13=0x0000 + +#WC4 +phy_xaui_tx_polarity_flip_17=0x0007 +phy_xaui_rx_polarity_flip_17=0x0000 + +#WC5 +phy_xaui_tx_polarity_flip_21=0x0000 +phy_xaui_rx_polarity_flip_21=0x0000 + +#WC6 +phy_xaui_tx_polarity_flip_25=0x0002 +phy_xaui_rx_polarity_flip_25=0x0005 + +#WC7 +phy_xaui_tx_polarity_flip_29=0x0002 +phy_xaui_rx_polarity_flip_29=0x0000 + +#WC28 +phy_xaui_tx_polarity_flip_118=0x000F +phy_xaui_rx_polarity_flip_118=0x000F + +#WC29 +phy_xaui_tx_polarity_flip_122=0x0004 +phy_xaui_rx_polarity_flip_122=0x0000 + +#WC30 +phy_xaui_tx_polarity_flip_126=0x000F +phy_xaui_rx_polarity_flip_126=0x0000 + +#WC31 +phy_xaui_tx_polarity_flip_130=0x0006 +phy_xaui_rx_polarity_flip_130=0x0000 + +#ce0 +serdes_driver_current_lane0_68=0x0b +serdes_driver_current_lane1_68=0x0b +serdes_driver_current_lane2_68=0x0b +serdes_driver_current_lane3_68=0x0b +serdes_preemphasis_lane0_68=0x2d3f04 +serdes_preemphasis_lane1_68=0x2b4104 +serdes_preemphasis_lane2_68=0x2b4104 +serdes_preemphasis_lane3_68=0x2d3f04 + +#ce1 +serdes_driver_current_lane0_72=0x0b +serdes_driver_current_lane1_72=0x0a +serdes_driver_current_lane2_72=0x0a +serdes_driver_current_lane3_72=0x0b +serdes_preemphasis_lane0_72=0x2b4104 +serdes_preemphasis_lane1_72=0x294403 +serdes_preemphasis_lane2_72=0x294403 +serdes_preemphasis_lane3_72=0x2b4104 + +#ce2 +serdes_driver_current_lane0_76=0x0a +serdes_driver_current_lane1_76=0x0a +serdes_driver_current_lane2_76=0x0a +serdes_driver_current_lane3_76=0x0a +serdes_preemphasis_lane0_76=0x294403 +serdes_preemphasis_lane1_76=0x294403 +serdes_preemphasis_lane2_76=0x294403 +serdes_preemphasis_lane3_76=0x294403 + +#ce3 +serdes_driver_current_lane0_80=0x0a +serdes_driver_current_lane1_80=0x0a +serdes_driver_current_lane2_80=0x0a +serdes_driver_current_lane3_80=0x0a +serdes_preemphasis_lane0_80=0x254902 +serdes_preemphasis_lane1_80=0x254902 +serdes_preemphasis_lane2_80=0x294403 +serdes_preemphasis_lane3_80=0x294403 + +#ce4 +serdes_driver_current_lane0_34=0x0b +serdes_driver_current_lane1_34=0x0b +serdes_driver_current_lane2_34=0x0b +serdes_driver_current_lane3_34=0x0b +serdes_preemphasis_lane0_34=0x2b4104 +serdes_preemphasis_lane1_34=0x2d3f04 +serdes_preemphasis_lane2_34=0x2d3f04 +serdes_preemphasis_lane3_34=0x2b4104 + +#ce5 +serdes_driver_current_lane0_38=0x0a +serdes_driver_current_lane1_38=0x0b +serdes_driver_current_lane2_38=0x0b +serdes_driver_current_lane3_38=0x0b +serdes_preemphasis_lane0_38=0x294403 +serdes_preemphasis_lane1_38=0x2b4104 +serdes_preemphasis_lane2_38=0x2b4104 +serdes_preemphasis_lane3_38=0x2b4104 + +#ce6 +serdes_driver_current_lane0_42=0x0a +serdes_driver_current_lane1_42=0x0b +serdes_driver_current_lane2_42=0x0a +serdes_driver_current_lane3_42=0x0a +serdes_preemphasis_lane0_42=0x294403 +serdes_preemphasis_lane1_42=0x2b4104 +serdes_preemphasis_lane2_42=0x294403 +serdes_preemphasis_lane3_42=0x294403 + +#ce7 +serdes_driver_current_lane0_46=0x0a +serdes_driver_current_lane1_46=0x0a +serdes_driver_current_lane2_46=0x0a +serdes_driver_current_lane3_46=0x0a +serdes_preemphasis_lane0_46=0x254902 +serdes_preemphasis_lane1_46=0x294403 +serdes_preemphasis_lane2_46=0x254902 +serdes_preemphasis_lane3_46=0x294403 + +#ce8 +serdes_driver_current_lane0_50=0x0a +serdes_driver_current_lane1_50=0x0a +serdes_driver_current_lane2_50=0x0a +serdes_driver_current_lane3_50=0x0a +serdes_preemphasis_lane0_50=0x294403 +serdes_preemphasis_lane1_50=0x254902 +serdes_preemphasis_lane2_50=0x254902 +serdes_preemphasis_lane3_50=0x254902 + +#ce9 +serdes_driver_current_lane0_54=0x0a +serdes_driver_current_lane1_54=0x09 +serdes_driver_current_lane2_54=0x0a +serdes_driver_current_lane3_54=0x09 +serdes_preemphasis_lane0_54=0x254902 +serdes_preemphasis_lane1_54=0x244a02 +serdes_preemphasis_lane2_54=0x254902 +serdes_preemphasis_lane3_54=0x244a02 + +#ce10 +serdes_driver_current_lane0_58=0x0a +serdes_driver_current_lane1_58=0x09 +serdes_driver_current_lane2_58=0x09 +serdes_driver_current_lane3_58=0x0a +serdes_preemphasis_lane0_58=0x254902 +serdes_preemphasis_lane1_58=0x244a02 +serdes_preemphasis_lane2_58=0x244a02 +serdes_preemphasis_lane3_58=0x254902 + +#ce11 +serdes_driver_current_lane0_62=0x09 +serdes_driver_current_lane1_62=0x0a +serdes_driver_current_lane2_62=0x09 +serdes_driver_current_lane3_62=0x09 +serdes_preemphasis_lane0_62=0x244a02 +serdes_preemphasis_lane1_62=0x254902 +serdes_preemphasis_lane2_62=0x244a02 +serdes_preemphasis_lane3_62=0x244a02 + +#ce12 +serdes_driver_current_lane0_84=0x09 +serdes_driver_current_lane1_84=0x09 +serdes_driver_current_lane2_84=0x09 +serdes_driver_current_lane3_84=0x09 +serdes_preemphasis_lane0_84=0x204e02 +serdes_preemphasis_lane1_84=0x204e02 +serdes_preemphasis_lane2_84=0x204e02 +serdes_preemphasis_lane3_84=0x204e02 + +#ce13 +serdes_driver_current_lane0_88=0x09 +serdes_driver_current_lane1_88=0x08 +serdes_driver_current_lane2_88=0x08 +serdes_driver_current_lane3_88=0x09 +serdes_preemphasis_lane0_88=0x204e02 +serdes_preemphasis_lane1_88=0x1d5102 +serdes_preemphasis_lane2_88=0x1d5102 +serdes_preemphasis_lane3_88=0x204e02 + +#ce14 +serdes_driver_current_lane0_92=0x09 +serdes_driver_current_lane1_92=0x08 +serdes_driver_current_lane2_92=0x08 +serdes_driver_current_lane3_92=0x09 +serdes_preemphasis_lane0_92=0x204e02 +serdes_preemphasis_lane1_92=0x1d5102 +serdes_preemphasis_lane2_92=0x1d5102 +serdes_preemphasis_lane3_92=0x204e02 + +#ce15 +serdes_driver_current_lane0_96=0x08 +serdes_driver_current_lane1_96=0x08 +serdes_driver_current_lane2_96=0x09 +serdes_driver_current_lane3_96=0x09 +serdes_preemphasis_lane0_96=0x1d5102 +serdes_preemphasis_lane1_96=0x1d5102 +serdes_preemphasis_lane2_96=0x204e02 +serdes_preemphasis_lane3_96=0x204e02 + +#ce16 +serdes_driver_current_lane0_102=0x09 +serdes_driver_current_lane1_102=0x08 +serdes_driver_current_lane2_102=0x08 +serdes_driver_current_lane3_102=0x09 +serdes_preemphasis_lane0_102=0x204e02 +serdes_preemphasis_lane1_102=0x1d5102 +serdes_preemphasis_lane2_102=0x1d5102 +serdes_preemphasis_lane3_102=0x224c02 + +#ce17 +serdes_driver_current_lane0_106=0x09 +serdes_driver_current_lane1_106=0x08 +serdes_driver_current_lane2_106=0x08 +serdes_driver_current_lane3_106=0x09 +serdes_preemphasis_lane0_106=0x204e02 +serdes_preemphasis_lane1_106=0x1d5102 +serdes_preemphasis_lane2_106=0x1d5102 +serdes_preemphasis_lane3_106=0x204e02 + +#ce18 +serdes_driver_current_lane0_110=0x09 +serdes_driver_current_lane1_110=0x08 +serdes_driver_current_lane2_110=0x08 +serdes_driver_current_lane3_110=0x09 +serdes_preemphasis_lane0_110=0x204e02 +serdes_preemphasis_lane1_110=0x1d5102 +serdes_preemphasis_lane2_110=0x1d5102 +serdes_preemphasis_lane3_110=0x204e02 + +#ce19 +serdes_driver_current_lane0_114=0x09 +serdes_driver_current_lane1_114=0x08 +serdes_driver_current_lane2_114=0x09 +serdes_driver_current_lane3_114=0x09 +serdes_preemphasis_lane0_114=0x204e02 +serdes_preemphasis_lane1_114=0x1d5102 +serdes_preemphasis_lane2_114=0x224c02 +serdes_preemphasis_lane3_114=0x224c02 + +#ce20 +serdes_driver_current_lane0_1=0x09 +serdes_driver_current_lane1_1=0x0a +serdes_driver_current_lane2_1=0x09 +serdes_driver_current_lane3_1=0x0a +serdes_preemphasis_lane0_1=0x244a02 +serdes_preemphasis_lane1_1=0x254902 +serdes_preemphasis_lane2_1=0x244a02 +serdes_preemphasis_lane3_1=0x254902 + +#ce21 +serdes_driver_current_lane0_5=0x09 +serdes_driver_current_lane1_5=0x09 +serdes_driver_current_lane2_5=0x09 +serdes_driver_current_lane3_5=0x0a +serdes_preemphasis_lane0_5=0x244a02 +serdes_preemphasis_lane1_5=0x244a02 +serdes_preemphasis_lane2_5=0x244a02 +serdes_preemphasis_lane3_5=0x254902 + +#ce22 +serdes_driver_current_lane0_9=0x0a +serdes_driver_current_lane1_9=0x0a +serdes_driver_current_lane2_9=0x0a +serdes_driver_current_lane3_9=0x0a +serdes_preemphasis_lane0_9=0x254902 +serdes_preemphasis_lane1_9=0x254902 +serdes_preemphasis_lane2_9=0x254902 +serdes_preemphasis_lane3_9=0x294403 + +#ce23 +serdes_driver_current_lane0_13=0x09 +serdes_driver_current_lane1_13=0x0a +serdes_driver_current_lane2_13=0x0a +serdes_driver_current_lane3_13=0x0a +serdes_preemphasis_lane0_13=0x244a02 +serdes_preemphasis_lane1_13=0x254902 +serdes_preemphasis_lane2_13=0x294403 +serdes_preemphasis_lane3_13=0x294403 + +#ce24 +serdes_driver_current_lane0_17=0x0a +serdes_driver_current_lane1_17=0x0a +serdes_driver_current_lane2_17=0x0a +serdes_driver_current_lane3_17=0x0a +serdes_preemphasis_lane0_17=0x254902 +serdes_preemphasis_lane1_17=0x294403 +serdes_preemphasis_lane2_17=0x294403 +serdes_preemphasis_lane3_17=0x294403 + +#ce25 +serdes_driver_current_lane0_21=0x0a +serdes_driver_current_lane1_21=0x0a +serdes_driver_current_lane2_21=0x0a +serdes_driver_current_lane3_21=0x0a +serdes_preemphasis_lane0_21=0x294403 +serdes_preemphasis_lane1_21=0x294403 +serdes_preemphasis_lane2_21=0x294403 +serdes_preemphasis_lane3_21=0x254902 + +#ce26 +serdes_driver_current_lane0_25=0x0b +serdes_driver_current_lane1_25=0x0b +serdes_driver_current_lane2_25=0x0b +serdes_driver_current_lane3_25=0x0b +serdes_preemphasis_lane0_25=0x2b4104 +serdes_preemphasis_lane1_25=0x2b4104 +serdes_preemphasis_lane2_25=0x2b4104 +serdes_preemphasis_lane3_25=0x2d3f04 + +#ce27 +serdes_driver_current_lane0_29=0x0b +serdes_driver_current_lane1_29=0x0b +serdes_driver_current_lane2_29=0x0b +serdes_driver_current_lane3_29=0x0a +serdes_preemphasis_lane0_29=0x2d3f04 +serdes_preemphasis_lane1_29=0x2d3f04 +serdes_preemphasis_lane2_29=0x2b4104 +serdes_preemphasis_lane3_29=0x294403 + +#ce28 +serdes_driver_current_lane0_118=0x0a +serdes_driver_current_lane1_118=0x0a +serdes_driver_current_lane2_118=0x0a +serdes_driver_current_lane3_118=0x0a +serdes_preemphasis_lane0_118=0x254902 +serdes_preemphasis_lane1_118=0x294403 +serdes_preemphasis_lane2_118=0x294403 +serdes_preemphasis_lane3_118=0x254902 + +#ce29 +serdes_driver_current_lane0_122=0x0a +serdes_driver_current_lane1_122=0x0a +serdes_driver_current_lane2_122=0x0a +serdes_driver_current_lane3_122=0x0a +serdes_preemphasis_lane0_122=0x294403 +serdes_preemphasis_lane1_122=0x294403 +serdes_preemphasis_lane2_122=0x294403 +serdes_preemphasis_lane3_122=0x294403 + +#ce30 +serdes_driver_current_lane0_126=0x0a +serdes_driver_current_lane1_126=0x0a +serdes_driver_current_lane2_126=0x0b +serdes_driver_current_lane3_126=0x0b +serdes_preemphasis_lane0_126=0x294403 +serdes_preemphasis_lane1_126=0x294403 +serdes_preemphasis_lane2_126=0x2b4104 +serdes_preemphasis_lane3_126=0x2b4104 + +#ce31 +serdes_driver_current_lane0_130=0x0b +serdes_driver_current_lane1_130=0x0b +serdes_driver_current_lane2_130=0x0b +serdes_driver_current_lane3_130=0x0b +serdes_preemphasis_lane0_130=0x2d3f04 +serdes_preemphasis_lane1_130=0x2d3f04 +serdes_preemphasis_lane2_130=0x2b4104 +serdes_preemphasis_lane3_130=0x2b4104 From c8b2810d483e19bd5eccb90468425dadf19e886e Mon Sep 17 00:00:00 2001 From: Taoyu Li Date: Thu, 19 Apr 2018 11:25:08 -0700 Subject: [PATCH 101/219] [sudoer] Enable read-only commands for all users (#1558) --- files/image_config/sudoers/sudoers | 3 +++ 1 file changed, 3 insertions(+) diff --git a/files/image_config/sudoers/sudoers b/files/image_config/sudoers/sudoers index 952a2313bad2..7cfa0baba0f1 100644 --- a/files/image_config/sudoers/sudoers +++ b/files/image_config/sudoers/sudoers @@ -37,6 +37,9 @@ Cmnd_Alias PASSWD_CMDS = /usr/bin/config tacacs passkey *, \ # User privilege specification root ALL=(ALL:ALL) ALL +# Allow all users to execute read only commands +ALL ALL=NOPASSWD: READ_ONLY_CMDS + # Allow members of group sudo to execute any command %sudo ALL=(ALL:ALL) NOPASSWD: ALL From 7378aa1e687c0abbb2a6b06df9018232c7d1b0bb Mon Sep 17 00:00:00 2001 From: sihuihan88 Date: Fri, 13 Jul 2018 02:18:55 -0700 Subject: [PATCH 102/219] [sonic-swss]: Update submodule in 201803 branch (#1855) * [submodule]: update 201803 branch Signed-off-by: Sihui Han * [submodule]: update 201803 branch with pospone queuemap enhancement Signed-off-by: Sihui Han --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index ed9c1c8b59de..6dba3161c79f 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit ed9c1c8b59ded974bd3ab7d0db6266d222689dfa +Subproject commit 6dba3161c79fff23332a0fa8933e0f464e4dec10 From de7b951c9dd15342cbda6b99a929640de44c4f72 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Fri, 13 Jul 2018 02:18:21 -0700 Subject: [PATCH 103/219] [sonic-dbsyncd]: Support empty string in lldp_rem_port_desc (#1857) Signed-off-by: Qi Luo --- src/sonic-dbsyncd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-dbsyncd b/src/sonic-dbsyncd index 1d0b2165e097..a091914b4e6d 160000 --- a/src/sonic-dbsyncd +++ b/src/sonic-dbsyncd @@ -1 +1 @@ -Subproject commit 1d0b2165e097ee668c8e982cf3cf413e4f2555d2 +Subproject commit a091914b4e6dd6ee85131106a1da1bdf036a5912 From fc51c107584c8557e6d14673911a44eced69a47f Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Fri, 13 Jul 2018 16:58:46 -0700 Subject: [PATCH 104/219] [sonic-dbsyncd]: Fix parse_chassis on partial lldp data (#1861) --- src/sonic-dbsyncd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-dbsyncd b/src/sonic-dbsyncd index a091914b4e6d..94f2700f67f8 160000 --- a/src/sonic-dbsyncd +++ b/src/sonic-dbsyncd @@ -1 +1 @@ -Subproject commit a091914b4e6dd6ee85131106a1da1bdf036a5912 +Subproject commit 94f2700f67f87b431c7ce45e4b9d7788707c6732 From ae8a088a28dd54b49c78ba568b7e5268e08aa58b Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Tue, 17 Apr 2018 21:10:17 -0700 Subject: [PATCH 105/219] [test] Adding Broadcom configuration file test (#1611) * [test] Adding Broadcom configuration file test In order to allow SONiC community to check in Broadcom configuration file directly under device folder. We need to add this test to make sure the contents of the configuration is compliant with Broadcom specifications. * Invoke test from Debian package builder * Use $() syntax * Remove the debug echo statement --- .../Arista-7260CX3-D108C8/sai.profile | 2 +- .../th2-a7260cx3-64-112x50G+8x100G.config.bcm | 939 ++++++++++++++++++ src/sonic-device-data/src/Makefile | 11 + src/sonic-device-data/tests/LICENSE | 42 + src/sonic-device-data/tests/config_checker | 92 ++ src/sonic-device-data/tests/permitted_list | 134 +++ 6 files changed, 1219 insertions(+), 1 deletion(-) create mode 100644 device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/th2-a7260cx3-64-112x50G+8x100G.config.bcm create mode 100644 src/sonic-device-data/src/Makefile create mode 100644 src/sonic-device-data/tests/LICENSE create mode 100755 src/sonic-device-data/tests/config_checker create mode 100644 src/sonic-device-data/tests/permitted_list diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/sai.profile b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/sai.profile index 9ceb20f96a48..235f2423df82 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/sai.profile +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/sai.profile @@ -1 +1 @@ -SAI_INIT_CONFIG_FILE=/etc/bcm/th2-a7260cx3-64-112x50G+8x100G.config.bcm +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th2-a7260cx3-64-112x50G+8x100G.config.bcm diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/th2-a7260cx3-64-112x50G+8x100G.config.bcm b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/th2-a7260cx3-64-112x50G+8x100G.config.bcm new file mode 100644 index 000000000000..120b13c037aa --- /dev/null +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/th2-a7260cx3-64-112x50G+8x100G.config.bcm @@ -0,0 +1,939 @@ +PHY_AN_ALLOW_PLL_CHANGE=1 +arl_clean_timeout_usec=15000000 +asf_mem_profile=2 +bcm_num_cos=8 +bcm_stat_flags=1 +bcm_stat_jumbo=9236 +cdma_timeout_usec=15000000 +core_clock_frequency=1700 +dma_desc_timeout_usec=15000000 +dpp_clock_ratio=2:3 +higig2_hdr_mode=1 +ipv6_lpm_128b_enable=1 +l3_alpm_enable=2 +lpm_scaling_enable=0 +l2xmsg_mode=1 +max_vp_lags=0 +mem_scan_enable=1 +miim_intr_enable=0 +module_64ports=1 +os=unix +oversubscribe_mode=1 +pbmp_xport_xe=0xfffffffd3fffffff4fffffffc7ffffffe +#pbmp_xport_xe=0x47fffffff1fffffffcfffffffe7ffffffe +phy_an_allow_pll_change_hg=0 +phy_an_c73=1 +phy_chain_rx_lane_map_physical{1.0}=0x3210 +phy_chain_rx_lane_map_physical{101.0}=0x0123 +phy_chain_rx_lane_map_physical{105.0}=0x0123 +phy_chain_rx_lane_map_physical{109.0}=0x0123 +phy_chain_rx_lane_map_physical{113.0}=0x2301 +phy_chain_rx_lane_map_physical{117.0}=0x3210 +phy_chain_rx_lane_map_physical{121.0}=0x3210 +phy_chain_rx_lane_map_physical{125.0}=0x1203 +phy_chain_rx_lane_map_physical{129.0}=0x3210 +phy_chain_rx_lane_map_physical{13.0}=0x0321 +phy_chain_rx_lane_map_physical{133.0}=0x1032 +phy_chain_rx_lane_map_physical{137.0}=0x3210 +phy_chain_rx_lane_map_physical{141.0}=0x0123 +phy_chain_rx_lane_map_physical{145.0}=0x3210 +phy_chain_rx_lane_map_physical{149.0}=0x2310 +phy_chain_rx_lane_map_physical{153.0}=0x0132 +phy_chain_rx_lane_map_physical{157.0}=0x1302 +phy_chain_rx_lane_map_physical{161.0}=0x3021 +phy_chain_rx_lane_map_physical{165.0}=0x2031 +phy_chain_rx_lane_map_physical{169.0}=0x2031 +phy_chain_rx_lane_map_physical{17.0}=0x3210 +phy_chain_rx_lane_map_physical{173.0}=0x1302 +phy_chain_rx_lane_map_physical{177.0}=0x2031 +phy_chain_rx_lane_map_physical{181.0}=0x0213 +phy_chain_rx_lane_map_physical{185.0}=0x0213 +phy_chain_rx_lane_map_physical{189.0}=0x1302 +phy_chain_rx_lane_map_physical{193.0}=0x3120 +phy_chain_rx_lane_map_physical{197.0}=0x0231 +phy_chain_rx_lane_map_physical{201.0}=0x2031 +phy_chain_rx_lane_map_physical{205.0}=0x0213 +phy_chain_rx_lane_map_physical{209.0}=0x2013 +phy_chain_rx_lane_map_physical{21.0}=0x3021 +phy_chain_rx_lane_map_physical{213.0}=0x3021 +phy_chain_rx_lane_map_physical{217.0}=0x0231 +phy_chain_rx_lane_map_physical{221.0}=0x2031 +phy_chain_rx_lane_map_physical{225.0}=0x1203 +phy_chain_rx_lane_map_physical{229.0}=0x1230 +phy_chain_rx_lane_map_physical{233.0}=0x3021 +phy_chain_rx_lane_map_physical{237.0}=0x1032 +phy_chain_rx_lane_map_physical{241.0}=0x2301 +phy_chain_rx_lane_map_physical{245.0}=0x0321 +phy_chain_rx_lane_map_physical{249.0}=0x2301 +phy_chain_rx_lane_map_physical{25.0}=0x2301 +phy_chain_rx_lane_map_physical{253.0}=0x2301 +phy_chain_rx_lane_map_physical{257.0}=0x3210 +phy_chain_rx_lane_map_physical{29.0}=0x3021 +phy_chain_rx_lane_map_physical{33.0}=0x1302 +phy_chain_rx_lane_map_physical{37.0}=0x2031 +phy_chain_rx_lane_map_physical{41.0}=0x3021 +phy_chain_rx_lane_map_physical{45.0}=0x1023 +phy_chain_rx_lane_map_physical{49.0}=0x0213 +phy_chain_rx_lane_map_physical{5.0}=0x3201 +phy_chain_rx_lane_map_physical{53.0}=0x3201 +phy_chain_rx_lane_map_physical{57.0}=0x2013 +phy_chain_rx_lane_map_physical{61.0}=0x0213 +phy_chain_rx_lane_map_physical{65.0}=0x1203 +phy_chain_rx_lane_map_physical{69.0}=0x0213 +phy_chain_rx_lane_map_physical{73.0}=0x0213 +phy_chain_rx_lane_map_physical{77.0}=0x3120 +phy_chain_rx_lane_map_physical{81.0}=0x0213 +phy_chain_rx_lane_map_physical{85.0}=0x2031 +phy_chain_rx_lane_map_physical{89.0}=0x2031 +phy_chain_rx_lane_map_physical{9.0}=0x0321 +phy_chain_rx_lane_map_physical{93.0}=0x3120 +phy_chain_rx_lane_map_physical{97.0}=0x1203 +phy_chain_rx_polarity_flip_physical{1.0}=0x1 +phy_chain_rx_polarity_flip_physical{10.0}=0x0 +phy_chain_rx_polarity_flip_physical{100.0}=0x1 +phy_chain_rx_polarity_flip_physical{101.0}=0x1 +phy_chain_rx_polarity_flip_physical{102.0}=0x0 +phy_chain_rx_polarity_flip_physical{103.0}=0x1 +phy_chain_rx_polarity_flip_physical{104.0}=0x0 +phy_chain_rx_polarity_flip_physical{105.0}=0x1 +phy_chain_rx_polarity_flip_physical{106.0}=0x0 +phy_chain_rx_polarity_flip_physical{107.0}=0x1 +phy_chain_rx_polarity_flip_physical{108.0}=0x0 +phy_chain_rx_polarity_flip_physical{109.0}=0x0 +phy_chain_rx_polarity_flip_physical{11.0}=0x1 +phy_chain_rx_polarity_flip_physical{110.0}=0x1 +phy_chain_rx_polarity_flip_physical{111.0}=0x0 +phy_chain_rx_polarity_flip_physical{112.0}=0x1 +phy_chain_rx_polarity_flip_physical{113.0}=0x1 +phy_chain_rx_polarity_flip_physical{114.0}=0x0 +phy_chain_rx_polarity_flip_physical{115.0}=0x1 +phy_chain_rx_polarity_flip_physical{116.0}=0x0 +phy_chain_rx_polarity_flip_physical{117.0}=0x0 +phy_chain_rx_polarity_flip_physical{118.0}=0x0 +phy_chain_rx_polarity_flip_physical{119.0}=0x1 +phy_chain_rx_polarity_flip_physical{12.0}=0x1 +phy_chain_rx_polarity_flip_physical{120.0}=0x0 +phy_chain_rx_polarity_flip_physical{121.0}=0x1 +phy_chain_rx_polarity_flip_physical{122.0}=0x0 +phy_chain_rx_polarity_flip_physical{123.0}=0x1 +phy_chain_rx_polarity_flip_physical{124.0}=0x0 +phy_chain_rx_polarity_flip_physical{125.0}=0x0 +phy_chain_rx_polarity_flip_physical{126.0}=0x1 +phy_chain_rx_polarity_flip_physical{127.0}=0x1 +phy_chain_rx_polarity_flip_physical{128.0}=0x1 +phy_chain_rx_polarity_flip_physical{129.0}=0x0 +phy_chain_rx_polarity_flip_physical{13.0}=0x1 +phy_chain_rx_polarity_flip_physical{130.0}=0x1 +phy_chain_rx_polarity_flip_physical{131.0}=0x1 +phy_chain_rx_polarity_flip_physical{132.0}=0x0 +phy_chain_rx_polarity_flip_physical{133.0}=0x1 +phy_chain_rx_polarity_flip_physical{134.0}=0x1 +phy_chain_rx_polarity_flip_physical{135.0}=0x1 +phy_chain_rx_polarity_flip_physical{136.0}=0x0 +phy_chain_rx_polarity_flip_physical{137.0}=0x0 +phy_chain_rx_polarity_flip_physical{138.0}=0x0 +phy_chain_rx_polarity_flip_physical{139.0}=0x1 +phy_chain_rx_polarity_flip_physical{14.0}=0x0 +phy_chain_rx_polarity_flip_physical{140.0}=0x0 +phy_chain_rx_polarity_flip_physical{141.0}=0x1 +phy_chain_rx_polarity_flip_physical{142.0}=0x0 +phy_chain_rx_polarity_flip_physical{143.0}=0x1 +phy_chain_rx_polarity_flip_physical{144.0}=0x0 +phy_chain_rx_polarity_flip_physical{145.0}=0x1 +phy_chain_rx_polarity_flip_physical{146.0}=0x0 +phy_chain_rx_polarity_flip_physical{147.0}=0x1 +phy_chain_rx_polarity_flip_physical{148.0}=0x0 +phy_chain_rx_polarity_flip_physical{149.0}=0x0 +phy_chain_rx_polarity_flip_physical{15.0}=0x1 +phy_chain_rx_polarity_flip_physical{150.0}=0x1 +phy_chain_rx_polarity_flip_physical{151.0}=0x1 +phy_chain_rx_polarity_flip_physical{152.0}=0x0 +phy_chain_rx_polarity_flip_physical{153.0}=0x0 +phy_chain_rx_polarity_flip_physical{154.0}=0x1 +phy_chain_rx_polarity_flip_physical{155.0}=0x1 +phy_chain_rx_polarity_flip_physical{156.0}=0x0 +phy_chain_rx_polarity_flip_physical{157.0}=0x0 +phy_chain_rx_polarity_flip_physical{158.0}=0x0 +phy_chain_rx_polarity_flip_physical{159.0}=0x1 +phy_chain_rx_polarity_flip_physical{16.0}=0x0 +phy_chain_rx_polarity_flip_physical{160.0}=0x0 +phy_chain_rx_polarity_flip_physical{161.0}=0x1 +phy_chain_rx_polarity_flip_physical{162.0}=0x1 +phy_chain_rx_polarity_flip_physical{163.0}=0x0 +phy_chain_rx_polarity_flip_physical{164.0}=0x1 +phy_chain_rx_polarity_flip_physical{165.0}=0x0 +phy_chain_rx_polarity_flip_physical{166.0}=0x0 +phy_chain_rx_polarity_flip_physical{167.0}=0x1 +phy_chain_rx_polarity_flip_physical{168.0}=0x1 +phy_chain_rx_polarity_flip_physical{169.0}=0x1 +phy_chain_rx_polarity_flip_physical{17.0}=0x1 +phy_chain_rx_polarity_flip_physical{170.0}=0x1 +phy_chain_rx_polarity_flip_physical{171.0}=0x0 +phy_chain_rx_polarity_flip_physical{172.0}=0x0 +phy_chain_rx_polarity_flip_physical{173.0}=0x0 +phy_chain_rx_polarity_flip_physical{174.0}=0x0 +phy_chain_rx_polarity_flip_physical{175.0}=0x1 +phy_chain_rx_polarity_flip_physical{176.0}=0x1 +phy_chain_rx_polarity_flip_physical{177.0}=0x1 +phy_chain_rx_polarity_flip_physical{178.0}=0x1 +phy_chain_rx_polarity_flip_physical{179.0}=0x0 +phy_chain_rx_polarity_flip_physical{18.0}=0x0 +phy_chain_rx_polarity_flip_physical{180.0}=0x0 +phy_chain_rx_polarity_flip_physical{181.0}=0x1 +phy_chain_rx_polarity_flip_physical{182.0}=0x1 +phy_chain_rx_polarity_flip_physical{183.0}=0x0 +phy_chain_rx_polarity_flip_physical{184.0}=0x0 +phy_chain_rx_polarity_flip_physical{185.0}=0x0 +phy_chain_rx_polarity_flip_physical{186.0}=0x0 +phy_chain_rx_polarity_flip_physical{187.0}=0x1 +phy_chain_rx_polarity_flip_physical{188.0}=0x1 +phy_chain_rx_polarity_flip_physical{189.0}=0x0 +phy_chain_rx_polarity_flip_physical{19.0}=0x1 +phy_chain_rx_polarity_flip_physical{190.0}=0x0 +phy_chain_rx_polarity_flip_physical{191.0}=0x1 +phy_chain_rx_polarity_flip_physical{192.0}=0x0 +phy_chain_rx_polarity_flip_physical{193.0}=0x0 +phy_chain_rx_polarity_flip_physical{194.0}=0x0 +phy_chain_rx_polarity_flip_physical{195.0}=0x1 +phy_chain_rx_polarity_flip_physical{196.0}=0x1 +phy_chain_rx_polarity_flip_physical{197.0}=0x1 +phy_chain_rx_polarity_flip_physical{198.0}=0x1 +phy_chain_rx_polarity_flip_physical{199.0}=0x0 +phy_chain_rx_polarity_flip_physical{2.0}=0x0 +phy_chain_rx_polarity_flip_physical{20.0}=0x0 +phy_chain_rx_polarity_flip_physical{200.0}=0x0 +phy_chain_rx_polarity_flip_physical{201.0}=0x0 +phy_chain_rx_polarity_flip_physical{202.0}=0x0 +phy_chain_rx_polarity_flip_physical{203.0}=0x1 +phy_chain_rx_polarity_flip_physical{204.0}=0x0 +phy_chain_rx_polarity_flip_physical{205.0}=0x1 +phy_chain_rx_polarity_flip_physical{206.0}=0x1 +phy_chain_rx_polarity_flip_physical{207.0}=0x0 +phy_chain_rx_polarity_flip_physical{208.0}=0x0 +phy_chain_rx_polarity_flip_physical{209.0}=0x1 +phy_chain_rx_polarity_flip_physical{21.0}=0x0 +phy_chain_rx_polarity_flip_physical{210.0}=0x1 +phy_chain_rx_polarity_flip_physical{211.0}=0x0 +phy_chain_rx_polarity_flip_physical{212.0}=0x0 +phy_chain_rx_polarity_flip_physical{213.0}=0x0 +phy_chain_rx_polarity_flip_physical{214.0}=0x0 +phy_chain_rx_polarity_flip_physical{215.0}=0x1 +phy_chain_rx_polarity_flip_physical{216.0}=0x0 +phy_chain_rx_polarity_flip_physical{217.0}=0x0 +phy_chain_rx_polarity_flip_physical{218.0}=0x0 +phy_chain_rx_polarity_flip_physical{219.0}=0x1 +phy_chain_rx_polarity_flip_physical{22.0}=0x0 +phy_chain_rx_polarity_flip_physical{220.0}=0x1 +phy_chain_rx_polarity_flip_physical{221.0}=0x0 +phy_chain_rx_polarity_flip_physical{222.0}=0x0 +phy_chain_rx_polarity_flip_physical{223.0}=0x1 +phy_chain_rx_polarity_flip_physical{224.0}=0x1 +phy_chain_rx_polarity_flip_physical{225.0}=0x1 +phy_chain_rx_polarity_flip_physical{226.0}=0x0 +phy_chain_rx_polarity_flip_physical{227.0}=0x0 +phy_chain_rx_polarity_flip_physical{228.0}=0x1 +phy_chain_rx_polarity_flip_physical{229.0}=0x0 +phy_chain_rx_polarity_flip_physical{23.0}=0x1 +phy_chain_rx_polarity_flip_physical{230.0}=0x0 +phy_chain_rx_polarity_flip_physical{231.0}=0x1 +phy_chain_rx_polarity_flip_physical{232.0}=0x1 +phy_chain_rx_polarity_flip_physical{233.0}=0x1 +phy_chain_rx_polarity_flip_physical{234.0}=0x0 +phy_chain_rx_polarity_flip_physical{235.0}=0x0 +phy_chain_rx_polarity_flip_physical{236.0}=0x0 +phy_chain_rx_polarity_flip_physical{237.0}=0x1 +phy_chain_rx_polarity_flip_physical{238.0}=0x0 +phy_chain_rx_polarity_flip_physical{239.0}=0x1 +phy_chain_rx_polarity_flip_physical{24.0}=0x0 +phy_chain_rx_polarity_flip_physical{240.0}=0x0 +phy_chain_rx_polarity_flip_physical{241.0}=0x1 +phy_chain_rx_polarity_flip_physical{242.0}=0x0 +phy_chain_rx_polarity_flip_physical{243.0}=0x1 +phy_chain_rx_polarity_flip_physical{244.0}=0x0 +phy_chain_rx_polarity_flip_physical{245.0}=0x1 +phy_chain_rx_polarity_flip_physical{246.0}=0x1 +phy_chain_rx_polarity_flip_physical{247.0}=0x1 +phy_chain_rx_polarity_flip_physical{248.0}=0x0 +phy_chain_rx_polarity_flip_physical{249.0}=0x0 +phy_chain_rx_polarity_flip_physical{25.0}=0x1 +phy_chain_rx_polarity_flip_physical{250.0}=0x1 +phy_chain_rx_polarity_flip_physical{251.0}=0x0 +phy_chain_rx_polarity_flip_physical{252.0}=0x1 +phy_chain_rx_polarity_flip_physical{253.0}=0x1 +phy_chain_rx_polarity_flip_physical{254.0}=0x0 +phy_chain_rx_polarity_flip_physical{255.0}=0x1 +phy_chain_rx_polarity_flip_physical{256.0}=0x0 +phy_chain_rx_polarity_flip_physical{257.0}=0x0 +phy_chain_rx_polarity_flip_physical{259.0}=0x0 +phy_chain_rx_polarity_flip_physical{26.0}=0x0 +phy_chain_rx_polarity_flip_physical{27.0}=0x1 +phy_chain_rx_polarity_flip_physical{28.0}=0x0 +phy_chain_rx_polarity_flip_physical{29.0}=0x0 +phy_chain_rx_polarity_flip_physical{3.0}=0x1 +phy_chain_rx_polarity_flip_physical{30.0}=0x0 +phy_chain_rx_polarity_flip_physical{31.0}=0x0 +phy_chain_rx_polarity_flip_physical{32.0}=0x1 +phy_chain_rx_polarity_flip_physical{33.0}=0x0 +phy_chain_rx_polarity_flip_physical{34.0}=0x0 +phy_chain_rx_polarity_flip_physical{35.0}=0x1 +phy_chain_rx_polarity_flip_physical{36.0}=0x1 +phy_chain_rx_polarity_flip_physical{37.0}=0x1 +phy_chain_rx_polarity_flip_physical{38.0}=0x1 +phy_chain_rx_polarity_flip_physical{39.0}=0x0 +phy_chain_rx_polarity_flip_physical{4.0}=0x0 +phy_chain_rx_polarity_flip_physical{40.0}=0x0 +phy_chain_rx_polarity_flip_physical{41.0}=0x0 +phy_chain_rx_polarity_flip_physical{42.0}=0x1 +phy_chain_rx_polarity_flip_physical{43.0}=0x1 +phy_chain_rx_polarity_flip_physical{44.0}=0x1 +phy_chain_rx_polarity_flip_physical{45.0}=0x1 +phy_chain_rx_polarity_flip_physical{46.0}=0x0 +phy_chain_rx_polarity_flip_physical{47.0}=0x0 +phy_chain_rx_polarity_flip_physical{48.0}=0x1 +phy_chain_rx_polarity_flip_physical{49.0}=0x1 +phy_chain_rx_polarity_flip_physical{5.0}=0x1 +phy_chain_rx_polarity_flip_physical{50.0}=0x1 +phy_chain_rx_polarity_flip_physical{51.0}=0x0 +phy_chain_rx_polarity_flip_physical{52.0}=0x0 +phy_chain_rx_polarity_flip_physical{53.0}=0x0 +phy_chain_rx_polarity_flip_physical{54.0}=0x0 +phy_chain_rx_polarity_flip_physical{55.0}=0x1 +phy_chain_rx_polarity_flip_physical{56.0}=0x0 +phy_chain_rx_polarity_flip_physical{57.0}=0x0 +phy_chain_rx_polarity_flip_physical{58.0}=0x0 +phy_chain_rx_polarity_flip_physical{59.0}=0x1 +phy_chain_rx_polarity_flip_physical{6.0}=0x0 +phy_chain_rx_polarity_flip_physical{60.0}=0x1 +phy_chain_rx_polarity_flip_physical{61.0}=0x0 +phy_chain_rx_polarity_flip_physical{62.0}=0x0 +phy_chain_rx_polarity_flip_physical{63.0}=0x1 +phy_chain_rx_polarity_flip_physical{64.0}=0x1 +phy_chain_rx_polarity_flip_physical{65.0}=0x1 +phy_chain_rx_polarity_flip_physical{66.0}=0x1 +phy_chain_rx_polarity_flip_physical{67.0}=0x0 +phy_chain_rx_polarity_flip_physical{68.0}=0x1 +phy_chain_rx_polarity_flip_physical{69.0}=0x0 +phy_chain_rx_polarity_flip_physical{7.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{71.0}=0x1 +phy_chain_rx_polarity_flip_physical{72.0}=0x1 +phy_chain_rx_polarity_flip_physical{73.0}=0x1 +phy_chain_rx_polarity_flip_physical{74.0}=0x1 +phy_chain_rx_polarity_flip_physical{75.0}=0x0 +phy_chain_rx_polarity_flip_physical{76.0}=0x0 +phy_chain_rx_polarity_flip_physical{77.0}=0x0 +phy_chain_rx_polarity_flip_physical{78.0}=0x0 +phy_chain_rx_polarity_flip_physical{79.0}=0x1 +phy_chain_rx_polarity_flip_physical{8.0}=0x1 +phy_chain_rx_polarity_flip_physical{80.0}=0x1 +phy_chain_rx_polarity_flip_physical{81.0}=0x1 +phy_chain_rx_polarity_flip_physical{82.0}=0x1 +phy_chain_rx_polarity_flip_physical{83.0}=0x0 +phy_chain_rx_polarity_flip_physical{84.0}=0x0 +phy_chain_rx_polarity_flip_physical{85.0}=0x1 +phy_chain_rx_polarity_flip_physical{86.0}=0x1 +phy_chain_rx_polarity_flip_physical{87.0}=0x0 +phy_chain_rx_polarity_flip_physical{88.0}=0x0 +phy_chain_rx_polarity_flip_physical{89.0}=0x0 +phy_chain_rx_polarity_flip_physical{9.0}=0x1 +phy_chain_rx_polarity_flip_physical{90.0}=0x0 +phy_chain_rx_polarity_flip_physical{91.0}=0x1 +phy_chain_rx_polarity_flip_physical{92.0}=0x1 +phy_chain_rx_polarity_flip_physical{93.0}=0x0 +phy_chain_rx_polarity_flip_physical{94.0}=0x0 +phy_chain_rx_polarity_flip_physical{95.0}=0x1 +phy_chain_rx_polarity_flip_physical{96.0}=0x0 +phy_chain_rx_polarity_flip_physical{97.0}=0x1 +phy_chain_rx_polarity_flip_physical{98.0}=0x1 +phy_chain_rx_polarity_flip_physical{99.0}=0x0 +phy_chain_tx_lane_map_physical{1.0}=0x2031 +phy_chain_tx_lane_map_physical{101.0}=0x1023 +phy_chain_tx_lane_map_physical{105.0}=0x1302 +phy_chain_tx_lane_map_physical{109.0}=0x0321 +phy_chain_tx_lane_map_physical{113.0}=0x2301 +phy_chain_tx_lane_map_physical{117.0}=0x3120 +phy_chain_tx_lane_map_physical{121.0}=0x3102 +phy_chain_tx_lane_map_physical{125.0}=0x3210 +phy_chain_tx_lane_map_physical{129.0}=0x1023 +phy_chain_tx_lane_map_physical{13.0}=0x3021 +phy_chain_tx_lane_map_physical{133.0}=0x3210 +phy_chain_tx_lane_map_physical{137.0}=0x2031 +phy_chain_tx_lane_map_physical{141.0}=0x1302 +phy_chain_tx_lane_map_physical{145.0}=0x3210 +phy_chain_tx_lane_map_physical{149.0}=0x0213 +phy_chain_tx_lane_map_physical{153.0}=0x3210 +phy_chain_tx_lane_map_physical{157.0}=0x1320 +phy_chain_tx_lane_map_physical{161.0}=0x3210 +phy_chain_tx_lane_map_physical{165.0}=0x0231 +phy_chain_tx_lane_map_physical{169.0}=0x3120 +phy_chain_tx_lane_map_physical{17.0}=0x1032 +phy_chain_tx_lane_map_physical{173.0}=0x0312 +phy_chain_tx_lane_map_physical{177.0}=0x0231 +phy_chain_tx_lane_map_physical{181.0}=0x3210 +phy_chain_tx_lane_map_physical{185.0}=0x3210 +phy_chain_tx_lane_map_physical{189.0}=0x1320 +phy_chain_tx_lane_map_physical{193.0}=0x0321 +phy_chain_tx_lane_map_physical{197.0}=0x3120 +phy_chain_tx_lane_map_physical{201.0}=0x3120 +phy_chain_tx_lane_map_physical{205.0}=0x0123 +phy_chain_tx_lane_map_physical{209.0}=0x3120 +phy_chain_tx_lane_map_physical{21.0}=0x0213 +phy_chain_tx_lane_map_physical{213.0}=0x3021 +phy_chain_tx_lane_map_physical{217.0}=0x0312 +phy_chain_tx_lane_map_physical{221.0}=0x2301 +phy_chain_tx_lane_map_physical{225.0}=0x0123 +phy_chain_tx_lane_map_physical{229.0}=0x2031 +phy_chain_tx_lane_map_physical{233.0}=0x0231 +phy_chain_tx_lane_map_physical{237.0}=0x0213 +phy_chain_tx_lane_map_physical{241.0}=0x1320 +phy_chain_tx_lane_map_physical{245.0}=0x2031 +phy_chain_tx_lane_map_physical{249.0}=0x3120 +phy_chain_tx_lane_map_physical{25.0}=0x0231 +phy_chain_tx_lane_map_physical{253.0}=0x0321 +phy_chain_tx_lane_map_physical{257.0}=0x3210 +phy_chain_tx_lane_map_physical{29.0}=0x1230 +phy_chain_tx_lane_map_physical{33.0}=0x1032 +phy_chain_tx_lane_map_physical{37.0}=0x0123 +phy_chain_tx_lane_map_physical{41.0}=0x0213 +phy_chain_tx_lane_map_physical{45.0}=0x0132 +phy_chain_tx_lane_map_physical{49.0}=0x2031 +phy_chain_tx_lane_map_physical{5.0}=0x2301 +phy_chain_tx_lane_map_physical{53.0}=0x2301 +phy_chain_tx_lane_map_physical{57.0}=0x2031 +phy_chain_tx_lane_map_physical{61.0}=0x2031 +phy_chain_tx_lane_map_physical{65.0}=0x1230 +phy_chain_tx_lane_map_physical{69.0}=0x2013 +phy_chain_tx_lane_map_physical{73.0}=0x0213 +phy_chain_tx_lane_map_physical{77.0}=0x2310 +phy_chain_tx_lane_map_physical{81.0}=0x0321 +phy_chain_tx_lane_map_physical{85.0}=0x2013 +phy_chain_tx_lane_map_physical{89.0}=0x0213 +phy_chain_tx_lane_map_physical{9.0}=0x3012 +phy_chain_tx_lane_map_physical{93.0}=0x3102 +phy_chain_tx_lane_map_physical{97.0}=0x3210 +phy_chain_tx_polarity_flip_physical{1.0}=0x0 +phy_chain_tx_polarity_flip_physical{10.0}=0x1 +phy_chain_tx_polarity_flip_physical{100.0}=0x0 +phy_chain_tx_polarity_flip_physical{101.0}=0x0 +phy_chain_tx_polarity_flip_physical{102.0}=0x1 +phy_chain_tx_polarity_flip_physical{103.0}=0x0 +phy_chain_tx_polarity_flip_physical{104.0}=0x0 +phy_chain_tx_polarity_flip_physical{105.0}=0x0 +phy_chain_tx_polarity_flip_physical{106.0}=0x1 +phy_chain_tx_polarity_flip_physical{107.0}=0x1 +phy_chain_tx_polarity_flip_physical{108.0}=0x1 +phy_chain_tx_polarity_flip_physical{109.0}=0x0 +phy_chain_tx_polarity_flip_physical{11.0}=0x1 +phy_chain_tx_polarity_flip_physical{110.0}=0x0 +phy_chain_tx_polarity_flip_physical{111.0}=0x0 +phy_chain_tx_polarity_flip_physical{112.0}=0x1 +phy_chain_tx_polarity_flip_physical{113.0}=0x1 +phy_chain_tx_polarity_flip_physical{114.0}=0x1 +phy_chain_tx_polarity_flip_physical{115.0}=0x1 +phy_chain_tx_polarity_flip_physical{116.0}=0x0 +phy_chain_tx_polarity_flip_physical{117.0}=0x1 +phy_chain_tx_polarity_flip_physical{118.0}=0x0 +phy_chain_tx_polarity_flip_physical{119.0}=0x0 +phy_chain_tx_polarity_flip_physical{12.0}=0x0 +phy_chain_tx_polarity_flip_physical{120.0}=0x0 +phy_chain_tx_polarity_flip_physical{121.0}=0x0 +phy_chain_tx_polarity_flip_physical{122.0}=0x0 +phy_chain_tx_polarity_flip_physical{123.0}=0x0 +phy_chain_tx_polarity_flip_physical{124.0}=0x1 +phy_chain_tx_polarity_flip_physical{125.0}=0x0 +phy_chain_tx_polarity_flip_physical{126.0}=0x1 +phy_chain_tx_polarity_flip_physical{127.0}=0x1 +phy_chain_tx_polarity_flip_physical{128.0}=0x1 +phy_chain_tx_polarity_flip_physical{129.0}=0x1 +phy_chain_tx_polarity_flip_physical{13.0}=0x0 +phy_chain_tx_polarity_flip_physical{130.0}=0x0 +phy_chain_tx_polarity_flip_physical{131.0}=0x1 +phy_chain_tx_polarity_flip_physical{132.0}=0x0 +phy_chain_tx_polarity_flip_physical{133.0}=0x1 +phy_chain_tx_polarity_flip_physical{134.0}=0x1 +phy_chain_tx_polarity_flip_physical{135.0}=0x1 +phy_chain_tx_polarity_flip_physical{136.0}=0x1 +phy_chain_tx_polarity_flip_physical{137.0}=0x1 +phy_chain_tx_polarity_flip_physical{138.0}=0x1 +phy_chain_tx_polarity_flip_physical{139.0}=0x1 +phy_chain_tx_polarity_flip_physical{14.0}=0x1 +phy_chain_tx_polarity_flip_physical{140.0}=0x1 +phy_chain_tx_polarity_flip_physical{141.0}=0x0 +phy_chain_tx_polarity_flip_physical{142.0}=0x1 +phy_chain_tx_polarity_flip_physical{143.0}=0x1 +phy_chain_tx_polarity_flip_physical{144.0}=0x1 +phy_chain_tx_polarity_flip_physical{145.0}=0x1 +phy_chain_tx_polarity_flip_physical{146.0}=0x1 +phy_chain_tx_polarity_flip_physical{147.0}=0x1 +phy_chain_tx_polarity_flip_physical{148.0}=0x0 +phy_chain_tx_polarity_flip_physical{149.0}=0x1 +phy_chain_tx_polarity_flip_physical{15.0}=0x0 +phy_chain_tx_polarity_flip_physical{150.0}=0x0 +phy_chain_tx_polarity_flip_physical{151.0}=0x0 +phy_chain_tx_polarity_flip_physical{152.0}=0x0 +phy_chain_tx_polarity_flip_physical{153.0}=0x1 +phy_chain_tx_polarity_flip_physical{154.0}=0x0 +phy_chain_tx_polarity_flip_physical{155.0}=0x0 +phy_chain_tx_polarity_flip_physical{156.0}=0x0 +phy_chain_tx_polarity_flip_physical{157.0}=0x0 +phy_chain_tx_polarity_flip_physical{158.0}=0x0 +phy_chain_tx_polarity_flip_physical{159.0}=0x0 +phy_chain_tx_polarity_flip_physical{16.0}=0x0 +phy_chain_tx_polarity_flip_physical{160.0}=0x0 +phy_chain_tx_polarity_flip_physical{161.0}=0x0 +phy_chain_tx_polarity_flip_physical{162.0}=0x1 +phy_chain_tx_polarity_flip_physical{163.0}=0x1 +phy_chain_tx_polarity_flip_physical{164.0}=0x0 +phy_chain_tx_polarity_flip_physical{165.0}=0x1 +phy_chain_tx_polarity_flip_physical{166.0}=0x1 +phy_chain_tx_polarity_flip_physical{167.0}=0x1 +phy_chain_tx_polarity_flip_physical{168.0}=0x0 +phy_chain_tx_polarity_flip_physical{169.0}=0x0 +phy_chain_tx_polarity_flip_physical{17.0}=0x0 +phy_chain_tx_polarity_flip_physical{170.0}=0x1 +phy_chain_tx_polarity_flip_physical{171.0}=0x1 +phy_chain_tx_polarity_flip_physical{172.0}=0x1 +phy_chain_tx_polarity_flip_physical{173.0}=0x0 +phy_chain_tx_polarity_flip_physical{174.0}=0x0 +phy_chain_tx_polarity_flip_physical{175.0}=0x1 +phy_chain_tx_polarity_flip_physical{176.0}=0x0 +phy_chain_tx_polarity_flip_physical{177.0}=0x1 +phy_chain_tx_polarity_flip_physical{178.0}=0x0 +phy_chain_tx_polarity_flip_physical{179.0}=0x0 +phy_chain_tx_polarity_flip_physical{18.0}=0x1 +phy_chain_tx_polarity_flip_physical{180.0}=0x0 +phy_chain_tx_polarity_flip_physical{181.0}=0x0 +phy_chain_tx_polarity_flip_physical{182.0}=0x0 +phy_chain_tx_polarity_flip_physical{183.0}=0x0 +phy_chain_tx_polarity_flip_physical{184.0}=0x1 +phy_chain_tx_polarity_flip_physical{185.0}=0x0 +phy_chain_tx_polarity_flip_physical{186.0}=0x1 +phy_chain_tx_polarity_flip_physical{187.0}=0x1 +phy_chain_tx_polarity_flip_physical{188.0}=0x1 +phy_chain_tx_polarity_flip_physical{189.0}=0x0 +phy_chain_tx_polarity_flip_physical{19.0}=0x1 +phy_chain_tx_polarity_flip_physical{190.0}=0x0 +phy_chain_tx_polarity_flip_physical{191.0}=0x0 +phy_chain_tx_polarity_flip_physical{192.0}=0x0 +phy_chain_tx_polarity_flip_physical{193.0}=0x1 +phy_chain_tx_polarity_flip_physical{194.0}=0x1 +phy_chain_tx_polarity_flip_physical{195.0}=0x1 +phy_chain_tx_polarity_flip_physical{196.0}=0x0 +phy_chain_tx_polarity_flip_physical{197.0}=0x0 +phy_chain_tx_polarity_flip_physical{198.0}=0x1 +phy_chain_tx_polarity_flip_physical{199.0}=0x1 +phy_chain_tx_polarity_flip_physical{2.0}=0x1 +phy_chain_tx_polarity_flip_physical{20.0}=0x1 +phy_chain_tx_polarity_flip_physical{200.0}=0x1 +phy_chain_tx_polarity_flip_physical{201.0}=0x1 +phy_chain_tx_polarity_flip_physical{202.0}=0x1 +phy_chain_tx_polarity_flip_physical{203.0}=0x1 +phy_chain_tx_polarity_flip_physical{204.0}=0x1 +phy_chain_tx_polarity_flip_physical{205.0}=0x0 +phy_chain_tx_polarity_flip_physical{206.0}=0x1 +phy_chain_tx_polarity_flip_physical{207.0}=0x1 +phy_chain_tx_polarity_flip_physical{208.0}=0x1 +phy_chain_tx_polarity_flip_physical{209.0}=0x1 +phy_chain_tx_polarity_flip_physical{21.0}=0x0 +phy_chain_tx_polarity_flip_physical{210.0}=0x1 +phy_chain_tx_polarity_flip_physical{211.0}=0x1 +phy_chain_tx_polarity_flip_physical{212.0}=0x0 +phy_chain_tx_polarity_flip_physical{213.0}=0x0 +phy_chain_tx_polarity_flip_physical{214.0}=0x1 +phy_chain_tx_polarity_flip_physical{215.0}=0x0 +phy_chain_tx_polarity_flip_physical{216.0}=0x1 +phy_chain_tx_polarity_flip_physical{217.0}=0x1 +phy_chain_tx_polarity_flip_physical{218.0}=0x1 +phy_chain_tx_polarity_flip_physical{219.0}=0x0 +phy_chain_tx_polarity_flip_physical{22.0}=0x0 +phy_chain_tx_polarity_flip_physical{220.0}=0x1 +phy_chain_tx_polarity_flip_physical{221.0}=0x0 +phy_chain_tx_polarity_flip_physical{222.0}=0x0 +phy_chain_tx_polarity_flip_physical{223.0}=0x0 +phy_chain_tx_polarity_flip_physical{224.0}=0x1 +phy_chain_tx_polarity_flip_physical{225.0}=0x1 +phy_chain_tx_polarity_flip_physical{226.0}=0x1 +phy_chain_tx_polarity_flip_physical{227.0}=0x1 +phy_chain_tx_polarity_flip_physical{228.0}=0x0 +phy_chain_tx_polarity_flip_physical{229.0}=0x0 +phy_chain_tx_polarity_flip_physical{23.0}=0x0 +phy_chain_tx_polarity_flip_physical{230.0}=0x1 +phy_chain_tx_polarity_flip_physical{231.0}=0x1 +phy_chain_tx_polarity_flip_physical{232.0}=0x1 +phy_chain_tx_polarity_flip_physical{233.0}=0x0 +phy_chain_tx_polarity_flip_physical{234.0}=0x0 +phy_chain_tx_polarity_flip_physical{235.0}=0x0 +phy_chain_tx_polarity_flip_physical{236.0}=0x0 +phy_chain_tx_polarity_flip_physical{237.0}=0x1 +phy_chain_tx_polarity_flip_physical{238.0}=0x1 +phy_chain_tx_polarity_flip_physical{239.0}=0x1 +phy_chain_tx_polarity_flip_physical{24.0}=0x0 +phy_chain_tx_polarity_flip_physical{240.0}=0x0 +phy_chain_tx_polarity_flip_physical{241.0}=0x1 +phy_chain_tx_polarity_flip_physical{242.0}=0x1 +phy_chain_tx_polarity_flip_physical{243.0}=0x1 +phy_chain_tx_polarity_flip_physical{244.0}=0x0 +phy_chain_tx_polarity_flip_physical{245.0}=0x1 +phy_chain_tx_polarity_flip_physical{246.0}=0x1 +phy_chain_tx_polarity_flip_physical{247.0}=0x1 +phy_chain_tx_polarity_flip_physical{248.0}=0x1 +phy_chain_tx_polarity_flip_physical{249.0}=0x1 +phy_chain_tx_polarity_flip_physical{25.0}=0x1 +phy_chain_tx_polarity_flip_physical{250.0}=0x0 +phy_chain_tx_polarity_flip_physical{251.0}=0x0 +phy_chain_tx_polarity_flip_physical{252.0}=0x0 +phy_chain_tx_polarity_flip_physical{253.0}=0x1 +phy_chain_tx_polarity_flip_physical{254.0}=0x1 +phy_chain_tx_polarity_flip_physical{255.0}=0x1 +phy_chain_tx_polarity_flip_physical{256.0}=0x0 +phy_chain_tx_polarity_flip_physical{257.0}=0x0 +phy_chain_tx_polarity_flip_physical{259.0}=0x0 +phy_chain_tx_polarity_flip_physical{26.0}=0x0 +phy_chain_tx_polarity_flip_physical{27.0}=0x0 +phy_chain_tx_polarity_flip_physical{28.0}=0x0 +phy_chain_tx_polarity_flip_physical{29.0}=0x1 +phy_chain_tx_polarity_flip_physical{3.0}=0x1 +phy_chain_tx_polarity_flip_physical{30.0}=0x1 +phy_chain_tx_polarity_flip_physical{31.0}=0x1 +phy_chain_tx_polarity_flip_physical{32.0}=0x0 +phy_chain_tx_polarity_flip_physical{33.0}=0x0 +phy_chain_tx_polarity_flip_physical{34.0}=0x0 +phy_chain_tx_polarity_flip_physical{35.0}=0x0 +phy_chain_tx_polarity_flip_physical{36.0}=0x1 +phy_chain_tx_polarity_flip_physical{37.0}=0x1 +phy_chain_tx_polarity_flip_physical{38.0}=0x1 +phy_chain_tx_polarity_flip_physical{39.0}=0x1 +phy_chain_tx_polarity_flip_physical{4.0}=0x1 +phy_chain_tx_polarity_flip_physical{40.0}=0x0 +phy_chain_tx_polarity_flip_physical{41.0}=0x0 +phy_chain_tx_polarity_flip_physical{42.0}=0x0 +phy_chain_tx_polarity_flip_physical{43.0}=0x0 +phy_chain_tx_polarity_flip_physical{44.0}=0x0 +phy_chain_tx_polarity_flip_physical{45.0}=0x1 +phy_chain_tx_polarity_flip_physical{46.0}=0x0 +phy_chain_tx_polarity_flip_physical{47.0}=0x1 +phy_chain_tx_polarity_flip_physical{48.0}=0x1 +phy_chain_tx_polarity_flip_physical{49.0}=0x0 +phy_chain_tx_polarity_flip_physical{5.0}=0x1 +phy_chain_tx_polarity_flip_physical{50.0}=0x0 +phy_chain_tx_polarity_flip_physical{51.0}=0x0 +phy_chain_tx_polarity_flip_physical{52.0}=0x1 +phy_chain_tx_polarity_flip_physical{53.0}=0x0 +phy_chain_tx_polarity_flip_physical{54.0}=0x1 +phy_chain_tx_polarity_flip_physical{55.0}=0x1 +phy_chain_tx_polarity_flip_physical{56.0}=0x0 +phy_chain_tx_polarity_flip_physical{57.0}=0x0 +phy_chain_tx_polarity_flip_physical{58.0}=0x1 +phy_chain_tx_polarity_flip_physical{59.0}=0x1 +phy_chain_tx_polarity_flip_physical{6.0}=0x1 +phy_chain_tx_polarity_flip_physical{60.0}=0x1 +phy_chain_tx_polarity_flip_physical{61.0}=0x0 +phy_chain_tx_polarity_flip_physical{62.0}=0x1 +phy_chain_tx_polarity_flip_physical{63.0}=0x1 +phy_chain_tx_polarity_flip_physical{64.0}=0x1 +phy_chain_tx_polarity_flip_physical{65.0}=0x0 +phy_chain_tx_polarity_flip_physical{66.0}=0x1 +phy_chain_tx_polarity_flip_physical{67.0}=0x1 +phy_chain_tx_polarity_flip_physical{68.0}=0x0 +phy_chain_tx_polarity_flip_physical{69.0}=0x1 +phy_chain_tx_polarity_flip_physical{7.0}=0x1 +phy_chain_tx_polarity_flip_physical{70.0}=0x1 +phy_chain_tx_polarity_flip_physical{71.0}=0x1 +phy_chain_tx_polarity_flip_physical{72.0}=0x0 +phy_chain_tx_polarity_flip_physical{73.0}=0x1 +phy_chain_tx_polarity_flip_physical{74.0}=0x0 +phy_chain_tx_polarity_flip_physical{75.0}=0x0 +phy_chain_tx_polarity_flip_physical{76.0}=0x0 +phy_chain_tx_polarity_flip_physical{77.0}=0x0 +phy_chain_tx_polarity_flip_physical{78.0}=0x0 +phy_chain_tx_polarity_flip_physical{79.0}=0x1 +phy_chain_tx_polarity_flip_physical{8.0}=0x0 +phy_chain_tx_polarity_flip_physical{80.0}=0x0 +phy_chain_tx_polarity_flip_physical{81.0}=0x1 +phy_chain_tx_polarity_flip_physical{82.0}=0x1 +phy_chain_tx_polarity_flip_physical{83.0}=0x1 +phy_chain_tx_polarity_flip_physical{84.0}=0x0 +phy_chain_tx_polarity_flip_physical{85.0}=0x1 +phy_chain_tx_polarity_flip_physical{86.0}=0x0 +phy_chain_tx_polarity_flip_physical{87.0}=0x0 +phy_chain_tx_polarity_flip_physical{88.0}=0x0 +phy_chain_tx_polarity_flip_physical{89.0}=0x1 +phy_chain_tx_polarity_flip_physical{9.0}=0x0 +phy_chain_tx_polarity_flip_physical{90.0}=0x1 +phy_chain_tx_polarity_flip_physical{91.0}=0x1 +phy_chain_tx_polarity_flip_physical{92.0}=0x0 +phy_chain_tx_polarity_flip_physical{93.0}=0x0 +phy_chain_tx_polarity_flip_physical{94.0}=0x0 +phy_chain_tx_polarity_flip_physical{95.0}=0x0 +phy_chain_tx_polarity_flip_physical{96.0}=0x0 +phy_chain_tx_polarity_flip_physical{97.0}=0x0 +phy_chain_tx_polarity_flip_physical{98.0}=0x1 +phy_chain_tx_polarity_flip_physical{99.0}=0x1 + +port_init_cl72_hg=1 + + + + + + + +robust_hash_disable_egress_vlan=1 +robust_hash_disable_mpls=1 +robust_hash_disable_vlan=1 +scache_filename=/tmp/scache +scache_filename=/tmp/scache +sram_scan_enable=0 +stable_size=0x5500000 +stable_size=0x5500000 +tdma_timeout_usec=15000000 +tslam_timeout_usec=15000000 +dport_map_direct=1 +portmap_1=5:50 +portmap_2=7:50 +portmap_3=13:50 +portmap_4=15:50 +portmap_5=25:50 +portmap_6=27:50 +portmap_7=21:50 +portmap_8=23:50 +portmap_9=37:50 +portmap_10=39:50 +portmap_11=45:50 +portmap_12=47:50 +portmap_13=57:100 +portmap_14=53:100 +portmap_15=9:50 +portmap_16=11:50 +portmap_17=1:50 +portmap_18=3:50 +portmap_19=17:50 +portmap_20=19:50 +portmap_21=29:50 +portmap_22=31:50 +portmap_23=41:50 +portmap_24=43:50 +portmap_25=33:50 +portmap_26=35:50 +portmap_27=49:50 +portmap_28=51:50 +portmap_29=61:50 +portmap_30=63:50 +portmap_34=77:50 +portmap_35=79:50 +portmap_36=65:50 +portmap_37=67:50 +portmap_38=85:50 +portmap_39=87:50 +portmap_40=89:50 +portmap_41=91:50 +portmap_42=109:50 +portmap_43=111:50 +portmap_44=97:50 +portmap_45=99:50 +portmap_46=117:100 +portmap_47=121:100 +portmap_48=69:50 +portmap_49=71:50 +portmap_50=73:50 +portmap_51=75:50 +portmap_52=93:50 +portmap_53=95:50 +portmap_54=81:50 +portmap_55=83:50 +portmap_56=101:50 +portmap_57=103:50 +portmap_58=105:50 +portmap_59=107:50 +portmap_60=125:50 +portmap_61=127:50 +portmap_62=113:50 +portmap_63=115:50 +portmap_66=257:10 +portmap_68=141:100 +portmap_69=133:100 +portmap_70=149:50 +portmap_71=151:50 +portmap_72=153:50 +portmap_73=155:50 +portmap_74=173:50 +portmap_75=175:50 +portmap_76=161:50 +portmap_77=163:50 +portmap_78=181:50 +portmap_79=183:50 +portmap_80=185:50 +portmap_81=187:50 +portmap_82=129:50 +portmap_83=131:50 +portmap_84=137:50 +portmap_85=139:50 +portmap_86=157:50 +portmap_87=159:50 +portmap_88=145:50 +portmap_89=147:50 +portmap_90=165:50 +portmap_91=167:50 +portmap_92=169:50 +portmap_93=171:50 +portmap_94=189:50 +portmap_95=191:50 +portmap_96=177:50 +portmap_97=179:50 +portmap_100=259:10 +portmap_102=197:100 +portmap_103=205:100 +portmap_104=217:50 +portmap_105=219:50 +portmap_106=213:50 +portmap_107=215:50 +portmap_108=229:50 +portmap_109=231:50 +portmap_110=237:50 +portmap_111=239:50 +portmap_112=249:50 +portmap_113=251:50 +portmap_114=245:50 +portmap_115=247:50 +portmap_116=201:50 +portmap_117=203:50 +portmap_118=193:50 +portmap_119=195:50 +portmap_120=209:50 +portmap_121=211:50 +portmap_122=221:50 +portmap_123=223:50 +portmap_124=233:50 +portmap_125=235:50 +portmap_126=225:50 +portmap_127=227:50 +portmap_128=241:50 +portmap_129=243:50 +portmap_130=253:50 +portmap_131=255:50 + +# tuning parameters +serdes_preemphasis_1=0x580c +serdes_preemphasis_2=0x580c +serdes_preemphasis_3=0x580c +serdes_preemphasis_4=0x580c +serdes_preemphasis_5=0x580c +serdes_preemphasis_6=0x580c +serdes_preemphasis_7=0x580c +serdes_preemphasis_8=0x580c +serdes_preemphasis_9=0x580c +serdes_preemphasis_10=0x580c +serdes_preemphasis_11=0x580c +serdes_preemphasis_12=0x580c +serdes_preemphasis_13=0x144108 +serdes_preemphasis_14=0x144108 +serdes_preemphasis_15=0x580c +serdes_preemphasis_16=0x580c +serdes_preemphasis_17=0x580c +serdes_preemphasis_18=0x580c +serdes_preemphasis_19=0x580c +serdes_preemphasis_20=0x580c +serdes_preemphasis_21=0x580c +serdes_preemphasis_22=0x580c +serdes_preemphasis_23=0x580c +serdes_preemphasis_24=0x580c +serdes_preemphasis_25=0x580c +serdes_preemphasis_26=0x580c +serdes_preemphasis_27=0x580c +serdes_preemphasis_28=0x580c +serdes_preemphasis_29=0x580c +serdes_preemphasis_30=0x580c +serdes_preemphasis_34=0x580c +serdes_preemphasis_35=0x580c +serdes_preemphasis_36=0x580c +serdes_preemphasis_37=0x580c +serdes_preemphasis_38=0x580c +serdes_preemphasis_39=0x580c +serdes_preemphasis_40=0x580c +serdes_preemphasis_41=0x580c +serdes_preemphasis_42=0x580c +serdes_preemphasis_43=0x580c +serdes_preemphasis_44=0x580c +serdes_preemphasis_45=0x580c +serdes_preemphasis_46=0x144108 +serdes_preemphasis_47=0x103a07 +serdes_preemphasis_48=0x580c +serdes_preemphasis_49=0x580c +serdes_preemphasis_50=0x580c +serdes_preemphasis_51=0x580c +serdes_preemphasis_52=0x580c +serdes_preemphasis_53=0x580c +serdes_preemphasis_54=0x580c +serdes_preemphasis_55=0x580c +serdes_preemphasis_56=0x580c +serdes_preemphasis_57=0x580c +serdes_preemphasis_58=0x580c +serdes_preemphasis_59=0x580c +serdes_preemphasis_60=0x580c +serdes_preemphasis_61=0x580c +serdes_preemphasis_62=0x580c +serdes_preemphasis_63=0x580c +serdes_preemphasis_66=0x62f01 +serdes_preemphasis_68=0x184606 +serdes_preemphasis_69=0x184407 +serdes_preemphasis_70=0x580c +serdes_preemphasis_71=0x580c +serdes_preemphasis_72=0x580c +serdes_preemphasis_73=0x580c +serdes_preemphasis_74=0x580c +serdes_preemphasis_75=0x580c +serdes_preemphasis_76=0x580c +serdes_preemphasis_77=0x580c +serdes_preemphasis_78=0x580c +serdes_preemphasis_79=0x580c +serdes_preemphasis_80=0x580c +serdes_preemphasis_81=0x580c +serdes_preemphasis_82=0x580c +serdes_preemphasis_83=0x580c +serdes_preemphasis_84=0x580c +serdes_preemphasis_85=0x580c +serdes_preemphasis_86=0x580c +serdes_preemphasis_87=0x580c +serdes_preemphasis_88=0x580c +serdes_preemphasis_89=0x580c +serdes_preemphasis_90=0x580c +serdes_preemphasis_91=0x580c +serdes_preemphasis_92=0x580c +serdes_preemphasis_93=0x580c +serdes_preemphasis_94=0x580c +serdes_preemphasis_95=0x580c +serdes_preemphasis_96=0x580c +serdes_preemphasis_97=0x580c +serdes_preemphasis_100=0x62f01 +serdes_preemphasis_102=0x174507 +serdes_preemphasis_103=0x184606 +serdes_preemphasis_104=0x580c +serdes_preemphasis_105=0x580c +serdes_preemphasis_106=0x580c +serdes_preemphasis_107=0x580c +serdes_preemphasis_108=0x580c +serdes_preemphasis_109=0x580c +serdes_preemphasis_110=0x580c +serdes_preemphasis_111=0x580c +serdes_preemphasis_112=0x580c +serdes_preemphasis_113=0x580c +serdes_preemphasis_114=0x580c +serdes_preemphasis_115=0x580c +serdes_preemphasis_116=0x580c +serdes_preemphasis_117=0x580c +serdes_preemphasis_118=0x580c +serdes_preemphasis_119=0x580c +serdes_preemphasis_120=0x580c +serdes_preemphasis_121=0x580c +serdes_preemphasis_122=0x580c +serdes_preemphasis_123=0x580c +serdes_preemphasis_124=0x580c +serdes_preemphasis_125=0x580c +serdes_preemphasis_126=0x580c +serdes_preemphasis_127=0x580c +serdes_preemphasis_128=0x580c +serdes_preemphasis_129=0x580c +serdes_preemphasis_130=0x580c +serdes_preemphasis_131=0x580c + +mmu_init_config="MSFT-TH2-Tier0" diff --git a/src/sonic-device-data/src/Makefile b/src/sonic-device-data/src/Makefile new file mode 100644 index 000000000000..9c0037fd50c7 --- /dev/null +++ b/src/sonic-device-data/src/Makefile @@ -0,0 +1,11 @@ +.ONESHELL: +SHELL = /bin/bash +.SHELLFLAGS += -e + +test: + # Execute Broadcom config file test + pushd ../tests/ + for f in $$(find ../../../device -name "*.config.bcm"); do + ./config_checker $$f + done + popd diff --git a/src/sonic-device-data/tests/LICENSE b/src/sonic-device-data/tests/LICENSE new file mode 100644 index 000000000000..fd8968a9bd4e --- /dev/null +++ b/src/sonic-device-data/tests/LICENSE @@ -0,0 +1,42 @@ +Copyright: Copyright 2017 Broadcom Corporation. + +This program is the proprietary software of Broadcom Corporation +and/or its licensors, and may only be used, duplicated, modified +or distributed pursuant to the terms and conditions of a separate, +written license agreement executed between you and Broadcom +(an "Authorized License"). Except as set forth in an Authorized +License, Broadcom grants no license (express or implied), right +to use, or waiver of any kind with respect to the Software, and +Broadcom expressly reserves all rights in and to the Software +and all intellectual property rights therein. IF YOU HAVE +NO AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS SOFTWARE +IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE +ALL USE OF THE SOFTWARE. + + Except as expressly set forth in the Authorized License, + + 1. This program, including its structure, sequence and organization, +constitutes the valuable trade secrets of Broadcom, and you shall use +all reasonable efforts to protect the confidentiality thereof, +and to use this information only in connection with your use of +Broadcom integrated circuit products. + + 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS +PROVIDED "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, +REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, +OR OTHERWISE, WITH RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY +DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY, +NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, +ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR +CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING +OUT OF USE OR PERFORMANCE OF THE SOFTWARE. + + 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL +BROADCOM OR ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, +INCIDENTAL, SPECIAL, INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER +ARISING OUT OF OR IN ANY WAY RELATING TO YOUR USE OF OR INABILITY +TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF +THE AMOUNT ACTUALLY PAID FOR THE SOFTWARE ITSELF OR USD 1.00, +WHICHEVER IS GREATER. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING +ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDY. diff --git a/src/sonic-device-data/tests/config_checker b/src/sonic-device-data/tests/config_checker new file mode 100755 index 000000000000..51c32c19c3e4 --- /dev/null +++ b/src/sonic-device-data/tests/config_checker @@ -0,0 +1,92 @@ +#!/usr/bin/env python +import re +import sys +import glob + +permitted_properties = [] + +def usage(): + print "Usage: " + sys.argv[0] + " " + sys.exit(1) + +def check_property(p): + if p in permitted_properties: + return True + # Try to remove trailing . + if re.sub(r".\d+$", "", p) in permitted_properties: + return True + # Try to remove trailing _. + if re.sub(r"_\d+.\d+$", "", p) in permitted_properties: + return True + # Try to remove trailing _hg. + if re.sub(r"_hg.0$", "", p) in permitted_properties: + return True + # Try to remove trailing _[cx]e + if re.sub(r"_[cx]e\d*$", "", p) in permitted_properties: + return True + # Try to remove trailing _lane_ + if re.sub(r"_lane\d_\d+$", "", p) in permitted_properties: + return True + # Try to remove trailing _lane_. + if re.sub(r"_lane\d_\d+.\d+$", "", p) in permitted_properties: + return True + # Try to remove trailing _lane_[cx]e + if re.sub(r"_lane\d_[cx]e\d+$", "", p) in permitted_properties: + return True + return False + +def check_file(file_name): + try: + file_ok = True + failed_properties = [] + lineno = 0 + with open(file_name) as f: + for line in f.readlines(): + lineno = lineno + 1 + # Check both commented and uncommented lines + line = line.strip().lstrip('#').strip().lower() + if line.find("=") == -1: + continue + p = line.split("=", 1)[0] + # Remove trailing "{.}" + p = re.sub('{[0-9]+\.[0-9]+}', '', p) + # Check if = in the line + if not check_property(p): + file_ok = False + print("[line %d] Error: %s is not permitted" % (lineno, p)) + if file_ok: + print "Result: " + file_name + " PASSED the config check!" + else: + print "Result: " + file_name + " FAILED the config check!" + return file_ok + except IOError: + print "Error: Cannot open file " + file_name + return False + + +def main(argv): + global permitted_properties + + if len(argv) > 0 and argv[0] == "-h": + usage() + + # Load permitted properties + with open("permitted_list") as f: + permitted_properties = [p.strip().lower() for p in f.readlines()] + + # Load target file + if len(argv) == 0: + files = glob.glob('*.config.bcm') + else: + files = argv + + all_good = True + for f in files: + good = check_file(f) + all_good = all_good and good + + if not all_good: + sys.exit(-1) + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/src/sonic-device-data/tests/permitted_list b/src/sonic-device-data/tests/permitted_list new file mode 100644 index 000000000000..150a16292c91 --- /dev/null +++ b/src/sonic-device-data/tests/permitted_list @@ -0,0 +1,134 @@ +arl_clean_timeout_usec +asf_mem_profile +bcm_linkscan_interval +bcm_num_cos +bcm_stat_flags +bcm_stat_interval +bcm_stat_jumbo +bcm_tunnel_term_compatible_mode +bcm_xlate_port_enable +cdma_timeout_usec +core_clock_frequency +ctr_evict_enable +dma_desc_timeout_usec +dport_map_direct +dport_map_enable +dport_map_indexed +dport_map_port +dpp_clock_ratio +force_core_pll +fpem_mem_entries +higig2_hdr_mode +ipmc_do_vlan +ipv6_lpm_128b_enable +knet_filter_persist +l2_mem_entries +l2delete_chunks +l2mod_dma_intr_enable +l2xmsg_hostbuf_size +l2xmsg_mode +l3_alpm_enable +l3_intf_vlan_split_egress +l3_max_ecmp_mode +l3_mem_entries +lls_num_l2uc +load_firmware +logical_ports +lpm_ipv6_128b_reserved +lpm_scaling_enable +max_vp_lags +mdio_output_delay +mem_cache_enable +mem_check_nocache_override +mem_clear_hw_a +mem_nocache +mem_scan_enable +memcmd_intr_enable +miim_intr_enable +miim_timeout_usec +mmu_init_config +mmu_lossless +module_64ports +multicast_l2_r +multicast_l2_range +multicast_l3_range +no_leds_proc +num_ipv6_lpm_128b_entries +os +oversubscribe_mode +parity_correction +parity_enable +pbmp_oversubscribe +pbmp_xport_xe +pci2eb_overrid +pfc_deadlock_seq_control +phy_84328 +phy_84752 +phy_an_allow_pll_change +phy_an_allow_pll_change_hg +phy_an_c37 +phy_an_c73 +phy_an_fec +phy_aux_voltage_enable +phy_chain_rx_lane_map_physical +phy_chain_rx_polarity_flip_physical +phy_chain_tx_lane_map_physical +phy_chain_tx_polarity_flip_physical +phy_ext_rom_boot +phy_gearbox_enable +phy_line_tx_mode +phy_pcs_rx_polarity_flip +phy_pcs_tx_polarity_flip +phy_port_primary_and_offset +phy_rx_polarity_flip +phy_system_tx_mode +phy_tx_polarity_flip +phy_xaui_rx_polarity_flip +phy_xaui_tx_polarity_flip +physical_ports +port_init_autoneg +port_init_cl72 +port_init_cl72_hg +port_init_speed_xe +port_phy_addr +port_phy_clause +port_phy_id0 +port_phy_id1 +portmap +prbs_polynomial +ptp_bs_fref +ptp_ts_pll_fref +rate_ext_mdio_divisor +robust_hash_disable_egress_vlan +robust_hash_disable_mpls +robust_hash_disable_vlan +scache_filename +schan_intr_enable +schan_timeout_usec +serdes_automed +serdes_automedium +serdes_driver_current +serdes_fiber_pref +serdes_firmware_mode +serdes_if_type +serdes_pre_driver_current +serdes_preemphasis +serdes_rx_los_xe +serdes_sgmii_m +skip_L2_USER_ENTRY +sram_scan_enable +stable_size +start_vlan +stat_if_parity_enable +switch_bypass_mode +table_dma_enable +tdma_intr_enable +tdma_timeout_usec +tslam_dma_enable +tslam_intr_enable +tslam_timeout_usec +uplink_ports +xgxs_lcpll_xtal_refclk +xgxs_pdetect_1 +xgxs_rx_lane_map +xgxs_tx_lane_map From c36adc1ad8a56647a8104fa04e342e3e8e4eb58e Mon Sep 17 00:00:00 2001 From: Wenda Ni Date: Thu, 28 Jun 2018 16:50:14 -0700 Subject: [PATCH 106/219] Correct a7060 config for tor (#1823) Move a7060 configs out of syncd docker Signed-off-by: Wenda --- .../Arista-7060CX-32S-Q32/sai.profile.j2 | 6 +- .../th-a7060-cx32s-32x40G-t0.config.bcm | 444 ++++++++++++++++++ .../th-a7060-cx32s-32x40G-t1.config.bcm | 444 ++++++++++++++++++ 3 files changed, 891 insertions(+), 3 deletions(-) create mode 100644 device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/th-a7060-cx32s-32x40G-t0.config.bcm create mode 100644 device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/th-a7060-cx32s-32x40G-t1.config.bcm diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/sai.profile.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/sai.profile.j2 index bef6932f1eac..638fd28b0765 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/sai.profile.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/sai.profile.j2 @@ -2,12 +2,12 @@ {%- if DEVICE_METADATA is defined -%} {%- set switch_role = DEVICE_METADATA['localhost']['type'] -%} {%- if switch_role.lower() == 'torrouter' %} -{% set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/etc/bcm/th-a7060-cx32s-32x40G.config.bcm' -%} +{% set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-a7060-cx32s-32x40G-t0.config.bcm' -%} {%- else %} -{%- set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/etc/bcm/th-a7060-cx32s-32x40G-t1.config.bcm' -%} +{%- set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-a7060-cx32s-32x40G-t1.config.bcm' -%} {%- endif %} {%- else %} -{%- set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/etc/bcm/th-a7060-cx32s-32x40G-t1.config.bcm' -%} +{%- set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-a7060-cx32s-32x40G-t1.config.bcm' -%} {%- endif %} {# Write the contents of sai_ profile_filename to sai.profile file #} {{ sai_profile_contents }} diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/th-a7060-cx32s-32x40G-t0.config.bcm b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/th-a7060-cx32s-32x40G-t0.config.bcm new file mode 100644 index 000000000000..0cb4ae4a474a --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/th-a7060-cx32s-32x40G-t0.config.bcm @@ -0,0 +1,444 @@ +# Arista 7060CX-32S + +phy_an_allow_pll_change=1 +arl_clean_timeout_usec=15000000 +asf_mem_profile=2 +bcm_num_cos=8 +bcm_stat_flags=1 +bcm_stat_jumbo=9236 +cdma_timeout_usec=15000000 +dma_desc_timeout_usec=15000000 +higig2_hdr_mode=1 +ipv6_lpm_128b_enable=1 +l3_alpm_enable=2 +lpm_scaling_enable=0 +l2xmsg_mode=1 +max_vp_lags=0 +miim_intr_enable=0 +module_64ports=1 +os=unix +oversubscribe_mode=1 +ptp_bs_fref.0=25000000 +ptp_ts_pll_fref.0=25000000 +robust_hash_disable_egress_vlan.0=1 +robust_hash_disable_mpls.0=1 +robust_hash_disable_vlan.0=1 +tdma_timeout_usec.0=15000000 +tslam_timeout_usec.0=15000000 +pbmp_xport_xe.0=0x7ffffffffffffffffffffffffffffffffe +phy_an_allow_pll_change_hg.0=0 +phy_an_c73_1.0=1 +phy_an_c73_2.0=1 +phy_an_c73_3.0=1 +phy_an_c73_4.0=1 +phy_an_c73_5.0=1 +phy_an_c73_6.0=1 +phy_an_c73_7.0=1 +phy_an_c73_8.0=1 +phy_an_c73_34.0=1 +phy_an_c73_35.0=1 +phy_an_c73_36.0=1 +phy_an_c73_37.0=1 +phy_an_c73_38.0=1 +phy_an_c73_39.0=1 +phy_an_c73_40.0=1 +phy_an_c73_41.0=1 +phy_an_c73_68.0=1 +phy_an_c73_69.0=1 +phy_an_c73_70.0=1 +phy_an_c73_71.0=1 +phy_an_c73_72.0=1 +phy_an_c73_73.0=1 +phy_an_c73_74.0=1 +phy_an_c73_75.0=1 +phy_an_c73_102.0=1 +phy_an_c73_103.0=1 +phy_an_c73_104.0=1 +phy_an_c73_105.0=1 +phy_an_c73_106.0=1 +phy_an_c73_107.0=1 +phy_an_c73_108.0=1 +phy_an_c73_109.0=1 +phy_an_fec_1.0=1 +phy_an_fec_2.0=1 +phy_an_fec_3.0=1 +phy_an_fec_4.0=1 +phy_an_fec_5.0=1 +phy_an_fec_6.0=1 +phy_an_fec_7.0=1 +phy_an_fec_8.0=1 +phy_an_fec_9.0=1 +phy_an_fec_10.0=1 +phy_an_fec_11.0=1 +phy_an_fec_12.0=1 +phy_an_fec_13.0=1 +phy_an_fec_14.0=1 +phy_an_fec_15.0=1 +phy_an_fec_16.0=1 +phy_an_fec_17.0=1 +phy_an_fec_18.0=1 +phy_an_fec_19.0=1 +phy_an_fec_20.0=1 +phy_an_fec_21.0=1 +phy_an_fec_22.0=1 +phy_an_fec_23.0=1 +phy_an_fec_24.0=1 +phy_an_fec_25.0=1 +phy_an_fec_26.0=1 +phy_an_fec_27.0=1 +phy_an_fec_28.0=1 +phy_an_fec_29.0=1 +phy_an_fec_30.0=1 +phy_an_fec_31.0=1 +phy_an_fec_32.0=1 +phy_an_fec_34.0=1 +phy_an_fec_38.0=1 +phy_an_fec_39.0=1 +phy_an_fec_40.0=1 +phy_an_fec_41.0=1 +phy_an_fec_42.0=1 +phy_an_fec_43.0=1 +phy_an_fec_44.0=1 +phy_an_fec_45.0=1 +phy_an_fec_46.0=1 +phy_an_fec_47.0=1 +phy_an_fec_48.0=1 +phy_an_fec_49.0=1 +phy_an_fec_50.0=1 +phy_an_fec_51.0=1 +phy_an_fec_52.0=1 +phy_an_fec_53.0=1 +phy_an_fec_54.0=1 +phy_an_fec_55.0=1 +phy_an_fec_56.0=1 +phy_an_fec_57.0=1 +phy_an_fec_58.0=1 +phy_an_fec_59.0=1 +phy_an_fec_60.0=1 +phy_an_fec_61.0=1 +phy_an_fec_62.0=1 +phy_an_fec_63.0=1 +phy_an_fec_64.0=1 +phy_an_fec_65.0=1 +phy_an_fec_68.0=1 +phy_an_fec_69.0=1 +phy_an_fec_70.0=1 +phy_an_fec_71.0=1 +phy_an_fec_72.0=1 +phy_an_fec_73.0=1 +phy_an_fec_74.0=1 +phy_an_fec_75.0=1 +phy_an_fec_76.0=1 +phy_an_fec_77.0=1 +phy_an_fec_78.0=1 +phy_an_fec_79.0=1 +phy_an_fec_80.0=1 +phy_an_fec_81.0=1 +phy_an_fec_82.0=1 +phy_an_fec_83.0=1 +phy_an_fec_84.0=1 +phy_an_fec_85.0=1 +phy_an_fec_86.0=1 +phy_an_fec_87.0=1 +phy_an_fec_88.0=1 +phy_an_fec_89.0=1 +phy_an_fec_90.0=1 +phy_an_fec_91.0=1 +phy_an_fec_92.0=1 +phy_an_fec_93.0=1 +phy_an_fec_94.0=1 +phy_an_fec_95.0=1 +phy_an_fec_96.0=1 +phy_an_fec_97.0=1 +phy_an_fec_98.0=1 +phy_an_fec_99.0=1 +phy_an_fec_102.0=1 +phy_an_fec_103.0=1 +phy_an_fec_104.0=1 +phy_an_fec_105.0=1 +phy_an_fec_106.0=1 +phy_an_fec_107.0=1 +phy_an_fec_108.0=1 +phy_an_fec_109.0=1 +phy_an_fec_110.0=1 +phy_an_fec_111.0=1 +phy_an_fec_112.0=1 +phy_an_fec_113.0=1 +phy_an_fec_114.0=1 +phy_an_fec_115.0=1 +phy_an_fec_116.0=1 +phy_an_fec_117.0=1 +phy_an_fec_118.0=1 +phy_an_fec_119.0=1 +phy_an_fec_120.0=1 +phy_an_fec_121.0=1 +phy_an_fec_122.0=1 +phy_an_fec_123.0=1 +phy_an_fec_124.0=1 +phy_an_fec_125.0=1 +phy_an_fec_126.0=1 +phy_an_fec_127.0=1 +phy_an_fec_128.0=1 +phy_an_fec_129.0=1 +phy_an_fec_130.0=1 +phy_an_fec_131.0=1 +phy_an_fec_132.0=1 +phy_an_fec_133.0=1 +phy_xaui_rx_polarity_flip_1.0=0x1 +phy_xaui_rx_polarity_flip_2.0=0x5 +phy_xaui_rx_polarity_flip_3.0=0x1 +phy_xaui_rx_polarity_flip_4.0=0x7 +phy_xaui_rx_polarity_flip_5.0=0xc +phy_xaui_rx_polarity_flip_6.0=0xf +phy_xaui_rx_polarity_flip_7.0=0xc +phy_xaui_rx_polarity_flip_8.0=0xf +phy_xaui_rx_polarity_flip_34.0=0x0 +phy_xaui_rx_polarity_flip_35.0=0x7 +phy_xaui_rx_polarity_flip_36.0=0x4 +phy_xaui_rx_polarity_flip_37.0=0x7 +phy_xaui_rx_polarity_flip_38.0=0x4 +phy_xaui_rx_polarity_flip_39.0=0x6 +phy_xaui_rx_polarity_flip_40.0=0x1 +phy_xaui_rx_polarity_flip_41.0=0x2 +phy_xaui_rx_polarity_flip_68.0=0xd +phy_xaui_rx_polarity_flip_69.0=0x6 +phy_xaui_rx_polarity_flip_70.0=0x1 +phy_xaui_rx_polarity_flip_71.0=0x8 +phy_xaui_rx_polarity_flip_72.0=0x7 +phy_xaui_rx_polarity_flip_73.0=0xc +phy_xaui_rx_polarity_flip_74.0=0x7 +phy_xaui_rx_polarity_flip_75.0=0x8 +phy_xaui_rx_polarity_flip_102.0=0xb +phy_xaui_rx_polarity_flip_103.0=0xc +phy_xaui_rx_polarity_flip_104.0=0x3 +phy_xaui_rx_polarity_flip_105.0=0xc +phy_xaui_rx_polarity_flip_106.0=0xb +phy_xaui_rx_polarity_flip_107.0=0x5 +phy_xaui_rx_polarity_flip_108.0=0x1 +phy_xaui_rx_polarity_flip_109.0=0x9 +phy_xaui_tx_polarity_flip_1.0=0x0 +phy_xaui_tx_polarity_flip_2.0=0xe +phy_xaui_tx_polarity_flip_3.0=0x2 +phy_xaui_tx_polarity_flip_4.0=0xe +phy_xaui_tx_polarity_flip_5.0=0xc +phy_xaui_tx_polarity_flip_6.0=0xf +phy_xaui_tx_polarity_flip_7.0=0xc +phy_xaui_tx_polarity_flip_8.0=0xf +phy_xaui_tx_polarity_flip_34.0=0x0 +phy_xaui_tx_polarity_flip_35.0=0xe +phy_xaui_tx_polarity_flip_36.0=0x0 +phy_xaui_tx_polarity_flip_37.0=0xe +phy_xaui_tx_polarity_flip_38.0=0xf +phy_xaui_tx_polarity_flip_39.0=0xe +phy_xaui_tx_polarity_flip_40.0=0x6 +phy_xaui_tx_polarity_flip_41.0=0xb +phy_xaui_tx_polarity_flip_68.0=0x9 +phy_xaui_tx_polarity_flip_69.0=0xb +phy_xaui_tx_polarity_flip_70.0=0xd +phy_xaui_tx_polarity_flip_71.0=0x9 +phy_xaui_tx_polarity_flip_72.0=0x6 +phy_xaui_tx_polarity_flip_73.0=0xc +phy_xaui_tx_polarity_flip_74.0=0x9 +phy_xaui_tx_polarity_flip_75.0=0x9 +phy_xaui_tx_polarity_flip_102.0=0x6 +phy_xaui_tx_polarity_flip_103.0=0xb +phy_xaui_tx_polarity_flip_104.0=0x6 +phy_xaui_tx_polarity_flip_105.0=0xb +phy_xaui_tx_polarity_flip_106.0=0x6 +phy_xaui_tx_polarity_flip_107.0=0xf +phy_xaui_tx_polarity_flip_108.0=0x6 +phy_xaui_tx_polarity_flip_109.0=0xc +portmap_1.0=1:40 +portmap_2.0=5:40 +portmap_3.0=9:40 +portmap_4.0=13:40 +portmap_5.0=17:40 +portmap_6.0=21:40 +portmap_7.0=25:40 +portmap_8.0=29:40 +portmap_34.0=33:40 +portmap_35.0=37:40 +portmap_36.0=41:40 +portmap_37.0=45:40 +portmap_38.0=49:40 +portmap_39.0=53:40 +portmap_40.0=57:40 +portmap_41.0=61:40 +portmap_68.0=65:40 +portmap_69.0=69:40 +portmap_70.0=73:40 +portmap_71.0=77:40 +portmap_72.0=81:40 +portmap_73.0=85:40 +portmap_74.0=89:40 +portmap_75.0=93:40 +portmap_102.0=97:40 +portmap_103.0=101:40 +portmap_104.0=105:40 +portmap_105.0=109:40 +portmap_106.0=113:40 +portmap_107.0=117:40 +portmap_108.0=121:40 +portmap_109.0=125:40 +port_phy_addr_1.0=0xff +port_phy_addr_2.0=0xff +port_phy_addr_3.0=0xff +port_phy_addr_4.0=0xff +port_phy_addr_5.0=0xff +port_phy_addr_6.0=0xff +port_phy_addr_7.0=0xff +port_phy_addr_8.0=0xff +port_phy_addr_34.0=0xff +port_phy_addr_35.0=0xff +port_phy_addr_36.0=0xff +port_phy_addr_37.0=0xff +port_phy_addr_38.0=0xff +port_phy_addr_39.0=0xff +port_phy_addr_40.0=0xff +port_phy_addr_41.0=0xff +port_phy_addr_68.0=0xff +port_phy_addr_69.0=0xff +port_phy_addr_70.0=0xff +port_phy_addr_71.0=0xff +port_phy_addr_72.0=0xff +port_phy_addr_73.0=0xff +port_phy_addr_74.0=0xff +port_phy_addr_75.0=0xff +port_phy_addr_102.0=0xff +port_phy_addr_103.0=0xff +port_phy_addr_104.0=0xff +port_phy_addr_105.0=0xff +port_phy_addr_106.0=0xff +port_phy_addr_107.0=0xff +port_phy_addr_108.0=0xff +port_phy_addr_109.0=0xff +xgxs_rx_lane_map_1.0=0x3210 +xgxs_rx_lane_map_2.0=0x3210 +xgxs_rx_lane_map_3.0=0x3210 +xgxs_rx_lane_map_4.0=0x3210 +xgxs_rx_lane_map_5.0=0x0123 +xgxs_rx_lane_map_6.0=0x2301 +xgxs_rx_lane_map_7.0=0x0123 +xgxs_rx_lane_map_8.0=0x2301 +xgxs_rx_lane_map_34.0=0x0123 +xgxs_rx_lane_map_35.0=0x0321 +xgxs_rx_lane_map_36.0=0x0321 +xgxs_rx_lane_map_37.0=0x0321 +xgxs_rx_lane_map_38.0=0x1230 +xgxs_rx_lane_map_39.0=0x2301 +xgxs_rx_lane_map_40.0=0x1230 +xgxs_rx_lane_map_41.0=0x2103 +xgxs_rx_lane_map_68.0=0x1230 +xgxs_rx_lane_map_69.0=0x2301 +xgxs_rx_lane_map_70.0=0x1230 +xgxs_rx_lane_map_71.0=0x2103 +xgxs_rx_lane_map_72.0=0x1230 +xgxs_rx_lane_map_73.0=0x2301 +xgxs_rx_lane_map_74.0=0x1230 +xgxs_rx_lane_map_75.0=0x2103 +xgxs_rx_lane_map_102.0=0x3210 +xgxs_rx_lane_map_103.0=0x3210 +xgxs_rx_lane_map_104.0=0x3210 +xgxs_rx_lane_map_105.0=0x3210 +xgxs_rx_lane_map_106.0=0x3210 +xgxs_rx_lane_map_107.0=0x3210 +xgxs_rx_lane_map_108.0=0x3210 +xgxs_rx_lane_map_109.0=0x3210 +xgxs_tx_lane_map_1.0=0x0321 +xgxs_tx_lane_map_2.0=0x2301 +xgxs_tx_lane_map_3.0=0x0321 +xgxs_tx_lane_map_4.0=0x2301 +xgxs_tx_lane_map_5.0=0x0123 +xgxs_tx_lane_map_6.0=0x0123 +xgxs_tx_lane_map_7.0=0x0123 +xgxs_tx_lane_map_8.0=0x0123 +xgxs_tx_lane_map_34.0=0x2301 +xgxs_tx_lane_map_35.0=0x0321 +xgxs_tx_lane_map_36.0=0x2301 +xgxs_tx_lane_map_37.0=0x0321 +xgxs_tx_lane_map_38.0=0x0123 +xgxs_tx_lane_map_39.0=0x1230 +xgxs_tx_lane_map_40.0=0x2301 +xgxs_tx_lane_map_41.0=0x1032 +xgxs_tx_lane_map_68.0=0x0123 +xgxs_tx_lane_map_69.0=0x1230 +xgxs_tx_lane_map_70.0=0x2301 +xgxs_tx_lane_map_71.0=0x1032 +xgxs_tx_lane_map_72.0=0x0123 +xgxs_tx_lane_map_73.0=0x1230 +xgxs_tx_lane_map_74.0=0x2301 +xgxs_tx_lane_map_75.0=0x1032 +xgxs_tx_lane_map_102.0=0x0321 +xgxs_tx_lane_map_103.0=0x2301 +xgxs_tx_lane_map_104.0=0x0321 +xgxs_tx_lane_map_105.0=0x2301 +xgxs_tx_lane_map_106.0=0x0321 +xgxs_tx_lane_map_107.0=0x2301 +xgxs_tx_lane_map_108.0=0x0321 +xgxs_tx_lane_map_109.0=0x2301 +serdes_driver_current_1=0x4 +serdes_preemphasis_1=0x145c00 +serdes_driver_current_2=0x4 +serdes_preemphasis_2=0x145c00 +serdes_driver_current_3=0x8 +serdes_preemphasis_3=0x185800 +serdes_driver_current_4=0x8 +serdes_preemphasis_4=0x185800 +serdes_driver_current_5=0x8 +serdes_preemphasis_5=0x185800 +serdes_driver_current_6=0x8 +serdes_preemphasis_6=0x185800 +serdes_driver_current_7=0xf +serdes_preemphasis_7=0x205000 +serdes_driver_current_8=0xf +serdes_preemphasis_8=0x205000 +serdes_driver_current_34=0xf +serdes_preemphasis_34=0x205000 +serdes_driver_current_35=0xf +serdes_preemphasis_35=0x205000 +serdes_driver_current_36=0xf +serdes_preemphasis_36=0x205000 +serdes_driver_current_37=0xf +serdes_preemphasis_37=0x205000 +serdes_driver_current_38=0x8 +serdes_preemphasis_38=0x185800 +serdes_driver_current_39=0x8 +serdes_preemphasis_39=0x185800 +serdes_driver_current_40=0x8 +serdes_preemphasis_40=0x185800 +serdes_driver_current_41=0x8 +serdes_preemphasis_41=0x185800 +serdes_driver_current_68=0x4 +serdes_preemphasis_68=0x145c00 +serdes_driver_current_69=0x4 +serdes_preemphasis_69=0x145c00 +serdes_driver_current_70=0x4 +serdes_preemphasis_70=0x145c00 +serdes_driver_current_71=0x4 +serdes_preemphasis_71=0x145c00 +serdes_driver_current_72=0x4 +serdes_preemphasis_72=0x145c00 +serdes_driver_current_73=0x4 +serdes_preemphasis_73=0x145c00 +serdes_driver_current_74=0x4 +serdes_preemphasis_74=0x145c00 +serdes_driver_current_75=0x4 +serdes_preemphasis_75=0x145c00 +serdes_driver_current_102=0x4 +serdes_preemphasis_102=0x145c00 +serdes_driver_current_103=0x4 +serdes_preemphasis_103=0x145c00 +serdes_driver_current_104=0x4 +serdes_preemphasis_104=0x145c00 +serdes_driver_current_105=0x4 +serdes_preemphasis_105=0x145c00 +serdes_driver_current_106=0x4 +serdes_preemphasis_106=0x145c00 +serdes_driver_current_107=0x4 +serdes_preemphasis_107=0x145c00 +serdes_driver_current_108=0x4 +serdes_preemphasis_108=0x145c00 +serdes_driver_current_109=0x4 +serdes_preemphasis_109=0x145c00 + +mmu_init_config="MSFT-TH-Tier0" diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/th-a7060-cx32s-32x40G-t1.config.bcm b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/th-a7060-cx32s-32x40G-t1.config.bcm new file mode 100644 index 000000000000..c3218645ac2d --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/th-a7060-cx32s-32x40G-t1.config.bcm @@ -0,0 +1,444 @@ +# Arista 7060CX-32S + +phy_an_allow_pll_change=1 +arl_clean_timeout_usec=15000000 +asf_mem_profile=2 +bcm_num_cos=8 +bcm_stat_flags=1 +bcm_stat_jumbo=9236 +cdma_timeout_usec=15000000 +dma_desc_timeout_usec=15000000 +higig2_hdr_mode=1 +ipv6_lpm_128b_enable=1 +l3_alpm_enable=2 +lpm_scaling_enable=0 +l2xmsg_mode=1 +max_vp_lags=0 +miim_intr_enable=0 +module_64ports=1 +os=unix +oversubscribe_mode=1 +ptp_bs_fref.0=25000000 +ptp_ts_pll_fref.0=25000000 +robust_hash_disable_egress_vlan.0=1 +robust_hash_disable_mpls.0=1 +robust_hash_disable_vlan.0=1 +tdma_timeout_usec.0=15000000 +tslam_timeout_usec.0=15000000 +pbmp_xport_xe.0=0x7ffffffffffffffffffffffffffffffffe +phy_an_allow_pll_change_hg.0=0 +phy_an_c73_1.0=1 +phy_an_c73_2.0=1 +phy_an_c73_3.0=1 +phy_an_c73_4.0=1 +phy_an_c73_5.0=1 +phy_an_c73_6.0=1 +phy_an_c73_7.0=1 +phy_an_c73_8.0=1 +phy_an_c73_34.0=1 +phy_an_c73_35.0=1 +phy_an_c73_36.0=1 +phy_an_c73_37.0=1 +phy_an_c73_38.0=1 +phy_an_c73_39.0=1 +phy_an_c73_40.0=1 +phy_an_c73_41.0=1 +phy_an_c73_68.0=1 +phy_an_c73_69.0=1 +phy_an_c73_70.0=1 +phy_an_c73_71.0=1 +phy_an_c73_72.0=1 +phy_an_c73_73.0=1 +phy_an_c73_74.0=1 +phy_an_c73_75.0=1 +phy_an_c73_102.0=1 +phy_an_c73_103.0=1 +phy_an_c73_104.0=1 +phy_an_c73_105.0=1 +phy_an_c73_106.0=1 +phy_an_c73_107.0=1 +phy_an_c73_108.0=1 +phy_an_c73_109.0=1 +phy_an_fec_1.0=1 +phy_an_fec_2.0=1 +phy_an_fec_3.0=1 +phy_an_fec_4.0=1 +phy_an_fec_5.0=1 +phy_an_fec_6.0=1 +phy_an_fec_7.0=1 +phy_an_fec_8.0=1 +phy_an_fec_9.0=1 +phy_an_fec_10.0=1 +phy_an_fec_11.0=1 +phy_an_fec_12.0=1 +phy_an_fec_13.0=1 +phy_an_fec_14.0=1 +phy_an_fec_15.0=1 +phy_an_fec_16.0=1 +phy_an_fec_17.0=1 +phy_an_fec_18.0=1 +phy_an_fec_19.0=1 +phy_an_fec_20.0=1 +phy_an_fec_21.0=1 +phy_an_fec_22.0=1 +phy_an_fec_23.0=1 +phy_an_fec_24.0=1 +phy_an_fec_25.0=1 +phy_an_fec_26.0=1 +phy_an_fec_27.0=1 +phy_an_fec_28.0=1 +phy_an_fec_29.0=1 +phy_an_fec_30.0=1 +phy_an_fec_31.0=1 +phy_an_fec_32.0=1 +phy_an_fec_34.0=1 +phy_an_fec_38.0=1 +phy_an_fec_39.0=1 +phy_an_fec_40.0=1 +phy_an_fec_41.0=1 +phy_an_fec_42.0=1 +phy_an_fec_43.0=1 +phy_an_fec_44.0=1 +phy_an_fec_45.0=1 +phy_an_fec_46.0=1 +phy_an_fec_47.0=1 +phy_an_fec_48.0=1 +phy_an_fec_49.0=1 +phy_an_fec_50.0=1 +phy_an_fec_51.0=1 +phy_an_fec_52.0=1 +phy_an_fec_53.0=1 +phy_an_fec_54.0=1 +phy_an_fec_55.0=1 +phy_an_fec_56.0=1 +phy_an_fec_57.0=1 +phy_an_fec_58.0=1 +phy_an_fec_59.0=1 +phy_an_fec_60.0=1 +phy_an_fec_61.0=1 +phy_an_fec_62.0=1 +phy_an_fec_63.0=1 +phy_an_fec_64.0=1 +phy_an_fec_65.0=1 +phy_an_fec_68.0=1 +phy_an_fec_69.0=1 +phy_an_fec_70.0=1 +phy_an_fec_71.0=1 +phy_an_fec_72.0=1 +phy_an_fec_73.0=1 +phy_an_fec_74.0=1 +phy_an_fec_75.0=1 +phy_an_fec_76.0=1 +phy_an_fec_77.0=1 +phy_an_fec_78.0=1 +phy_an_fec_79.0=1 +phy_an_fec_80.0=1 +phy_an_fec_81.0=1 +phy_an_fec_82.0=1 +phy_an_fec_83.0=1 +phy_an_fec_84.0=1 +phy_an_fec_85.0=1 +phy_an_fec_86.0=1 +phy_an_fec_87.0=1 +phy_an_fec_88.0=1 +phy_an_fec_89.0=1 +phy_an_fec_90.0=1 +phy_an_fec_91.0=1 +phy_an_fec_92.0=1 +phy_an_fec_93.0=1 +phy_an_fec_94.0=1 +phy_an_fec_95.0=1 +phy_an_fec_96.0=1 +phy_an_fec_97.0=1 +phy_an_fec_98.0=1 +phy_an_fec_99.0=1 +phy_an_fec_102.0=1 +phy_an_fec_103.0=1 +phy_an_fec_104.0=1 +phy_an_fec_105.0=1 +phy_an_fec_106.0=1 +phy_an_fec_107.0=1 +phy_an_fec_108.0=1 +phy_an_fec_109.0=1 +phy_an_fec_110.0=1 +phy_an_fec_111.0=1 +phy_an_fec_112.0=1 +phy_an_fec_113.0=1 +phy_an_fec_114.0=1 +phy_an_fec_115.0=1 +phy_an_fec_116.0=1 +phy_an_fec_117.0=1 +phy_an_fec_118.0=1 +phy_an_fec_119.0=1 +phy_an_fec_120.0=1 +phy_an_fec_121.0=1 +phy_an_fec_122.0=1 +phy_an_fec_123.0=1 +phy_an_fec_124.0=1 +phy_an_fec_125.0=1 +phy_an_fec_126.0=1 +phy_an_fec_127.0=1 +phy_an_fec_128.0=1 +phy_an_fec_129.0=1 +phy_an_fec_130.0=1 +phy_an_fec_131.0=1 +phy_an_fec_132.0=1 +phy_an_fec_133.0=1 +phy_xaui_rx_polarity_flip_1.0=0x1 +phy_xaui_rx_polarity_flip_2.0=0x5 +phy_xaui_rx_polarity_flip_3.0=0x1 +phy_xaui_rx_polarity_flip_4.0=0x7 +phy_xaui_rx_polarity_flip_5.0=0xc +phy_xaui_rx_polarity_flip_6.0=0xf +phy_xaui_rx_polarity_flip_7.0=0xc +phy_xaui_rx_polarity_flip_8.0=0xf +phy_xaui_rx_polarity_flip_34.0=0x0 +phy_xaui_rx_polarity_flip_35.0=0x7 +phy_xaui_rx_polarity_flip_36.0=0x4 +phy_xaui_rx_polarity_flip_37.0=0x7 +phy_xaui_rx_polarity_flip_38.0=0x4 +phy_xaui_rx_polarity_flip_39.0=0x6 +phy_xaui_rx_polarity_flip_40.0=0x1 +phy_xaui_rx_polarity_flip_41.0=0x2 +phy_xaui_rx_polarity_flip_68.0=0xd +phy_xaui_rx_polarity_flip_69.0=0x6 +phy_xaui_rx_polarity_flip_70.0=0x1 +phy_xaui_rx_polarity_flip_71.0=0x8 +phy_xaui_rx_polarity_flip_72.0=0x7 +phy_xaui_rx_polarity_flip_73.0=0xc +phy_xaui_rx_polarity_flip_74.0=0x7 +phy_xaui_rx_polarity_flip_75.0=0x8 +phy_xaui_rx_polarity_flip_102.0=0xb +phy_xaui_rx_polarity_flip_103.0=0xc +phy_xaui_rx_polarity_flip_104.0=0x3 +phy_xaui_rx_polarity_flip_105.0=0xc +phy_xaui_rx_polarity_flip_106.0=0xb +phy_xaui_rx_polarity_flip_107.0=0x5 +phy_xaui_rx_polarity_flip_108.0=0x1 +phy_xaui_rx_polarity_flip_109.0=0x9 +phy_xaui_tx_polarity_flip_1.0=0x0 +phy_xaui_tx_polarity_flip_2.0=0xe +phy_xaui_tx_polarity_flip_3.0=0x2 +phy_xaui_tx_polarity_flip_4.0=0xe +phy_xaui_tx_polarity_flip_5.0=0xc +phy_xaui_tx_polarity_flip_6.0=0xf +phy_xaui_tx_polarity_flip_7.0=0xc +phy_xaui_tx_polarity_flip_8.0=0xf +phy_xaui_tx_polarity_flip_34.0=0x0 +phy_xaui_tx_polarity_flip_35.0=0xe +phy_xaui_tx_polarity_flip_36.0=0x0 +phy_xaui_tx_polarity_flip_37.0=0xe +phy_xaui_tx_polarity_flip_38.0=0xf +phy_xaui_tx_polarity_flip_39.0=0xe +phy_xaui_tx_polarity_flip_40.0=0x6 +phy_xaui_tx_polarity_flip_41.0=0xb +phy_xaui_tx_polarity_flip_68.0=0x9 +phy_xaui_tx_polarity_flip_69.0=0xb +phy_xaui_tx_polarity_flip_70.0=0xd +phy_xaui_tx_polarity_flip_71.0=0x9 +phy_xaui_tx_polarity_flip_72.0=0x6 +phy_xaui_tx_polarity_flip_73.0=0xc +phy_xaui_tx_polarity_flip_74.0=0x9 +phy_xaui_tx_polarity_flip_75.0=0x9 +phy_xaui_tx_polarity_flip_102.0=0x6 +phy_xaui_tx_polarity_flip_103.0=0xb +phy_xaui_tx_polarity_flip_104.0=0x6 +phy_xaui_tx_polarity_flip_105.0=0xb +phy_xaui_tx_polarity_flip_106.0=0x6 +phy_xaui_tx_polarity_flip_107.0=0xf +phy_xaui_tx_polarity_flip_108.0=0x6 +phy_xaui_tx_polarity_flip_109.0=0xc +portmap_1.0=1:40 +portmap_2.0=5:40 +portmap_3.0=9:40 +portmap_4.0=13:40 +portmap_5.0=17:40 +portmap_6.0=21:40 +portmap_7.0=25:40 +portmap_8.0=29:40 +portmap_34.0=33:40 +portmap_35.0=37:40 +portmap_36.0=41:40 +portmap_37.0=45:40 +portmap_38.0=49:40 +portmap_39.0=53:40 +portmap_40.0=57:40 +portmap_41.0=61:40 +portmap_68.0=65:40 +portmap_69.0=69:40 +portmap_70.0=73:40 +portmap_71.0=77:40 +portmap_72.0=81:40 +portmap_73.0=85:40 +portmap_74.0=89:40 +portmap_75.0=93:40 +portmap_102.0=97:40 +portmap_103.0=101:40 +portmap_104.0=105:40 +portmap_105.0=109:40 +portmap_106.0=113:40 +portmap_107.0=117:40 +portmap_108.0=121:40 +portmap_109.0=125:40 +port_phy_addr_1.0=0xff +port_phy_addr_2.0=0xff +port_phy_addr_3.0=0xff +port_phy_addr_4.0=0xff +port_phy_addr_5.0=0xff +port_phy_addr_6.0=0xff +port_phy_addr_7.0=0xff +port_phy_addr_8.0=0xff +port_phy_addr_34.0=0xff +port_phy_addr_35.0=0xff +port_phy_addr_36.0=0xff +port_phy_addr_37.0=0xff +port_phy_addr_38.0=0xff +port_phy_addr_39.0=0xff +port_phy_addr_40.0=0xff +port_phy_addr_41.0=0xff +port_phy_addr_68.0=0xff +port_phy_addr_69.0=0xff +port_phy_addr_70.0=0xff +port_phy_addr_71.0=0xff +port_phy_addr_72.0=0xff +port_phy_addr_73.0=0xff +port_phy_addr_74.0=0xff +port_phy_addr_75.0=0xff +port_phy_addr_102.0=0xff +port_phy_addr_103.0=0xff +port_phy_addr_104.0=0xff +port_phy_addr_105.0=0xff +port_phy_addr_106.0=0xff +port_phy_addr_107.0=0xff +port_phy_addr_108.0=0xff +port_phy_addr_109.0=0xff +xgxs_rx_lane_map_1.0=0x3210 +xgxs_rx_lane_map_2.0=0x3210 +xgxs_rx_lane_map_3.0=0x3210 +xgxs_rx_lane_map_4.0=0x3210 +xgxs_rx_lane_map_5.0=0x0123 +xgxs_rx_lane_map_6.0=0x2301 +xgxs_rx_lane_map_7.0=0x0123 +xgxs_rx_lane_map_8.0=0x2301 +xgxs_rx_lane_map_34.0=0x0123 +xgxs_rx_lane_map_35.0=0x0321 +xgxs_rx_lane_map_36.0=0x0321 +xgxs_rx_lane_map_37.0=0x0321 +xgxs_rx_lane_map_38.0=0x1230 +xgxs_rx_lane_map_39.0=0x2301 +xgxs_rx_lane_map_40.0=0x1230 +xgxs_rx_lane_map_41.0=0x2103 +xgxs_rx_lane_map_68.0=0x1230 +xgxs_rx_lane_map_69.0=0x2301 +xgxs_rx_lane_map_70.0=0x1230 +xgxs_rx_lane_map_71.0=0x2103 +xgxs_rx_lane_map_72.0=0x1230 +xgxs_rx_lane_map_73.0=0x2301 +xgxs_rx_lane_map_74.0=0x1230 +xgxs_rx_lane_map_75.0=0x2103 +xgxs_rx_lane_map_102.0=0x3210 +xgxs_rx_lane_map_103.0=0x3210 +xgxs_rx_lane_map_104.0=0x3210 +xgxs_rx_lane_map_105.0=0x3210 +xgxs_rx_lane_map_106.0=0x3210 +xgxs_rx_lane_map_107.0=0x3210 +xgxs_rx_lane_map_108.0=0x3210 +xgxs_rx_lane_map_109.0=0x3210 +xgxs_tx_lane_map_1.0=0x0321 +xgxs_tx_lane_map_2.0=0x2301 +xgxs_tx_lane_map_3.0=0x0321 +xgxs_tx_lane_map_4.0=0x2301 +xgxs_tx_lane_map_5.0=0x0123 +xgxs_tx_lane_map_6.0=0x0123 +xgxs_tx_lane_map_7.0=0x0123 +xgxs_tx_lane_map_8.0=0x0123 +xgxs_tx_lane_map_34.0=0x2301 +xgxs_tx_lane_map_35.0=0x0321 +xgxs_tx_lane_map_36.0=0x2301 +xgxs_tx_lane_map_37.0=0x0321 +xgxs_tx_lane_map_38.0=0x0123 +xgxs_tx_lane_map_39.0=0x1230 +xgxs_tx_lane_map_40.0=0x2301 +xgxs_tx_lane_map_41.0=0x1032 +xgxs_tx_lane_map_68.0=0x0123 +xgxs_tx_lane_map_69.0=0x1230 +xgxs_tx_lane_map_70.0=0x2301 +xgxs_tx_lane_map_71.0=0x1032 +xgxs_tx_lane_map_72.0=0x0123 +xgxs_tx_lane_map_73.0=0x1230 +xgxs_tx_lane_map_74.0=0x2301 +xgxs_tx_lane_map_75.0=0x1032 +xgxs_tx_lane_map_102.0=0x0321 +xgxs_tx_lane_map_103.0=0x2301 +xgxs_tx_lane_map_104.0=0x0321 +xgxs_tx_lane_map_105.0=0x2301 +xgxs_tx_lane_map_106.0=0x0321 +xgxs_tx_lane_map_107.0=0x2301 +xgxs_tx_lane_map_108.0=0x0321 +xgxs_tx_lane_map_109.0=0x2301 +serdes_driver_current_1=0x4 +serdes_preemphasis_1=0x145c00 +serdes_driver_current_2=0x4 +serdes_preemphasis_2=0x145c00 +serdes_driver_current_3=0x8 +serdes_preemphasis_3=0x185800 +serdes_driver_current_4=0x8 +serdes_preemphasis_4=0x185800 +serdes_driver_current_5=0x8 +serdes_preemphasis_5=0x185800 +serdes_driver_current_6=0x8 +serdes_preemphasis_6=0x185800 +serdes_driver_current_7=0xf +serdes_preemphasis_7=0x205000 +serdes_driver_current_8=0xf +serdes_preemphasis_8=0x205000 +serdes_driver_current_34=0xf +serdes_preemphasis_34=0x205000 +serdes_driver_current_35=0xf +serdes_preemphasis_35=0x205000 +serdes_driver_current_36=0xf +serdes_preemphasis_36=0x205000 +serdes_driver_current_37=0xf +serdes_preemphasis_37=0x205000 +serdes_driver_current_38=0x8 +serdes_preemphasis_38=0x185800 +serdes_driver_current_39=0x8 +serdes_preemphasis_39=0x185800 +serdes_driver_current_40=0x8 +serdes_preemphasis_40=0x185800 +serdes_driver_current_41=0x8 +serdes_preemphasis_41=0x185800 +serdes_driver_current_68=0x4 +serdes_preemphasis_68=0x145c00 +serdes_driver_current_69=0x4 +serdes_preemphasis_69=0x145c00 +serdes_driver_current_70=0x4 +serdes_preemphasis_70=0x145c00 +serdes_driver_current_71=0x4 +serdes_preemphasis_71=0x145c00 +serdes_driver_current_72=0x4 +serdes_preemphasis_72=0x145c00 +serdes_driver_current_73=0x4 +serdes_preemphasis_73=0x145c00 +serdes_driver_current_74=0x4 +serdes_preemphasis_74=0x145c00 +serdes_driver_current_75=0x4 +serdes_preemphasis_75=0x145c00 +serdes_driver_current_102=0x4 +serdes_preemphasis_102=0x145c00 +serdes_driver_current_103=0x4 +serdes_preemphasis_103=0x145c00 +serdes_driver_current_104=0x4 +serdes_preemphasis_104=0x145c00 +serdes_driver_current_105=0x4 +serdes_preemphasis_105=0x145c00 +serdes_driver_current_106=0x4 +serdes_preemphasis_106=0x145c00 +serdes_driver_current_107=0x4 +serdes_preemphasis_107=0x145c00 +serdes_driver_current_108=0x4 +serdes_preemphasis_108=0x145c00 +serdes_driver_current_109=0x4 +serdes_preemphasis_109=0x145c00 + +mmu_init_config="MSFT-TH-Tier1" From 2109a1133fb0770af8e570dcf91109759ba8f912 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Tue, 17 Jul 2018 15:00:30 +0000 Subject: [PATCH 107/219] [pfcwd] update sonic-utilities submodule - include knob to start pfcwd for all ports Signed-off-by: Ying Xie --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 27bea61072d0..47c2bee08c89 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 27bea61072d0a4c8756b4be89b4b349f72918889 +Subproject commit 47c2bee08c894c0ff4458e3fbb01e25868d2da11 From 1e43b9950b3a89d9432d59fefe510e3e106e88d5 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Thu, 12 Jul 2018 01:52:19 -0700 Subject: [PATCH 108/219] Pavelsh/restart swss counters (#1854) * sonic-quagga update. Don't spam with 'Vtysh connected from' message * Restart counters in 60 seconds after manual swss restart --- files/build_templates/enable_counters.service | 3 ++- files/build_templates/enable_counters.timer | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/files/build_templates/enable_counters.service b/files/build_templates/enable_counters.service index f19249369f87..95424474cb15 100644 --- a/files/build_templates/enable_counters.service +++ b/files/build_templates/enable_counters.service @@ -1,7 +1,8 @@ [Unit] Description=Enable SONiC counters +PartOf=swss.service [Service] Type=oneshot -ExecStart=/bin/bash -c '/usr/bin/counterpoll queue enable ; /usr/bin/counterpoll port enable ; /usr/bin/pfcwd counter_poll enable' +ExecStart=/bin/bash -c 'sleep 60 ; /usr/bin/counterpoll queue enable ; /usr/bin/counterpoll port enable ; /usr/bin/pfcwd counter_poll enable' RemainAfterExit=yes diff --git a/files/build_templates/enable_counters.timer b/files/build_templates/enable_counters.timer index 7382a1658c1b..40a91525a712 100644 --- a/files/build_templates/enable_counters.timer +++ b/files/build_templates/enable_counters.timer @@ -2,7 +2,7 @@ Description=Delays the SONiC counters gathering until SONiC has started [Timer] -OnBootSec=3min +OnBootSec=2min Unit=enable_counters.service [Install] From b42bd5b7b7dec02b5440416cd7329aa344324c1d Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Wed, 18 Jul 2018 13:04:57 -0700 Subject: [PATCH 109/219] Convert arp_update into a 'start-it-once' mode (#1864) * Run arp_update just once, don't restart it. It will run continuosly with 5 min pauses --- dockers/docker-orchagent/supervisord.conf | 4 ++-- files/scripts/arp_update | 21 +++++++++++--------- platform/p4/docker-sonic-p4/supervisord.conf | 4 ++-- platform/vs/docker-sonic-vs/supervisord.conf | 4 ++-- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/dockers/docker-orchagent/supervisord.conf b/dockers/docker-orchagent/supervisord.conf index 84beaed440a3..dc28e3369ca5 100644 --- a/dockers/docker-orchagent/supervisord.conf +++ b/dockers/docker-orchagent/supervisord.conf @@ -61,10 +61,10 @@ stdout_logfile=syslog stderr_logfile=syslog [program:arp_update] -command=bash -c "/usr/bin/arp_update; sleep 300" +command=/usr/bin/arp_update priority=8 autostart=false -autorestart=true +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog diff --git a/files/scripts/arp_update b/files/scripts/arp_update index cfd87c1dc51f..ab44ca6a4580 100755 --- a/files/scripts/arp_update +++ b/files/scripts/arp_update @@ -4,14 +4,17 @@ # arp_update: Send gratuitous ARP requests to VLAN member neighbors to refresh # the neighbors state. -VLAN=`sonic-cfggen -d -v 'VLAN.keys() | join(" ") if VLAN'` -for vlan in $VLAN; do - # generate a list of arping commands: - # arping -q -w 0 -c 1 -i ; - # arping -q -w 0 -c 1 -i ; - # ... - arpingcmd="sed -e 's/ / -i /' -e 's/^/arping -q -w 0 -c 1 /' -e 's/$/;/'" - ipcmd="ip -4 neigh show | grep $vlan | cut -d ' ' -f 1,3 | $arpingcmd" +while /bin/true; do + VLAN=`sonic-cfggen -d -v 'VLAN.keys() | join(" ") if VLAN'` + for vlan in $VLAN; do + # generate a list of arping commands: + # arping -q -w 0 -c 1 -i ; + # arping -q -w 0 -c 1 -i ; + # ... + arpingcmd="sed -e 's/ / -i /' -e 's/^/arping -q -w 0 -c 1 /' -e 's/$/;/'" + ipcmd="ip -4 neigh show | grep $vlan | cut -d ' ' -f 1,3 | $arpingcmd" - eval `eval $ipcmd` + eval `eval $ipcmd` + done + sleep 300 done diff --git a/platform/p4/docker-sonic-p4/supervisord.conf b/platform/p4/docker-sonic-p4/supervisord.conf index 46178e9f11f5..5815689f9301 100644 --- a/platform/p4/docker-sonic-p4/supervisord.conf +++ b/platform/p4/docker-sonic-p4/supervisord.conf @@ -133,9 +133,9 @@ stdout_logfile=syslog stderr_logfile=syslog [program:arp_update] -command=bash -c "/usr/bin/arp_update; sleep 300" +command=/usr/bin/arp_update priority=15 autostart=false -autorestart=true +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog diff --git a/platform/vs/docker-sonic-vs/supervisord.conf b/platform/vs/docker-sonic-vs/supervisord.conf index 571c802cda1e..a4b24334d1bd 100644 --- a/platform/vs/docker-sonic-vs/supervisord.conf +++ b/platform/vs/docker-sonic-vs/supervisord.conf @@ -116,10 +116,10 @@ stdout_logfile=syslog stderr_logfile=syslog [program:arp_update] -command=bash -c "/usr/bin/arp_update; sleep 300" +command=/usr/bin/arp_update priority=15 autostart=false -autorestart=true +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog From c115e307dd391918264732b00836167159294bd7 Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Thu, 19 Jul 2018 22:04:28 +0700 Subject: [PATCH 110/219] Change dx010 console speed (#1867) --- device/celestica/x86_64-cel_seastone-r0/installer.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/device/celestica/x86_64-cel_seastone-r0/installer.conf b/device/celestica/x86_64-cel_seastone-r0/installer.conf index 925a32fc0c3a..306c42218785 100644 --- a/device/celestica/x86_64-cel_seastone-r0/installer.conf +++ b/device/celestica/x86_64-cel_seastone-r0/installer.conf @@ -1,3 +1,3 @@ CONSOLE_PORT=0x3f8 CONSOLE_DEV=0 -CONSOLE_SPEED=115200 +CONSOLE_SPEED=9600 From dab944b5abc694d83177c9e7e944d7c3e089e683 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Thu, 19 Jul 2018 17:29:04 +0000 Subject: [PATCH 111/219] [bcm syncd]: Wait initializing led_proc for 60 seconds (#1863) * Wait initializing led_proc for 60 seconds. bcm sdk need time to be ready accept a connection --- platform/broadcom/docker-syncd-brcm/start.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/broadcom/docker-syncd-brcm/start.sh b/platform/broadcom/docker-syncd-brcm/start.sh index 3ed445ded691..cc82e1ba33a8 100755 --- a/platform/broadcom/docker-syncd-brcm/start.sh +++ b/platform/broadcom/docker-syncd-brcm/start.sh @@ -33,5 +33,6 @@ wait_syncd() { # If this platform has an initialization file for the Broadcom LED microprocessor, load it if [ -r ${PLATFORM_DIR}/led_proc_init.soc ]; then wait_syncd + sleep 60 # wait until bcm sdk is ready to get a request /usr/bin/bcmcmd -t 60 "rcload ${PLATFORM_DIR}/led_proc_init.soc" fi From 14a0de768d532fa55bc58d3df7075786d2ae1876 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Mon, 23 Jul 2018 18:01:30 +0000 Subject: [PATCH 112/219] [submodule]: update sonic-platform-common 10bef06 2018-06-21 | [sfputilbase.py] Fix bug where 'title' list always gets overwritten with empty list (#8) (HEAD -> 201803, origin/201803) [Joe LeVeque] --- src/sonic-platform-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-common b/src/sonic-platform-common index b553dba4ca82..10bef06fd66b 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit b553dba4ca82997dcc60a3b3a68111d7af8d62fc +Subproject commit 10bef06fd66b233b8e3fdecb19809dedee9f0e75 From 502ba0e86dc7cce80bb19de7828c71c8da965503 Mon Sep 17 00:00:00 2001 From: Rodny Molina Date: Fri, 27 Jul 2018 17:46:33 -0700 Subject: [PATCH 113/219] Fix for bash's memory-leak (#1879) * Fix for bash's memory-leak Memory leak is observed during the execution of scripts that make use of bash-arrays. In scenarios where the offending script is executed on a regular basis (e.g. fancontrol), the leaking process may end up consuming most of the system resources. In this PR i'm replacing bash in all the contexts where it executes (both host and dockers). The official patch for this issue is here: https://ftp.gnu.org/gnu/bash/bash-4.3-patches/bash43-040 * Fixing minor issue during code-merge Signed-off-by: Rodny Molina --- files/build_templates/sonic_debian_extension.j2 | 5 +++++ rules/bash.mk | 17 +++++++++++++++++ rules/docker-base.mk | 1 + slave.mk | 1 + sonic-slave/Dockerfile | 4 +++- src/bash/Makefile | 16 ++++++++++++++++ 6 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 rules/bash.mk create mode 100644 src/bash/Makefile diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 4898bdb294cf..b9c469d3ed2d 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -93,6 +93,11 @@ sudo rm -rf $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY2_WHEEL_NAME sudo dpkg --root=$FILESYSTEM_ROOT -i target/debs/python-sonic-utilities_*.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f +# Install customized bash version to patch memory-leak issue. This instruction shall be removed +# once the migration to Debian-9 (Stretch) is completed. +sudo dpkg --root=$FILESYSTEM_ROOT -i target/debs/bash_*.deb || \ + sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f + # SONiC utilities installs bash-completion as a dependency. However, it is disabled by default # in bash.bashrc, so we copy a version of the file with it enabled here. sudo cp -f $IMAGE_CONFIGS/bash/bash.bashrc $FILESYSTEM_ROOT/etc/ diff --git a/rules/bash.mk b/rules/bash.mk new file mode 100644 index 000000000000..e31b237ae11b --- /dev/null +++ b/rules/bash.mk @@ -0,0 +1,17 @@ +# bash package +# +# Created to patch memory-leak issue in the bash-package included in Debian-8 (Jessie) +# release. This rule file, and the associated building-infra created to solve this +# bug (src/bash/), should be eliminated once the migration to Debian-9 (Stretch) is +# completed. + +# Bash major release-number corresponding to Debian-8 (Jessie) +BASH_VERSION_MAJOR = 4.3 +# Bash complete release-number. This image contains all 4.3 fixes up to patch '42'. +BASH_VERSION_FULL = $(BASH_VERSION_MAJOR)-14 + +export BASH_VERSION_MAJOR BASH_VERSION_FULL + +BASH = bash_$(BASH_VERSION_FULL)_amd64.deb +$(BASH)_SRC_PATH = $(SRC_PATH)/bash +SONIC_MAKE_DEBS += $(BASH) diff --git a/rules/docker-base.mk b/rules/docker-base.mk index 4a419008e915..a6b0cba47677 100644 --- a/rules/docker-base.mk +++ b/rules/docker-base.mk @@ -4,6 +4,7 @@ DOCKER_BASE = docker-base.gz $(DOCKER_BASE)_PATH = $(DOCKERS_PATH)/docker-base $(DOCKER_BASE)_DEPENDS += $(SUPERVISOR) $(DOCKER_BASE)_DEPENDS += $(LIBWRAP) +$(DOCKER_BASE)_DEPENDS += $(BASH) ifeq ($(SONIC_CONFIG_DEBUG),y) GDB = gdb diff --git a/slave.mk b/slave.mk index 7430f3a80d10..2beb127b0c6f 100644 --- a/slave.mk +++ b/slave.mk @@ -428,6 +428,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(IXGBE_DRIVER) \ $(SONIC_DEVICE_DATA) \ $(SONIC_UTILS) \ + $(BASH) \ $(LIBWRAP) \ $(LIBPAM_TACPLUS) \ $(LIBNSS_TACPLUS)) \ diff --git a/sonic-slave/Dockerfile b/sonic-slave/Dockerfile index 213daf1a8e47..cb4529e67aa4 100644 --- a/sonic-slave/Dockerfile +++ b/sonic-slave/Dockerfile @@ -213,7 +213,9 @@ RUN apt-get update && apt-get install -y \ linuxdoc-tools \ lynx \ texlive-latex-extra \ - texlive-latex-recommended + texlive-latex-recommended \ +# For bash + texi2html # For linux build RUN apt-get -y build-dep linux diff --git a/src/bash/Makefile b/src/bash/Makefile new file mode 100644 index 000000000000..2e9f093aedb4 --- /dev/null +++ b/src/bash/Makefile @@ -0,0 +1,16 @@ +SHELL = /bin/bash +.ONESHELL: +.SHELLFLAGS += -e + +MAIN_TARGET = bash_$(BASH_VERSION_FULL)_amd64.deb + +$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + rm -rf bash-$(BASH_VERSION_MAJOR) + + dget -u https://launchpad.net/debian/+archive/primary/+sourcefiles/bash/$(BASH_VERSION_FULL)/bash_$(BASH_VERSION_FULL).dsc + + pushd bash-$(BASH_VERSION_MAJOR) + DEB_BUILD_OPTIONS=nocheck dpkg-buildpackage -us -uc -b -j$(SONIC_CONFIG_MAKE_JOBS) + popd + + mv $* $(DEST)/ From 1f19c27006cb5b52496519d2e3513fb1ca11199f Mon Sep 17 00:00:00 2001 From: Taoyu Li Date: Thu, 21 Jun 2018 10:41:50 -0700 Subject: [PATCH 114/219] Modify sudo lecture message to be more informational (#1800) --- files/build_templates/sonic_debian_extension.j2 | 1 + files/image_config/sudoers/sudoers | 1 + files/image_config/sudoers/sudoers.lecture | 4 ++++ 3 files changed, 6 insertions(+) create mode 100644 files/image_config/sudoers/sudoers.lecture diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index b9c469d3ed2d..bf65cad02d1e 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -184,6 +184,7 @@ sudo cp $IMAGE_CONFIGS/asn/deployment_id_asn_map.yml $FILESYSTEM_ROOT/etc/sonic/ # Copy sudoers configuration file sudo cp $IMAGE_CONFIGS/sudoers/sudoers $FILESYSTEM_ROOT/etc/ +sudo cp $IMAGE_CONFIGS/sudoers/sudoers.lecture $FILESYSTEM_ROOT/etc/ # Copy control plane ACL management daemon files sudo cp $IMAGE_CONFIGS/caclmgrd/caclmgrd.service $FILESYSTEM_ROOT/etc/systemd/system/ diff --git a/files/image_config/sudoers/sudoers b/files/image_config/sudoers/sudoers index 7cfa0baba0f1..47d98b3fed41 100644 --- a/files/image_config/sudoers/sudoers +++ b/files/image_config/sudoers/sudoers @@ -10,6 +10,7 @@ Defaults env_reset #Defaults mail_badpass Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" Defaults env_keep += "VTYSH_PAGER" +Defaults lecture_file = /etc/sudoers.lecture # Host alias specification diff --git a/files/image_config/sudoers/sudoers.lecture b/files/image_config/sudoers/sudoers.lecture new file mode 100644 index 000000000000..e89340092c70 --- /dev/null +++ b/files/image_config/sudoers/sudoers.lecture @@ -0,0 +1,4 @@ + +Make sure your account has RW permission to current device. +Otherwise sudo requests will be rejected. + From 36604f76b9372ae41f4b1d6d80e411f9a75eaf6c Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Thu, 26 Jul 2018 13:39:08 -0700 Subject: [PATCH 115/219] [swss]: Start counter from swss container (#1875) * sonic-quagga update. Don't spam with 'Vtysh connected from' message * Enable counters inside swss container. systemd is not flexible enough to follow our business rules --- dockers/docker-orchagent/Dockerfile.j2 | 1 + dockers/docker-orchagent/enable_counters.py | 34 +++++++++++++++++++ dockers/docker-orchagent/start.sh | 2 ++ dockers/docker-orchagent/supervisord.conf | 8 +++++ files/build_templates/enable_counters.service | 8 ----- files/build_templates/enable_counters.timer | 9 ----- files/build_templates/snmp.service.j2 | 4 +-- .../build_templates/sonic_debian_extension.j2 | 3 -- 8 files changed, 47 insertions(+), 22 deletions(-) create mode 100755 dockers/docker-orchagent/enable_counters.py delete mode 100644 files/build_templates/enable_counters.service delete mode 100644 files/build_templates/enable_counters.timer diff --git a/dockers/docker-orchagent/Dockerfile.j2 b/dockers/docker-orchagent/Dockerfile.j2 index 3d6671996358..1597b436c3fe 100755 --- a/dockers/docker-orchagent/Dockerfile.j2 +++ b/dockers/docker-orchagent/Dockerfile.j2 @@ -27,6 +27,7 @@ RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs COPY ["files/arp_update", "/usr/bin"] +COPY ["enable_counters.py", "/usr/bin"] COPY ["start.sh", "orchagent.sh", "swssconfig.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] diff --git a/dockers/docker-orchagent/enable_counters.py b/dockers/docker-orchagent/enable_counters.py new file mode 100755 index 000000000000..712d34492b47 --- /dev/null +++ b/dockers/docker-orchagent/enable_counters.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python + +import swsssdk +import time + +def enable_counter_group(db, name): + info = {} + info['FLEX_COUNTER_STATUS'] = 'enable' + db.mod_entry("FLEX_COUNTER_TABLE", name, info) + +def enable_counters(): + db = swsssdk.ConfigDBConnector() + db.connect() + enable_counter_group(db, 'PORT') + enable_counter_group(db, 'QUEUE') + enable_counter_group(db, 'PFCWD') + +def get_uptime(): + with open('/proc/uptime') as fp: + return float(fp.read().split(' ')[0]) + +def main(): + # If the switch was just started (uptime less than 5 minutes), + # wait for 3 minutes and enable counters + # otherwise wait for 60 seconds and enable counters + uptime = get_uptime() + if uptime < 300: + time.sleep(180) + else: + time.sleep(60) + enable_counters() + +if __name__ == '__main__': + main() diff --git a/dockers/docker-orchagent/start.sh b/dockers/docker-orchagent/start.sh index e26be9286aa3..0321bf8428f4 100755 --- a/dockers/docker-orchagent/start.sh +++ b/dockers/docker-orchagent/start.sh @@ -28,6 +28,8 @@ supervisorctl start intfmgrd supervisorctl start buffermgrd +supervisorctl start enable_counters + # Start arp_update when VLAN exists VLAN=`sonic-cfggen -d -v 'VLAN.keys() | join(" ") if VLAN'` if [ "$VLAN" != "" ]; then diff --git a/dockers/docker-orchagent/supervisord.conf b/dockers/docker-orchagent/supervisord.conf index dc28e3369ca5..2369a4c31b05 100644 --- a/dockers/docker-orchagent/supervisord.conf +++ b/dockers/docker-orchagent/supervisord.conf @@ -91,3 +91,11 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog + +[program:enable_counters] +command=/usr/bin/enable_counters.py +priority=11 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog diff --git a/files/build_templates/enable_counters.service b/files/build_templates/enable_counters.service deleted file mode 100644 index 95424474cb15..000000000000 --- a/files/build_templates/enable_counters.service +++ /dev/null @@ -1,8 +0,0 @@ -[Unit] -Description=Enable SONiC counters -PartOf=swss.service - -[Service] -Type=oneshot -ExecStart=/bin/bash -c 'sleep 60 ; /usr/bin/counterpoll queue enable ; /usr/bin/counterpoll port enable ; /usr/bin/pfcwd counter_poll enable' -RemainAfterExit=yes diff --git a/files/build_templates/enable_counters.timer b/files/build_templates/enable_counters.timer deleted file mode 100644 index 40a91525a712..000000000000 --- a/files/build_templates/enable_counters.timer +++ /dev/null @@ -1,9 +0,0 @@ -[Unit] -Description=Delays the SONiC counters gathering until SONiC has started - -[Timer] -OnBootSec=2min -Unit=enable_counters.service - -[Install] -WantedBy=timers.target diff --git a/files/build_templates/snmp.service.j2 b/files/build_templates/snmp.service.j2 index 93ef869b86e1..6398477ab6a1 100644 --- a/files/build_templates/snmp.service.j2 +++ b/files/build_templates/snmp.service.j2 @@ -1,7 +1,7 @@ [Unit] Description=SNMP container -Requires=updategraph.service swss.service enable_counters.service -After=updategraph.service swss.service enable_counters.service +Requires=updategraph.service swss.service +After=updategraph.service swss.service [Service] ExecStartPre=/usr/bin/{{docker_container_name}}.sh start diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index bf65cad02d1e..7e22aad82fb4 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -280,10 +280,7 @@ sudo LANG=C chroot $FILESYSTEM_ROOT umount -lf /sys # Copy systemd timer configuration # It implements delayed start of services -sudo cp $BUILD_TEMPLATES/enable_counters.timer $FILESYSTEM_ROOT/etc/systemd/system/ -sudo cp $BUILD_TEMPLATES/enable_counters.service $FILESYSTEM_ROOT/etc/systemd/system/ sudo cp $BUILD_TEMPLATES/snmp.timer $FILESYSTEM_ROOT/etc/systemd/system/ -sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable enable_counters.timer sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable snmp.timer sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get remove -y python-dev From f2b8442d942b61304a182a393ddc612de4afba2a Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 28 Jul 2018 01:04:27 +0000 Subject: [PATCH 116/219] [sonic-swss]: update sonic-swss submodule * 8f52e29 2018-07-25 | Postpone intf task after buffer configuration applied on the port. (#539) (HEAD, origin/201803) [Jipan Yang] * 2d2fdaa 2018-07-26 | [portsorch]: Refix: Don't print error when alias equal to PortConfigDone (#548) [Qi Luo] * 87d34db 2018-07-12 | [MirrorOrch]: Fix bug when NULL is returned from the getenv function (#537) [Shuotian Cheng] --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 6dba3161c79f..8f52e297e83a 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 6dba3161c79fff23332a0fa8933e0f464e4dec10 +Subproject commit 8f52e297e83acc3e5d8ce82ef67285ee730e0ea4 From a7ca027a34761d47f5e8ea17193faaa38249a3a2 Mon Sep 17 00:00:00 2001 From: lguohan Date: Fri, 27 Jul 2018 22:47:59 -0700 Subject: [PATCH 117/219] [platform]: add sonic port alias for mellanox SN2700 platform (#1883) --- .../ACS-MSN2700/port_config.ini | 66 +++++----- .../Mellanox-SN2700-D48C8/port_config.ini | 114 +++++++++--------- 2 files changed, 90 insertions(+), 90 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/port_config.ini b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/port_config.ini index 816bb0e94a70..1e1906ff0ef5 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/port_config.ini @@ -1,33 +1,33 @@ -# name lanes -Ethernet0 0,1,2,3 -Ethernet4 4,5,6,7 -Ethernet8 8,9,10,11 -Ethernet12 12,13,14,15 -Ethernet16 16,17,18,19 -Ethernet20 20,21,22,23 -Ethernet24 24,25,26,27 -Ethernet28 28,29,30,31 -Ethernet32 32,33,34,35 -Ethernet36 36,37,38,39 -Ethernet40 40,41,42,43 -Ethernet44 44,45,46,47 -Ethernet48 48,49,50,51 -Ethernet52 52,53,54,55 -Ethernet56 56,57,58,59 -Ethernet60 60,61,62,63 -Ethernet64 64,65,66,67 -Ethernet68 68,69,70,71 -Ethernet72 72,73,74,75 -Ethernet76 76,77,78,79 -Ethernet80 80,81,82,83 -Ethernet84 84,85,86,87 -Ethernet88 88,89,90,91 -Ethernet92 92,93,94,95 -Ethernet96 96,97,98,99 -Ethernet100 100,101,102,103 -Ethernet104 104,105,106,107 -Ethernet108 108,109,110,111 -Ethernet112 112,113,114,115 -Ethernet116 116,117,118,119 -Ethernet120 120,121,122,123 -Ethernet124 124,125,126,127 +# name lanes alias +Ethernet0 0,1,2,3 etp1 +Ethernet4 4,5,6,7 etp2 +Ethernet8 8,9,10,11 etp3 +Ethernet12 12,13,14,15 etp4 +Ethernet16 16,17,18,19 etp5 +Ethernet20 20,21,22,23 etp6 +Ethernet24 24,25,26,27 etp7 +Ethernet28 28,29,30,31 etp8 +Ethernet32 32,33,34,35 etp9 +Ethernet36 36,37,38,39 etp10 +Ethernet40 40,41,42,43 etp11 +Ethernet44 44,45,46,47 etp12 +Ethernet48 48,49,50,51 etp13 +Ethernet52 52,53,54,55 etp14 +Ethernet56 56,57,58,59 etp15 +Ethernet60 60,61,62,63 etp16 +Ethernet64 64,65,66,67 etp17 +Ethernet68 68,69,70,71 etp18 +Ethernet72 72,73,74,75 etp19 +Ethernet76 76,77,78,79 etp20 +Ethernet80 80,81,82,83 etp21 +Ethernet84 84,85,86,87 etp22 +Ethernet88 88,89,90,91 etp23 +Ethernet92 92,93,94,95 etp24 +Ethernet96 96,97,98,99 etp25 +Ethernet100 100,101,102,103 etp26 +Ethernet104 104,105,106,107 etp27 +Ethernet108 108,109,110,111 etp28 +Ethernet112 112,113,114,115 etp29 +Ethernet116 116,117,118,119 etp30 +Ethernet120 120,121,122,123 etp31 +Ethernet124 124,125,126,127 etp32 diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini index d54a31851614..ffe3fe0ce6d9 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini @@ -1,57 +1,57 @@ -# name lanes speed -Ethernet0 0,1 50000 -Ethernet2 2,3 50000 -Ethernet4 4,5 50000 -Ethernet6 6,7 50000 -Ethernet8 8,9 50000 -Ethernet10 10,11 50000 -Ethernet12 12,13 50000 -Ethernet14 14,15 50000 -Ethernet16 16,17 50000 -Ethernet18 18,19 50000 -Ethernet20 20,21 50000 -Ethernet22 22,23 50000 -Ethernet24 24,25,26,27 100000 -Ethernet28 28,29,30,31 100000 -Ethernet32 32,33,34,35 100000 -Ethernet36 36,37,38,39 100000 -Ethernet40 40,41 50000 -Ethernet42 42,43 50000 -Ethernet44 44,45 50000 -Ethernet46 46,47 50000 -Ethernet48 48,49 50000 -Ethernet50 50,51 50000 -Ethernet52 52,53 50000 -Ethernet54 54,55 50000 -Ethernet56 56,57 50000 -Ethernet58 58,59 50000 -Ethernet60 60,61 50000 -Ethernet62 62,63 50000 -Ethernet64 64,65 50000 -Ethernet66 66,67 50000 -Ethernet68 68,69 50000 -Ethernet70 70,71 50000 -Ethernet72 72,73 50000 -Ethernet74 74,75 50000 -Ethernet76 76,77 50000 -Ethernet78 78,79 50000 -Ethernet80 80,81 50000 -Ethernet82 82,83 50000 -Ethernet84 84,85 50000 -Ethernet86 86,87 50000 -Ethernet88 88,89,90,91 100000 -Ethernet92 92,93,94,95 100000 -Ethernet96 96,97,98,99 100000 -Ethernet100 100,101,102,103 100000 -Ethernet104 104,105 50000 -Ethernet106 106,107 50000 -Ethernet108 108,109 50000 -Ethernet110 110,111 50000 -Ethernet112 112,113 50000 -Ethernet114 114,115 50000 -Ethernet116 116,117 50000 -Ethernet118 118,119 50000 -Ethernet120 120,121 50000 -Ethernet122 122,123 50000 -Ethernet124 124,125 50000 -Ethernet126 126,127 50000 +# name lanes speed alias +Ethernet0 0,1 50000 etp1a +Ethernet2 2,3 50000 etp1b +Ethernet4 4,5 50000 etp2a +Ethernet6 6,7 50000 etp2b +Ethernet8 8,9 50000 etp3a +Ethernet10 10,11 50000 etp3b +Ethernet12 12,13 50000 etp4a +Ethernet14 14,15 50000 etp4b +Ethernet16 16,17 50000 etp5a +Ethernet18 18,19 50000 etp5b +Ethernet20 20,21 50000 etp6a +Ethernet22 22,23 50000 etp6b +Ethernet24 24,25,26,27 100000 etp7 +Ethernet28 28,29,30,31 100000 etp8 +Ethernet32 32,33,34,35 100000 etp9 +Ethernet36 36,37,38,39 100000 etp10 +Ethernet40 40,41 50000 etp11a +Ethernet42 42,43 50000 etp11b +Ethernet44 44,45 50000 etp12a +Ethernet46 46,47 50000 etp12b +Ethernet48 48,49 50000 etp13a +Ethernet50 50,51 50000 etp13b +Ethernet52 52,53 50000 etp14a +Ethernet54 54,55 50000 etp14b +Ethernet56 56,57 50000 etp15a +Ethernet58 58,59 50000 etp15b +Ethernet60 60,61 50000 etp16a +Ethernet62 62,63 50000 etp16b +Ethernet64 64,65 50000 etp17a +Ethernet66 66,67 50000 etp17b +Ethernet68 68,69 50000 etp18a +Ethernet70 70,71 50000 etp18b +Ethernet72 72,73 50000 etp19a +Ethernet74 74,75 50000 etp19b +Ethernet76 76,77 50000 etp20a +Ethernet78 78,79 50000 etp20b +Ethernet80 80,81 50000 etp21a +Ethernet82 82,83 50000 etp21b +Ethernet84 84,85 50000 etp22a +Ethernet86 86,87 50000 etp22b +Ethernet88 88,89,90,91 100000 etp23 +Ethernet92 92,93,94,95 100000 etp24 +Ethernet96 96,97,98,99 100000 etp25 +Ethernet100 100,101,102,103 100000 etp26 +Ethernet104 104,105 50000 etp27a +Ethernet106 106,107 50000 etp27b +Ethernet108 108,109 50000 etp28a +Ethernet110 110,111 50000 etp28b +Ethernet112 112,113 50000 etp29a +Ethernet114 114,115 50000 etp29b +Ethernet116 116,117 50000 etp30a +Ethernet118 118,119 50000 etp30b +Ethernet120 120,121 50000 etp31a +Ethernet122 122,123 50000 etp31b +Ethernet124 124,125 50000 etp32a +Ethernet126 126,127 50000 etp32b From 7419f0a1884141d732087461859fc72ca175f727 Mon Sep 17 00:00:00 2001 From: simonJi2018 <37395146+simonJi2018@users.noreply.github.com> Date: Tue, 31 Jul 2018 07:01:20 +0800 Subject: [PATCH 118/219] [nephos]: add new device accton 7116 support for sonic 201803 branch (#1887) --- .../Accton-AS7116-54X/buffers.json.j2 | 111 ++ .../Accton-AS7116-54X/pg_profile_lookup.ini | 17 + .../Accton-AS7116-54X/port_config.ini | 55 + .../Accton-AS7116-54X/port_config.nps | 358 +++++ .../Accton-AS7116-54X/port_config.nps.AOC.R0B | 358 +++++ .../Accton-AS7116-54X/port_config.nps.DAC.R0B | 357 +++++ .../Accton-AS7116-54X/qos.json.j2 | 136 ++ .../Accton-AS7116-54X/sai.profile | 2 + .../installer.conf | 4 + .../led_proc_init.nps | 10 + .../x86_64-accton_as7116_54x-r0/minigraph.xml | 68 + .../plugins/eeprom.py | 21 + .../plugins/psuutil.py | 92 ++ .../plugins/sfputil.py | 150 ++ .../x86_64-accton_as7116_54x-r0/sensors.conf | 13 + .../INGRASYS-S9130-32X/buffers.json.j2 | 111 ++ .../INGRASYS-S9130-32X/pg_profile_lookup.ini | 17 + .../INGRASYS-S9130-32X/qos.json.j2 | 136 ++ .../minigraph.xml | 86 +- .../INGRASYS-S9230-64X/buffers.json.j2 | 111 ++ .../INGRASYS-S9230-64X/pg_profile_lookup.ini | 17 + .../INGRASYS-S9230-64X/qos.json.j2 | 136 ++ platform/nephos/one-image.mk | 3 +- platform/nephos/platform-modules-accton.mk | 11 + platform/nephos/rules.mk | 1 + platform/nephos/sai.mk | 8 +- platform/nephos/sdk.mk | 4 +- .../sonic-platform-modules-accton/LICENSE | 16 + .../sonic-platform-modules-accton/README.md | 1 + .../as7116-54x/classes/__init__.py | 0 .../as7116-54x/classes/fanutil.py | 0 .../as7116-54x/classes/thermalutil.py | 0 .../as7116-54x/modules/Makefile | 2 + .../modules/x86-64-accton-as7116-54x-cpld.c | 242 +++ .../modules/x86-64-accton-as7116-54x-fan.c | 544 +++++++ .../modules/x86-64-accton-as7116-54x-led.c | 448 ++++++ .../modules/x86-64-accton-as7116-54x-psu.c | 349 +++++ .../modules/x86-64-accton-as7116-54x-sfp.c | 1384 +++++++++++++++++ .../service/as7116-platform-init.service | 13 + .../as7116-54x/setup.py | 15 + .../as7116-54x/utils/README | 60 + .../as7116-54x/utils/accton_as7116_util.py | 526 +++++++ .../debian/changelog | 6 + .../debian/compat | 1 + .../debian/control | 11 + .../debian/rules | 86 + 46 files changed, 6006 insertions(+), 91 deletions(-) create mode 100644 device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/buffers.json.j2 create mode 100644 device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/pg_profile_lookup.ini create mode 100644 device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.ini create mode 100644 device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps create mode 100644 device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps.AOC.R0B create mode 100644 device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps.DAC.R0B create mode 100644 device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/qos.json.j2 create mode 100644 device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/sai.profile create mode 100644 device/accton/x86_64-accton_as7116_54x-r0/installer.conf create mode 100644 device/accton/x86_64-accton_as7116_54x-r0/led_proc_init.nps create mode 100644 device/accton/x86_64-accton_as7116_54x-r0/minigraph.xml create mode 100644 device/accton/x86_64-accton_as7116_54x-r0/plugins/eeprom.py create mode 100644 device/accton/x86_64-accton_as7116_54x-r0/plugins/psuutil.py create mode 100644 device/accton/x86_64-accton_as7116_54x-r0/plugins/sfputil.py create mode 100644 device/accton/x86_64-accton_as7116_54x-r0/sensors.conf create mode 100644 device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/buffers.json.j2 create mode 100644 device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/pg_profile_lookup.ini create mode 100644 device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/qos.json.j2 create mode 100644 device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/buffers.json.j2 create mode 100644 device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/pg_profile_lookup.ini create mode 100644 device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/qos.json.j2 create mode 100644 platform/nephos/platform-modules-accton.mk create mode 100644 platform/nephos/sonic-platform-modules-accton/LICENSE create mode 100644 platform/nephos/sonic-platform-modules-accton/README.md create mode 100644 platform/nephos/sonic-platform-modules-accton/as7116-54x/classes/__init__.py create mode 100644 platform/nephos/sonic-platform-modules-accton/as7116-54x/classes/fanutil.py create mode 100644 platform/nephos/sonic-platform-modules-accton/as7116-54x/classes/thermalutil.py create mode 100644 platform/nephos/sonic-platform-modules-accton/as7116-54x/modules/Makefile create mode 100644 platform/nephos/sonic-platform-modules-accton/as7116-54x/modules/x86-64-accton-as7116-54x-cpld.c create mode 100644 platform/nephos/sonic-platform-modules-accton/as7116-54x/modules/x86-64-accton-as7116-54x-fan.c create mode 100644 platform/nephos/sonic-platform-modules-accton/as7116-54x/modules/x86-64-accton-as7116-54x-led.c create mode 100644 platform/nephos/sonic-platform-modules-accton/as7116-54x/modules/x86-64-accton-as7116-54x-psu.c create mode 100644 platform/nephos/sonic-platform-modules-accton/as7116-54x/modules/x86-64-accton-as7116-54x-sfp.c create mode 100755 platform/nephos/sonic-platform-modules-accton/as7116-54x/service/as7116-platform-init.service create mode 100644 platform/nephos/sonic-platform-modules-accton/as7116-54x/setup.py create mode 100755 platform/nephos/sonic-platform-modules-accton/as7116-54x/utils/README create mode 100755 platform/nephos/sonic-platform-modules-accton/as7116-54x/utils/accton_as7116_util.py create mode 100755 platform/nephos/sonic-platform-modules-accton/debian/changelog create mode 100644 platform/nephos/sonic-platform-modules-accton/debian/compat create mode 100755 platform/nephos/sonic-platform-modules-accton/debian/control create mode 100755 platform/nephos/sonic-platform-modules-accton/debian/rules diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/buffers.json.j2 b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/buffers.json.j2 new file mode 100644 index 000000000000..2c391214fa65 --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/buffers.json.j2 @@ -0,0 +1,111 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '40m' %} +{% set default_speed = '10G' %} +{% 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(0,default_ports_num) %} + {% 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 %} + } + }, + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "20971328", + "type": "ingress", + "mode": "static" + }, + "ingress_lossy_pool": { + "size": "20971328", + "type": "ingress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "20971328", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xon":"78400", + "xoff":"132160", + "size":"3584", + "static_th":"82880" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"3584", + "dynamic_th":"-1" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"3584", + "dynamic_th":"-4" + } + }, + "BUFFER_PG": { + }, + "BUFFER_QUEUE": { + } +} + \ No newline at end of file diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/pg_profile_lookup.ini b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/pg_profile_lookup.ini new file mode 100644 index 000000000000..d98b0eca6d19 --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 10000 5m 3584 32256 59136 36736 + 25000 5m 3584 41216 68096 45696 + 40000 5m 3584 47488 74368 51968 + 50000 5m 3584 52864 79744 57344 + 100000 5m 3584 78400 132160 82880 + 10000 40m 3584 32256 59136 36736 + 25000 40m 3584 41216 68096 45696 + 40000 40m 3584 47488 74368 51968 + 50000 40m 3584 52864 79744 57344 + 100000 40m 3584 78400 132160 82880 + 10000 300m 3584 32256 65856 36736 + 25000 300m 3584 41216 84672 45696 + 40000 300m 3584 47488 101024 51968 + 50000 300m 3584 52864 113120 57344 + 100000 300m 3584 78400 198688 82880 \ No newline at end of file diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.ini b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.ini new file mode 100644 index 000000000000..52c59bc9d297 --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.ini @@ -0,0 +1,55 @@ +# name lanes alias index +Ethernet0 8 Ethernet1/1 0 +Ethernet1 9 Ethernet2/1 1 +Ethernet2 10 Ethernet3/1 2 +Ethernet3 11 Ethernet4/1 3 +Ethernet4 12 Ethernet5/1 4 +Ethernet5 13 Ethernet6/1 5 +Ethernet6 14 Ethernet7/1 6 +Ethernet7 15 Ethernet8/1 7 +Ethernet8 16 Ethernet9/1 8 +Ethernet9 17 Ethernet10/1 9 +Ethernet10 18 Ethernet11/1 10 +Ethernet11 19 Ethernet12/1 11 +Ethernet12 20 Ethernet13/1 12 +Ethernet13 21 Ethernet14/1 13 +Ethernet14 22 Ethernet15/1 14 +Ethernet15 23 Ethernet16/1 15 +Ethernet16 32 Ethernet17/1 16 +Ethernet17 33 Ethernet18/1 17 +Ethernet18 34 Ethernet19/1 18 +Ethernet19 35 Ethernet20/1 19 +Ethernet20 40 Ethernet21/1 20 +Ethernet21 41 Ethernet22/1 21 +Ethernet22 42 Ethernet23/1 22 +Ethernet23 43 Ethernet24/1 23 +Ethernet24 48 Ethernet25/1 24 +Ethernet25 49 Ethernet26/1 25 +Ethernet26 50 Ethernet27/1 26 +Ethernet27 51 Ethernet28/1 27 +Ethernet28 56 Ethernet29/1 28 +Ethernet29 57 Ethernet30/1 29 +Ethernet30 58 Ethernet31/1 30 +Ethernet31 59 Ethernet32/1 31 +Ethernet32 64 Ethernet33/1 32 +Ethernet33 65 Ethernet34/1 33 +Ethernet34 66 Ethernet35/1 34 +Ethernet35 67 Ethernet36/1 35 +Ethernet36 68 Ethernet37/1 36 +Ethernet37 69 Ethernet38/1 37 +Ethernet38 70 Ethernet39/1 38 +Ethernet39 71 Ethernet40/1 39 +Ethernet40 72 Ethernet41/1 40 +Ethernet41 73 Ethernet42/1 41 +Ethernet42 74 Ethernet43/1 42 +Ethernet43 75 Ethernet44/1 43 +Ethernet44 76 Ethernet45/1 44 +Ethernet45 77 Ethernet46/1 45 +Ethernet46 78 Ethernet47/1 46 +Ethernet47 79 Ethernet48/1 47 +Ethernet48 84,85,86,87 Ethernet49/1 48 +Ethernet49 80,81,82,83 Ethernet50/1 49 +Ethernet50 104,105,106,107 Ethernet51/1 50 +Ethernet51 108,109,110,111 Ethernet52/1 51 +Ethernet52 112,113,114,115 Ethernet53/1 52 +Ethernet53 116,117,118,119 Ethernet54/1 53 \ No newline at end of file diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps new file mode 100644 index 000000000000..34e5a2daab80 --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps @@ -0,0 +1,358 @@ +init start stage unit=0 low-level +init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=25g active=true +init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=25g active=true +init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=25g active=true +init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=25g active=true +init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=25g active=true +init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=25g active=true +init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=25g active=true +init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=25g active=true +init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=25g active=true +init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=25g active=true +init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=25g active=true +init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=25g active=true +init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=25g active=true +init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=25g active=true +init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=25g active=true +init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=25g active=true +init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=25g active=true +init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=25g active=true +init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=25g active=true +init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=25g active=true +init set port-map unit=0 port=20 eth-macro=10 lane=0 max-speed=25g active=true +init set port-map unit=0 port=21 eth-macro=10 lane=1 max-speed=25g active=true +init set port-map unit=0 port=22 eth-macro=10 lane=2 max-speed=25g active=true +init set port-map unit=0 port=23 eth-macro=10 lane=3 max-speed=25g active=true +init set port-map unit=0 port=24 eth-macro=12 lane=0 max-speed=25g active=true +init set port-map unit=0 port=25 eth-macro=12 lane=1 max-speed=25g active=true +init set port-map unit=0 port=26 eth-macro=12 lane=2 max-speed=25g active=true +init set port-map unit=0 port=27 eth-macro=12 lane=3 max-speed=25g active=true +init set port-map unit=0 port=28 eth-macro=14 lane=0 max-speed=25g active=true +init set port-map unit=0 port=29 eth-macro=14 lane=1 max-speed=25g active=true +init set port-map unit=0 port=30 eth-macro=14 lane=2 max-speed=25g active=true +init set port-map unit=0 port=31 eth-macro=14 lane=3 max-speed=25g active=true +init set port-map unit=0 port=32 eth-macro=16 lane=0 max-speed=25g active=true +init set port-map unit=0 port=33 eth-macro=16 lane=1 max-speed=25g active=true +init set port-map unit=0 port=34 eth-macro=16 lane=2 max-speed=25g active=true +init set port-map unit=0 port=35 eth-macro=16 lane=3 max-speed=25g active=true +init set port-map unit=0 port=36 eth-macro=17 lane=0 max-speed=25g active=true +init set port-map unit=0 port=37 eth-macro=17 lane=1 max-speed=25g active=true +init set port-map unit=0 port=38 eth-macro=17 lane=2 max-speed=25g active=true +init set port-map unit=0 port=39 eth-macro=17 lane=3 max-speed=25g active=true +init set port-map unit=0 port=40 eth-macro=18 lane=0 max-speed=25g active=true +init set port-map unit=0 port=41 eth-macro=18 lane=1 max-speed=25g active=true +init set port-map unit=0 port=42 eth-macro=18 lane=2 max-speed=25g active=true +init set port-map unit=0 port=43 eth-macro=18 lane=3 max-speed=25g active=true +init set port-map unit=0 port=44 eth-macro=19 lane=0 max-speed=25g active=true +init set port-map unit=0 port=45 eth-macro=19 lane=1 max-speed=25g active=true +init set port-map unit=0 port=46 eth-macro=19 lane=2 max-speed=25g active=true +init set port-map unit=0 port=47 eth-macro=19 lane=3 max-speed=25g active=true +init set port-map unit=0 port=48 eth-macro=21 lane=0 max-speed=100g active=true +init set port-map unit=0 port=49 eth-macro=20 lane=0 max-speed=100g active=true +init set port-map unit=0 port=50 eth-macro=26 lane=0 max-speed=100g active=true +init set port-map unit=0 port=51 eth-macro=27 lane=0 max-speed=100g active=true +init set port-map unit=0 port=52 eth-macro=28 lane=0 max-speed=100g active=true +init set port-map unit=0 port=53 eth-macro=29 lane=0 max-speed=100g active=true +init set port-map unit=0 port=129 eth-macro=0 lane=1 max-speed=10g active=true guarantee=true cpi=true +init set port-map unit=0 port=130 eth-macro=0 lane=0 max-speed=10g active=true guarantee=true cpi=true init-done=true +init start stage unit=0 task-rsrc +init start stage unit=0 module +init start stage unit=0 task +phy set lane-swap portlist=0 lane-cnt=1 property=tx data=0x0 +phy set lane-swap portlist=1 lane-cnt=1 property=tx data=0x1 +phy set lane-swap portlist=2 lane-cnt=1 property=tx data=0x2 +phy set lane-swap portlist=3 lane-cnt=1 property=tx data=0x3 +phy set lane-swap portlist=4 lane-cnt=1 property=tx data=0x3 +phy set lane-swap portlist=5 lane-cnt=1 property=tx data=0x2 +phy set lane-swap portlist=6 lane-cnt=1 property=tx data=0x1 +phy set lane-swap portlist=7 lane-cnt=1 property=tx data=0x0 +phy set lane-swap portlist=8 lane-cnt=1 property=tx data=0x0 +phy set lane-swap portlist=9 lane-cnt=1 property=tx data=0x1 +phy set lane-swap portlist=10 lane-cnt=1 property=tx data=0x2 +phy set lane-swap portlist=11 lane-cnt=1 property=tx data=0x3 +phy set lane-swap portlist=12 lane-cnt=1 property=tx data=0x3 +phy set lane-swap portlist=13 lane-cnt=1 property=tx data=0x2 +phy set lane-swap portlist=14 lane-cnt=1 property=tx data=0x1 +phy set lane-swap portlist=15 lane-cnt=1 property=tx data=0x0 +phy set lane-swap portlist=16 lane-cnt=1 property=tx data=0x3 +phy set lane-swap portlist=17 lane-cnt=1 property=tx data=0x2 +phy set lane-swap portlist=18 lane-cnt=1 property=tx data=0x0 +phy set lane-swap portlist=19 lane-cnt=1 property=tx data=0x1 +phy set lane-swap portlist=20 lane-cnt=1 property=tx data=0x3 +phy set lane-swap portlist=21 lane-cnt=1 property=tx data=0x2 +phy set lane-swap portlist=22 lane-cnt=1 property=tx data=0x1 +phy set lane-swap portlist=23 lane-cnt=1 property=tx data=0x0 +phy set lane-swap portlist=24 lane-cnt=1 property=tx data=0x3 +phy set lane-swap portlist=25 lane-cnt=1 property=tx data=0x2 +phy set lane-swap portlist=26 lane-cnt=1 property=tx data=0x1 +phy set lane-swap portlist=27 lane-cnt=1 property=tx data=0x0 +phy set lane-swap portlist=28 lane-cnt=1 property=tx data=0x3 +phy set lane-swap portlist=29 lane-cnt=1 property=tx data=0x2 +phy set lane-swap portlist=30 lane-cnt=1 property=tx data=0x1 +phy set lane-swap portlist=31 lane-cnt=1 property=tx data=0x0 +phy set lane-swap portlist=32 lane-cnt=1 property=tx data=0x0 +phy set lane-swap portlist=33 lane-cnt=1 property=tx data=0x1 +phy set lane-swap portlist=34 lane-cnt=1 property=tx data=0x2 +phy set lane-swap portlist=35 lane-cnt=1 property=tx data=0x3 +phy set lane-swap portlist=36 lane-cnt=1 property=tx data=0x0 +phy set lane-swap portlist=37 lane-cnt=1 property=tx data=0x1 +phy set lane-swap portlist=38 lane-cnt=1 property=tx data=0x2 +phy set lane-swap portlist=39 lane-cnt=1 property=tx data=0x3 +phy set lane-swap portlist=40 lane-cnt=1 property=tx data=0x0 +phy set lane-swap portlist=41 lane-cnt=1 property=tx data=0x1 +phy set lane-swap portlist=42 lane-cnt=1 property=tx data=0x2 +phy set lane-swap portlist=43 lane-cnt=1 property=tx data=0x3 +phy set lane-swap portlist=44 lane-cnt=1 property=tx data=0x0 +phy set lane-swap portlist=45 lane-cnt=1 property=tx data=0x1 +phy set lane-swap portlist=46 lane-cnt=1 property=tx data=0x2 +phy set lane-swap portlist=47 lane-cnt=1 property=tx data=0x3 +phy set lane-swap portlist=48 lane-cnt=4 property=tx data=0x1.3.0.2 +phy set lane-swap portlist=49 lane-cnt=4 property=tx data=0x0.3.1.2 +phy set lane-swap portlist=50 lane-cnt=4 property=tx data=0x1.3.0.2 +phy set lane-swap portlist=51 lane-cnt=4 property=tx data=0x2.0.3.1 +phy set lane-swap portlist=52 lane-cnt=4 property=tx data=0x3.2.1.0 +phy set lane-swap portlist=53 lane-cnt=4 property=tx data=0x3.2.1.0 +phy set lane-swap portlist=0 lane-cnt=1 property=rx data=0x0 +phy set lane-swap portlist=1 lane-cnt=1 property=rx data=0x1 +phy set lane-swap portlist=2 lane-cnt=1 property=rx data=0x2 +phy set lane-swap portlist=3 lane-cnt=1 property=rx data=0x3 +phy set lane-swap portlist=4 lane-cnt=1 property=rx data=0x3 +phy set lane-swap portlist=5 lane-cnt=1 property=rx data=0x2 +phy set lane-swap portlist=6 lane-cnt=1 property=rx data=0x1 +phy set lane-swap portlist=7 lane-cnt=1 property=rx data=0x0 +phy set lane-swap portlist=8 lane-cnt=1 property=rx data=0x0 +phy set lane-swap portlist=9 lane-cnt=1 property=rx data=0x1 +phy set lane-swap portlist=10 lane-cnt=1 property=rx data=0x2 +phy set lane-swap portlist=11 lane-cnt=1 property=rx data=0x3 +phy set lane-swap portlist=12 lane-cnt=1 property=rx data=0x3 +phy set lane-swap portlist=13 lane-cnt=1 property=rx data=0x2 +phy set lane-swap portlist=14 lane-cnt=1 property=rx data=0x0 +phy set lane-swap portlist=15 lane-cnt=1 property=rx data=0x1 +phy set lane-swap portlist=16 lane-cnt=1 property=rx data=0x0 +phy set lane-swap portlist=17 lane-cnt=1 property=rx data=0x3 +phy set lane-swap portlist=18 lane-cnt=1 property=rx data=0x2 +phy set lane-swap portlist=19 lane-cnt=1 property=rx data=0x1 +phy set lane-swap portlist=20 lane-cnt=1 property=rx data=0x3 +phy set lane-swap portlist=21 lane-cnt=1 property=rx data=0x0 +phy set lane-swap portlist=22 lane-cnt=1 property=rx data=0x1 +phy set lane-swap portlist=23 lane-cnt=1 property=rx data=0x2 +phy set lane-swap portlist=24 lane-cnt=1 property=rx data=0x3 +phy set lane-swap portlist=25 lane-cnt=1 property=rx data=0x0 +phy set lane-swap portlist=26 lane-cnt=1 property=rx data=0x1 +phy set lane-swap portlist=27 lane-cnt=1 property=rx data=0x2 +phy set lane-swap portlist=28 lane-cnt=1 property=rx data=0x3 +phy set lane-swap portlist=29 lane-cnt=1 property=rx data=0x0 +phy set lane-swap portlist=30 lane-cnt=1 property=rx data=0x1 +phy set lane-swap portlist=31 lane-cnt=1 property=rx data=0x2 +phy set lane-swap portlist=32 lane-cnt=1 property=rx data=0x1 +phy set lane-swap portlist=33 lane-cnt=1 property=rx data=0x2 +phy set lane-swap portlist=34 lane-cnt=1 property=rx data=0x3 +phy set lane-swap portlist=35 lane-cnt=1 property=rx data=0x0 +phy set lane-swap portlist=36 lane-cnt=1 property=rx data=0x1 +phy set lane-swap portlist=37 lane-cnt=1 property=rx data=0x2 +phy set lane-swap portlist=38 lane-cnt=1 property=rx data=0x3 +phy set lane-swap portlist=39 lane-cnt=1 property=rx data=0x0 +phy set lane-swap portlist=40 lane-cnt=1 property=rx data=0x1 +phy set lane-swap portlist=41 lane-cnt=1 property=rx data=0x2 +phy set lane-swap portlist=42 lane-cnt=1 property=rx data=0x3 +phy set lane-swap portlist=43 lane-cnt=1 property=rx data=0x0 +phy set lane-swap portlist=44 lane-cnt=1 property=rx data=0x1 +phy set lane-swap portlist=45 lane-cnt=1 property=rx data=0x2 +phy set lane-swap portlist=46 lane-cnt=1 property=rx data=0x3 +phy set lane-swap portlist=47 lane-cnt=1 property=rx data=0x0 +phy set lane-swap portlist=48 lane-cnt=4 property=rx data=0x2.1.0.3 +phy set lane-swap portlist=49 lane-cnt=4 property=rx data=0x0.1.3.2 +phy set lane-swap portlist=50 lane-cnt=4 property=rx data=0x3.1.0.2 +phy set lane-swap portlist=51 lane-cnt=4 property=rx data=0x1.3.0.2 +phy set lane-swap portlist=52 lane-cnt=4 property=rx data=0x3.2.1.0 +phy set lane-swap portlist=53 lane-cnt=4 property=rx data=0x3.2.1.0 +phy set polarity-rev portlist=0 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=1 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=2 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=3 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=4 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=5 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=6 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=7 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=8 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=9 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=10 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=11 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=12 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=13 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=14 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=15 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=16 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=17 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=18 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=19 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=20 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=21 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=22 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=23 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=24 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=25 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=26 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=27 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=28 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=29 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=30 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=31 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=32 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=33 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=34 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=35 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=36 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=37 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=38 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=39 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=40 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=41 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=42 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=43 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=44 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=45 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=46 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=47 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=48 lane-cnt=4 property=tx data=0x0.0.0.1 +phy set polarity-rev portlist=49 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=50 lane-cnt=4 property=tx data=0x1.1.0.0 +phy set polarity-rev portlist=51 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=52 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=53 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=0 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=1 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=2 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=3 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=4 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=5 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=6 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=7 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=8 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=9 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=10 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=11 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=12 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=13 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=14 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=15 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=16 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=17 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=18 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=19 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=20 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=21 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=22 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=23 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=24 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=25 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=26 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=27 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=28 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=29 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=30 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=31 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=32 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=33 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=34 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=35 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=36 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=37 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=38 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=39 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=40 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=41 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=42 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=43 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=44 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=45 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=46 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=47 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=48 lane-cnt=4 property=rx data=0x0.1.0.1 +phy set polarity-rev portlist=49 lane-cnt=4 property=rx data=0x1.0.1.0 +phy set polarity-rev portlist=50 lane-cnt=4 property=rx data=0x0.0.1.0 +phy set polarity-rev portlist=51 lane-cnt=4 property=rx data=0x0.0.0.1 +phy set polarity-rev portlist=52 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=53 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set pre-emphasis portlist=0 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=0 lane-cnt=4 property=cn1 data=0x1.1.1.1 +phy set pre-emphasis portlist=0 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a +phy set pre-emphasis portlist=0 lane-cnt=4 property=c1 data=0x7.7.7.7 +phy set pre-emphasis portlist=4 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=4 lane-cnt=4 property=cn1 data=0x1.1.1.1 +phy set pre-emphasis portlist=4 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a +phy set pre-emphasis portlist=4 lane-cnt=4 property=c1 data=0x7.7.7.7 +phy set pre-emphasis portlist=8 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=8 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=8 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c +phy set pre-emphasis portlist=8 lane-cnt=4 property=c1 data=0x6.6.6.6 +phy set pre-emphasis portlist=12 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=12 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=12 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b +phy set pre-emphasis portlist=12 lane-cnt=4 property=c1 data=0x7.7.7.7 +phy set pre-emphasis portlist=16 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=16 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=16 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c +phy set pre-emphasis portlist=16 lane-cnt=4 property=c1 data=0x6.6.6.6 +phy set pre-emphasis portlist=20 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=20 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=20 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c +phy set pre-emphasis portlist=20 lane-cnt=4 property=c1 data=0x6.6.6.6 +phy set pre-emphasis portlist=24 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=24 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=24 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c +phy set pre-emphasis portlist=24 lane-cnt=4 property=c1 data=0x6.6.6.6 +phy set pre-emphasis portlist=28 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=28 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=28 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c +phy set pre-emphasis portlist=28 lane-cnt=4 property=c1 data=0x6.6.6.6 +phy set pre-emphasis portlist=32 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=32 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=32 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c +phy set pre-emphasis portlist=32 lane-cnt=4 property=c1 data=0x6.6.6.6 +phy set pre-emphasis portlist=36 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=36 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=36 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c +phy set pre-emphasis portlist=36 lane-cnt=4 property=c1 data=0x6.6.6.6 +phy set pre-emphasis portlist=40 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=40 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=40 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c +phy set pre-emphasis portlist=40 lane-cnt=4 property=c1 data=0x6.6.6.6 +phy set pre-emphasis portlist=44 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=44 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=44 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c +phy set pre-emphasis portlist=44 lane-cnt=4 property=c1 data=0x6.6.6.6 +phy set pre-emphasis portlist=48 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=48 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=48 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b +phy set pre-emphasis portlist=48 lane-cnt=4 property=c1 data=0x6.6.6.6 +phy set pre-emphasis portlist=49 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=49 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=49 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b +phy set pre-emphasis portlist=49 lane-cnt=4 property=c1 data=0x6.6.6.6 +phy set pre-emphasis portlist=50 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=50 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=50 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b +phy set pre-emphasis portlist=50 lane-cnt=4 property=c1 data=0x7.7.7.7 +phy set pre-emphasis portlist=51 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=51 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=51 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b +phy set pre-emphasis portlist=51 lane-cnt=4 property=c1 data=0x7.7.7.7 +phy set pre-emphasis portlist=52 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=52 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=52 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a +phy set pre-emphasis portlist=52 lane-cnt=4 property=c1 data=0x8.8.8.8 +phy set pre-emphasis portlist=53 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=53 lane-cnt=4 property=cn1 data=0x1.1.1.1 +phy set pre-emphasis portlist=53 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a +phy set pre-emphasis portlist=53 lane-cnt=4 property=c1 data=0x7.7.7.7 +port set property portlist=0-47 speed=25g +port set property portlist=48-53 speed=100g +port set property portlist=129-130 speed=10g +port set property portlist=0-47 medium-type=sr +port set property portlist=48-53 medium-type=sr4 +port set property portlist=129-130 medium-type=kr +port set adver portlist=129-130 speed-10g-kr +port set property portlist=129-130 an=enable +port set property portlist=0-53,129-130 admin=enable + diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps.AOC.R0B b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps.AOC.R0B new file mode 100644 index 000000000000..34e5a2daab80 --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps.AOC.R0B @@ -0,0 +1,358 @@ +init start stage unit=0 low-level +init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=25g active=true +init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=25g active=true +init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=25g active=true +init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=25g active=true +init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=25g active=true +init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=25g active=true +init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=25g active=true +init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=25g active=true +init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=25g active=true +init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=25g active=true +init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=25g active=true +init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=25g active=true +init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=25g active=true +init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=25g active=true +init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=25g active=true +init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=25g active=true +init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=25g active=true +init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=25g active=true +init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=25g active=true +init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=25g active=true +init set port-map unit=0 port=20 eth-macro=10 lane=0 max-speed=25g active=true +init set port-map unit=0 port=21 eth-macro=10 lane=1 max-speed=25g active=true +init set port-map unit=0 port=22 eth-macro=10 lane=2 max-speed=25g active=true +init set port-map unit=0 port=23 eth-macro=10 lane=3 max-speed=25g active=true +init set port-map unit=0 port=24 eth-macro=12 lane=0 max-speed=25g active=true +init set port-map unit=0 port=25 eth-macro=12 lane=1 max-speed=25g active=true +init set port-map unit=0 port=26 eth-macro=12 lane=2 max-speed=25g active=true +init set port-map unit=0 port=27 eth-macro=12 lane=3 max-speed=25g active=true +init set port-map unit=0 port=28 eth-macro=14 lane=0 max-speed=25g active=true +init set port-map unit=0 port=29 eth-macro=14 lane=1 max-speed=25g active=true +init set port-map unit=0 port=30 eth-macro=14 lane=2 max-speed=25g active=true +init set port-map unit=0 port=31 eth-macro=14 lane=3 max-speed=25g active=true +init set port-map unit=0 port=32 eth-macro=16 lane=0 max-speed=25g active=true +init set port-map unit=0 port=33 eth-macro=16 lane=1 max-speed=25g active=true +init set port-map unit=0 port=34 eth-macro=16 lane=2 max-speed=25g active=true +init set port-map unit=0 port=35 eth-macro=16 lane=3 max-speed=25g active=true +init set port-map unit=0 port=36 eth-macro=17 lane=0 max-speed=25g active=true +init set port-map unit=0 port=37 eth-macro=17 lane=1 max-speed=25g active=true +init set port-map unit=0 port=38 eth-macro=17 lane=2 max-speed=25g active=true +init set port-map unit=0 port=39 eth-macro=17 lane=3 max-speed=25g active=true +init set port-map unit=0 port=40 eth-macro=18 lane=0 max-speed=25g active=true +init set port-map unit=0 port=41 eth-macro=18 lane=1 max-speed=25g active=true +init set port-map unit=0 port=42 eth-macro=18 lane=2 max-speed=25g active=true +init set port-map unit=0 port=43 eth-macro=18 lane=3 max-speed=25g active=true +init set port-map unit=0 port=44 eth-macro=19 lane=0 max-speed=25g active=true +init set port-map unit=0 port=45 eth-macro=19 lane=1 max-speed=25g active=true +init set port-map unit=0 port=46 eth-macro=19 lane=2 max-speed=25g active=true +init set port-map unit=0 port=47 eth-macro=19 lane=3 max-speed=25g active=true +init set port-map unit=0 port=48 eth-macro=21 lane=0 max-speed=100g active=true +init set port-map unit=0 port=49 eth-macro=20 lane=0 max-speed=100g active=true +init set port-map unit=0 port=50 eth-macro=26 lane=0 max-speed=100g active=true +init set port-map unit=0 port=51 eth-macro=27 lane=0 max-speed=100g active=true +init set port-map unit=0 port=52 eth-macro=28 lane=0 max-speed=100g active=true +init set port-map unit=0 port=53 eth-macro=29 lane=0 max-speed=100g active=true +init set port-map unit=0 port=129 eth-macro=0 lane=1 max-speed=10g active=true guarantee=true cpi=true +init set port-map unit=0 port=130 eth-macro=0 lane=0 max-speed=10g active=true guarantee=true cpi=true init-done=true +init start stage unit=0 task-rsrc +init start stage unit=0 module +init start stage unit=0 task +phy set lane-swap portlist=0 lane-cnt=1 property=tx data=0x0 +phy set lane-swap portlist=1 lane-cnt=1 property=tx data=0x1 +phy set lane-swap portlist=2 lane-cnt=1 property=tx data=0x2 +phy set lane-swap portlist=3 lane-cnt=1 property=tx data=0x3 +phy set lane-swap portlist=4 lane-cnt=1 property=tx data=0x3 +phy set lane-swap portlist=5 lane-cnt=1 property=tx data=0x2 +phy set lane-swap portlist=6 lane-cnt=1 property=tx data=0x1 +phy set lane-swap portlist=7 lane-cnt=1 property=tx data=0x0 +phy set lane-swap portlist=8 lane-cnt=1 property=tx data=0x0 +phy set lane-swap portlist=9 lane-cnt=1 property=tx data=0x1 +phy set lane-swap portlist=10 lane-cnt=1 property=tx data=0x2 +phy set lane-swap portlist=11 lane-cnt=1 property=tx data=0x3 +phy set lane-swap portlist=12 lane-cnt=1 property=tx data=0x3 +phy set lane-swap portlist=13 lane-cnt=1 property=tx data=0x2 +phy set lane-swap portlist=14 lane-cnt=1 property=tx data=0x1 +phy set lane-swap portlist=15 lane-cnt=1 property=tx data=0x0 +phy set lane-swap portlist=16 lane-cnt=1 property=tx data=0x3 +phy set lane-swap portlist=17 lane-cnt=1 property=tx data=0x2 +phy set lane-swap portlist=18 lane-cnt=1 property=tx data=0x0 +phy set lane-swap portlist=19 lane-cnt=1 property=tx data=0x1 +phy set lane-swap portlist=20 lane-cnt=1 property=tx data=0x3 +phy set lane-swap portlist=21 lane-cnt=1 property=tx data=0x2 +phy set lane-swap portlist=22 lane-cnt=1 property=tx data=0x1 +phy set lane-swap portlist=23 lane-cnt=1 property=tx data=0x0 +phy set lane-swap portlist=24 lane-cnt=1 property=tx data=0x3 +phy set lane-swap portlist=25 lane-cnt=1 property=tx data=0x2 +phy set lane-swap portlist=26 lane-cnt=1 property=tx data=0x1 +phy set lane-swap portlist=27 lane-cnt=1 property=tx data=0x0 +phy set lane-swap portlist=28 lane-cnt=1 property=tx data=0x3 +phy set lane-swap portlist=29 lane-cnt=1 property=tx data=0x2 +phy set lane-swap portlist=30 lane-cnt=1 property=tx data=0x1 +phy set lane-swap portlist=31 lane-cnt=1 property=tx data=0x0 +phy set lane-swap portlist=32 lane-cnt=1 property=tx data=0x0 +phy set lane-swap portlist=33 lane-cnt=1 property=tx data=0x1 +phy set lane-swap portlist=34 lane-cnt=1 property=tx data=0x2 +phy set lane-swap portlist=35 lane-cnt=1 property=tx data=0x3 +phy set lane-swap portlist=36 lane-cnt=1 property=tx data=0x0 +phy set lane-swap portlist=37 lane-cnt=1 property=tx data=0x1 +phy set lane-swap portlist=38 lane-cnt=1 property=tx data=0x2 +phy set lane-swap portlist=39 lane-cnt=1 property=tx data=0x3 +phy set lane-swap portlist=40 lane-cnt=1 property=tx data=0x0 +phy set lane-swap portlist=41 lane-cnt=1 property=tx data=0x1 +phy set lane-swap portlist=42 lane-cnt=1 property=tx data=0x2 +phy set lane-swap portlist=43 lane-cnt=1 property=tx data=0x3 +phy set lane-swap portlist=44 lane-cnt=1 property=tx data=0x0 +phy set lane-swap portlist=45 lane-cnt=1 property=tx data=0x1 +phy set lane-swap portlist=46 lane-cnt=1 property=tx data=0x2 +phy set lane-swap portlist=47 lane-cnt=1 property=tx data=0x3 +phy set lane-swap portlist=48 lane-cnt=4 property=tx data=0x1.3.0.2 +phy set lane-swap portlist=49 lane-cnt=4 property=tx data=0x0.3.1.2 +phy set lane-swap portlist=50 lane-cnt=4 property=tx data=0x1.3.0.2 +phy set lane-swap portlist=51 lane-cnt=4 property=tx data=0x2.0.3.1 +phy set lane-swap portlist=52 lane-cnt=4 property=tx data=0x3.2.1.0 +phy set lane-swap portlist=53 lane-cnt=4 property=tx data=0x3.2.1.0 +phy set lane-swap portlist=0 lane-cnt=1 property=rx data=0x0 +phy set lane-swap portlist=1 lane-cnt=1 property=rx data=0x1 +phy set lane-swap portlist=2 lane-cnt=1 property=rx data=0x2 +phy set lane-swap portlist=3 lane-cnt=1 property=rx data=0x3 +phy set lane-swap portlist=4 lane-cnt=1 property=rx data=0x3 +phy set lane-swap portlist=5 lane-cnt=1 property=rx data=0x2 +phy set lane-swap portlist=6 lane-cnt=1 property=rx data=0x1 +phy set lane-swap portlist=7 lane-cnt=1 property=rx data=0x0 +phy set lane-swap portlist=8 lane-cnt=1 property=rx data=0x0 +phy set lane-swap portlist=9 lane-cnt=1 property=rx data=0x1 +phy set lane-swap portlist=10 lane-cnt=1 property=rx data=0x2 +phy set lane-swap portlist=11 lane-cnt=1 property=rx data=0x3 +phy set lane-swap portlist=12 lane-cnt=1 property=rx data=0x3 +phy set lane-swap portlist=13 lane-cnt=1 property=rx data=0x2 +phy set lane-swap portlist=14 lane-cnt=1 property=rx data=0x0 +phy set lane-swap portlist=15 lane-cnt=1 property=rx data=0x1 +phy set lane-swap portlist=16 lane-cnt=1 property=rx data=0x0 +phy set lane-swap portlist=17 lane-cnt=1 property=rx data=0x3 +phy set lane-swap portlist=18 lane-cnt=1 property=rx data=0x2 +phy set lane-swap portlist=19 lane-cnt=1 property=rx data=0x1 +phy set lane-swap portlist=20 lane-cnt=1 property=rx data=0x3 +phy set lane-swap portlist=21 lane-cnt=1 property=rx data=0x0 +phy set lane-swap portlist=22 lane-cnt=1 property=rx data=0x1 +phy set lane-swap portlist=23 lane-cnt=1 property=rx data=0x2 +phy set lane-swap portlist=24 lane-cnt=1 property=rx data=0x3 +phy set lane-swap portlist=25 lane-cnt=1 property=rx data=0x0 +phy set lane-swap portlist=26 lane-cnt=1 property=rx data=0x1 +phy set lane-swap portlist=27 lane-cnt=1 property=rx data=0x2 +phy set lane-swap portlist=28 lane-cnt=1 property=rx data=0x3 +phy set lane-swap portlist=29 lane-cnt=1 property=rx data=0x0 +phy set lane-swap portlist=30 lane-cnt=1 property=rx data=0x1 +phy set lane-swap portlist=31 lane-cnt=1 property=rx data=0x2 +phy set lane-swap portlist=32 lane-cnt=1 property=rx data=0x1 +phy set lane-swap portlist=33 lane-cnt=1 property=rx data=0x2 +phy set lane-swap portlist=34 lane-cnt=1 property=rx data=0x3 +phy set lane-swap portlist=35 lane-cnt=1 property=rx data=0x0 +phy set lane-swap portlist=36 lane-cnt=1 property=rx data=0x1 +phy set lane-swap portlist=37 lane-cnt=1 property=rx data=0x2 +phy set lane-swap portlist=38 lane-cnt=1 property=rx data=0x3 +phy set lane-swap portlist=39 lane-cnt=1 property=rx data=0x0 +phy set lane-swap portlist=40 lane-cnt=1 property=rx data=0x1 +phy set lane-swap portlist=41 lane-cnt=1 property=rx data=0x2 +phy set lane-swap portlist=42 lane-cnt=1 property=rx data=0x3 +phy set lane-swap portlist=43 lane-cnt=1 property=rx data=0x0 +phy set lane-swap portlist=44 lane-cnt=1 property=rx data=0x1 +phy set lane-swap portlist=45 lane-cnt=1 property=rx data=0x2 +phy set lane-swap portlist=46 lane-cnt=1 property=rx data=0x3 +phy set lane-swap portlist=47 lane-cnt=1 property=rx data=0x0 +phy set lane-swap portlist=48 lane-cnt=4 property=rx data=0x2.1.0.3 +phy set lane-swap portlist=49 lane-cnt=4 property=rx data=0x0.1.3.2 +phy set lane-swap portlist=50 lane-cnt=4 property=rx data=0x3.1.0.2 +phy set lane-swap portlist=51 lane-cnt=4 property=rx data=0x1.3.0.2 +phy set lane-swap portlist=52 lane-cnt=4 property=rx data=0x3.2.1.0 +phy set lane-swap portlist=53 lane-cnt=4 property=rx data=0x3.2.1.0 +phy set polarity-rev portlist=0 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=1 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=2 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=3 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=4 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=5 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=6 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=7 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=8 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=9 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=10 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=11 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=12 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=13 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=14 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=15 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=16 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=17 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=18 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=19 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=20 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=21 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=22 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=23 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=24 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=25 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=26 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=27 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=28 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=29 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=30 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=31 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=32 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=33 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=34 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=35 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=36 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=37 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=38 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=39 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=40 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=41 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=42 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=43 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=44 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=45 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=46 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=47 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=48 lane-cnt=4 property=tx data=0x0.0.0.1 +phy set polarity-rev portlist=49 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=50 lane-cnt=4 property=tx data=0x1.1.0.0 +phy set polarity-rev portlist=51 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=52 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=53 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=0 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=1 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=2 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=3 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=4 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=5 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=6 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=7 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=8 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=9 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=10 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=11 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=12 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=13 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=14 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=15 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=16 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=17 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=18 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=19 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=20 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=21 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=22 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=23 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=24 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=25 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=26 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=27 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=28 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=29 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=30 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=31 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=32 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=33 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=34 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=35 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=36 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=37 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=38 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=39 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=40 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=41 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=42 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=43 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=44 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=45 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=46 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=47 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=48 lane-cnt=4 property=rx data=0x0.1.0.1 +phy set polarity-rev portlist=49 lane-cnt=4 property=rx data=0x1.0.1.0 +phy set polarity-rev portlist=50 lane-cnt=4 property=rx data=0x0.0.1.0 +phy set polarity-rev portlist=51 lane-cnt=4 property=rx data=0x0.0.0.1 +phy set polarity-rev portlist=52 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=53 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set pre-emphasis portlist=0 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=0 lane-cnt=4 property=cn1 data=0x1.1.1.1 +phy set pre-emphasis portlist=0 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a +phy set pre-emphasis portlist=0 lane-cnt=4 property=c1 data=0x7.7.7.7 +phy set pre-emphasis portlist=4 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=4 lane-cnt=4 property=cn1 data=0x1.1.1.1 +phy set pre-emphasis portlist=4 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a +phy set pre-emphasis portlist=4 lane-cnt=4 property=c1 data=0x7.7.7.7 +phy set pre-emphasis portlist=8 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=8 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=8 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c +phy set pre-emphasis portlist=8 lane-cnt=4 property=c1 data=0x6.6.6.6 +phy set pre-emphasis portlist=12 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=12 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=12 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b +phy set pre-emphasis portlist=12 lane-cnt=4 property=c1 data=0x7.7.7.7 +phy set pre-emphasis portlist=16 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=16 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=16 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c +phy set pre-emphasis portlist=16 lane-cnt=4 property=c1 data=0x6.6.6.6 +phy set pre-emphasis portlist=20 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=20 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=20 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c +phy set pre-emphasis portlist=20 lane-cnt=4 property=c1 data=0x6.6.6.6 +phy set pre-emphasis portlist=24 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=24 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=24 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c +phy set pre-emphasis portlist=24 lane-cnt=4 property=c1 data=0x6.6.6.6 +phy set pre-emphasis portlist=28 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=28 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=28 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c +phy set pre-emphasis portlist=28 lane-cnt=4 property=c1 data=0x6.6.6.6 +phy set pre-emphasis portlist=32 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=32 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=32 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c +phy set pre-emphasis portlist=32 lane-cnt=4 property=c1 data=0x6.6.6.6 +phy set pre-emphasis portlist=36 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=36 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=36 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c +phy set pre-emphasis portlist=36 lane-cnt=4 property=c1 data=0x6.6.6.6 +phy set pre-emphasis portlist=40 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=40 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=40 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c +phy set pre-emphasis portlist=40 lane-cnt=4 property=c1 data=0x6.6.6.6 +phy set pre-emphasis portlist=44 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=44 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=44 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c +phy set pre-emphasis portlist=44 lane-cnt=4 property=c1 data=0x6.6.6.6 +phy set pre-emphasis portlist=48 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=48 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=48 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b +phy set pre-emphasis portlist=48 lane-cnt=4 property=c1 data=0x6.6.6.6 +phy set pre-emphasis portlist=49 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=49 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=49 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b +phy set pre-emphasis portlist=49 lane-cnt=4 property=c1 data=0x6.6.6.6 +phy set pre-emphasis portlist=50 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=50 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=50 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b +phy set pre-emphasis portlist=50 lane-cnt=4 property=c1 data=0x7.7.7.7 +phy set pre-emphasis portlist=51 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=51 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=51 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b +phy set pre-emphasis portlist=51 lane-cnt=4 property=c1 data=0x7.7.7.7 +phy set pre-emphasis portlist=52 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=52 lane-cnt=4 property=cn1 data=0x0.0.0.0 +phy set pre-emphasis portlist=52 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a +phy set pre-emphasis portlist=52 lane-cnt=4 property=c1 data=0x8.8.8.8 +phy set pre-emphasis portlist=53 lane-cnt=4 property=c2 data=0x2.2.2.2 +phy set pre-emphasis portlist=53 lane-cnt=4 property=cn1 data=0x1.1.1.1 +phy set pre-emphasis portlist=53 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a +phy set pre-emphasis portlist=53 lane-cnt=4 property=c1 data=0x7.7.7.7 +port set property portlist=0-47 speed=25g +port set property portlist=48-53 speed=100g +port set property portlist=129-130 speed=10g +port set property portlist=0-47 medium-type=sr +port set property portlist=48-53 medium-type=sr4 +port set property portlist=129-130 medium-type=kr +port set adver portlist=129-130 speed-10g-kr +port set property portlist=129-130 an=enable +port set property portlist=0-53,129-130 admin=enable + diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps.DAC.R0B b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps.DAC.R0B new file mode 100644 index 000000000000..af9927ae2884 --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps.DAC.R0B @@ -0,0 +1,357 @@ +init start stage unit=0 low-level +init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=25g active=true +init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=25g active=true +init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=25g active=true +init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=25g active=true +init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=25g active=true +init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=25g active=true +init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=25g active=true +init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=25g active=true +init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=25g active=true +init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=25g active=true +init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=25g active=true +init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=25g active=true +init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=25g active=true +init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=25g active=true +init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=25g active=true +init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=25g active=true +init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=25g active=true +init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=25g active=true +init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=25g active=true +init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=25g active=true +init set port-map unit=0 port=20 eth-macro=10 lane=0 max-speed=25g active=true +init set port-map unit=0 port=21 eth-macro=10 lane=1 max-speed=25g active=true +init set port-map unit=0 port=22 eth-macro=10 lane=2 max-speed=25g active=true +init set port-map unit=0 port=23 eth-macro=10 lane=3 max-speed=25g active=true +init set port-map unit=0 port=24 eth-macro=12 lane=0 max-speed=25g active=true +init set port-map unit=0 port=25 eth-macro=12 lane=1 max-speed=25g active=true +init set port-map unit=0 port=26 eth-macro=12 lane=2 max-speed=25g active=true +init set port-map unit=0 port=27 eth-macro=12 lane=3 max-speed=25g active=true +init set port-map unit=0 port=28 eth-macro=14 lane=0 max-speed=25g active=true +init set port-map unit=0 port=29 eth-macro=14 lane=1 max-speed=25g active=true +init set port-map unit=0 port=30 eth-macro=14 lane=2 max-speed=25g active=true +init set port-map unit=0 port=31 eth-macro=14 lane=3 max-speed=25g active=true +init set port-map unit=0 port=32 eth-macro=16 lane=0 max-speed=25g active=true +init set port-map unit=0 port=33 eth-macro=16 lane=1 max-speed=25g active=true +init set port-map unit=0 port=34 eth-macro=16 lane=2 max-speed=25g active=true +init set port-map unit=0 port=35 eth-macro=16 lane=3 max-speed=25g active=true +init set port-map unit=0 port=36 eth-macro=17 lane=0 max-speed=25g active=true +init set port-map unit=0 port=37 eth-macro=17 lane=1 max-speed=25g active=true +init set port-map unit=0 port=38 eth-macro=17 lane=2 max-speed=25g active=true +init set port-map unit=0 port=39 eth-macro=17 lane=3 max-speed=25g active=true +init set port-map unit=0 port=40 eth-macro=18 lane=0 max-speed=25g active=true +init set port-map unit=0 port=41 eth-macro=18 lane=1 max-speed=25g active=true +init set port-map unit=0 port=42 eth-macro=18 lane=2 max-speed=25g active=true +init set port-map unit=0 port=43 eth-macro=18 lane=3 max-speed=25g active=true +init set port-map unit=0 port=44 eth-macro=19 lane=0 max-speed=25g active=true +init set port-map unit=0 port=45 eth-macro=19 lane=1 max-speed=25g active=true +init set port-map unit=0 port=46 eth-macro=19 lane=2 max-speed=25g active=true +init set port-map unit=0 port=47 eth-macro=19 lane=3 max-speed=25g active=true +init set port-map unit=0 port=48 eth-macro=21 lane=0 max-speed=100g active=true +init set port-map unit=0 port=49 eth-macro=20 lane=0 max-speed=100g active=true +init set port-map unit=0 port=50 eth-macro=26 lane=0 max-speed=100g active=true +init set port-map unit=0 port=51 eth-macro=27 lane=0 max-speed=100g active=true +init set port-map unit=0 port=52 eth-macro=28 lane=0 max-speed=100g active=true +init set port-map unit=0 port=53 eth-macro=29 lane=0 max-speed=100g active=true +init set port-map unit=0 port=129 eth-macro=0 lane=1 max-speed=10g active=true guarantee=true cpi=true +init set port-map unit=0 port=130 eth-macro=0 lane=0 max-speed=10g active=true guarantee=true cpi=true init-done=true +init start stage unit=0 task-rsrc +init start stage unit=0 module +init start stage unit=0 task +phy set lane-swap unit=0 portlist=0 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=1 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=2 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=3 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=4 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=5 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=6 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=7 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=8 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=9 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=10 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=11 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=12 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=13 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=14 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=15 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=16 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=17 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=18 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=19 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=20 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=21 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=22 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=23 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=24 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=25 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=26 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=27 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=28 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=29 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=30 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=31 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=32 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=33 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=34 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=35 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=36 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=37 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=38 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=39 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=40 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=41 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=42 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=43 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=44 lane-cnt=1 property=tx data=0x0 +phy set lane-swap unit=0 portlist=45 lane-cnt=1 property=tx data=0x1 +phy set lane-swap unit=0 portlist=46 lane-cnt=1 property=tx data=0x2 +phy set lane-swap unit=0 portlist=47 lane-cnt=1 property=tx data=0x3 +phy set lane-swap unit=0 portlist=48 lane-cnt=4 property=tx data=0x1.3.0.2 +phy set lane-swap unit=0 portlist=49 lane-cnt=4 property=tx data=0x0.3.1.2 +phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=tx data=0x1.3.0.2 +phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=tx data=0x2.0.3.1 +phy set lane-swap unit=0 portlist=52 lane-cnt=4 property=tx data=0x3.2.1.0 +phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=tx data=0x3.2.1.0 +phy set lane-swap unit=0 portlist=0 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=1 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=2 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=3 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=4 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=5 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=6 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=7 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=8 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=9 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=10 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=11 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=12 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=13 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=14 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=15 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=16 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=17 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=18 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=19 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=20 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=21 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=22 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=23 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=24 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=25 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=26 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=27 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=28 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=29 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=30 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=31 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=32 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=33 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=34 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=35 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=36 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=37 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=38 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=39 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=40 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=41 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=42 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=43 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=44 lane-cnt=1 property=rx data=0x1 +phy set lane-swap unit=0 portlist=45 lane-cnt=1 property=rx data=0x2 +phy set lane-swap unit=0 portlist=46 lane-cnt=1 property=rx data=0x3 +phy set lane-swap unit=0 portlist=47 lane-cnt=1 property=rx data=0x0 +phy set lane-swap unit=0 portlist=48 lane-cnt=4 property=rx data=0x2.1.0.3 +phy set lane-swap unit=0 portlist=49 lane-cnt=4 property=rx data=0x0.1.3.2 +phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=rx data=0x3.1.0.2 +phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=rx data=0x1.3.0.2 +phy set lane-swap unit=0 portlist=52 lane-cnt=4 property=rx data=0x3.2.1.0 +phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=rx data=0x3.2.1.0 +phy set polarity-rev unit=0 portlist=0 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=1 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=2 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=3 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=4 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=5 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=6 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=7 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=8 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=9 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=10 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=11 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=12 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=13 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=14 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=15 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=16 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=17 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=18 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=19 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=20 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=21 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=22 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=23 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=24 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=25 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=26 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=27 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=28 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=29 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=30 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=31 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=32 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=33 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=34 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=35 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=36 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=37 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=38 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=39 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=40 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=41 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=42 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=43 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=44 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=45 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=46 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=47 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev unit=0 portlist=48 lane-cnt=4 property=tx data=0x0.0.0.1 +phy set polarity-rev unit=0 portlist=49 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=tx data=0x1.1.0.0 +phy set polarity-rev unit=0 portlist=51 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev unit=0 portlist=52 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev unit=0 portlist=53 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev unit=0 portlist=0 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=1 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=2 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=3 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=4 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=5 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=6 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=7 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=8 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=9 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=10 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=11 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=12 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=13 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=14 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=15 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=16 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=17 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=18 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=19 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=20 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=21 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=22 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=23 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=24 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=25 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=26 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=27 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=28 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=29 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=30 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=31 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=32 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=33 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=34 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=35 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=36 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=37 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=38 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=39 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=40 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=41 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=42 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=43 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=44 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=45 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=46 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=47 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev unit=0 portlist=48 lane-cnt=4 property=rx data=0x0.1.0.1 +phy set polarity-rev unit=0 portlist=49 lane-cnt=4 property=rx data=0x1.0.1.0 +phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=rx data=0x0.0.1.0 +phy set polarity-rev unit=0 portlist=51 lane-cnt=4 property=rx data=0x0.0.0.1 +phy set polarity-rev unit=0 portlist=52 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev unit=0 portlist=53 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=0 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=0 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=0 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=0 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=4 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=4 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=4 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=4 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=8 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=8 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=8 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=8 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=12 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=12 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=12 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=12 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=16 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=16 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=16 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=16 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=20 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=20 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=20 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=20 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=24 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=24 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=24 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=24 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=28 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=28 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=28 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=28 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=32 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=32 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=32 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=32 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=36 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=36 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=36 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=36 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=40 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=40 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=40 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=40 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=44 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=44 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=44 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=44 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=48 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=48 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=48 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=48 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=49 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=49 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=49 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=49 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=50 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=50 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=50 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=50 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=51 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=51 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=51 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=51 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=52 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=52 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=52 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=52 lane-cnt=4 property=c1 data=0x2.2.2.2 +phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c2 data=0x0.0.0.0 +phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=cn1 data=0x4.4.4.4 +phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e +phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c1 data=0x2.2.2.2 +port set property unit=0 portlist=0-47 speed=25g +port set property unit=0 portlist=48-53 speed=100g +port set property unit=0 portlist=129-130 speed=10g +port set property unit=0 portlist=0-47 medium-type=cr +port set property unit=0 portlist=48-53 medium-type=cr4 +port set property unit=0 portlist=129-130 medium-type=kr +port set adver unit=0 portlist=129-130 speed-10g-kr +port set property unit=0 portlist=129-130 an=enable +port set property unit=0 portlist=0-53,129-130 admin=enable diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/qos.json.j2 b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/qos.json.j2 new file mode 100644 index 000000000000..5c5fc6e4969b --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/qos.json.j2 @@ -0,0 +1,136 @@ +{ + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "1", + "1": "0", + "3": "3", + "4": "4" + } + }, + "MAP_PFC_PRIORITY_TO_QUEUE": { + "AZURE": { + "3": "3", + "4": "4" + } + }, + "TC_TO_QUEUE_MAP": { + "AZURE": { + "0": "1", + "1": "0", + "3": "3", + "4": "4" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"1", + "1":"0", + "2":"0", + "3":"3", + "4":"4", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "SCHEDULER": { + "scheduler.0" : { + "type":"DWRR", + "weight": "25" + }, + "scheduler.1" : { + "type":"DWRR", + "weight": "30" + }, + "scheduler.2" : { + "type":"DWRR", + "weight": "20" + } + }, + "PORT_QOS_MAP": { + }, + "WRED_PROFILE": { + "AZURE_LOSSY" : { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "wred_red_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"613984", + "red_min_threshold":"76608", + "yellow_max_threshold":"628320", + "yellow_min_threshold":"78400", + "green_max_threshold": "642656", + "green_min_threshold": "80192" + }, + "AZURE_LOSSLESS" : { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "wred_red_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"613984", + "red_min_threshold":"76608", + "yellow_max_threshold":"628320", + "yellow_min_threshold":"78400", + "green_max_threshold": "642656", + "green_min_threshold": "80192" + } + }, + "QUEUE": { + } +} diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/sai.profile b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/sai.profile new file mode 100644 index 000000000000..880f47910ac1 --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/platform/led_proc_init.nps +SAI_DSH_CONFIG_FILE=/usr/share/sonic/hwsku/port_config.nps diff --git a/device/accton/x86_64-accton_as7116_54x-r0/installer.conf b/device/accton/x86_64-accton_as7116_54x-r0/installer.conf new file mode 100644 index 000000000000..4eeedca86a48 --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/installer.conf @@ -0,0 +1,4 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="pci=noaer" \ No newline at end of file diff --git a/device/accton/x86_64-accton_as7116_54x-r0/led_proc_init.nps b/device/accton/x86_64-accton_as7116_54x-r0/led_proc_init.nps new file mode 100644 index 000000000000..e25c78018adb --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/led_proc_init.nps @@ -0,0 +1,10 @@ +#unit NPS_CFG_TYPE_XXX param0 param1 value +#---- ---------------- ------ ------ ----- +0 NPS_CFG_TYPE_USE_UNIT_PORT 0 0 1 +0 NPS_CFG_TYPE_LED_CFG 0 0 5 +0 NPS_CFG_TYPE_CPI_PORT_MODE 129 0 1 +0 NPS_CFG_TYPE_CPI_PORT_MODE 130 0 1 +0 NPS_CFG_TYPE_USER_BUF_CTRL 0 0 1 +0 NPS_CFG_TYPE_HASH_L2_FDB_REGION_ENTRY_NUM 0 0 49152 +0 NPS_CFG_TYPE_HASH_L3_WITH_IPV6_PREFIX_64_REGION_ENTRY_NUM 0 0 32768 + diff --git a/device/accton/x86_64-accton_as7116_54x-r0/minigraph.xml b/device/accton/x86_64-accton_as7116_54x-r0/minigraph.xml new file mode 100644 index 000000000000..91269c2f68f6 --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/minigraph.xml @@ -0,0 +1,68 @@ + + + + + + + + + + HostIP + Loopback0 + + 10.1.0.32/32 + + 10.1.0.32/32 + + + + + + + + switch1 + + + + + + + + + + + + + switch1 + Accton-AS7116-54X + + + + + + + switch1 + + + DhcpResources + + + + + NtpResources + + 0.debian.pool.ntp.org;1.debian.pool.ntp.org;2.debian.pool.ntp.org;3.debian.pool.ntp.org + + + SyslogResources + + + + + + + + + switch1 + Accton-AS7116-54X + diff --git a/device/accton/x86_64-accton_as7116_54x-r0/plugins/eeprom.py b/device/accton/x86_64-accton_as7116_54x-r0/plugins/eeprom.py new file mode 100644 index 000000000000..1e7d1046d93d --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/plugins/eeprom.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python + +try: + import exceptions + import binascii + import time + import optparse + import warnings + import os + import sys + from sonic_eeprom import eeprom_base + from sonic_eeprom import eeprom_tlvinfo + import subprocess +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +class board(eeprom_tlvinfo.TlvInfoDecoder): + _TLV_INFO_MAX_LEN = 256 + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/bus/i2c/devices/0-0056/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/accton/x86_64-accton_as7116_54x-r0/plugins/psuutil.py b/device/accton/x86_64-accton_as7116_54x-r0/plugins/psuutil.py new file mode 100644 index 000000000000..08fd2648f314 --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/plugins/psuutil.py @@ -0,0 +1,92 @@ +# +# psuutil.py +# Platform-specific PSU status interface for SONiC +# + + +import os.path + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + SYSFS_PSU_DIR = ["/sys/bus/i2c/devices/10-0050", + "/sys/bus/i2c/devices/11-0053"] + + def __init__(self): + PsuBase.__init__(self) + + + # Get sysfs attribute + def get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", attr_path, " file !") + + retval = retval.rstrip('\r\n') + return retval + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + :return: An integer, the number of PSUs available on the device + """ + MAX_PSUS = 2 + return MAX_PSUS + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is\ + faulty + """ + status = 0 + attr_file = 'psu_power_good' + attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file + + attr_value = self.get_attr_value(attr_path) + + if (attr_value != 'ERR'): + attr_value = int(attr_value, 16) + # Check for PSU status + if (attr_value == 1): + status = 1 + + return status + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + status = 0 + psu_absent = 0 + attr_file ='psu_present' + attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file + + attr_value = self.get_attr_value(attr_path) + + if (attr_value != 'ERR'): + attr_value = int(attr_value, 16) + # Check for PSU presence + if (attr_value == 1): + status = 1 + + return status + diff --git a/device/accton/x86_64-accton_as7116_54x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7116_54x-r0/plugins/sfputil.py new file mode 100644 index 000000000000..8abcd46ccb56 --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/plugins/sfputil.py @@ -0,0 +1,150 @@ +#!/usr/bin/env python + +try: + import time + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +class SfpUtil(SfpUtilBase): + """Platform specific SfpUtill class""" + + _port_start = 0 + _port_end = 53 + _qsfp_port_start = 48 + _ports_in_block = 54 + + _port_to_eeprom_mapping = {} + _port_to_i2c_mapping = { + 0 : 37, + 1 : 38, + 2 : 39, + 3 : 40, + 4 : 41, + 5 : 42, + 6 : 43, + 7 : 44, + 8 : 45, + 9 : 46, + 10 : 47, + 11 : 48, + 12 : 49, + 13 : 50, + 14 : 51, + 15 : 52, + 16 : 53, + 17 : 54, + 18 : 55, + 19 : 56, + 20 : 57, + 21 : 58, + 22 : 59, + 23 : 60, + 24 : 61, + 25 : 62, + 26 : 63, + 27 : 64, + 28 : 65, + 29 : 66, + 30 : 67, + 31 : 68, + 32 : 69, + 33 : 70, + 34 : 71, + 35 : 72, + 36 : 73, + 37 : 74, + 38 : 75, + 39 : 76, + 40 : 77, + 41 : 78, + 42 : 79, + 43 : 80, + 44 : 81, + 45 : 82, + 46 : 83, + 47 : 84, + 48 : 21, + 49 : 22, + 50 : 23, + 51 : 24, + 52 : 25, + 53 : 26, + } + + _qsfp_ports = range(_qsfp_port_start, _ports_in_block + 1) + + def __init__(self): + eeprom_path = '/sys/bus/i2c/devices/{0}-0050/sfp_eeprom' + for x in range(self._port_start, self._port_end + 1): + port_eeprom_path = eeprom_path.format(self._port_to_i2c_mapping[x]) + self._port_to_eeprom_mapping[x] = port_eeprom_path + + SfpUtilBase.__init__(self) + + def reset(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_port_reset" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + try: + reg_file = open(port_ps, 'w') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + #toggle reset + reg_file.seek(0) + reg_file.write('1') + time.sleep(1) + reg_file.seek(0) + reg_file.write('0') + reg_file.close() + return True + + def set_low_power_mode(self, port_nuM, lpmode): + raise NotImplementedError + + def get_low_power_mode(self, port_num): + raise NotImplementedError + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_is_present" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + + try: + reg_file = open(port_ps) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = reg_file.readline().rstrip() + if reg_value == '1': + return True + + return False + + @property + def port_start(self): + return self._port_start + + @property + def port_end(self): + return self._port_end + + @property + def qsfp_ports(self): + return self._qsfp_ports + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sensors.conf b/device/accton/x86_64-accton_as7116_54x-r0/sensors.conf new file mode 100644 index 000000000000..9edb51a9e72d --- /dev/null +++ b/device/accton/x86_64-accton_as7116_54x-r0/sensors.conf @@ -0,0 +1,13 @@ +# libsensors configuration file + +chip "as7116_54x_fan-*" + label fan1 "front fan 1" + label fan2 "front fan 2" + label fan3 "front fan 3" + label fan4 "front fan 4" + label fan5 "front fan 5" + label fan6 "rear fan 1" + label fan7 "rear fan 2" + label fan8 "rear fan 3" + label fan9 "rear fan 4" + label fan10 "rear fan 5" diff --git a/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/buffers.json.j2 b/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/buffers.json.j2 new file mode 100644 index 000000000000..ff2adc67e149 --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/buffers.json.j2 @@ -0,0 +1,111 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '40m' %} +{% set default_speed = '100G' %} +{% set default_ports_num = 32 -%} + +{# 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(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% 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 %} + } + }, + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "20971328", + "type": "ingress", + "mode": "static" + }, + "ingress_lossy_pool": { + "size": "20971328", + "type": "ingress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "20971328", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xon":"78400", + "xoff":"132160", + "size":"3584", + "static_th":"82880" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"3584", + "dynamic_th":"-1" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"11200", + "dynamic_th":"-4" + } + }, + "BUFFER_PG": { + }, + "BUFFER_QUEUE": { + } +} + \ No newline at end of file diff --git a/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/pg_profile_lookup.ini b/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/pg_profile_lookup.ini new file mode 100644 index 000000000000..d98b0eca6d19 --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 10000 5m 3584 32256 59136 36736 + 25000 5m 3584 41216 68096 45696 + 40000 5m 3584 47488 74368 51968 + 50000 5m 3584 52864 79744 57344 + 100000 5m 3584 78400 132160 82880 + 10000 40m 3584 32256 59136 36736 + 25000 40m 3584 41216 68096 45696 + 40000 40m 3584 47488 74368 51968 + 50000 40m 3584 52864 79744 57344 + 100000 40m 3584 78400 132160 82880 + 10000 300m 3584 32256 65856 36736 + 25000 300m 3584 41216 84672 45696 + 40000 300m 3584 47488 101024 51968 + 50000 300m 3584 52864 113120 57344 + 100000 300m 3584 78400 198688 82880 \ No newline at end of file diff --git a/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/qos.json.j2 b/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/qos.json.j2 new file mode 100644 index 000000000000..42eef17c362b --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/qos.json.j2 @@ -0,0 +1,136 @@ +{ + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "1", + "1": "0", + "3": "3", + "4": "4" + } + }, + "MAP_PFC_PRIORITY_TO_QUEUE": { + "AZURE": { + "3": "3", + "4": "4" + } + }, + "TC_TO_QUEUE_MAP": { + "AZURE": { + "0": "1", + "1": "0", + "3": "3", + "4": "4" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"1", + "1":"0", + "2":"0", + "3":"3", + "4":"4", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "SCHEDULER": { + "scheduler.0" : { + "type":"DWRR", + "weight": "25" + }, + "scheduler.1" : { + "type":"DWRR", + "weight": "30" + }, + "scheduler.2" : { + "type":"DWRR", + "weight": "20" + } + }, + "PORT_QOS_MAP": { + }, + "WRED_PROFILE": { + "AZURE_LOSSY" : { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "wred_red_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"516096", + "red_min_threshold":"516096", + "yellow_max_threshold":"516096", + "yellow_min_threshold":"516096", + "green_max_threshold": "184128", + "green_min_threshold": "184128" + }, + "AZURE_LOSSLESS" : { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "wred_red_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"516096", + "red_min_threshold":"516096", + "yellow_max_threshold":"516096", + "yellow_min_threshold":"516096", + "green_max_threshold": "184128", + "green_min_threshold": "184128" + } + }, + "QUEUE": { + } +} diff --git a/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/minigraph.xml b/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/minigraph.xml index 6b29a7eb83b8..949ea6641b07 100644 --- a/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/minigraph.xml +++ b/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/minigraph.xml @@ -1,55 +1,6 @@ - - - OCPSCH0104001MS - 10.10.1.26 - OCPSCH01040GGLF - 10.10.1.25 - 1 - 10 - 3 - - - OCPSCH0104002MS - 10.10.2.26 - OCPSCH01040GGLF - 10.10.2.25 - 1 - 10 - 3 - - - - - 64536 - OCPSCH01040GGLF - - -
10.10.1.26
- - -
- -
10.10.2.26
- - -
-
- -
- - 64542 - OCPSCH0104001MS - - - - 64543 - OCPSCH0104002MS - - -
@@ -72,18 +23,7 @@ OCPSCH01040GGLF - - - - Ethernet0 - 10.10.1.25/30 - - - - Ethernet4 - 10.10.2.25/30 - - + @@ -91,24 +31,7 @@ - - - 40000 - DeviceInterfaceLink - OCPSCH0104001MS - Ethernet24 - OCPSCH01040GGLF - Ethernet0 - - - 40000 - DeviceInterfaceLink - OCPSCH0104002MS - Ethernet24 - OCPSCH01040GGLF - Ethernet4 - - + OCPSCH01040GGLF @@ -136,11 +59,6 @@ - - ErspanDestinationIpv4 - - 2.2.2.2 - diff --git a/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/buffers.json.j2 b/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/buffers.json.j2 new file mode 100644 index 000000000000..1f1cbe9fa0bc --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/buffers.json.j2 @@ -0,0 +1,111 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '40m' %} +{% set default_speed = '100G' %} +{% set default_ports_num = 64 -%} + +{# 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(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% 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 %} + } + }, + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "20971328", + "type": "ingress", + "mode": "static" + }, + "ingress_lossy_pool": { + "size": "20971328", + "type": "ingress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "20971328", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xon":"78400", + "xoff":"132160", + "size":"3584", + "static_th":"82880" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"3584", + "dynamic_th":"-1" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"11200", + "dynamic_th":"-4" + } + }, + "BUFFER_PG": { + }, + "BUFFER_QUEUE": { + } +} + \ No newline at end of file diff --git a/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/pg_profile_lookup.ini b/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/pg_profile_lookup.ini new file mode 100644 index 000000000000..d98b0eca6d19 --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 10000 5m 3584 32256 59136 36736 + 25000 5m 3584 41216 68096 45696 + 40000 5m 3584 47488 74368 51968 + 50000 5m 3584 52864 79744 57344 + 100000 5m 3584 78400 132160 82880 + 10000 40m 3584 32256 59136 36736 + 25000 40m 3584 41216 68096 45696 + 40000 40m 3584 47488 74368 51968 + 50000 40m 3584 52864 79744 57344 + 100000 40m 3584 78400 132160 82880 + 10000 300m 3584 32256 65856 36736 + 25000 300m 3584 41216 84672 45696 + 40000 300m 3584 47488 101024 51968 + 50000 300m 3584 52864 113120 57344 + 100000 300m 3584 78400 198688 82880 \ No newline at end of file diff --git a/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/qos.json.j2 b/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/qos.json.j2 new file mode 100644 index 000000000000..42eef17c362b --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/qos.json.j2 @@ -0,0 +1,136 @@ +{ + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "1", + "1": "0", + "3": "3", + "4": "4" + } + }, + "MAP_PFC_PRIORITY_TO_QUEUE": { + "AZURE": { + "3": "3", + "4": "4" + } + }, + "TC_TO_QUEUE_MAP": { + "AZURE": { + "0": "1", + "1": "0", + "3": "3", + "4": "4" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"1", + "1":"0", + "2":"0", + "3":"3", + "4":"4", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "SCHEDULER": { + "scheduler.0" : { + "type":"DWRR", + "weight": "25" + }, + "scheduler.1" : { + "type":"DWRR", + "weight": "30" + }, + "scheduler.2" : { + "type":"DWRR", + "weight": "20" + } + }, + "PORT_QOS_MAP": { + }, + "WRED_PROFILE": { + "AZURE_LOSSY" : { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "wred_red_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"516096", + "red_min_threshold":"516096", + "yellow_max_threshold":"516096", + "yellow_min_threshold":"516096", + "green_max_threshold": "184128", + "green_min_threshold": "184128" + }, + "AZURE_LOSSLESS" : { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "wred_red_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"516096", + "red_min_threshold":"516096", + "yellow_max_threshold":"516096", + "yellow_min_threshold":"516096", + "green_max_threshold": "184128", + "green_min_threshold": "184128" + } + }, + "QUEUE": { + } +} diff --git a/platform/nephos/one-image.mk b/platform/nephos/one-image.mk index 8e9406dca89c..61dcd6e30468 100644 --- a/platform/nephos/one-image.mk +++ b/platform/nephos/one-image.mk @@ -5,6 +5,7 @@ $(SONIC_ONE_IMAGE)_MACHINE = nephos $(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie $(SONIC_ONE_IMAGE)_INSTALLS += $(NEPHOS_NPS_KERNEL) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(INGRASYS_S9130_32X_PLATFORM_MODULE) \ - $(INGRASYS_S9230_64X_PLATFORM_MODULE) + $(INGRASYS_S9230_64X_PLATFORM_MODULE) \ + $(ACCTON_AS7116_54X_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_IMAGES) SONIC_INSTALLERS += $(SONIC_ONE_IMAGE) diff --git a/platform/nephos/platform-modules-accton.mk b/platform/nephos/platform-modules-accton.mk new file mode 100644 index 000000000000..110d0f3a5a11 --- /dev/null +++ b/platform/nephos/platform-modules-accton.mk @@ -0,0 +1,11 @@ +# Accton AS7116 54X Platform modules + +ACCTON_AS7116_54X_PLATFORM_MODULE_VERSION = 1.0.0 + +export ACCTON_AS7116_54X_PLATFORM_MODULE_VERSION + +ACCTON_AS7116_54X_PLATFORM_MODULE = sonic-platform-accton-as7116-54x_$(ACCTON_AS7116_54X_PLATFORM_MODULE_VERSION)_amd64.deb +$(ACCTON_AS7116_54X_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-accton +$(ACCTON_AS7116_54X_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +$(ACCTON_AS7116_54X_PLATFORM_MODULE)_PLATFORM = x86_64-accton_as7116_54x-r0 +SONIC_DPKG_DEBS += $(ACCTON_AS7116_54X_PLATFORM_MODULE) diff --git a/platform/nephos/rules.mk b/platform/nephos/rules.mk index 96f39ef8aad1..bf77ad0e6edf 100644 --- a/platform/nephos/rules.mk +++ b/platform/nephos/rules.mk @@ -1,6 +1,7 @@ include $(PLATFORM_PATH)/sdk.mk include $(PLATFORM_PATH)/sai.mk include $(PLATFORM_PATH)/platform-modules-ingrasys.mk +include $(PLATFORM_PATH)/platform-modules-accton.mk include $(PLATFORM_PATH)/docker-orchagent-nephos.mk include $(PLATFORM_PATH)/docker-syncd-nephos.mk include $(PLATFORM_PATH)/docker-syncd-nephos-rpc.mk diff --git a/platform/nephos/sai.mk b/platform/nephos/sai.mk index 7c898bbada6b..79f7569f1c16 100644 --- a/platform/nephos/sai.mk +++ b/platform/nephos/sai.mk @@ -1,9 +1,9 @@ -NEPHOS_SAI = libsainps_2.0.4_amd64.deb -$(NEPHOS_SAI)_URL = "https://github.com/NephosInc/SONiC/raw/master/sai/libsainps_2.0.4_amd64.deb" +NEPHOS_SAI = libsainps_2.0.3_sai_1.2.4_3147dc_amd64.deb +$(NEPHOS_SAI)_URL = "https://github.com/NephosInc/SONiC/raw/master/sai/libsainps_2.0.3_sai_1.2.4_3147dc_amd64.deb" -NEPHOS_SAI_DEV = libsainps-dev_2.0.4_sai_1.2.4_amd64.deb +NEPHOS_SAI_DEV = libsainps-dev_2.0.3_sai_1.2.4_3147dc_amd64.deb $(eval $(call add_derived_package,$(NEPHOS_SAI),$(NEPHOS_SAI_DEV))) -$(NEPHOS_SAI_DEV)_URL = "https://github.com/NephosInc/SONiC/raw/master/sai/libsainps-dev_2.0.4_sai_1.2.4_amd64.deb" +$(NEPHOS_SAI_DEV)_URL = "https://github.com/NephosInc/SONiC/raw/master/sai/libsainps-dev_2.0.3_sai_1.2.4_3147dc_amd64.deb" SONIC_ONLINE_DEBS += $(NEPHOS_SAI) $(NEPHOS_SAI_DEV) $(NEPHOS_SAI_DEV)_DEPENDS += $(NEPHOS_SAI) diff --git a/platform/nephos/sdk.mk b/platform/nephos/sdk.mk index 743512366db6..ce5748745242 100644 --- a/platform/nephos/sdk.mk +++ b/platform/nephos/sdk.mk @@ -1,4 +1,4 @@ -NEPHOS_NPS_KERNEL = nps-modules-3.16.0-5-amd64_2.0.3_amd64.deb -$(NEPHOS_NPS_KERNEL)_URL = "https://github.com/NephosInc/SONiC/raw/master/sdk/nps-modules-3.16.0-5-amd64_2.0.3_amd64.deb" +NEPHOS_NPS_KERNEL = nps-modules-3.16.0-5_2.0.3_3147dc_amd64.deb +$(NEPHOS_NPS_KERNEL)_URL = "https://github.com/NephosInc/SONiC/raw/master/sdk/nps-modules-3.16.0-5_2.0.3_3147dc_amd64.deb" SONIC_ONLINE_DEBS += $(NEPHOS_NPS_KERNEL) diff --git a/platform/nephos/sonic-platform-modules-accton/LICENSE b/platform/nephos/sonic-platform-modules-accton/LICENSE new file mode 100644 index 000000000000..bc693f7a4c40 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-accton/LICENSE @@ -0,0 +1,16 @@ +Copyright (C) 2016 Microsoft, Inc +Copyright (C) 2017 Accton Technology Corporation + +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/nephos/sonic-platform-modules-accton/README.md b/platform/nephos/sonic-platform-modules-accton/README.md new file mode 100644 index 000000000000..0ff20bb2d21b --- /dev/null +++ b/platform/nephos/sonic-platform-modules-accton/README.md @@ -0,0 +1 @@ +platform drivers of Accton products for the SONiC project diff --git a/platform/nephos/sonic-platform-modules-accton/as7116-54x/classes/__init__.py b/platform/nephos/sonic-platform-modules-accton/as7116-54x/classes/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/platform/nephos/sonic-platform-modules-accton/as7116-54x/classes/fanutil.py b/platform/nephos/sonic-platform-modules-accton/as7116-54x/classes/fanutil.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/platform/nephos/sonic-platform-modules-accton/as7116-54x/classes/thermalutil.py b/platform/nephos/sonic-platform-modules-accton/as7116-54x/classes/thermalutil.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/platform/nephos/sonic-platform-modules-accton/as7116-54x/modules/Makefile b/platform/nephos/sonic-platform-modules-accton/as7116-54x/modules/Makefile new file mode 100644 index 000000000000..19c7029f14a2 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-accton/as7116-54x/modules/Makefile @@ -0,0 +1,2 @@ +obj-m := x86-64-accton-as7116-54x-cpld.o x86-64-accton-as7116-54x-fan.o \ + x86-64-accton-as7116-54x-led.o x86-64-accton-as7116-54x-psu.o x86-64-accton-as7116-54x-sfp.o diff --git a/platform/nephos/sonic-platform-modules-accton/as7116-54x/modules/x86-64-accton-as7116-54x-cpld.c b/platform/nephos/sonic-platform-modules-accton/as7116-54x/modules/x86-64-accton-as7116-54x-cpld.c new file mode 100644 index 000000000000..eb52512343a8 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-accton/as7116-54x/modules/x86-64-accton-as7116-54x-cpld.c @@ -0,0 +1,242 @@ +/* + * A hwmon driver for the as7116_54x_cpld + * + * Copyright (C) 2017 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include + +static LIST_HEAD(cpld_client_list); +static struct mutex list_lock; + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; + +/* Addresses scanned for as7116_54x_cpld + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +static ssize_t show_cpld_version(struct device *dev, struct device_attribute *attr, char *buf) +{ + int val = 0; + struct i2c_client *client = to_i2c_client(dev); + + val = i2c_smbus_read_byte_data(client, 0x1); + + if (val < 0) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x1) err %d\n", client->addr, val); + } + + return sprintf(buf, "%d\n", val); +} + +static struct device_attribute ver = __ATTR(version, 0600, show_cpld_version, NULL); + +static void as7116_54x_cpld_add_client(struct i2c_client *client) +{ + struct cpld_client_node *node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", client->addr); + return; + } + + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &cpld_client_list); + mutex_unlock(&list_lock); +} + +static void as7116_54x_cpld_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client == client) { + found = 1; + break; + } + } + + if (found) { + list_del(list_node); + kfree(cpld_node); + } + + mutex_unlock(&list_lock); +} + +static int as7116_54x_cpld_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_dbg(&client->dev, "i2c_check_functionality failed (0x%x)\n", client->addr); + status = -EIO; + goto exit; + } + + status = sysfs_create_file(&client->dev.kobj, &ver.attr); + if (status) { + goto exit; + } + + dev_info(&client->dev, "chip found\n"); + as7116_54x_cpld_add_client(client); + + return 0; + +exit: + return status; +} + +static int as7116_54x_cpld_remove(struct i2c_client *client) +{ + sysfs_remove_file(&client->dev.kobj, &ver.attr); + as7116_54x_cpld_remove_client(client); + + return 0; +} + +enum cpld_chips +{ + as7116_54x_cpld1, + as7116_54x_cpld2, + as7116_54x_cpld3 +}; + +static const struct i2c_device_id as7116_54x_cpld_id[] = { + { "as7116_54x_cpld1", as7116_54x_cpld1 }, + { "as7116_54x_cpld2", as7116_54x_cpld2 }, + { "as7116_54x_cpld3", as7116_54x_cpld3 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, as7116_54x_cpld_id); + +static struct i2c_driver as7116_54x_cpld_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "as7116_54x_cpld", + }, + .probe = as7116_54x_cpld_probe, + .remove = as7116_54x_cpld_remove, + .id_table = as7116_54x_cpld_id, + .address_list = normal_i2c, +}; + +int as7116_54x_cpld_read(unsigned short cpld_addr, u8 reg) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EPERM; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = i2c_smbus_read_byte_data(cpld_node->client, reg); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(as7116_54x_cpld_read); + +int as7116_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EIO; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = i2c_smbus_write_byte_data(cpld_node->client, reg, value); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(as7116_54x_cpld_write); + +static int __init as7116_54x_cpld_init(void) +{ + mutex_init(&list_lock); + return i2c_add_driver(&as7116_54x_cpld_driver); +} + +static void __exit as7116_54x_cpld_exit(void) +{ + i2c_del_driver(&as7116_54x_cpld_driver); +} + +static struct dmi_system_id as7116_54x_dmi_table[] = { + { + .ident = "Accton AS7716", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Accton"), + DMI_MATCH(DMI_PRODUCT_NAME, "AS7116"), + }, + } +}; + +int platform_accton_as7116_54x(void) +{ + //return dmi_check_system(as7116_54x_dmi_table); + return 1; +} +EXPORT_SYMBOL(platform_accton_as7116_54x); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton_as7116_54x driver"); +MODULE_LICENSE("GPL"); + +module_init(as7116_54x_cpld_init); +module_exit(as7116_54x_cpld_exit); + diff --git a/platform/nephos/sonic-platform-modules-accton/as7116-54x/modules/x86-64-accton-as7116-54x-fan.c b/platform/nephos/sonic-platform-modules-accton/as7116-54x/modules/x86-64-accton-as7116-54x-fan.c new file mode 100644 index 000000000000..f5159c8f166e --- /dev/null +++ b/platform/nephos/sonic-platform-modules-accton/as7116-54x/modules/x86-64-accton-as7116-54x-fan.c @@ -0,0 +1,544 @@ +/* + * A hwmon driver for the Accton as7716 32x fan + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "as7116_54x_fan" + +static struct as7116_54x_fan_data *as7116_54x_fan_update_device(struct device *dev); +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); + +/* fan related data, the index should match sysfs_fan_attributes + */ +static const u8 fan_reg[] = { + 0x02, /* fan 1-6 present status */ + 0x03, /* fan 1-6 direction(0:F2B 1:B2F) */ + 0x06, /* fan PWM(for all fan) */ + 0x04, /* front fan fault */ + 0x05, /* rear fan fault */ + 0x07, /* front fan 1 speed(rpm) */ + 0x08, /* front fan 2 speed(rpm) */ + 0x09, /* front fan 3 speed(rpm) */ + 0x0A, /* front fan 4 speed(rpm) */ + 0x0B, /* front fan 5 speed(rpm) */ + 0x0C, /* rear fan 1 speed(rpm) */ + 0x0D, /* rear fan 2 speed(rpm) */ + 0x0E, /* rear fan 3 speed(rpm) */ + 0x0f, /* rear fan 4 speed(rpm) */ + 0x10, /* rear fan 5 speed(rpm) */ +}; + +/* Each client has this additional data */ +struct as7116_54x_fan_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[ARRAY_SIZE(fan_reg)]; /* Register value */ +}; + +enum fan_id { + FAN1_ID, + FAN2_ID, + FAN3_ID, + FAN4_ID, + FAN5_ID +}; + +enum sysfs_fan_attributes { + FAN_PRESENT_REG, + FAN_DIRECTION_REG, + FAN_DUTY_CYCLE_PERCENTAGE, /* Only one CPLD register to control duty cycle for all fans */ + FAN_FRONT_FAULT_REG, + FAN_REAR_FAULT_REG, + FAN1_FRONT_SPEED_RPM, + FAN2_FRONT_SPEED_RPM, + FAN3_FRONT_SPEED_RPM, + FAN4_FRONT_SPEED_RPM, + FAN5_FRONT_SPEED_RPM, + FAN1_REAR_SPEED_RPM, + FAN2_REAR_SPEED_RPM, + FAN3_REAR_SPEED_RPM, + FAN4_REAR_SPEED_RPM, + FAN5_REAR_SPEED_RPM, + FAN1_DIRECTION, + FAN2_DIRECTION, + FAN3_DIRECTION, + FAN4_DIRECTION, + FAN5_DIRECTION, + FAN1_PRESENT, + FAN2_PRESENT, + FAN3_PRESENT, + FAN4_PRESENT, + FAN5_PRESENT, + FAN1_FRONT_FAULT, + FAN2_FRONT_FAULT, + FAN3_FRONT_FAULT, + FAN4_FRONT_FAULT, + FAN5_FRONT_FAULT, + FAN1_REAR_FAULT, + FAN2_REAR_FAULT, + FAN3_REAR_FAULT, + FAN4_REAR_FAULT, + FAN5_REAR_FAULT, + FAN1_INPUT, /* FAN1_FRONT_SPEED_RPM, */ + FAN2_INPUT, /* FAN2_FRONT_SPEED_RPM, */ + FAN3_INPUT, /* FAN3_FRONT_SPEED_RPM, */ + FAN4_INPUT, /* FAN4_FRONT_SPEED_RPM, */ + FAN5_INPUT, /* FAN5_FRONT_SPEED_RPM, */ + FAN6_INPUT, /* FAN1_REAR_SPEED_RPM, */ + FAN7_INPUT, /* FAN2_REAR_SPEED_RPM, */ + FAN8_INPUT, /* FAN3_REAR_SPEED_RPM, */ + FAN9_INPUT, /* FAN4_REAR_SPEED_RPM, */ + FAN10_INPUT, /* FAN5_REAR_SPEED_RPM */ +}; + +/* Define attributes + */ +#define DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_front_fault, S_IRUGO, fan_show_value, NULL, FAN##index##_FRONT_FAULT);\ + static SENSOR_DEVICE_ATTR(fan##index##_rear_fault, S_IRUGO, fan_show_value, NULL, FAN##index##_REAR_FAULT) +#define DECLARE_FAN_FAULT_ATTR(index) &sensor_dev_attr_fan##index##_front_fault.dev_attr.attr,\ + &sensor_dev_attr_fan##index##_rear_fault.dev_attr.attr + +#define DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_direction, S_IRUGO, fan_show_value, NULL, FAN##index##_DIRECTION) +#define DECLARE_FAN_DIRECTION_ATTR(index) &sensor_dev_attr_fan##index##_direction.dev_attr.attr + +#define DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_duty_cycle_percentage, S_IWUSR | S_IRUGO, fan_show_value, set_duty_cycle, FAN##index##_DUTY_CYCLE_PERCENTAGE) +#define DECLARE_FAN_DUTY_CYCLE_ATTR(index) &sensor_dev_attr_fan##index##_duty_cycle_percentage.dev_attr.attr + +#define DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_present, S_IRUGO, fan_show_value, NULL, FAN##index##_PRESENT) +#define DECLARE_FAN_PRESENT_ATTR(index) &sensor_dev_attr_fan##index##_present.dev_attr.attr + +#define DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_front_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_FRONT_SPEED_RPM);\ + static SENSOR_DEVICE_ATTR(fan##index##_rear_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_REAR_SPEED_RPM) +#define DECLARE_FAN_SPEED_RPM_ATTR(index) &sensor_dev_attr_fan##index##_front_speed_rpm.dev_attr.attr, \ + &sensor_dev_attr_fan##index##_rear_speed_rpm.dev_attr.attr + +#define DECLARE_FAN_INPUT_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_input, S_IRUGO, fan_show_value, NULL, FAN##index##_INPUT) +#define DECLARE_FAN_INPUT_ATTR(index) &sensor_dev_attr_fan##index##_input.dev_attr.attr + +/* 6 fan fault attributes in this platform */ +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(1); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(2); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(3); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(4); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(5); +/* 6 fan speed(rpm) attributes in this platform */ +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(1); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(2); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(3); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(4); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(5); +/* 6 fan present attributes in this platform */ +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(1); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(2); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(3); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(4); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(5); +/* 6 fan direction attribute in this platform */ +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(1); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(2); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(3); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(4); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(5); +/* 1 fan duty cycle attribute in this platform */ +DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(); + +/* fan input attributes in this platform */ +DECLARE_FAN_INPUT_SENSOR_DEV_ATTR(1); +DECLARE_FAN_INPUT_SENSOR_DEV_ATTR(2); +DECLARE_FAN_INPUT_SENSOR_DEV_ATTR(3); +DECLARE_FAN_INPUT_SENSOR_DEV_ATTR(4); +DECLARE_FAN_INPUT_SENSOR_DEV_ATTR(5); + +DECLARE_FAN_INPUT_SENSOR_DEV_ATTR(6); +DECLARE_FAN_INPUT_SENSOR_DEV_ATTR(7); +DECLARE_FAN_INPUT_SENSOR_DEV_ATTR(8); +DECLARE_FAN_INPUT_SENSOR_DEV_ATTR(9); +DECLARE_FAN_INPUT_SENSOR_DEV_ATTR(10); + +static struct attribute *as7116_54x_fan_attributes[] = { + /* fan related attributes */ + DECLARE_FAN_FAULT_ATTR(1), + DECLARE_FAN_FAULT_ATTR(2), + DECLARE_FAN_FAULT_ATTR(3), + DECLARE_FAN_FAULT_ATTR(4), + DECLARE_FAN_FAULT_ATTR(5), + DECLARE_FAN_SPEED_RPM_ATTR(1), + DECLARE_FAN_SPEED_RPM_ATTR(2), + DECLARE_FAN_SPEED_RPM_ATTR(3), + DECLARE_FAN_SPEED_RPM_ATTR(4), + DECLARE_FAN_SPEED_RPM_ATTR(5), + DECLARE_FAN_PRESENT_ATTR(1), + DECLARE_FAN_PRESENT_ATTR(2), + DECLARE_FAN_PRESENT_ATTR(3), + DECLARE_FAN_PRESENT_ATTR(4), + DECLARE_FAN_PRESENT_ATTR(5), + DECLARE_FAN_DIRECTION_ATTR(1), + DECLARE_FAN_DIRECTION_ATTR(2), + DECLARE_FAN_DIRECTION_ATTR(3), + DECLARE_FAN_DIRECTION_ATTR(4), + DECLARE_FAN_DIRECTION_ATTR(5), + DECLARE_FAN_DUTY_CYCLE_ATTR(), + DECLARE_FAN_INPUT_ATTR(1), + DECLARE_FAN_INPUT_ATTR(2), + DECLARE_FAN_INPUT_ATTR(3), + DECLARE_FAN_INPUT_ATTR(4), + DECLARE_FAN_INPUT_ATTR(5), + DECLARE_FAN_INPUT_ATTR(6), + DECLARE_FAN_INPUT_ATTR(7), + DECLARE_FAN_INPUT_ATTR(8), + DECLARE_FAN_INPUT_ATTR(9), + DECLARE_FAN_INPUT_ATTR(10), + NULL +}; + +#define FAN_DUTY_CYCLE_REG_MASK 0x1F +#define FAN_MIN_DUTY_CYCLE 20 +#define FAN_MAX_DUTY_CYCLE 100 +#define FAN_REG_VAL_TO_SPEED_RPM_STEP 150 + +static int as7116_54x_fan_read_value(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int as7116_54x_fan_write_value(struct i2c_client *client, u8 reg, u8 value) +{ + return i2c_smbus_write_byte_data(client, reg, value); +} + +/* fan utility functions + */ +static u32 reg_val_to_duty_cycle(u8 reg_val) +{ + return (reg_val & FAN_DUTY_CYCLE_REG_MASK) * 5; +} + +static u8 duty_cycle_to_reg_val(u8 duty_cycle) +{ + return (duty_cycle / 5); +} + +static u32 reg_val_to_speed_rpm(u8 reg_val) +{ + return (u32)reg_val * FAN_REG_VAL_TO_SPEED_RPM_STEP; +} + +static u8 reg_val_to_direction(u8 reg_val, enum fan_id id) +{ + return !!(reg_val & (1 << id)); +} + +static u8 reg_val_to_is_present(u8 reg_val, enum fan_id id) +{ + return !(reg_val & (1 << id)); +} + +static u8 is_fan_fault(u8 reg_val, enum fan_id id) +{ + return !!(reg_val & (1 << id)); +} +#if 0 +static u8 is_fan_fault(struct as7116_54x_fan_data *data, enum fan_id id) +{ + u8 ret = 1; + int front_fan_index = FAN1_FRONT_SPEED_RPM + id; + int rear_fan_index = FAN1_REAR_SPEED_RPM + id; + + /* Check if the speed of front or rear fan is ZERO, + */ + if (reg_val_to_speed_rpm(data->reg_val[front_fan_index]) && + reg_val_to_speed_rpm(data->reg_val[rear_fan_index])) { + ret = 0; + } + + return ret; +} +#endif + +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int error, value; + struct i2c_client *client = to_i2c_client(dev); + + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (value < FAN_MIN_DUTY_CYCLE) { + value = FAN_MIN_DUTY_CYCLE; + } + + if (value > FAN_MAX_DUTY_CYCLE) { + value = FAN_MAX_DUTY_CYCLE; + } + + as7116_54x_fan_write_value(client, fan_reg[FAN_DUTY_CYCLE_PERCENTAGE], duty_cycle_to_reg_val(value)); + return count; +} + +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct as7116_54x_fan_data *data = as7116_54x_fan_update_device(dev); + ssize_t ret = 0; + + if (data->valid) { + switch (attr->index) { + case FAN_DUTY_CYCLE_PERCENTAGE: + { + u32 duty_cycle = reg_val_to_duty_cycle(data->reg_val[FAN_DUTY_CYCLE_PERCENTAGE]); + ret = sprintf(buf, "%u\n", duty_cycle); + break; + } + case FAN1_FRONT_SPEED_RPM: + case FAN2_FRONT_SPEED_RPM: + case FAN3_FRONT_SPEED_RPM: + case FAN4_FRONT_SPEED_RPM: + case FAN5_FRONT_SPEED_RPM: + case FAN1_REAR_SPEED_RPM: + case FAN2_REAR_SPEED_RPM: + case FAN3_REAR_SPEED_RPM: + case FAN4_REAR_SPEED_RPM: + case FAN5_REAR_SPEED_RPM: + ret = sprintf(buf, "%u\n", reg_val_to_speed_rpm(data->reg_val[attr->index])); + break; + case FAN1_PRESENT: + case FAN2_PRESENT: + case FAN3_PRESENT: + case FAN4_PRESENT: + case FAN5_PRESENT: + ret = sprintf(buf, "%d\n", + reg_val_to_is_present(data->reg_val[FAN_PRESENT_REG], + attr->index - FAN1_PRESENT)); + break; + case FAN1_FRONT_FAULT: + case FAN2_FRONT_FAULT: + case FAN3_FRONT_FAULT: + case FAN4_FRONT_FAULT: + case FAN5_FRONT_FAULT: + ret = sprintf(buf, "%d\n", + is_fan_fault(data->reg_val[FAN_FRONT_FAULT_REG], + attr->index - FAN1_FRONT_FAULT)); + break; + case FAN1_REAR_FAULT: + case FAN2_REAR_FAULT: + case FAN3_REAR_FAULT: + case FAN4_REAR_FAULT: + case FAN5_REAR_FAULT: + ret = sprintf(buf, "%d\n", + is_fan_fault(data->reg_val[FAN_REAR_FAULT_REG], + attr->index - FAN1_REAR_FAULT)); + break; + case FAN1_DIRECTION: + case FAN2_DIRECTION: + case FAN3_DIRECTION: + case FAN4_DIRECTION: + case FAN5_DIRECTION: + ret = sprintf(buf, "%d\n", + reg_val_to_direction(data->reg_val[FAN_DIRECTION_REG], + attr->index - FAN1_DIRECTION)); + break; + case FAN1_INPUT: + case FAN2_INPUT: + case FAN3_INPUT: + case FAN4_INPUT: + case FAN5_INPUT: + case FAN6_INPUT: + case FAN7_INPUT: + case FAN8_INPUT: + case FAN9_INPUT: + case FAN10_INPUT: + ret = sprintf(buf, "%u\n", reg_val_to_speed_rpm(data->reg_val[attr->index + - FAN1_INPUT + FAN1_FRONT_SPEED_RPM])); + break; + default: + break; + } + } + + return ret; +} + +static const struct attribute_group as7116_54x_fan_group = { + .attrs = as7116_54x_fan_attributes, +}; + +static struct as7116_54x_fan_data *as7116_54x_fan_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as7116_54x_fan_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || + !data->valid) { + int i; + + dev_dbg(&client->dev, "Starting as7116_54x_fan update\n"); + data->valid = 0; + + /* Update fan data + */ + for (i = 0; i < ARRAY_SIZE(data->reg_val); i++) { + int status = as7116_54x_fan_read_value(client, fan_reg[i]); + + if (status < 0) { + data->valid = 0; + mutex_unlock(&data->update_lock); + dev_dbg(&client->dev, "reg %d, err %d\n", fan_reg[i], status); + return data; + } + else { + data->reg_val[i] = status; + } + } + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +static int as7116_54x_fan_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct as7116_54x_fan_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct as7116_54x_fan_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as7116_54x_fan_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: fan '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as7116_54x_fan_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as7116_54x_fan_remove(struct i2c_client *client) +{ + struct as7116_54x_fan_data *data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as7116_54x_fan_group); + + return 0; +} + +/* Addresses to scan */ +static const unsigned short normal_i2c[] = { 0x66, I2C_CLIENT_END }; + +static const struct i2c_device_id as7116_54x_fan_id[] = { + { "as7116_54x_fan", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, as7116_54x_fan_id); + +static struct i2c_driver as7116_54x_fan_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = DRVNAME, + }, + .probe = as7116_54x_fan_probe, + .remove = as7116_54x_fan_remove, + .id_table = as7116_54x_fan_id, + .address_list = normal_i2c, +}; + +static int __init as7116_54x_fan_init(void) +{ +#if 0 + extern int platform_accton_as7116_54x(void); + if (!platform_accton_as7116_54x()) { + return -ENODEV; + } +#endif + return i2c_add_driver(&as7116_54x_fan_driver); +} + +static void __exit as7116_54x_fan_exit(void) +{ + i2c_del_driver(&as7116_54x_fan_driver); +} + +module_init(as7116_54x_fan_init); +module_exit(as7116_54x_fan_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("as7116_54x_fan driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/nephos/sonic-platform-modules-accton/as7116-54x/modules/x86-64-accton-as7116-54x-led.c b/platform/nephos/sonic-platform-modules-accton/as7116-54x/modules/x86-64-accton-as7116-54x-led.c new file mode 100644 index 000000000000..cd69f711c826 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-accton/as7116-54x/modules/x86-64-accton-as7116-54x-led.c @@ -0,0 +1,448 @@ +/* + * A LED driver for the accton_as7116_54x_led + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "as7116_54x_fan" + +#define DEBUG_MODE 0 +#if (DEBUG_MODE == 1) + #define DEBUG_PRINT(fmt, args...) \ + printk (KERN_INFO "%s:%s[%d]: " fmt "\r\n", __FILE__, __FUNCTION__, __LINE__, ##args) +#else + #define DEBUG_PRINT(fmt, args...) +#endif + +extern int as7116_54x_cpld_read(unsigned short cpld_addr, u8 reg); +extern int as7116_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +struct as7116_54x_led_data { + struct platform_device *pdev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[1]; /* LOC/DIAG LED */ +}; + +static struct as7116_54x_led_data *ledctl = NULL; + +/* LED related data + */ + +#define LED_CNTRLER_I2C_ADDRESS (0x60) + +#define LED_TYPE_DIAG_REG_MASK (0x0C) +#define LED_MODE_DIAG_GREEN_VALUE (0x08) +#define LED_MODE_DIAG_AMBER_VALUE (0x04) +#define LED_MODE_DIAG_YELLOW_VALUE (0x00) +#define LED_MODE_DIAG_OFF_VALUE (0x0C) + +#define LED_TYPE_FAN_REG_MASK (0x03) +#define LED_MODE_FAN_GREEN_VALUE (0x02) +#define LED_MODE_FAN_AMBER_VALUE (0x01) +#define LED_MODE_FAN_OFF_VALUE (0x03) +#define LED_MODE_FAN_AUTO_VALUE (0x00) + +#define LED_TYPE_PSU1_REG_MASK (0x03) +#define LED_MODE_PSU1_GREEN_VALUE (0x02) +#define LED_MODE_PSU1_AMBER_VALUE (0x01) +#define LED_MODE_PSU1_OFF_VALUE (0x03) +#define LED_MODE_PSU1_AUTO_VALUE (0x00) + +#define LED_TYPE_PSU2_REG_MASK (0x0C) +#define LED_MODE_PSU2_GREEN_VALUE (0x08) +#define LED_MODE_PSU2_AMBER_VALUE (0x04) +#define LED_MODE_PSU2_OFF_VALUE (0x0C) +#define LED_MODE_PSU2_AUTO_VALUE (0x00) + +#define LED_TYPE_LOC_REG_MASK (0x30) +#define LED_MODE_LOC_AMBER_VALUE (0x00) +#define LED_MODE_LOC_AMBER_BLINKING_VALUE1 (0x20) +#define LED_MODE_LOC_AMBER_BLINKING_VALUE2 (0x30) +#define LED_MODE_LOC_OFF_VALUE (0x10) + +static const u8 led_reg[] = { + 0x0A, /* LOC/DIAG/FAN LED */ + 0x0B, /* PSU1/PSU2 LED */ +}; + +enum led_type { + LED_TYPE_DIAG, + LED_TYPE_LOC, + LED_TYPE_FAN, + LED_TYPE_PSU1, + LED_TYPE_PSU2 +}; + +enum led_light_mode { + LED_MODE_OFF = 0, + LED_MODE_GREEN, + LED_MODE_GREEN_BLINK, + LED_MODE_AMBER, + LED_MODE_AMBER_BLINK, + LED_MODE_YELLOW, + LED_MODE_YELLOW_BLINK, + LED_MODE_BLUE, + LED_MODE_BLUE_BLINK, + LED_MODE_AUTO, + LED_MODE_UNKNOWN +}; + +struct led_type_mode { + enum led_type type; + enum led_light_mode mode; + int type_mask; + int mode_value; +}; + +static struct led_type_mode led_type_mode_data[] = { +{LED_TYPE_FAN, LED_MODE_OFF, LED_TYPE_FAN_REG_MASK, LED_MODE_FAN_OFF_VALUE}, +{LED_TYPE_FAN, LED_MODE_GREEN, LED_TYPE_FAN_REG_MASK, LED_MODE_FAN_GREEN_VALUE}, +{LED_TYPE_FAN, LED_MODE_AMBER, LED_TYPE_FAN_REG_MASK, LED_MODE_FAN_AMBER_VALUE}, +{LED_TYPE_FAN, LED_MODE_AUTO, LED_TYPE_FAN_REG_MASK, LED_MODE_FAN_AUTO_VALUE}, +{LED_TYPE_PSU1, LED_MODE_OFF, LED_TYPE_PSU1_REG_MASK, LED_MODE_PSU1_OFF_VALUE}, +{LED_TYPE_PSU1, LED_MODE_GREEN, LED_TYPE_PSU1_REG_MASK, LED_MODE_PSU1_GREEN_VALUE}, +{LED_TYPE_PSU1, LED_MODE_AMBER, LED_TYPE_PSU1_REG_MASK, LED_MODE_PSU1_AMBER_VALUE}, +{LED_TYPE_PSU1, LED_MODE_AUTO, LED_TYPE_PSU1_REG_MASK, LED_MODE_PSU1_AUTO_VALUE}, +{LED_TYPE_PSU2, LED_MODE_OFF, LED_TYPE_PSU2_REG_MASK, LED_MODE_PSU2_OFF_VALUE}, +{LED_TYPE_PSU2, LED_MODE_GREEN, LED_TYPE_PSU2_REG_MASK, LED_MODE_PSU2_GREEN_VALUE}, +{LED_TYPE_PSU2, LED_MODE_AMBER, LED_TYPE_PSU2_REG_MASK, LED_MODE_PSU2_AMBER_VALUE}, +{LED_TYPE_PSU2, LED_MODE_AUTO, LED_TYPE_PSU2_REG_MASK, LED_MODE_PSU2_AUTO_VALUE}, +{LED_TYPE_DIAG, LED_MODE_OFF, LED_TYPE_DIAG_REG_MASK, LED_MODE_DIAG_OFF_VALUE}, +{LED_TYPE_DIAG, LED_MODE_GREEN, LED_TYPE_DIAG_REG_MASK, LED_MODE_DIAG_GREEN_VALUE}, +{LED_TYPE_DIAG, LED_MODE_AMBER, LED_TYPE_DIAG_REG_MASK, LED_MODE_DIAG_AMBER_VALUE}, +{LED_TYPE_DIAG, LED_MODE_YELLOW, LED_TYPE_DIAG_REG_MASK, LED_MODE_DIAG_YELLOW_VALUE}, +{LED_TYPE_LOC, LED_MODE_OFF, LED_TYPE_LOC_REG_MASK, LED_MODE_LOC_OFF_VALUE}, +{LED_TYPE_LOC, LED_MODE_AMBER, LED_TYPE_LOC_REG_MASK, LED_MODE_LOC_AMBER_VALUE}, +{LED_TYPE_LOC, LED_MODE_AMBER_BLINK, LED_TYPE_LOC_REG_MASK, LED_MODE_LOC_AMBER_BLINKING_VALUE1}, +{LED_TYPE_LOC, LED_MODE_AMBER_BLINK, LED_TYPE_LOC_REG_MASK, LED_MODE_LOC_AMBER_BLINKING_VALUE2} +}; + +static int led_reg_val_to_light_mode(enum led_type type, u8 reg_val) { + int i; + + for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) { + if (type != led_type_mode_data[i].type) { + continue; + } + + if ((led_type_mode_data[i].type_mask & reg_val) == + led_type_mode_data[i].mode_value) { + return led_type_mode_data[i].mode; + } + } + + return LED_MODE_UNKNOWN; +} + +static u8 led_light_mode_to_reg_val(enum led_type type, + enum led_light_mode mode, u8 reg_val) { + int i; + + for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) { + int type_mask, mode_value; + + if (type != led_type_mode_data[i].type) + continue; + + if (mode != led_type_mode_data[i].mode) + continue; + + type_mask = led_type_mode_data[i].type_mask; + mode_value = led_type_mode_data[i].mode_value; + reg_val = (reg_val & ~type_mask) | mode_value; + } + + return reg_val; +} + +static int as7116_54x_led_read_value(u8 reg) +{ + return as7116_54x_cpld_read(LED_CNTRLER_I2C_ADDRESS, reg); +} + +static int as7116_54x_led_write_value(u8 reg, u8 value) +{ + return as7116_54x_cpld_write(LED_CNTRLER_I2C_ADDRESS, reg, value); +} + +static void as7116_54x_led_update(void) +{ + mutex_lock(&ledctl->update_lock); + + if (time_after(jiffies, ledctl->last_updated + HZ + HZ / 2) + || !ledctl->valid) { + int i; + + dev_dbg(&ledctl->pdev->dev, "Starting accton_as7116_54x_led update\n"); + ledctl->valid = 0; + + /* Update LED data + */ + for (i = 0; i < ARRAY_SIZE(ledctl->reg_val); i++) { + int status = as7116_54x_led_read_value(led_reg[i]); + + if (status < 0) { + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", led_reg[i], status); + goto exit; + } + else { + ledctl->reg_val[i] = status; + } + } + + ledctl->last_updated = jiffies; + ledctl->valid = 1; + } + +exit: + mutex_unlock(&ledctl->update_lock); +} + +static void as7116_54x_led_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode, + u8 reg, enum led_type type) +{ + int reg_val; + + mutex_lock(&ledctl->update_lock); + + reg_val = as7116_54x_led_read_value(reg); + + if (reg_val < 0) { + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", reg, reg_val); + goto exit; + } + reg_val = led_light_mode_to_reg_val(type, led_light_mode, reg_val); + as7116_54x_led_write_value(reg, reg_val); + + /* to prevent the slow-update issue */ + ledctl->valid = 0; + +exit: + mutex_unlock(&ledctl->update_lock); +} + + +static void as7116_54x_led_diag_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + as7116_54x_led_set(led_cdev, led_light_mode, led_reg[0], LED_TYPE_DIAG); +} + +static enum led_brightness as7116_54x_led_diag_get(struct led_classdev *cdev) +{ + as7116_54x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_DIAG, ledctl->reg_val[0]); +} + +static void as7116_54x_led_loc_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + as7116_54x_led_set(led_cdev, led_light_mode, led_reg[0], LED_TYPE_LOC); +} + +static enum led_brightness as7116_54x_led_loc_get(struct led_classdev *cdev) +{ + as7116_54x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_LOC, ledctl->reg_val[0]); +} + +static void as7116_54x_led_fan_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + as7116_54x_led_set(led_cdev, led_light_mode, led_reg[0], LED_TYPE_FAN); +} + +static enum led_brightness as7116_54x_led_fan_get(struct led_classdev *cdev) +{ + as7116_54x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_FAN, ledctl->reg_val[0]); +} + +static void as7116_54x_led_psu1_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + as7116_54x_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_PSU1); +} + +static enum led_brightness as7116_54x_led_psu1_get(struct led_classdev *cdev) +{ + as7116_54x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_PSU1, ledctl->reg_val[1]); +} + +static void as7116_54x_led_psu2_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + as7116_54x_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_PSU2); +} + +static enum led_brightness as7116_54x_led_psu2_get(struct led_classdev *cdev) +{ + as7116_54x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_PSU2, ledctl->reg_val[1]); +} + +static struct led_classdev as7116_54x_leds[] = { + [LED_TYPE_DIAG] = { + .name = "as7116_54x_led::diag", + .default_trigger = "unused", + .brightness_set = as7116_54x_led_diag_set, + .brightness_get = as7116_54x_led_diag_get, + .max_brightness = LED_MODE_YELLOW, + }, + [LED_TYPE_LOC] = { + .name = "as7116_54x_led::loc", + .default_trigger = "unused", + .brightness_set = as7116_54x_led_loc_set, + .brightness_get = as7116_54x_led_loc_get, + .max_brightness = LED_MODE_AMBER_BLINK, + }, + [LED_TYPE_FAN] = { + .name = "as7116_54x_led::fan", + .default_trigger = "unused", + .brightness_set = as7116_54x_led_fan_set, + .brightness_get = as7116_54x_led_fan_get, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_PSU1] = { + .name = "as7116_54x_led::psu1", + .default_trigger = "unused", + .brightness_set = as7116_54x_led_psu1_set, + .brightness_get = as7116_54x_led_psu1_get, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_PSU2] = { + .name = "as7116_54x_led::psu2", + .default_trigger = "unused", + .brightness_set = as7116_54x_led_psu2_set, + .brightness_get = as7116_54x_led_psu2_get, + .max_brightness = LED_MODE_AUTO, + }, +}; + + +static int as7116_54x_led_probe(struct platform_device *pdev) +{ + int ret, i; + + for (i = 0; i < ARRAY_SIZE(as7116_54x_leds); i++) { + ret = led_classdev_register(&pdev->dev, &as7116_54x_leds[i]); + + if (ret < 0) { + break; + } + } + + /* Check if all LEDs were successfully registered */ + if (i != ARRAY_SIZE(as7116_54x_leds)){ + int j; + + /* only unregister the LEDs that were successfully registered */ + for (j = 0; j < i; j++) { + led_classdev_unregister(&as7116_54x_leds[i]); + } + } + + return ret; +} + +static int as7116_54x_led_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(as7116_54x_leds); i++) { + led_classdev_unregister(&as7116_54x_leds[i]); + } + + return 0; +} + +static struct platform_driver as7116_54x_led_driver = { + .probe = as7116_54x_led_probe, + .remove = as7116_54x_led_remove, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +static int __init as7116_54x_led_init(void) +{ + int ret; + +#if 0 + extern int platform_accton_as7116_54x(void); + if (!platform_accton_as7116_54x()) { + return -ENODEV; + } +#endif + + ret = platform_driver_register(&as7116_54x_led_driver); + if (ret < 0) { + goto exit; + } + + ledctl = kzalloc(sizeof(struct as7116_54x_led_data), GFP_KERNEL); + if (!ledctl) { + ret = -ENOMEM; + goto exit_driver; + } + + mutex_init(&ledctl->update_lock); + + ledctl->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(ledctl->pdev)) { + ret = PTR_ERR(ledctl->pdev); + goto exit_free; + } + + return 0; + +exit_free: + kfree(ledctl); +exit_driver: + platform_driver_unregister(&as7116_54x_led_driver); +exit: + return ret; +} + +static void __exit as7116_54x_led_exit(void) +{ + platform_device_unregister(ledctl->pdev); + platform_driver_unregister(&as7116_54x_led_driver); + kfree(ledctl); +} + +module_init(as7116_54x_led_init); +module_exit(as7116_54x_led_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton_as7116_54x_led driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/nephos/sonic-platform-modules-accton/as7116-54x/modules/x86-64-accton-as7116-54x-psu.c b/platform/nephos/sonic-platform-modules-accton/as7116-54x/modules/x86-64-accton-as7116-54x-psu.c new file mode 100644 index 000000000000..b4e14297f414 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-accton/as7116-54x/modules/x86-64-accton-as7116-54x-psu.c @@ -0,0 +1,349 @@ +/* + * An hwmon driver for accton as7116_54x Power Module + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PSU_STATUS_I2C_ADDR 0x60 +#define PSU_STATUS_I2C_REG_OFFSET 0x2 + +#define MODEL_NAME_LEN 11 +#define MODEL_NAME_REG_OFFSET 0x20 + +#define SERIAL_NUM_LEN 18 +#define SERIAL_NUM_REG_OFFSET 0x35 + +#define IS_POWER_GOOD(id, value) (!!(value & BIT(id*4 + 1))) +#define IS_PRESENT(id, value) (!(value & BIT(id*4))) + +static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_string(struct device *dev, struct device_attribute *da, char *buf); +static int as7116_54x_psu_read_block(struct i2c_client *client, u8 command, u8 *data,int data_len); +extern int as7116_54x_cpld_read(unsigned short cpld_addr, u8 reg); +static struct as7116_54x_psu_data *as7116_54x_psu_update_device(struct device *dev, u8 update_eeprom); + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +/* Each client has this additional data + */ +struct as7116_54x_psu_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 index; /* PSU index */ + u8 status; /* Status(present/power_good) register read from CPLD */ + char model_name[MODEL_NAME_LEN+1]; /* Model name, read from eeprom */ + char serial[SERIAL_NUM_LEN+1]; /* Serial number, read from eeprom*/ +}; + +enum as7116_54x_psu_sysfs_attributes { + PSU_PRESENT, + PSU_MODEL_NAME, + PSU_POWER_GOOD, + PSU_SERIAL_NUMBER +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, show_status, NULL, PSU_PRESENT); +static SENSOR_DEVICE_ATTR(psu_model_name, S_IRUGO, show_string, NULL, PSU_MODEL_NAME); +static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_status, NULL, PSU_POWER_GOOD); +static SENSOR_DEVICE_ATTR(psu_serial_numer, S_IRUGO, show_string, NULL, PSU_SERIAL_NUMBER); + +static struct attribute *as7116_54x_psu_attributes[] = { + &sensor_dev_attr_psu_present.dev_attr.attr, + &sensor_dev_attr_psu_model_name.dev_attr.attr, + &sensor_dev_attr_psu_power_good.dev_attr.attr, + &sensor_dev_attr_psu_serial_numer.dev_attr.attr, + NULL +}; + +static ssize_t show_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct as7116_54x_psu_data *data = as7116_54x_psu_update_device(dev, 0); + u8 status = 0; + + if (!data->valid) { + return -EIO; + } + + if (attr->index == PSU_PRESENT) { + status = IS_PRESENT(data->index, data->status); + } + else { /* PSU_POWER_GOOD */ + status = IS_POWER_GOOD(data->index, data->status); + } + + return sprintf(buf, "%d\n", status); +} + +static ssize_t show_string(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct as7116_54x_psu_data *data = as7116_54x_psu_update_device(dev, 1); + char *ptr = NULL; + + if (!data->valid) { + return -EIO; + } + + if (!IS_PRESENT(data->index, data->status)) { + return -ENXIO; + } + + if (attr->index == PSU_MODEL_NAME) { + ptr = data->model_name; + } + else { /* PSU_SERIAL_NUBMER */ + ptr = data->serial; + } + + return sprintf(buf, "%s\n", ptr); +} + +static const struct attribute_group as7116_54x_psu_group = { + .attrs = as7116_54x_psu_attributes, +}; + +static int as7116_54x_psu_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct as7116_54x_psu_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct as7116_54x_psu_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + data->index = dev_id->driver_data; + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as7116_54x_psu_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as7116_54x_psu_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as7116_54x_psu_remove(struct i2c_client *client) +{ + struct as7116_54x_psu_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as7116_54x_psu_group); + kfree(data); + + return 0; +} + +enum psu_index +{ + as7116_54x_psu1, + as7116_54x_psu2 +}; + +static const struct i2c_device_id as7116_54x_psu_id[] = { + { "as7116_54x_psu1", as7116_54x_psu1 }, + { "as7116_54x_psu2", as7116_54x_psu2 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, as7116_54x_psu_id); + +static struct i2c_driver as7116_54x_psu_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "as7116_54x_psu", + }, + .probe = as7116_54x_psu_probe, + .remove = as7116_54x_psu_remove, + .id_table = as7116_54x_psu_id, + .address_list = normal_i2c, +}; + +static int as7116_54x_psu_read_block(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ + int result = 0; + int retry_count = 5; + + while (retry_count) { + retry_count--; + + result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + + if (unlikely(result < 0)) { + msleep(10); + continue; + } + + if (unlikely(result != data_len)) { + result = -EIO; + msleep(10); + continue; + } + + result = 0; + break; + } + + return result; +} + +static struct as7116_54x_psu_data *as7116_54x_psu_update_device(struct device *dev, u8 update_eeprom) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as7116_54x_psu_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int status; + + data->valid = 0; + dev_dbg(&client->dev, "Starting as7116_54x update\n"); + + /* Read psu status */ + status = as7116_54x_cpld_read(PSU_STATUS_I2C_ADDR, PSU_STATUS_I2C_REG_OFFSET); + + if (status < 0) { + dev_dbg(&client->dev, "cpld reg (0x%x) err %d\n", PSU_STATUS_I2C_ADDR, status); + goto exit; + } + else { + data->status = status; + } + + + memset(data->model_name, 0, sizeof(data->model_name)); + memset(data->serial, 0, sizeof(data->serial)); + + if (update_eeprom && IS_PRESENT(data->index, data->status)) { + /* Read model name */ + status = as7116_54x_psu_read_block(client, MODEL_NAME_REG_OFFSET, data->model_name, + ARRAY_SIZE(data->model_name)-1); + + if (status < 0) { + data->model_name[0] = '\0'; + dev_dbg(&client->dev, "unable to read model name from (0x%x)\n", client->addr); + goto exit; + } + else { + /* Skip the meaningless data byte 8*/ + data->model_name[8] = data->model_name[9]; + data->model_name[9] = data->model_name[10]; + data->model_name[10] = '\0'; + } + + /* Read serial number */ + status = as7116_54x_psu_read_block(client, SERIAL_NUM_REG_OFFSET, data->serial, + ARRAY_SIZE(data->serial)-1); + + if (status < 0) { + data->serial[0] = '\0'; + dev_dbg(&client->dev, "unable to read serial number from (0x%x)\n", client->addr); + goto exit; + } + else { + data->serial[SERIAL_NUM_LEN] = '\0'; + } + } + + data->last_updated = jiffies; + data->valid = 1; + } + +exit: + mutex_unlock(&data->update_lock); + + return data; +} + +static int __init as7116_54x_psu_init(void) +{ + //extern int platform_accton_as7116_54x(void); + //if (!platform_accton_as7116_54x()) { + // return -ENODEV; + //} + + return i2c_add_driver(&as7116_54x_psu_driver); +} + +static void __exit as7116_54x_psu_exit(void) +{ + i2c_del_driver(&as7116_54x_psu_driver); +} + +module_init(as7116_54x_psu_init); +module_exit(as7116_54x_psu_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("as7116_54x_psu driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/nephos/sonic-platform-modules-accton/as7116-54x/modules/x86-64-accton-as7116-54x-sfp.c b/platform/nephos/sonic-platform-modules-accton/as7116-54x/modules/x86-64-accton-as7116-54x-sfp.c new file mode 100644 index 000000000000..540ceb21722f --- /dev/null +++ b/platform/nephos/sonic-platform-modules-accton/as7116-54x/modules/x86-64-accton-as7116-54x-sfp.c @@ -0,0 +1,1384 @@ +/* + * SFP driver for accton as7116_54x sfp + * + * Copyright (C) Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "as7116_54x_sfp" /* Platform dependent */ + +#define DEBUG_MODE 0 + +#if (DEBUG_MODE == 1) + #define DEBUG_PRINT(fmt, args...) \ + printk (KERN_INFO "%s:%s[%d]: " fmt "\r\n", __FILE__, __FUNCTION__, __LINE__, ##args) +#else + #define DEBUG_PRINT(fmt, args...) +#endif + +#define EEPROM_NAME "sfp_eeprom" +#define EEPROM_SIZE 256 /* 256 byte eeprom */ +#define BIT_INDEX(i) (1ULL << (i)) +#define USE_I2C_BLOCK_READ 1 /* Platform dependent */ +#define I2C_RW_RETRY_COUNT 3 +#define I2C_RW_RETRY_INTERVAL 100 /* ms */ + +#define SFP_EEPROM_A0_I2C_ADDR (0xA0 >> 1) +#define SFP_EEPROM_A2_I2C_ADDR (0xA2 >> 1) + +#define SFF8024_PHYSICAL_DEVICE_ID_ADDR 0x0 +#define SFF8024_DEVICE_ID_SFP 0x3 +#define SFF8024_DEVICE_ID_QSFP 0xC +#define SFF8024_DEVICE_ID_QSFP_PLUS 0xD +#define SFF8024_DEVICE_ID_QSFP28 0x11 + +#define SFF8472_DIAG_MON_TYPE_ADDR 92 +#define SFF8472_DIAG_MON_TYPE_DDM_MASK 0x40 +#define SFF8472_10G_ETH_COMPLIANCE_ADDR 0x3 +#define SFF8472_10G_BASE_MASK 0xF0 + +#define SFF8436_RX_LOS_ADDR 3 +#define SFF8436_TX_FAULT_ADDR 4 +#define SFF8436_TX_DISABLE_ADDR 86 + +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_port_type(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_present(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute *da, const char *buf, size_t count);; +static ssize_t sfp_show_ddm_implemented(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_eeprom_read(struct i2c_client *, u8, u8 *,int); +static ssize_t sfp_eeprom_write(struct i2c_client *, u8 , const char *,int); +extern int as7116_54x_cpld_read(unsigned short cpld_addr, u8 reg); +extern int as7116_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +enum sfp_sysfs_attributes { + PRESENT, + PRESENT_ALL, + PORT_NUMBER, + PORT_TYPE, + DDM_IMPLEMENTED, + TX_FAULT, + TX_FAULT1, + TX_FAULT2, + TX_FAULT3, + TX_FAULT4, + TX_DISABLE, + TX_DISABLE1, + TX_DISABLE2, + TX_DISABLE3, + TX_DISABLE4, + RX_LOS, + RX_LOS1, + RX_LOS2, + RX_LOS3, + RX_LOS4, + RX_LOS_ALL +}; + +/* SFP/QSFP common attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_port_number, S_IRUGO, show_port_number, NULL, PORT_NUMBER); +static SENSOR_DEVICE_ATTR(sfp_port_type, S_IRUGO, show_port_type, NULL, PORT_TYPE); +static SENSOR_DEVICE_ATTR(sfp_is_present, S_IRUGO, show_present, NULL, PRESENT); +static SENSOR_DEVICE_ATTR(sfp_is_present_all, S_IRUGO, show_present, NULL, PRESENT_ALL); +static SENSOR_DEVICE_ATTR(sfp_rx_los, S_IRUGO, sfp_show_tx_rx_status, NULL, RX_LOS); +static SENSOR_DEVICE_ATTR(sfp_tx_disable, S_IWUSR | S_IRUGO, sfp_show_tx_rx_status, sfp_set_tx_disable, TX_DISABLE); +static SENSOR_DEVICE_ATTR(sfp_tx_fault, S_IRUGO, sfp_show_tx_rx_status, NULL, TX_FAULT); + +/* QSFP attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_rx_los1, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS1); +static SENSOR_DEVICE_ATTR(sfp_rx_los2, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS2); +static SENSOR_DEVICE_ATTR(sfp_rx_los3, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS3); +static SENSOR_DEVICE_ATTR(sfp_rx_los4, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS4); +static SENSOR_DEVICE_ATTR(sfp_tx_disable1, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE1); +static SENSOR_DEVICE_ATTR(sfp_tx_disable2, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE2); +static SENSOR_DEVICE_ATTR(sfp_tx_disable3, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE3); +static SENSOR_DEVICE_ATTR(sfp_tx_disable4, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE4); +static SENSOR_DEVICE_ATTR(sfp_tx_fault1, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT1); +static SENSOR_DEVICE_ATTR(sfp_tx_fault2, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT2); +static SENSOR_DEVICE_ATTR(sfp_tx_fault3, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT3); +static SENSOR_DEVICE_ATTR(sfp_tx_fault4, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT4); +static struct attribute *qsfp_attributes[] = { + &sensor_dev_attr_sfp_port_number.dev_attr.attr, + &sensor_dev_attr_sfp_port_type.dev_attr.attr, + &sensor_dev_attr_sfp_is_present.dev_attr.attr, + &sensor_dev_attr_sfp_is_present_all.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los1.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los2.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los3.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los4.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable1.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable2.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable3.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable4.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault1.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault2.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault3.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault4.dev_attr.attr, + NULL +}; + +/* SFP msa attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_ddm_implemented, S_IRUGO, sfp_show_ddm_implemented, NULL, DDM_IMPLEMENTED); +static SENSOR_DEVICE_ATTR(sfp_rx_los_all, S_IRUGO, sfp_show_tx_rx_status, NULL, RX_LOS_ALL); +static struct attribute *sfp_msa_attributes[] = { + &sensor_dev_attr_sfp_port_number.dev_attr.attr, + &sensor_dev_attr_sfp_port_type.dev_attr.attr, + &sensor_dev_attr_sfp_is_present.dev_attr.attr, + &sensor_dev_attr_sfp_is_present_all.dev_attr.attr, + &sensor_dev_attr_sfp_ddm_implemented.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los_all.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable.dev_attr.attr, + NULL +}; + +/* SFP ddm attributes for sysfs */ +static struct attribute *sfp_ddm_attributes[] = { + NULL +}; + +/* Platform dependent +++ */ +#define CPLD_PORT_TO_FRONT_PORT(port) (port+1) + +enum port_numbers { +as7116_54x_sfp1, as7116_54x_sfp2, as7116_54x_sfp3, as7116_54x_sfp4, +as7116_54x_sfp5, as7116_54x_sfp6, as7116_54x_sfp7, as7116_54x_sfp8, +as7116_54x_sfp9, as7116_54x_sfp10, as7116_54x_sfp11, as7116_54x_sfp12, +as7116_54x_sfp13, as7116_54x_sfp14, as7116_54x_sfp15, as7116_54x_sfp16, +as7116_54x_sfp17, as7116_54x_sfp18, as7116_54x_sfp19, as7116_54x_sfp20, +as7116_54x_sfp21, as7116_54x_sfp22, as7116_54x_sfp23, as7116_54x_sfp24, +as7116_54x_sfp25, as7116_54x_sfp26, as7116_54x_sfp27, as7116_54x_sfp28, +as7116_54x_sfp29, as7116_54x_sfp30, as7116_54x_sfp31, as7116_54x_sfp32, +as7116_54x_sfp33, as7116_54x_sfp34, as7116_54x_sfp35, as7116_54x_sfp36, +as7116_54x_sfp37, as7116_54x_sfp38, as7116_54x_sfp39, as7116_54x_sfp40, +as7116_54x_sfp41, as7116_54x_sfp42, as7116_54x_sfp43, as7116_54x_sfp44, +as7116_54x_sfp45, as7116_54x_sfp46, as7116_54x_sfp47, as7116_54x_sfp48, +as7116_54x_sfp49, as7116_54x_sfp50, as7116_54x_sfp51, as7116_54x_sfp52, +as7116_54x_sfp53, as7116_54x_sfp54 +}; + +#define I2C_DEV_ID(x) { #x, x} + +static const struct i2c_device_id sfp_device_id[] = { +I2C_DEV_ID(as7116_54x_sfp1), +I2C_DEV_ID(as7116_54x_sfp2), +I2C_DEV_ID(as7116_54x_sfp3), +I2C_DEV_ID(as7116_54x_sfp4), +I2C_DEV_ID(as7116_54x_sfp5), +I2C_DEV_ID(as7116_54x_sfp6), +I2C_DEV_ID(as7116_54x_sfp7), +I2C_DEV_ID(as7116_54x_sfp8), +I2C_DEV_ID(as7116_54x_sfp9), +I2C_DEV_ID(as7116_54x_sfp10), +I2C_DEV_ID(as7116_54x_sfp11), +I2C_DEV_ID(as7116_54x_sfp12), +I2C_DEV_ID(as7116_54x_sfp13), +I2C_DEV_ID(as7116_54x_sfp14), +I2C_DEV_ID(as7116_54x_sfp15), +I2C_DEV_ID(as7116_54x_sfp16), +I2C_DEV_ID(as7116_54x_sfp17), +I2C_DEV_ID(as7116_54x_sfp18), +I2C_DEV_ID(as7116_54x_sfp19), +I2C_DEV_ID(as7116_54x_sfp20), +I2C_DEV_ID(as7116_54x_sfp21), +I2C_DEV_ID(as7116_54x_sfp22), +I2C_DEV_ID(as7116_54x_sfp23), +I2C_DEV_ID(as7116_54x_sfp24), +I2C_DEV_ID(as7116_54x_sfp25), +I2C_DEV_ID(as7116_54x_sfp26), +I2C_DEV_ID(as7116_54x_sfp27), +I2C_DEV_ID(as7116_54x_sfp28), +I2C_DEV_ID(as7116_54x_sfp29), +I2C_DEV_ID(as7116_54x_sfp30), +I2C_DEV_ID(as7116_54x_sfp31), +I2C_DEV_ID(as7116_54x_sfp32), +I2C_DEV_ID(as7116_54x_sfp33), +I2C_DEV_ID(as7116_54x_sfp34), +I2C_DEV_ID(as7116_54x_sfp35), +I2C_DEV_ID(as7116_54x_sfp36), +I2C_DEV_ID(as7116_54x_sfp37), +I2C_DEV_ID(as7116_54x_sfp38), +I2C_DEV_ID(as7116_54x_sfp39), +I2C_DEV_ID(as7116_54x_sfp40), +I2C_DEV_ID(as7116_54x_sfp41), +I2C_DEV_ID(as7116_54x_sfp42), +I2C_DEV_ID(as7116_54x_sfp43), +I2C_DEV_ID(as7116_54x_sfp44), +I2C_DEV_ID(as7116_54x_sfp45), +I2C_DEV_ID(as7116_54x_sfp46), +I2C_DEV_ID(as7116_54x_sfp47), +I2C_DEV_ID(as7116_54x_sfp48), +I2C_DEV_ID(as7116_54x_sfp49), +I2C_DEV_ID(as7116_54x_sfp50), +I2C_DEV_ID(as7116_54x_sfp51), +I2C_DEV_ID(as7116_54x_sfp52), +I2C_DEV_ID(as7116_54x_sfp53), +I2C_DEV_ID(as7116_54x_sfp54), +{ /* LIST END */ } +}; +MODULE_DEVICE_TABLE(i2c, sfp_device_id); + +/* + * list of valid port types + * note OOM_PORT_TYPE_NOT_PRESENT to indicate no + * module is present in this port + */ +typedef enum oom_driver_port_type_e { + OOM_DRIVER_PORT_TYPE_INVALID, + OOM_DRIVER_PORT_TYPE_NOT_PRESENT, + OOM_DRIVER_PORT_TYPE_SFP, + OOM_DRIVER_PORT_TYPE_SFP_PLUS, + OOM_DRIVER_PORT_TYPE_QSFP, + OOM_DRIVER_PORT_TYPE_QSFP_PLUS, + OOM_DRIVER_PORT_TYPE_QSFP28 +} oom_driver_port_type_t; + +enum driver_type_e { + DRIVER_TYPE_SFP_MSA, + DRIVER_TYPE_SFP_DDM, + DRIVER_TYPE_QSFP +}; + +/* Each client has this additional data + */ +struct eeprom_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + struct bin_attribute bin; /* eeprom data */ +}; + +struct sfp_msa_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u64 status[6]; /* bit0:port0, bit1:port1 and so on */ + /* index 0 => tx_fail + 1 => tx_disable + 2 => rx_loss + 3 => device id + 4 => 10G Ethernet Compliance Codes + to distinguish SFP or SFP+ + 5 => DIAGNOSTIC MONITORING TYPE */ + struct eeprom_data eeprom; +}; + +struct sfp_ddm_data { + struct eeprom_data eeprom; +}; + +struct qsfp_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 status[3]; /* bit0:port0, bit1:port1 and so on */ + /* index 0 => tx_fail + 1 => tx_disable + 2 => rx_loss */ + + u8 device_id; + struct eeprom_data eeprom; +}; + +struct sfp_port_data { + struct mutex update_lock; + enum driver_type_e driver_type; + int port; /* CPLD port index */ + oom_driver_port_type_t port_type; + u64 present; /* present status, bit0:port0, bit1:port1 and so on */ + + struct sfp_msa_data *msa; + struct sfp_ddm_data *ddm; + struct qsfp_data *qsfp; + + struct i2c_client *client; +}; + +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + return sprintf(buf, "%d\n", CPLD_PORT_TO_FRONT_PORT(data->port)); +} + +/* Platform dependent +++ */ +static struct sfp_port_data *sfp_update_present(struct i2c_client *client) +{ + int i = 0, j = 0, status = -1; + u8 reg; + unsigned short cpld_addr; + struct sfp_port_data *data = i2c_get_clientdata(client); + + DEBUG_PRINT("Starting sfp present status update"); + mutex_lock(&data->update_lock); + data->present = 0; + + /* Read present status of port 1~48(SFP port) */ + for (i = 0; i < 2; i++) { + for (j = 0; j < 3; j++) { + cpld_addr = 0x61+i; + reg = 0x6+j; + status = as7116_54x_cpld_read(cpld_addr, reg); + + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_addr, reg, status); + goto exit; + } + + DEBUG_PRINT("Present status = 0x%lx\r\n", data->present); + data->present |= (u64)status << ((i*24) + (j%3)*8); + } + } + + /* Read present status of port 49-54(QSFP port) */ + cpld_addr = 0x62; + reg = 0x14; + status = as7116_54x_cpld_read(cpld_addr, reg); + + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_addr, reg, status); + goto exit; + } + else { + data->present |= (u64)status << 48; + } + + DEBUG_PRINT("Present status = 0x%lx", data->present); +exit: + mutex_unlock(&data->update_lock); + return (status < 0) ? ERR_PTR(status) : data; +} + +static struct sfp_port_data *sfp_update_tx_rx_status(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int i = 0, j = 0; + int status = -1; + + if (time_before(jiffies, data->msa->last_updated + HZ + HZ / 2) && data->msa->valid) { + return data; + } + + DEBUG_PRINT("Starting as7116_54x sfp tx rx status update"); + mutex_lock(&data->update_lock); + data->msa->valid = 0; + memset(data->msa->status, 0, sizeof(data->msa->status)); + + /* Read status of port 1~48(SFP port) */ + for (i = 0; i < 2; i++) { + for (j = 0; j < 9; j++) { + u8 reg; + unsigned short cpld_addr; + reg = 0x9+j; + cpld_addr = 0x61+i; + + status = as7116_54x_cpld_read(cpld_addr, reg); + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_addr, reg, status); + goto exit; + } + + data->msa->status[j/3] |= (u64)status << ((i*24) + (j%3)*8); + } + } + + data->msa->valid = 1; + data->msa->last_updated = jiffies; + +exit: + mutex_unlock(&data->update_lock); + return (status < 0) ? ERR_PTR(status) : data; +} + +static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + unsigned short cpld_addr = 0; + u8 cpld_reg = 0, cpld_val = 0, cpld_bit = 0; + long disable; + int error; + + if (data->driver_type == DRIVER_TYPE_QSFP) { + return qsfp_set_tx_disable(dev, da, buf, count); + } + + error = kstrtol(buf, 10, &disable); + if (error) { + return error; + } + + mutex_lock(&data->update_lock); + + if(data->port < 24) { + cpld_addr = 0x61; + cpld_reg = 0xC + data->port / 8; + cpld_bit = 1 << (data->port % 8); + } + else { /* port 24 ~ 48 */ + cpld_addr = 0x62; + cpld_reg = 0xC + (data->port - 24) / 8; + cpld_bit = 1 << (data->port % 8); + } + + /* Read current status */ + cpld_val = as7116_54x_cpld_read(cpld_addr, cpld_reg); + + /* Update tx_disable status */ + if (disable) { + data->msa->status[1] |= BIT_INDEX(data->port); + cpld_val |= cpld_bit; + } + else { + data->msa->status[1] &= ~BIT_INDEX(data->port); + cpld_val &= ~cpld_bit; + } + + as7116_54x_cpld_write(cpld_addr, cpld_reg, cpld_val); + mutex_unlock(&data->update_lock); + return count; +} +/* Platform dependent --- */ + +static int sfp_is_port_present(struct i2c_client *client, int port) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + + data = sfp_update_present(client); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + return !(data->present & BIT_INDEX(data->port)); /* Platform dependent */ +} + +/* Platform dependent +++ */ +static ssize_t show_present(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + + if (PRESENT_ALL == attr->index) { + int i; + u8 values[7] = {0}; + struct sfp_port_data *data = sfp_update_present(client); + + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + for (i = 0; i < ARRAY_SIZE(values); i++) { + values[i] = ~(u8)(data->present >> (i * 8)); + } + + /* Return values 1 -> 54 in order */ + return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], + values[3], values[4], values[5], + values[6] & 0x3F); + } + else { + struct sfp_port_data *data = i2c_get_clientdata(client); + int present = sfp_is_port_present(client, data->port); + + if (IS_ERR_VALUE(present)) { + return present; + } + + /* PRESENT */ + return sprintf(buf, "%d\n", present); + } +} +/* Platform dependent --- */ + +static struct sfp_port_data *sfp_update_port_type(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + u8 buf = 0; + int status; + + mutex_lock(&data->update_lock); + + switch (data->driver_type) { + case DRIVER_TYPE_SFP_MSA: + { + status = sfp_eeprom_read(client, SFF8024_PHYSICAL_DEVICE_ID_ADDR, &buf, sizeof(buf)); + if (unlikely(status < 0)) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + if (buf != SFF8024_DEVICE_ID_SFP) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + status = sfp_eeprom_read(client, SFF8472_10G_ETH_COMPLIANCE_ADDR, &buf, sizeof(buf)); + if (unlikely(status < 0)) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + DEBUG_PRINT("sfp port type (0x3) data = (0x%x)", buf); + data->port_type = buf & SFF8472_10G_BASE_MASK ? OOM_DRIVER_PORT_TYPE_SFP_PLUS : OOM_DRIVER_PORT_TYPE_SFP; + break; + } + case DRIVER_TYPE_QSFP: + { + status = sfp_eeprom_read(client, SFF8024_PHYSICAL_DEVICE_ID_ADDR, &buf, sizeof(buf)); + if (unlikely(status < 0)) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + DEBUG_PRINT("qsfp port type (0x0) buf = (0x%x)", buf); + switch (buf) { + case SFF8024_DEVICE_ID_QSFP: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP; + break; + case SFF8024_DEVICE_ID_QSFP_PLUS: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP_PLUS; + break; + case SFF8024_DEVICE_ID_QSFP28: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP_PLUS; + break; + default: + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + break; + } + default: + break; + } + + mutex_unlock(&data->update_lock); + return data; +} + +static ssize_t show_port_type(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int present = sfp_is_port_present(client, data->port); + + if (IS_ERR_VALUE(present)) { + return present; + } + + if (!present) { + /* port is not present */ + return sprintf(buf, "%d\n", OOM_DRIVER_PORT_TYPE_NOT_PRESENT); + } + + sfp_update_port_type(dev); + return sprintf(buf, "%d\n", data->port_type); +} + +static struct sfp_port_data *qsfp_update_tx_rx_status(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int i, status = -1; + u8 buf = 0; + u8 reg[] = {SFF8436_TX_FAULT_ADDR, SFF8436_TX_DISABLE_ADDR, SFF8436_RX_LOS_ADDR}; + + DEBUG_PRINT(""); + if (time_before(jiffies, data->qsfp->last_updated + HZ + HZ / 2) && data->qsfp->valid) { + return data; + } + + DEBUG_PRINT("Starting sfp tx rx status update"); + mutex_lock(&data->update_lock); + data->qsfp->valid = 0; + memset(data->qsfp->status, 0, sizeof(data->qsfp->status)); + + DEBUG_PRINT(""); + /* Notify device to update tx fault/ tx disable/ rx los status */ + for (i = 0; i < ARRAY_SIZE(reg); i++) { + status = sfp_eeprom_read(client, reg[i], &buf, sizeof(buf)); + if (unlikely(status < 0)) { + DEBUG_PRINT(""); + goto exit; + } + } + msleep(200); + DEBUG_PRINT(""); + + /* Read actual tx fault/ tx disable/ rx los status */ + for (i = 0; i < ARRAY_SIZE(reg); i++) { + status = sfp_eeprom_read(client, reg[i], &buf, sizeof(buf)); + if (unlikely(status < 0)) { + DEBUG_PRINT(""); + goto exit; + } + + DEBUG_PRINT("qsfp reg(0x%x) status = (0x%x)", reg[i], data->qsfp->status[i]); + data->qsfp->status[i] = (buf & 0xF); + } + + DEBUG_PRINT(""); + data->qsfp->valid = 1; + data->qsfp->last_updated = jiffies; + +exit: + DEBUG_PRINT(""); + mutex_unlock(&data->update_lock); + return (status < 0) ? ERR_PTR(status) : data; +} + +static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + int present; + u8 val = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + DEBUG_PRINT(""); + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + DEBUG_PRINT(""); + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + DEBUG_PRINT(""); + data = qsfp_update_tx_rx_status(dev); + DEBUG_PRINT(""); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + DEBUG_PRINT(""); + switch (attr->index) { + case TX_FAULT: + val = !!(data->qsfp->status[2] & 0xF); + break; + case TX_FAULT1: + case TX_FAULT2: + case TX_FAULT3: + case TX_FAULT4: + val = !!(data->qsfp->status[2] & BIT_INDEX(attr->index - TX_FAULT1)); + break; + case TX_DISABLE: + val = data->qsfp->status[1] & 0xF; + break; + case TX_DISABLE1: + case TX_DISABLE2: + case TX_DISABLE3: + case TX_DISABLE4: + val = !!(data->qsfp->status[1] & BIT_INDEX(attr->index - TX_DISABLE1)); + break; + case RX_LOS: + val = !!(data->qsfp->status[0] & 0xF); + break; + case RX_LOS1: + case RX_LOS2: + case RX_LOS3: + case RX_LOS4: + val = !!(data->qsfp->status[0] & BIT_INDEX(attr->index - RX_LOS1)); + break; + default: + break; + } + + DEBUG_PRINT(""); + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + long disable; + int status; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + status = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(status)) { + return status; + } + + if (!status) { + /* port is not present */ + return -ENXIO; + } + + status = kstrtol(buf, 10, &disable); + if (status) { + return status; + } + + data = qsfp_update_tx_rx_status(dev); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + mutex_lock(&data->update_lock); + + if (attr->index == TX_DISABLE) { + data->qsfp->status[1] = disable & 0xF; + } + else {/* TX_DISABLE1 ~ TX_DISABLE4*/ + if (disable) { + data->qsfp->status[1] |= (1 << (attr->index - TX_DISABLE1)); + } + else { + data->qsfp->status[1] &= ~(1 << (attr->index - TX_DISABLE1)); + } + } + + DEBUG_PRINT("index = (%d), status = (0x%x)", attr->index, data->qsfp->status[1]); + status = sfp_eeprom_write(data->client, SFF8436_TX_DISABLE_ADDR, &data->qsfp->status[1], sizeof(data->qsfp->status[1])); + if (unlikely(status < 0)) { + count = status; + } + + mutex_unlock(&data->update_lock); + return count; +} + +static ssize_t sfp_show_ddm_implemented(struct device *dev, struct device_attribute *da, + char *buf) +{ + int status; + char ddm; + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + status = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(status)) { + return status; + } + + if (status == 0) { + /* port is not present */ + return -ENODEV; + } + + status = sfp_eeprom_read(client, SFF8472_DIAG_MON_TYPE_ADDR, &ddm, sizeof(ddm)); + if (unlikely(status < 0)) { + return status; + } + + return sprintf(buf, "%d\n", !!(ddm & SFF8472_DIAG_MON_TYPE_DDM_MASK)); +} + +/* Platform dependent +++ */ +static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + u8 val = 0, index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + DEBUG_PRINT("driver type = (%d)", data->driver_type); + if (data->driver_type == DRIVER_TYPE_QSFP) { + DEBUG_PRINT(""); + return qsfp_show_tx_rx_status(dev, da, buf); + } + + DEBUG_PRINT(""); + data = sfp_update_tx_rx_status(dev); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + if(attr->index == RX_LOS_ALL) { + int i = 0; + u8 values[6] = {0}; + + for (i = 0; i < ARRAY_SIZE(values); i++) { + values[i] = (u8)(data->msa->status[2] >> (i * 8)); + } + + /** Return values 1 -> 48 in order */ + return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], + values[3], values[4], values[5]); + } + + switch (attr->index) { + case TX_FAULT: + index = 0; + break; + case TX_DISABLE: + index = 1; + break; + case RX_LOS: + index = 2; + break; + default: + break; + } + + val = !!(data->msa->status[index] & BIT_INDEX(data->port)); + return sprintf(buf, "%d\n", val); +} +/* Platform dependent --- */ +static ssize_t sfp_eeprom_write(struct i2c_client *client, u8 command, const char *data, + int data_len) +{ +#if USE_I2C_BLOCK_READ + int status, retry = I2C_RW_RETRY_COUNT; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_write_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + return status; + } + + return data_len; +#else + int status, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_write_byte_data(client, command, *data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + return status; + } + + return 1; +#endif + + +} + +static ssize_t sfp_port_write(struct sfp_port_data *data, + const char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + return count; + } + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&data->update_lock); + + while (count) { + ssize_t status; + + status = sfp_eeprom_write(data->client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&data->update_lock); + return retval; +} + + +static ssize_t sfp_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct sfp_port_data *data; + DEBUG_PRINT("%s(%d) offset = (%d), count = (%d)", off, count); + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + + present = sfp_is_port_present(data->client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + return sfp_port_write(data, buf, off, count); +} + +static ssize_t sfp_eeprom_read(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ +#if USE_I2C_BLOCK_READ + int status, retry = I2C_RW_RETRY_COUNT; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + goto abort; + } + if (unlikely(status != data_len)) { + status = -EIO; + goto abort; + } + + //result = data_len; + +abort: + return status; +#else + int status, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_read_byte_data(client, command); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "sfp read byte data failed, command(0x%2x), data(0x%2x)\r\n", command, status); + goto abort; + } + + *data = (u8)status; + status = 1; + +abort: + return status; +#endif +} + +static ssize_t sfp_port_read(struct sfp_port_data *data, + char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + DEBUG_PRINT("Count = 0, return"); + return count; + } + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&data->update_lock); + + while (count) { + ssize_t status; + + status = sfp_eeprom_read(data->client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&data->update_lock); + return retval; + +} + +static ssize_t sfp_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct sfp_port_data *data; + DEBUG_PRINT("offset = (%d), count = (%d)", off, count); + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + + present = sfp_is_port_present(data->client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + return sfp_port_read(data, buf, off, count); +} + +static int sfp_sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom) +{ + int err; + + sysfs_bin_attr_init(eeprom); + eeprom->attr.name = EEPROM_NAME; + eeprom->attr.mode = S_IWUSR | S_IRUGO; + eeprom->read = sfp_bin_read; + eeprom->write = sfp_bin_write; + eeprom->size = EEPROM_SIZE; + + /* Create eeprom file */ + err = sysfs_create_bin_file(kobj, eeprom); + if (err) { + return err; + } + + return 0; +} + +static int sfp_sysfs_eeprom_cleanup(struct kobject *kobj, struct bin_attribute *eeprom) +{ + sysfs_remove_bin_file(kobj, eeprom); + return 0; +} + +static const struct attribute_group sfp_msa_group = { + .attrs = sfp_msa_attributes, +}; + +static int sfp_i2c_check_functionality(struct i2c_client *client) +{ +#if USE_I2C_BLOCK_READ + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK); +#else + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA); +#endif +} + +static int sfp_msa_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct sfp_msa_data **data) +{ + int status; + struct sfp_msa_data *msa; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + msa = kzalloc(sizeof(struct sfp_msa_data), GFP_KERNEL); + if (!msa) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &sfp_msa_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &msa->eeprom.bin); + if (status) { + goto exit_remove; + } + + *data = msa; + dev_info(&client->dev, "sfp msa '%s'\n", client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &sfp_msa_group); +exit_free: + kfree(msa); +exit: + + return status; +} + +static const struct attribute_group sfp_ddm_group = { + .attrs = sfp_ddm_attributes, +}; + +static int sfp_ddm_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct sfp_ddm_data **data) +{ + int status; + struct sfp_ddm_data *ddm; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + ddm = kzalloc(sizeof(struct sfp_ddm_data), GFP_KERNEL); + if (!ddm) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &sfp_ddm_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &ddm->eeprom.bin); + if (status) { + goto exit_remove; + } + + *data = ddm; + dev_info(&client->dev, "sfp ddm '%s'\n", client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &sfp_ddm_group); +exit_free: + kfree(ddm); +exit: + + return status; +} + +static const struct attribute_group qsfp_group = { + .attrs = qsfp_attributes, +}; + +static int qsfp_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct qsfp_data **data) +{ + int status; + struct qsfp_data *qsfp; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + qsfp = kzalloc(sizeof(struct qsfp_data), GFP_KERNEL); + if (!qsfp) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &qsfp_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &qsfp->eeprom.bin); + if (status) { + goto exit_remove; + } + + /* Bring QSFPs out of reset */ + as7116_54x_cpld_write(0x62, 0x15, 0x3F); + + *data = qsfp; + dev_info(&client->dev, "qsfp '%s'\n", client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &qsfp_group); +exit_free: + kfree(qsfp); +exit: + + return status; +} + +/* Platform dependent +++ */ +static int sfp_device_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct sfp_port_data *data = NULL; + + data = kzalloc(sizeof(struct sfp_port_data), GFP_KERNEL); + if (!data) { + return -ENOMEM; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->port = dev_id->driver_data; + data->client = client; + + if (dev_id->driver_data >= as7116_54x_sfp1 && dev_id->driver_data <= as7116_54x_sfp48) { + if (client->addr == SFP_EEPROM_A0_I2C_ADDR) { + data->driver_type = DRIVER_TYPE_SFP_MSA; + return sfp_msa_probe(client, dev_id, &data->msa); + } + else if (client->addr == SFP_EEPROM_A2_I2C_ADDR) { + data->driver_type = DRIVER_TYPE_SFP_DDM; + return sfp_ddm_probe(client, dev_id, &data->ddm); + } + } + else { /* as7116_54x_sfp49 ~ as7116_54x_sfp54 */ + if (client->addr == SFP_EEPROM_A0_I2C_ADDR) { + data->driver_type = DRIVER_TYPE_QSFP; + return qsfp_probe(client, dev_id, &data->qsfp); + } + } + + return -ENODEV; +} +/* Platform dependent --- */ + +static int sfp_msa_remove(struct i2c_client *client, struct sfp_msa_data *data) +{ + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + sysfs_remove_group(&client->dev.kobj, &sfp_msa_group); + kfree(data); + return 0; +} + +static int sfp_ddm_remove(struct i2c_client *client, struct sfp_ddm_data *data) +{ + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + sysfs_remove_group(&client->dev.kobj, &sfp_ddm_group); + kfree(data); + return 0; +} + +static int qfp_remove(struct i2c_client *client, struct qsfp_data *data) +{ + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + sysfs_remove_group(&client->dev.kobj, &qsfp_group); + kfree(data); + return 0; +} + +static int sfp_device_remove(struct i2c_client *client) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + + switch (data->driver_type) { + case DRIVER_TYPE_SFP_MSA: + return sfp_msa_remove(client, data->msa); + case DRIVER_TYPE_SFP_DDM: + return sfp_ddm_remove(client, data->ddm); + case DRIVER_TYPE_QSFP: + return qfp_remove(client, data->qsfp); + } + + return 0; +} + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +static struct i2c_driver sfp_driver = { + .driver = { + .name = DRIVER_NAME, + }, + .probe = sfp_device_probe, + .remove = sfp_device_remove, + .id_table = sfp_device_id, + .address_list = normal_i2c, +}; + +static int __init sfp_init(void) +{ + //extern int platform_accton_as7116_54x(void); + //if (!platform_accton_as7116_54x()) { + // return -ENODEV; + //} + + return i2c_add_driver(&sfp_driver); +} + +static void __exit sfp_exit(void) +{ + i2c_del_driver(&sfp_driver); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton as7116_54x_sfp driver"); +MODULE_LICENSE("GPL"); + +module_init(sfp_init); +module_exit(sfp_exit); + diff --git a/platform/nephos/sonic-platform-modules-accton/as7116-54x/service/as7116-platform-init.service b/platform/nephos/sonic-platform-modules-accton/as7116-54x/service/as7116-platform-init.service new file mode 100755 index 000000000000..be8688d2c2d2 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-accton/as7116-54x/service/as7116-platform-init.service @@ -0,0 +1,13 @@ +[Unit] +Description=Accton AS7116-54X Platform initialization service +Before=pmon.service +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/accton_as7116_util.py install +ExecStop=/usr/local/bin/accton_as7116_util.py clean +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/nephos/sonic-platform-modules-accton/as7116-54x/setup.py b/platform/nephos/sonic-platform-modules-accton/as7116-54x/setup.py new file mode 100644 index 000000000000..bb740409e310 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-accton/as7116-54x/setup.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +import os +import sys +from setuptools import setup +os.listdir + +setup( + name='as7116-54x', + version='1.0.0', + description='Module to initialize Accton AS7116-54X platforms', + + packages=['as7116-54x'], + package_dir={'as7116-54x': 'as7116-54x/classes'}, + ) diff --git a/platform/nephos/sonic-platform-modules-accton/as7116-54x/utils/README b/platform/nephos/sonic-platform-modules-accton/as7116-54x/utils/README new file mode 100755 index 000000000000..0b9fc1633999 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-accton/as7116-54x/utils/README @@ -0,0 +1,60 @@ +Copyright (C) 2016 Accton Networks, 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 3 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, see . + +To initialize the system, run "accton_as7712_util.py install". +To clean up the drivers & devices, run "accton_as7712_util.py clean". +To dump information of sensors, run "accton_as7712_util.py show". +To dump SFP EEPROM, run "accton_as7712_util.py sff". +To set fan speed, run "accton_as7712_util.py set fan". +To enable/disable SFP emission, run "accton_as7712_util.py set sfp". +To set system LEDs' color, run "accton_as7712_util.py set led" +For more information, run "accton_as7712_util.py --help". + +==================================================================== +Besides applying accton_as7712_util.py to access peripherals, you can +access peripherals by sysfs nodes directly after the installation is run. + +LED controls can be found under /sys/class/leds. The sysfs interface +color mappings are as follows: +Brightness: + 0 => off + 1 => green + 2 => amber + 3 => red + 4 => blue + +There are 5 system LEDs, loc, diag, fan, ps1, and ps2. +They are lit automatically by CPLD, but the loc and diag. +The loc led has only 1 color, blue. +The diag one has 3 colors: red, amber, and green. + +Fan controls can be found in /sys/bus/i2c/devices/2-0066. +There are 12 fans inside 6 fan modules. +All fans share 1 duty setting, ranged from 0~100. + +Three temperature sensors are controlled by the lm75 kernel modules. +They should already be visible under /sys/bus/i2c/drivers/lm75/. + +Two power supplies are controlled by the CPLD. +Here provide their status under +/sys/bus/i2c/devices/10-0050 and /sys/bus/i2c/devices/11-0053. + +There are 32 QSFP+ modules are equipped. +Apply "accton_as7712_util.py show" to get their status. +Apply "accton_as7712_util.py set sfp" to turn on/off light transmission. +Apply "accton_as7712_util.py sff" to dump EEPROM information. +Before operating on that QSFP+, please make sure it is well plugged. +Otherwise, operation is going to fail. + diff --git a/platform/nephos/sonic-platform-modules-accton/as7116-54x/utils/accton_as7116_util.py b/platform/nephos/sonic-platform-modules-accton/as7116-54x/utils/accton_as7116_util.py new file mode 100755 index 000000000000..26a8a3cc8f84 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-accton/as7116-54x/utils/accton_as7116_util.py @@ -0,0 +1,526 @@ +#!/usr/bin/env python +# +# Copyright (C) 2016 Accton Networks, 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 3 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, see . + +""" +Usage: %(scriptName)s [options] command object + +options: + -h | --help : this help message + -d | --debug : run with debug mode + -f | --force : ignore error during installation or clean +command: + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes + show : show all systen status + sff : dump SFP eeprom + set : change board setting with fan|led|sfp +""" + +import os +import commands +import sys, getopt +import logging +import re +import time +from collections import namedtuple + + + + +PROJECT_NAME = 'as7116_54x' +version = '0.1.0' +verbose = False +DEBUG = False +args = [] +ALL_DEVICE = {} +DEVICE_NO = {'led':5, 'fan':1, 'thermal':3, 'psu':2, 'sfp':54} +FORCE = 0 +#logging.basicConfig(filename= PROJECT_NAME+'.log', filemode='w',level=logging.DEBUG) +#logging.basicConfig(level=logging.INFO) + + +if DEBUG == True: + print sys.argv[0] + print 'ARGV :', sys.argv[1:] + + +def main(): + global DEBUG + global args + global FORCE + + if len(sys.argv)<2: + show_help() + + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', + 'debug', + 'force', + ]) + if DEBUG == True: + print options + print args + print len(sys.argv) + + for opt, arg in options: + if opt in ('-h', '--help'): + show_help() + elif opt in ('-d', '--debug'): + DEBUG = True + logging.basicConfig(level=logging.INFO) + elif opt in ('-f', '--force'): + FORCE = 1 + else: + logging.info('no option') + for arg in args: + if arg == 'install': + do_install() + elif arg == 'clean': + do_uninstall() + elif arg == 'show': + device_traversal() + elif arg == 'sff': + if len(args)!=2: + show_eeprom_help() + elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']: + show_eeprom_help() + else: + show_eeprom(args[1]) + return + elif arg == 'set': + if len(args)<3: + show_set_help() + else: + set_device(args[1:]) + return + else: + show_help() + + + return 0 + +def show_help(): + print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + sys.exit(0) + +def show_set_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print cmd +" [led|sfp|fan]" + print " use \""+ cmd + " led 0-4 \" to set led color" + print " use \""+ cmd + " fan 0-100\" to set fan duty percetage" + print " use \""+ cmd + " sfp 1-54 {0|1}\" to set sfp# tx_disable" + sys.exit(0) + +def show_eeprom_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print " use \""+ cmd + " 1-54 \" to dump sfp# eeprom" + sys.exit(0) + +def my_log(txt): + if DEBUG == True: + print "[ROY]"+txt + return + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) + my_log (cmd +"with result:" + str(status)) + my_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + +def driver_check(): + ret, lsmod = log_os_system("lsmod| grep accton", 0) + logging.info('mods:'+lsmod) + if len(lsmod) ==0: + return False + return True + + + +kos = [ + 'depmod', + 'modprobe i2c_dev', + 'modprobe i2c_mux_pca954x force_deselect_on_exit=1', + 'modprobe x86-64-accton-as7116-54x-cpld' , + 'modprobe x86-64-accton-as7116-54x-fan' , + 'modprobe x86-64-accton-as7116-54x-psu' , + 'modprobe x86-64-accton-as7116-54x-sfp' , + 'modprobe x86-64-accton-as7116-54x-led' ] + +def driver_install(): + global FORCE + for i in range(0,len(kos)): + status, output = log_os_system(kos[i], 1) + if status: + if FORCE == 0: + return status + return 0 + +def driver_uninstall(): + global FORCE + for i in range(0,len(kos)): + rm = kos[-(i+1)].replace("modprobe", "modprobe -rq") + rm = rm.replace("insmod", "rmmod") + status, output = log_os_system(rm, 1) + if status: + if FORCE == 0: + return status + return 0 + +led_prefix ='/sys/class/leds/'+PROJECT_NAME+'_led::' +hwmon_types = {'led': ['diag','fan','loc','psu1','psu2']} +hwmon_nodes = {'led': ['brightness'] } +hwmon_prefix ={'led': led_prefix} + +i2c_prefix = '/sys/bus/i2c/devices/' +i2c_bus = {'fan': ['1-0063'] , + 'thermal': ['17-004b','19-0049', '20-004a'] , + 'psu': ['10-0050','11-0058'], + 'sfp': ['-0050']} +i2c_nodes = {'fan': ['present', 'front_speed_rpm', 'rear_speed_rpm'] , + 'thermal': ['hwmon/hwmon*/temp1_input'] , + 'psu': ['psu_present ', 'psu_power_good'] , + 'sfp': ['sfp_is_present ', 'sfp_tx_disable_all']} + +sfp_map = [37,38,39,40, + 41,42,43,44,45,46,47,48,49,50, + 51,52,53,54,55,56,57,58,59,60, + 61,62,63,64,65,66,67,68,69,70, + 71,72,73,74,75,76,77,78,79,80, + 81,82,83,84, + 21,22,23,24,25,26] + +mknod =[ + 'echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-0/new_device', + 'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-1/new_device', + 'echo pca9545 0x71 > /sys/bus/i2c/devices/i2c-1/new_device', + 'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-1/new_device', + 'echo as7116_54x_fan 0x63 > /sys/bus/i2c/devices/i2c-1/new_device', + 'echo lm75 0x4b > /sys/bus/i2c/devices/i2c-17/new_device', + 'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-19/new_device', + 'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-20/new_device', + 'echo as7116_54x_cpld1 0x60 > /sys/bus/i2c/devices/i2c-2/new_device', + 'echo as7116_54x_cpld2 0x61 > /sys/bus/i2c/devices/i2c-2/new_device', + 'echo as7116_54x_cpld3 0x62 > /sys/bus/i2c/devices/i2c-2/new_device', + 'echo as7116_54x_psu1 0x50 > /sys/bus/i2c/devices/i2c-10/new_device', + 'echo ym2401 0x58 > /sys/bus/i2c/devices/i2c-10/new_device', + 'echo as7116_54x_psu2 0x53 > /sys/bus/i2c/devices/i2c-11/new_device', + 'echo ym2401 0x5b > /sys/bus/i2c/devices/i2c-11/new_device', + 'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-2/new_device', + 'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-29/new_device', + 'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-30/new_device', + 'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-31/new_device', + 'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-32/new_device', + 'echo pca9548 0x75 > /sys/bus/i2c/devices/i2c-33/new_device', + 'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-34/new_device', + 'echo 24c02 0x56 > /sys/bus/i2c/devices/i2c-0/new_device'] + +def device_install(): + global FORCE + + for i in range(0,len(mknod)): + #for pca954x need times to built new i2c buses + if mknod[i].find('pca954') != -1: + time.sleep(1) + + status, output = log_os_system(mknod[i], 1) + if status: + print output + if FORCE == 0: + return status + + for i in range(0,len(sfp_map)): + status, output =log_os_system("echo as7116_54x_sfp"+str(i+1)+" 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + + if i <= 47: + status, output =log_os_system("echo as7116_54x_sfp"+str(i+1)+" 0x51 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + + return + +def device_uninstall(): + global FORCE + + status, output =log_os_system("ls /sys/bus/i2c/devices/1-0077", 0) + + for i in range(0,len(sfp_map)): + target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device" + status, output =log_os_system("echo 0x50 > "+ target, 1) + if status: + print output + if FORCE == 0: + return status + + nodelist = mknod + + for i in range(len(nodelist)): + target = nodelist[-(i+1)] + temp = target.split() + del temp[1] + temp[-1] = temp[-1].replace('new_device', 'delete_device') + status, output = log_os_system(" ".join(temp), 1) + if status: + print output + if FORCE == 0: + return status + + return + +def system_ready(): + if driver_check() == False: + return False + if not device_exist(): + return False + return True + +def do_install(): + print "Checking system...." + if driver_check() == False: + print "No driver, installing...." + status = driver_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" drivers detected...." + if not device_exist(): + print "No device, installing...." + status = device_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" devices detected...." + return + +def do_uninstall(): + print "Checking system...." + if not device_exist(): + print PROJECT_NAME.upper() +" has no device installed...." + else: + print "Removing device...." + status = device_uninstall() + if status: + if FORCE == 0: + return status + + if driver_check()== False : + print PROJECT_NAME.upper() +" has no driver installed...." + else: + print "Removing installed driver...." + status = driver_uninstall() + if status: + if FORCE == 0: + return status + + return + +def devices_info(): + global DEVICE_NO + global ALL_DEVICE + global i2c_bus, hwmon_types + for key in DEVICE_NO: + ALL_DEVICE[key]= {} + for i in range(0,DEVICE_NO[key]): + ALL_DEVICE[key][key+str(i+1)] = [] + + for key in i2c_bus: + buses = i2c_bus[key] + nodes = i2c_nodes[key] + for i in range(0,len(buses)): + for j in range(0,len(nodes)): + if 'fan' == key: + for k in range(0,DEVICE_NO[key]): + node = key+str(k+1) + path = i2c_prefix+ buses[i]+"/fan"+str(k+1)+"_"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + elif 'sfp' == key: + for k in range(0,DEVICE_NO[key]): + node = key+str(k+1) + path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + else: + node = key+str(i+1) + path = i2c_prefix+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + + for key in hwmon_types: + itypes = hwmon_types[key] + nodes = hwmon_nodes[key] + for i in range(0,len(itypes)): + for j in range(0,len(nodes)): + node = key+"_"+itypes[i] + path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][ key+str(i+1)].append(path) + + #show dict all in the order + if DEBUG == True: + for i in sorted(ALL_DEVICE.keys()): + print(i+": ") + for j in sorted(ALL_DEVICE[i].keys()): + print(" "+j) + for k in (ALL_DEVICE[i][j]): + print(" "+" "+k) + return + +def show_eeprom(index): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0] + node = node.replace(node.split("/")[-1], 'sfp_eeprom') + # check if got hexdump command in current environment + ret, log = log_os_system("which hexdump", 0) + ret, log2 = log_os_system("which busybox hexdump", 0) + if len(log): + hex_cmd = 'hexdump' + elif len(log2): + hex_cmd = ' busybox hexdump' + else: + log = 'Failed : no hexdump cmd!!' + logging.info(log) + print log + return 1 + + print node + ":" + ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1) + if ret==0: + print log + else: + print "**********device no found**********" + return + +def set_device(args): + global DEVICE_NO + global ALL_DEVICE + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + + if args[0]=='led': + if int(args[1])>4: + show_set_help() + return + #print ALL_DEVICE['led'] + for i in range(0,len(ALL_DEVICE['led'])): + for k in (ALL_DEVICE['led']['led'+str(i+1)]): + ret, log = log_os_system("echo "+args[1]+" >"+k, 1) + if ret: + return ret + elif args[0]=='fan': + if int(args[1])>100: + show_set_help() + return + #print ALL_DEVICE['fan'] + #fan1~6 is all fine, all fan share same setting + node = ALL_DEVICE['fan'] ['fan1'][0] + node = node.replace(node.split("/")[-1], 'fan_duty_cycle_percentage') + ret, log = log_os_system("cat "+ node, 1) + if ret==0: + print ("Previous fan duty: " + log.strip() +"%") + ret, log = log_os_system("echo "+args[1]+" >"+node, 1) + if ret==0: + print ("Current fan duty: " + args[1] +"%") + return ret + elif args[0]=='sfp': + if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0: + show_set_help() + return + if len(args)<2: + show_set_help() + return + + if int(args[2])>1: + show_set_help() + return + + #print ALL_DEVICE[args[0]] + for i in range(0,len(ALL_DEVICE[args[0]])): + for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]: + if j.find('tx_disable')!= -1: + ret, log = log_os_system("echo "+args[2]+" >"+ j, 1) + if ret: + return ret + + return + +#get digits inside a string. +#Ex: 31 for "sfp31" +def get_value(input): + digit = re.findall('\d+', input) + return int(digit[0]) + +def device_traversal(): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + for i in sorted(ALL_DEVICE.keys()): + print("============================================") + print(i.upper()+": ") + print("============================================") + + for j in sorted(ALL_DEVICE[i].keys(), key=get_value): + print " "+j+":", + for k in (ALL_DEVICE[i][j]): + ret, log = log_os_system("cat "+k, 0) + func = k.split("/")[-1].strip() + func = re.sub(j+'_','',func,1) + func = re.sub(i.lower()+'_','',func,1) + if ret==0: + print func+"="+log+" ", + else: + print func+"="+"X"+" ", + print + print("----------------------------------------------------------------") + + + print + return + +def device_exist(): + ret1, log = log_os_system("ls "+i2c_prefix+"*0077", 0) + ret2, log = log_os_system("ls "+i2c_prefix+"i2c-2", 0) + return not(ret1 or ret2) + +if __name__ == "__main__": + main() diff --git a/platform/nephos/sonic-platform-modules-accton/debian/changelog b/platform/nephos/sonic-platform-modules-accton/debian/changelog new file mode 100755 index 000000000000..49f8f44bca48 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-accton/debian/changelog @@ -0,0 +1,6 @@ +sonic-accton-platform-modules (1.0.0) unstable; urgency=low + + * Add support for AS7116-54X series + + -- developer Wed, 29 Mar 2017 11:00:00 +0800 + diff --git a/platform/nephos/sonic-platform-modules-accton/debian/compat b/platform/nephos/sonic-platform-modules-accton/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-accton/debian/compat @@ -0,0 +1 @@ +9 diff --git a/platform/nephos/sonic-platform-modules-accton/debian/control b/platform/nephos/sonic-platform-modules-accton/debian/control new file mode 100755 index 000000000000..e1a403b3a719 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-accton/debian/control @@ -0,0 +1,11 @@ +Source: sonic-accton-platform-modules +Section: main +Priority: extra +Maintainer: simon.ji@nephosinc.com +Build-Depends: debhelper (>= 8.0.0), bzip2 +Standards-Version: 3.9.3 + +Package: sonic-platform-accton-as7116-54x +Architecture: amd64 +Depends: linux-image-3.16.0-5-amd64 +Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/nephos/sonic-platform-modules-accton/debian/rules b/platform/nephos/sonic-platform-modules-accton/debian/rules new file mode 100755 index 000000000000..cb232bd42425 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-accton/debian/rules @@ -0,0 +1,86 @@ +#!/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 + +PYTHON ?= python2 + +PACKAGE_PRE_NAME := sonic-platform-accton +KVERSION ?= $(shell uname -r) +KERNEL_SRC := /lib/modules/$(KVERSION) +MOD_SRC_DIR:= $(shell pwd) +MODULE_DIRS:= as7116-54x +MODULE_DIR := modules +UTILS_DIR := utils +SERVICE_DIR := service +CLASSES_DIR := classes +CONF_DIR := conf + +%: + dh $@ --with systemd,python2,python3 --buildsystem=pybuild + +clean: + dh_testdir + dh_testroot + dh_clean + +build: + #make modules -C $(KERNEL_SRC)/build M=$(MODULE_SRC) + (for mod in $(MODULE_DIRS); do \ + make modules -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ + $(PYTHON) $${mod}/setup.py build; \ + 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}/usr/local/bin; \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system; \ + cp $(MOD_SRC_DIR)/$${mod}/$(MODULE_DIR)/*.ko debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin/; \ + cp $(MOD_SRC_DIR)/$${mod}/$(SERVICE_DIR)/*.service debian/$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system/; \ + $(PYTHON) $${mod}/setup.py install --root=$(MOD_SRC_DIR)/debian/$(PACKAGE_PRE_NAME)-$${mod} --install-layout=deb; \ + done) + # 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 From c2beed2bbffd0f374d3ef478d01e4ab1029fe9da Mon Sep 17 00:00:00 2001 From: stanepc1 <35956037+stanepc1@users.noreply.github.com> Date: Tue, 7 Aug 2018 23:41:40 +0800 Subject: [PATCH 119/219] [device] Update driver and configuration for ly1200 of MiTAC (#1772) Signed-off-by: Stane Shieh --- .../MiTAC-LY1200-B32H0-C3/buffers.json.j2 | 2 + .../buffers_defaults_t0.j2 | 47 + .../buffers_defaults_t1.j2 | 47 + .../pg_profile_lookup.ini | 17 + .../MiTAC-LY1200-B32H0-C3/qos.json | 167 +++ .../minigraph.xml | 1307 +++-------------- .../broadcom/sonic-platform-modules-mitac | 2 +- 7 files changed, 514 insertions(+), 1075 deletions(-) create mode 100644 device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/buffers.json.j2 create mode 100644 device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/buffers_defaults_t0.j2 create mode 100644 device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/buffers_defaults_t1.j2 create mode 100644 device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/pg_profile_lookup.ini create mode 100644 device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/qos.json diff --git a/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/buffers.json.j2 b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/buffers.json.j2 new file mode 100644 index 000000000000..0b1cb2c541b6 --- /dev/null +++ b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} diff --git a/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/buffers_defaults_t0.j2 b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..3e39d411e8bf --- /dev/null +++ b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/buffers_defaults_t0.j2 @@ -0,0 +1,47 @@ + +{%- set default_cable = '5m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0,128,4) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11213696", + "type": "ingress", + "mode": "dynamic", + "xoff": "3855488" + }, + "egress_lossy_pool": { + "size": "9532224", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "15982720", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "static_th":"3995680" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/buffers_defaults_t1.j2 b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..d9f562f95624 --- /dev/null +++ b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/buffers_defaults_t1.j2 @@ -0,0 +1,47 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0,128,4) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "10443264", + "type": "ingress", + "mode": "dynamic", + "xoff": "4625920" + }, + "egress_lossy_pool": { + "size": "8877440", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "15982720", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "static_th":"3995680" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/pg_profile_lookup.ini b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/pg_profile_lookup.ini new file mode 100644 index 000000000000..3b2a417cebcd --- /dev/null +++ b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 1248 2288 35776 -4 2288 + 25000 5m 1248 2288 53248 -4 2288 + 40000 5m 1248 2288 66560 -4 2288 + 50000 5m 1248 2288 90272 -4 2288 + 100000 5m 1248 2288 165568 -4 2288 + 10000 40m 1248 2288 37024 -4 2288 + 25000 40m 1248 2288 53248 -4 2288 + 40000 40m 1248 2288 71552 -4 2288 + 50000 40m 1248 2288 96096 -4 2288 + 100000 40m 1248 2288 177632 -4 2288 + 10000 300m 1248 2288 46176 -4 2288 + 25000 300m 1248 2288 79040 -4 2288 + 40000 300m 1248 2288 108160 -4 2288 + 50000 300m 1248 2288 141856 -4 2288 + 100000 300m 1248 2288 268736 -4 2288 diff --git a/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/qos.json b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/qos.json new file mode 100644 index 000000000000..b724b48c2c23 --- /dev/null +++ b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/MiTAC-LY1200-B32H0-C3/qos.json @@ -0,0 +1,167 @@ +{ + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "MAP_PFC_PRIORITY_TO_QUEUE": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"3", + "4":"4", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "SCHEDULER": { + "scheduler.0" : { + "type":"DWRR", + "weight": "25" + }, + "scheduler.1" : { + "type":"DWRR", + "weight": "30" + }, + "scheduler.2" : { + "type":"DWRR", + "weight": "20" + } + }, + "PORT_QOS_MAP": { + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable": "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSY" : { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"512000", + "red_min_threshold":"512000", + "yellow_max_threshold":"512000", + "yellow_min_threshold":"512000", + "green_max_threshold": "184320", + "green_min_threshold": "184320" + }, + "AZURE_LOSSLESS" : { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"512000", + "red_min_threshold":"512000", + "yellow_max_threshold":"512000", + "yellow_min_threshold":"512000", + "green_max_threshold": "184320", + "green_min_threshold": "184320" + } + }, + "QUEUE": { + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0-1" : { + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3-4" : { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0" : { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|1" : { + "scheduler" : "[SCHEDULER|scheduler.2]" + } + } +} diff --git a/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/minigraph.xml b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/minigraph.xml index 210eac2fd620..215ac176c5dd 100644 --- a/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/minigraph.xml +++ b/device/mitac/x86_64-mitac_ly1200_b32h0_c3-r0/minigraph.xml @@ -1,1074 +1,233 @@ - - - - - - ARISTA01T0 - 10.0.0.33 - sonic - 10.0.0.32 - 1 - 180 - 60 - - - sonic - 10.0.0.0 - ARISTA01T2 - 10.0.0.1 - 1 - 180 - 60 - - - ARISTA02T0 - 10.0.0.35 - sonic - 10.0.0.34 - 1 - 180 - 60 - - - sonic - 10.0.0.2 - ARISTA02T2 - 10.0.0.3 - 1 - 180 - 60 - - - ARISTA03T0 - 10.0.0.37 - sonic - 10.0.0.36 - 1 - 180 - 60 - - - sonic - 10.0.0.4 - ARISTA03T2 - 10.0.0.5 - 1 - 180 - 60 - - - ARISTA04T0 - 10.0.0.39 - sonic - 10.0.0.38 - 1 - 180 - 60 - - - sonic - 10.0.0.6 - ARISTA04T2 - 10.0.0.7 - 1 - 180 - 60 - - - ARISTA05T0 - 10.0.0.41 - sonic - 10.0.0.40 - 1 - 180 - 60 - - - sonic - 10.0.0.8 - ARISTA05T2 - 10.0.0.9 - 1 - 180 - 60 - - - ARISTA06T0 - 10.0.0.43 - sonic - 10.0.0.42 - 1 - 180 - 60 - - - sonic - 10.0.0.10 - ARISTA06T2 - 10.0.0.11 - 1 - 180 - 60 - - - ARISTA07T0 - 10.0.0.45 - sonic - 10.0.0.44 - 1 - 180 - 60 - - - sonic - 10.0.0.12 - ARISTA07T2 - 10.0.0.13 - 1 - 180 - 60 - - - ARISTA08T0 - 10.0.0.47 - sonic - 10.0.0.46 - 1 - 180 - 60 - - - sonic - 10.0.0.14 - ARISTA08T2 - 10.0.0.15 - 1 - 180 - 60 - - - ARISTA09T0 - 10.0.0.49 - sonic - 10.0.0.48 - 1 - 180 - 60 - - - sonic - 10.0.0.16 - ARISTA09T2 - 10.0.0.17 - 1 - 180 - 60 - - - ARISTA10T0 - 10.0.0.51 - sonic - 10.0.0.50 - 1 - 180 - 60 - - - sonic - 10.0.0.18 - ARISTA10T2 - 10.0.0.19 - 1 - 180 - 60 - - - ARISTA11T0 - 10.0.0.53 - sonic - 10.0.0.52 - 1 - 180 - 60 - - - sonic - 10.0.0.20 - ARISTA11T2 - 10.0.0.21 - 1 - 180 - 60 - - - ARISTA12T0 - 10.0.0.55 - sonic - 10.0.0.54 - 1 - 180 - 60 - - - sonic - 10.0.0.22 - ARISTA12T2 - 10.0.0.23 - 1 - 180 - 60 - - - ARISTA13T0 - 10.0.0.57 - sonic - 10.0.0.56 - 1 - 180 - 60 - - - sonic - 10.0.0.24 - ARISTA13T2 - 10.0.0.25 - 1 - 180 - 60 - - - ARISTA14T0 - 10.0.0.59 - sonic - 10.0.0.58 - 1 - 180 - 60 - - - sonic - 10.0.0.26 - ARISTA14T2 - 10.0.0.27 - 1 - 180 - 60 - - - ARISTA15T0 - 10.0.0.61 - sonic - 10.0.0.60 - 1 - 180 - 60 - - - sonic - 10.0.0.28 - ARISTA15T2 - 10.0.0.29 - 1 - 180 - 60 - - - ARISTA16T0 - 10.0.0.63 - sonic - 10.0.0.62 - 1 - 180 - 60 - - - sonic - 10.0.0.30 - ARISTA16T2 - 10.0.0.31 - 1 - 180 - 60 - - - - - 65100 - sonic - - -
10.0.0.33
- - -
- -
10.0.0.1
- - -
- -
10.0.0.35
- - -
- -
10.0.0.3
- - -
- -
10.0.0.37
- - -
- -
10.0.0.5
- - -
- -
10.0.0.39
- - -
- -
10.0.0.7
- - -
- -
10.0.0.41
- - -
- -
10.0.0.9
- - -
- -
10.0.0.43
- - -
- -
10.0.0.11
- - -
- -
10.0.0.45
- - -
- -
10.0.0.13
- - -
- -
10.0.0.47
- - -
- -
10.0.0.15
- - -
- -
10.0.0.49
- - -
- -
10.0.0.17
- - -
- -
10.0.0.51
- - -
- -
10.0.0.19
- - -
- -
10.0.0.53
- - -
- -
10.0.0.21
- - -
- -
10.0.0.55
- - -
- -
10.0.0.23
- - -
- -
10.0.0.57
- - -
- -
10.0.0.25
- - -
- -
10.0.0.59
- - -
- -
10.0.0.27
- - -
- -
10.0.0.61
- - -
- -
10.0.0.29
- - -
- -
10.0.0.63
- - -
- -
10.0.0.31
- - -
-
- -
- - 64001 - ARISTA01T0 - - - - 65200 - ARISTA01T2 - - - - 64002 - ARISTA02T0 - - - - 65200 - ARISTA02T2 - - - - 64003 - ARISTA03T0 - - - - 65200 - ARISTA03T2 - - - - 64004 - ARISTA04T0 - - - - 65200 - ARISTA04T2 - - - - 64005 - ARISTA05T0 - - - - 65200 - ARISTA05T2 - - - - 64006 - ARISTA06T0 - - - - 65200 - ARISTA06T2 - - - - 64007 - ARISTA07T0 - - - - 65200 - ARISTA07T2 - - - - 64008 - ARISTA08T0 - - - - 65200 - ARISTA08T2 - - - - 64009 - ARISTA09T0 - - - - 65200 - ARISTA09T2 - - - - 64010 - ARISTA10T0 - - - - 65200 - ARISTA10T2 - - - - 64011 - ARISTA11T0 - - - - 65200 - ARISTA11T2 - - - - 64012 - ARISTA12T0 - - - - 65200 - ARISTA12T2 - - - - 64013 - ARISTA13T0 - - - - 65200 - ARISTA13T2 - - - - 64014 - ARISTA14T0 - - - - 65200 - ARISTA14T2 - - - - 64015 - ARISTA15T0 - - - - 65200 - ARISTA15T2 - - - - 64016 - ARISTA16T0 - - - - 65200 - ARISTA16T2 - - -
-
- - - - - - HostIP - Loopback0 - - 10.1.0.32/32 - - 10.1.0.32/32 - - - - - - - - sonic - - - - - - Ethernet0 - 10.0.0.0/31 - - - - Ethernet4 - 10.0.0.2/31 - - - - Ethernet8 - 10.0.0.4/31 - - - - Ethernet12 - 10.0.0.6/31 - - - - Ethernet16 - 10.0.0.8/31 - - - - Ethernet20 - 10.0.0.10/31 - - - - Ethernet24 - 10.0.0.12/31 - - - - Ethernet28 - 10.0.0.14/31 - - - - Ethernet32 - 10.0.0.16/31 - - - - Ethernet36 - 10.0.0.18/31 - - - - Ethernet40 - 10.0.0.20/31 - - - - Ethernet44 - 10.0.0.22/31 - - - - Ethernet48 - 10.0.0.24/31 - - - - Ethernet52 - 10.0.0.26/31 - - - - Ethernet56 - 10.0.0.28/31 - - - - Ethernet60 - 10.0.0.30/31 - - - - Ethernet64 - 10.0.0.32/31 - - - - Ethernet68 - 10.0.0.34/31 - - - - Ethernet72 - 10.0.0.36/31 - - - - Ethernet76 - 10.0.0.38/31 - - - - Ethernet80 - 10.0.0.40/31 - - - - Ethernet84 - 10.0.0.42/31 - - - - Ethernet88 - 10.0.0.44/31 - - - - Ethernet92 - 10.0.0.46/31 - - - - Ethernet96 - 10.0.0.48/31 - - - - Ethernet100 - 10.0.0.50/31 - - - - Ethernet104 - 10.0.0.52/31 - - - - Ethernet108 - 10.0.0.54/31 - - - - Ethernet112 - 10.0.0.56/31 - - - - Ethernet116 - 10.0.0.58/31 - - - - Ethernet120 - 10.0.0.60/31 - - - - Ethernet124 - 10.0.0.62/31 - - - - - - - - - - - - DeviceInterfaceLink - sonic - Ethernet0 - ARISTA01T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet4 - ARISTA02T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet8 - ARISTA03T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet12 - ARISTA04T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet16 - ARISTA05T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet20 - ARISTA06T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet24 - ARISTA07T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet28 - ARISTA08T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet32 - ARISTA09T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet36 - ARISTA10T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet40 - ARISTA11T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet44 - ARISTA12T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet48 - ARISTA13T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet52 - ARISTA14T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet56 - ARISTA15T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet60 - ARISTA16T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet64 - ARISTA01T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet68 - ARISTA02T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet72 - ARISTA03T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet76 - ARISTA04T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet80 - ARISTA05T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet84 - ARISTA06T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet88 - ARISTA07T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet92 - ARISTA08T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet96 - ARISTA09T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet100 - ARISTA10T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet104 - ARISTA11T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet108 - ARISTA12T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet112 - ARISTA13T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet116 - ARISTA14T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet120 - ARISTA15T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet124 - ARISTA16T0 - Ethernet1 - - - - - sonic - MiTAC-LY1200-B32H0-C3 - - - - - - - sonic - - - DhcpResources - - - - - NtpResources - - 0.debian.pool.ntp.org;1.debian.pool.ntp.org;2.debian.pool.ntp.org;3.debian.pool.ntp.org - - - SyslogResources - - - - - - - - - sonic - MiTAC-LY1200-B32H0-C3 -
+ + + + + + + + + + + + + + HostIP + Loopback0 + + 10.1.0.32/32 + + 10.1.0.32/32 + + + + + + + + sonic + + + + + + Ethernet0 + 10.0.0.0/31 + + + + Ethernet4 + 10.0.0.2/31 + + + + Ethernet8 + 10.0.0.4/31 + + + + Ethernet12 + 10.0.0.6/31 + + + + Ethernet16 + 10.0.0.8/31 + + + + Ethernet20 + 10.0.0.10/31 + + + + Ethernet24 + 10.0.0.12/31 + + + + Ethernet28 + 10.0.0.14/31 + + + + Ethernet32 + 10.0.0.16/31 + + + + Ethernet36 + 10.0.0.18/31 + + + + Ethernet40 + 10.0.0.20/31 + + + + Ethernet44 + 10.0.0.22/31 + + + + Ethernet48 + 10.0.0.24/31 + + + + Ethernet52 + 10.0.0.26/31 + + + + Ethernet56 + 10.0.0.28/31 + + + + Ethernet60 + 10.0.0.30/31 + + + + Ethernet64 + 10.0.0.32/31 + + + + Ethernet68 + 10.0.0.34/31 + + + + Ethernet72 + 10.0.0.36/31 + + + + Ethernet76 + 10.0.0.38/31 + + + + Ethernet80 + 10.0.0.40/31 + + + + Ethernet84 + 10.0.0.42/31 + + + + Ethernet88 + 10.0.0.44/31 + + + + Ethernet92 + 10.0.0.46/31 + + + + Ethernet96 + 10.0.0.48/31 + + + + Ethernet100 + 10.0.0.50/31 + + + + Ethernet104 + 10.0.0.52/31 + + + + Ethernet108 + 10.0.0.54/31 + + + + Ethernet112 + 10.0.0.56/31 + + + + Ethernet116 + 10.0.0.58/31 + + + + Ethernet120 + 10.0.0.60/31 + + + + Ethernet124 + 10.0.0.62/31 + + + + + + + + + + + + sonic + MiTAC-LY1200-B32H0-C3 + + + + + + + sonic + + + DhcpResources + + + + + NtpResources + + 0.debian.pool.ntp.org;1.debian.pool.ntp.org;2.debian.pool.ntp.org;3.debian.pool.ntp.org + + + SyslogResources + + + + + + + + + sonic + MiTAC-LY1200-B32H0-C3 + \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-mitac b/platform/broadcom/sonic-platform-modules-mitac index db8e7de1b41a..5b1ce26b7688 160000 --- a/platform/broadcom/sonic-platform-modules-mitac +++ b/platform/broadcom/sonic-platform-modules-mitac @@ -1 +1 @@ -Subproject commit db8e7de1b41a407028ee2c4361177bd7b52f9431 +Subproject commit 5b1ce26b76880979de5bbbb54140a750b2809367 From 355246151a83ecdabdd7332959c8809ee42add4c Mon Sep 17 00:00:00 2001 From: Taoyu Li Date: Tue, 7 Aug 2018 08:43:08 -0700 Subject: [PATCH 120/219] [minigraph.py] add support to parse deployment id of neighbor devices (#1890) * [minigraph.py] add support to parse deployment id of neighbor devices * Add unitest * Fix function name --- src/sonic-config-engine/minigraph.py | 11 ++++-- .../tests/simple-sample-graph-case.xml | 36 +++++++++++-------- .../tests/test_minigraph_case.py | 5 +++ 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 14bf34a34b05..2b6b3d9d57e7 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -41,6 +41,7 @@ def parse_device(device): d_type = None # don't shadow type() hwsku = None name = None + deployment_id = None if str(QName(ns3, "type")) in device.attrib: d_type = device.attrib[str(QName(ns3, "type"))] @@ -53,7 +54,9 @@ def parse_device(device): name = node.text elif node.tag == str(QName(ns, "HwSku")): hwsku = node.text - return (lo_prefix, mgmt_prefix, name, hwsku, d_type) + elif node.tag == str(QName(ns, "DeploymentId")): + deployment_id = node.text + return (lo_prefix, mgmt_prefix, name, hwsku, d_type, deployment_id) def parse_png(png, hname): neighbors = {} @@ -92,8 +95,10 @@ def parse_png(png, hname): if child.tag == str(QName(ns, "Devices")): for device in child.findall(str(QName(ns, "Device"))): - (lo_prefix, mgmt_prefix, name, hwsku, d_type) = parse_device(device) + (lo_prefix, mgmt_prefix, name, hwsku, d_type, deployment_id) = parse_device(device) device_data = {'lo_addr': lo_prefix, 'type': d_type, 'mgmt_addr': mgmt_prefix, 'hwsku': hwsku } + if deployment_id: + device_data['deployment_id'] = deployment_id devices[name] = device_data if child.tag == str(QName(ns, "DeviceInterfaceLinks")): @@ -530,7 +535,7 @@ def parse_xml(filename, platform=None, port_config_file=None): def parse_device_desc_xml(filename): root = ET.parse(filename).getroot() - (lo_prefix, mgmt_prefix, hostname, hwsku, d_type) = parse_device(root) + (lo_prefix, mgmt_prefix, hostname, hwsku, d_type, _) = parse_device(root) results = {} results['DEVICE_METADATA'] = {'localhost': { diff --git a/src/sonic-config-engine/tests/simple-sample-graph-case.xml b/src/sonic-config-engine/tests/simple-sample-graph-case.xml index 2d2f08f4d0d2..722d50f5ecd6 100644 --- a/src/sonic-config-engine/tests/simple-sample-graph-case.xml +++ b/src/sonic-config-engine/tests/simple-sample-graph-case.xml @@ -181,27 +181,33 @@ - + + + DeviceInterfaceLink + true + 10000 + switch-t0 + fortyGigE0/0 + switch-01t1 + port1 + + switch-t0 Force10-S6000 - ARISTA01T1 - Arista - - - ARISTA02T1 - Arista - - - ARISTA03T1 - Arista - - - ARISTA04T1 - Arista + switch-01t1 +
+ 10.1.0.186/32 +
+ 2 + + + 10.7.0.196/26 + + Force10-S6000
diff --git a/src/sonic-config-engine/tests/test_minigraph_case.py b/src/sonic-config-engine/tests/test_minigraph_case.py index 754bdae799f4..4ceccb32a686 100644 --- a/src/sonic-config-engine/tests/test_minigraph_case.py +++ b/src/sonic-config-engine/tests/test_minigraph_case.py @@ -94,6 +94,11 @@ def test_minigraph_deployment_id(self): output = self.run_script(argument) self.assertEqual(output.strip(), "1") + def test_minigraph_neighbor_metadata(self): + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "DEVICE_NEIGHBOR_METADATA"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "{'switch-01t1': {'lo_addr': '10.1.0.186/32', 'mgmt_addr': '10.7.0.196/26', 'hwsku': 'Force10-S6000', 'type': 'LeafRouter', 'deployment_id': '2'}}") + def test_metadata_everflow(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "MIRROR_SESSION"' output = self.run_script(argument) From 4b73fabe15b796ade688305203fe4808f16aa00b Mon Sep 17 00:00:00 2001 From: simonJi2018 <37395146+simonJi2018@users.noreply.github.com> Date: Sun, 12 Aug 2018 17:31:07 +0800 Subject: [PATCH 121/219] 201803: update submodule sonic-platform-modules-ingrasys to 796169 (#1911) * add new device accton 7116 support for sonic 201803 branch * update submodule sonic-platform-modules-ingrasys to 796169 --- platform/nephos/sonic-platform-modules-ingrasys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/nephos/sonic-platform-modules-ingrasys b/platform/nephos/sonic-platform-modules-ingrasys index 7181a00e42c2..796169e43aee 160000 --- a/platform/nephos/sonic-platform-modules-ingrasys +++ b/platform/nephos/sonic-platform-modules-ingrasys @@ -1 +1 @@ -Subproject commit 7181a00e42c292472e1327b9890bdcfac810e407 +Subproject commit 796169e43aee944fdf7b549d04cb181117e0fb89 From bf26a9a22c94a49b90fcc5e856c0a6ee01abaa28 Mon Sep 17 00:00:00 2001 From: yangbashuang <37615000+yangbashuang@users.noreply.github.com> Date: Sun, 12 Aug 2018 17:36:18 +0800 Subject: [PATCH 122/219] [platform && device]update centec e582 platform device config files and drivers, update sai to 1.2.4 on branch 201803 (#1703) * update centec platform drivers and sai * update centec platform drivers and sai --- .../E582-48x6q/buffers.json.j2 | 70 + .../E582-48x6q/pg_profile_lookup.ini | 21 + .../E582-48x6q/port_config.ini | 86 +- .../E582-48x6q/qos.json | 133 ++ .../E582-48x6q/sai.profile | 2 + .../x86_64-centec_e582_48x6q-r0/fancontrol | 11 + .../installer.conf | 1 + .../x86_64-centec_e582_48x6q-r0/minigraph.xml | 1049 ---------- .../plugins/eeprom.py | 31 + .../plugins/led_control.py | 153 ++ .../plugins/psuutil.py | 74 + .../plugins/sfputil.py | 160 ++ dockers/docker-orchagent/orchagent.sh | 5 + platform/centec/one-image.mk | 2 +- .../centec/platform-modules-centec-e582.mk | 19 + platform/centec/rules.mk | 2 +- platform/centec/sai.mk | 5 - platform/centec/sdk.mk | 7 +- .../48x2q4z/cfg/48x2q4z-modules.conf | 17 + .../48x2q4z/modules/Makefile | 2 + .../48x2q4z/modules/centec_at24c64.c | 657 ++++++ .../modules/centec_e582_48x2q4z_platform.c | 142 ++ .../48x2q4z/modules/dal_kernel.c | 1814 ++++++++++++++++ .../48x2q4z/modules/dal_kernel.h | 170 ++ .../48x2q4z/modules/dal_mpool.c | 343 ++++ .../48x2q4z/modules/dal_mpool.h | 71 + .../48x2q4z/scripts/48x2q4z_platform.sh | 36 + .../48x6q/cfg/48x6q-modules.conf | 14 + .../48x6q/cfg/config_db.json | 303 +++ .../48x6q/cfg/config_db_l2l3.json | 610 ++++++ .../48x6q/cfg/minigraph.xml | 38 + .../48x6q/modules/Makefile | 2 + .../48x6q/modules/centec_at24c64.c | 658 ++++++ .../modules/centec_e582_48x6q_platform.c | 1380 +++++++++++++ .../48x6q/modules/dal_kernel.c | 1822 +++++++++++++++++ .../48x6q/modules/dal_kernel.h | 170 ++ .../48x6q/modules/dal_mpool.c | 343 ++++ .../48x6q/modules/dal_mpool.h | 71 + .../48x6q/scripts/48x6q_platform.sh | 62 + .../48x6q/scripts/48x6q_platform_monitor.py | 217 ++ .../sonic-platform-modules-e582/LICENSE | 15 + .../sonic-platform-modules-e582/README.md | 1 + .../debian/changelog | 11 + .../sonic-platform-modules-e582/debian/compat | 1 + .../debian/control | 17 + .../debian/platform-modules-e582-48x2q4z.init | 38 + .../platform-modules-e582-48x2q4z.install | 2 + .../debian/platform-modules-e582-48x6q.init | 38 + .../platform-modules-e582-48x6q.install | 6 + .../sonic-platform-modules-e582/debian/rules | 35 + 50 files changed, 9846 insertions(+), 1091 deletions(-) create mode 100644 device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/buffers.json.j2 create mode 100644 device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/pg_profile_lookup.ini create mode 100644 device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/qos.json create mode 100644 device/centec/x86_64-centec_e582_48x6q-r0/fancontrol delete mode 100644 device/centec/x86_64-centec_e582_48x6q-r0/minigraph.xml create mode 100644 device/centec/x86_64-centec_e582_48x6q-r0/plugins/eeprom.py create mode 100644 device/centec/x86_64-centec_e582_48x6q-r0/plugins/led_control.py create mode 100644 device/centec/x86_64-centec_e582_48x6q-r0/plugins/psuutil.py create mode 100644 device/centec/x86_64-centec_e582_48x6q-r0/plugins/sfputil.py create mode 100644 platform/centec/platform-modules-centec-e582.mk delete mode 100644 platform/centec/sai.mk create mode 100644 platform/centec/sonic-platform-modules-e582/48x2q4z/cfg/48x2q4z-modules.conf create mode 100644 platform/centec/sonic-platform-modules-e582/48x2q4z/modules/Makefile create mode 100644 platform/centec/sonic-platform-modules-e582/48x2q4z/modules/centec_at24c64.c create mode 100644 platform/centec/sonic-platform-modules-e582/48x2q4z/modules/centec_e582_48x2q4z_platform.c create mode 100644 platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_kernel.c create mode 100644 platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_kernel.h create mode 100644 platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_mpool.c create mode 100644 platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_mpool.h create mode 100755 platform/centec/sonic-platform-modules-e582/48x2q4z/scripts/48x2q4z_platform.sh create mode 100644 platform/centec/sonic-platform-modules-e582/48x6q/cfg/48x6q-modules.conf create mode 100644 platform/centec/sonic-platform-modules-e582/48x6q/cfg/config_db.json create mode 100644 platform/centec/sonic-platform-modules-e582/48x6q/cfg/config_db_l2l3.json create mode 100644 platform/centec/sonic-platform-modules-e582/48x6q/cfg/minigraph.xml create mode 100644 platform/centec/sonic-platform-modules-e582/48x6q/modules/Makefile create mode 100644 platform/centec/sonic-platform-modules-e582/48x6q/modules/centec_at24c64.c create mode 100644 platform/centec/sonic-platform-modules-e582/48x6q/modules/centec_e582_48x6q_platform.c create mode 100644 platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_kernel.c create mode 100644 platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_kernel.h create mode 100644 platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_mpool.c create mode 100644 platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_mpool.h create mode 100755 platform/centec/sonic-platform-modules-e582/48x6q/scripts/48x6q_platform.sh create mode 100644 platform/centec/sonic-platform-modules-e582/48x6q/scripts/48x6q_platform_monitor.py create mode 100644 platform/centec/sonic-platform-modules-e582/LICENSE create mode 100644 platform/centec/sonic-platform-modules-e582/README.md create mode 100644 platform/centec/sonic-platform-modules-e582/debian/changelog create mode 100644 platform/centec/sonic-platform-modules-e582/debian/compat create mode 100644 platform/centec/sonic-platform-modules-e582/debian/control create mode 100755 platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x2q4z.init create mode 100644 platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x2q4z.install create mode 100755 platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x6q.init create mode 100644 platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x6q.install create mode 100755 platform/centec/sonic-platform-modules-e582/debian/rules diff --git a/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/buffers.json.j2 b/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/buffers.json.j2 new file mode 100644 index 000000000000..08e21e428b6c --- /dev/null +++ b/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/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_e582_48x6q-r0/E582-48x6q/pg_profile_lookup.ini b/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/pg_profile_lookup.ini new file mode 100644 index 000000000000..a65244e69b5b --- /dev/null +++ b/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/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_e582_48x6q-r0/E582-48x6q/port_config.ini b/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/port_config.ini index b9a831f22e8d..95190282b25d 100644 --- a/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/port_config.ini +++ b/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/port_config.ini @@ -1,33 +1,55 @@ # name lanes -Ethernet0 1 -Ethernet4 2 -Ethernet8 3 -Ethernet12 4 -Ethernet16 5 -Ethernet20 6 -Ethernet24 7 -Ethernet28 8 -Ethernet32 9 -Ethernet36 10 -Ethernet40 11 -Ethernet44 12 -Ethernet48 13 -Ethernet52 14 -Ethernet56 15 -Ethernet60 16 -Ethernet64 17 -Ethernet68 18 -Ethernet72 19 -Ethernet76 20 -Ethernet80 21 -Ethernet84 22 -Ethernet88 23 -Ethernet92 24 -Ethernet96 25 -Ethernet100 26 -Ethernet104 27 -Ethernet108 28 -Ethernet112 29 -Ethernet116 30 -Ethernet120 31 -Ethernet124 32 +Ethernet1 4 +Ethernet2 5 +Ethernet3 6 +Ethernet4 8 +Ethernet5 9 +Ethernet6 10 +Ethernet7 12 +Ethernet8 13 +Ethernet9 14 +Ethernet10 16 +Ethernet11 17 +Ethernet12 18 +Ethernet13 20 +Ethernet14 21 +Ethernet15 22 +Ethernet16 24 +Ethernet17 25 +Ethernet18 26 +Ethernet19 28 +Ethernet20 30 +Ethernet21 31 +Ethernet22 32 +Ethernet23 34 +Ethernet24 35 +Ethernet25 40 +Ethernet26 41 +Ethernet27 43 +Ethernet28 36 +Ethernet29 37 +Ethernet30 39 +Ethernet31 44 +Ethernet32 45 +Ethernet33 46 +Ethernet34 47 +Ethernet35 80 +Ethernet36 81 +Ethernet37 82 +Ethernet38 88 +Ethernet39 89 +Ethernet40 90 +Ethernet41 84 +Ethernet42 85 +Ethernet43 86 +Ethernet44 87 +Ethernet45 92 +Ethernet46 93 +Ethernet47 94 +Ethernet48 95 +Ethernet49 52,53,54,55 +Ethernet50 56,57,58,59 +Ethernet51 60,61,62,63 +Ethernet52 68,69,70,71 +Ethernet53 72,73,74,75 +Ethernet54 76,77,78,79 diff --git a/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/qos.json b/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/qos.json new file mode 100644 index 000000000000..b9dc80abb07f --- /dev/null +++ b/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/qos.json @@ -0,0 +1,133 @@ +{ + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"0", + "4":"0", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"1", + "10":"1", + "11":"1", + "12":"1", + "13":"1", + "14":"1", + "15":"1", + "16":"2", + "17":"2", + "18":"2", + "19":"2", + "20":"2", + "21":"2", + "22":"2", + "23":"2", + "24":"3", + "25":"3", + "26":"3", + "27":"3", + "28":"3", + "29":"3", + "30":"3", + "31":"3", + "32":"4", + "33":"4", + "34":"4", + "35":"4", + "36":"4", + "37":"4", + "38":"4", + "39":"4", + "40":"5", + "41":"5", + "42":"5", + "43":"5", + "44":"5", + "45":"5", + "46":"5", + "47":"5", + "48":"6", + "49":"6", + "50":"6", + "51":"6", + "52":"6", + "53":"6", + "54":"6", + "55":"6", + "56":"7", + "57":"7", + "58":"7", + "59":"7", + "60":"7", + "61":"7", + "62":"7", + "63":"7" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type":"DWRR", + "weight": "25" + }, + "scheduler.1": { + "type":"DWRR", + "weight": "30" + }, + "scheduler.2": { + "type":"DWRR", + "weight": "20" + } + }, + "PORT_QOS_MAP": { + "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "pfc_enable": "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSY": { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "red_max_threshold":"32760", + "red_min_threshold":"4095", + "yellow_max_threshold":"32760", + "yellow_min_threshold":"4095", + "green_max_threshold": "32760", + "green_min_threshold": "4095" + }, + "AZURE_LOSSLESS": { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "red_max_threshold":"32760", + "red_min_threshold":"4095", + "yellow_max_threshold":"32760", + "yellow_min_threshold":"4095", + "green_max_threshold": "32760", + "green_min_threshold": "4095" + } + }, + "QUEUE": { + "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|0-2": { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, + "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|5-7": { + "scheduler" : "[SCHEDULER|scheduler.2]" + }, + "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|0-2": { + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]" + }, + + "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|5-7": { + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]" + }, + "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|3-4": { + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" + } + } +} + + diff --git a/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/sai.profile b/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/sai.profile index 2eb3ce5f612b..9842dcf57fac 100644 --- a/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/sai.profile +++ b/device/centec/x86_64-centec_e582_48x6q-r0/E582-48x6q/sai.profile @@ -1 +1,3 @@ BOARD_CONFIG_FILE_PATH=/etc/centec/E582-48x6q.json +SAI_INIT_CONFIG_FILE=/etc/centec/E582-48x6q-chip-profile.txt +SAI_HW_PORT_PROFILE_ID_CONFIG_FILE=/etc/centec/E582-48x6q-datapath-cfg.txt diff --git a/device/centec/x86_64-centec_e582_48x6q-r0/fancontrol b/device/centec/x86_64-centec_e582_48x6q-r0/fancontrol new file mode 100644 index 000000000000..886a4bc6c030 --- /dev/null +++ b/device/centec/x86_64-centec_e582_48x6q-r0/fancontrol @@ -0,0 +1,11 @@ +# Configuration file generated by pwmconfig, changes will be lost +INTERVAL=10 +DEVPATH=hwmon0= hwmon5=devices/pci0000:00/0000:00:1f.3/i2c-0/i2c-15/15-002f +DEVNAME=hwmon0=acpitz hwmon5=adt7470 +FCTEMPS=hwmon5/device/pwm4=hwmon0/temp1_input hwmon5/device/pwm3=hwmon0/temp1_input hwmon5/device/pwm2=hwmon0/temp1_input hwmon5/device/pwm1=hwmon0/temp1_input +FCFANS=hwmon5/device/pwm4=hwmon5/device/fan4_input hwmon5/device/pwm3=hwmon5/device/fan3_input hwmon5/device/pwm2=hwmon5/device/fan2_input hwmon5/device/pwm1=hwmon5/device/fan1_input +MINTEMP=hwmon5/device/pwm4=20 hwmon5/device/pwm3=20 hwmon5/device/pwm2=20 hwmon5/device/pwm1=20 +MAXTEMP=hwmon5/device/pwm4=60 hwmon5/device/pwm3=60 hwmon5/device/pwm2=60 hwmon5/device/pwm1=60 +MINSTART=hwmon5/device/pwm4=150 hwmon5/device/pwm3=12 hwmon5/device/pwm2=12 hwmon5/device/pwm1=150 +MINSTOP=hwmon5/device/pwm4=0 hwmon5/device/pwm3=12 hwmon5/device/pwm2=12 hwmon5/device/pwm1=0 +MAXPWM= hwmon5/device/pwm4=150 diff --git a/device/centec/x86_64-centec_e582_48x6q-r0/installer.conf b/device/centec/x86_64-centec_e582_48x6q-r0/installer.conf index 5e62742c11bf..7d60bf73d366 100644 --- a/device/centec/x86_64-centec_e582_48x6q-r0/installer.conf +++ b/device/centec/x86_64-centec_e582_48x6q-r0/installer.conf @@ -1 +1,2 @@ CONSOLE_SPEED=115200 +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="acpi_enforce_resources=no" diff --git a/device/centec/x86_64-centec_e582_48x6q-r0/minigraph.xml b/device/centec/x86_64-centec_e582_48x6q-r0/minigraph.xml deleted file mode 100644 index 950c52a64134..000000000000 --- a/device/centec/x86_64-centec_e582_48x6q-r0/minigraph.xml +++ /dev/null @@ -1,1049 +0,0 @@ - - - - - - ARISTA01T0 - 10.0.0.33 - sonic - 10.0.0.32 - 1 - 180 - 60 - - - sonic - 10.0.0.0 - ARISTA01T2 - 10.0.0.1 - 1 - 180 - 60 - - - ARISTA02T0 - 10.0.0.35 - sonic - 10.0.0.34 - 1 - 180 - 60 - - - sonic - 10.0.0.2 - ARISTA02T2 - 10.0.0.3 - 1 - 180 - 60 - - - ARISTA03T0 - 10.0.0.37 - sonic - 10.0.0.36 - 1 - 180 - 60 - - - sonic - 10.0.0.4 - ARISTA03T2 - 10.0.0.5 - 1 - 180 - 60 - - - ARISTA04T0 - 10.0.0.39 - sonic - 10.0.0.38 - 1 - 180 - 60 - - - sonic - 10.0.0.6 - ARISTA04T2 - 10.0.0.7 - 1 - 180 - 60 - - - ARISTA05T0 - 10.0.0.41 - sonic - 10.0.0.40 - 1 - 180 - 60 - - - sonic - 10.0.0.8 - ARISTA05T2 - 10.0.0.9 - 1 - 180 - 60 - - - ARISTA06T0 - 10.0.0.43 - sonic - 10.0.0.42 - 1 - 180 - 60 - - - sonic - 10.0.0.10 - ARISTA06T2 - 10.0.0.11 - 1 - 180 - 60 - - - ARISTA07T0 - 10.0.0.45 - sonic - 10.0.0.44 - 1 - 180 - 60 - - - sonic - 10.0.0.12 - ARISTA07T2 - 10.0.0.13 - 1 - 180 - 60 - - - ARISTA08T0 - 10.0.0.47 - sonic - 10.0.0.46 - 1 - 180 - 60 - - - sonic - 10.0.0.14 - ARISTA08T2 - 10.0.0.15 - 1 - 180 - 60 - - - ARISTA09T0 - 10.0.0.49 - sonic - 10.0.0.48 - 1 - 180 - 60 - - - sonic - 10.0.0.16 - ARISTA09T2 - 10.0.0.17 - 1 - 180 - 60 - - - ARISTA10T0 - 10.0.0.51 - sonic - 10.0.0.50 - 1 - 180 - 60 - - - sonic - 10.0.0.18 - ARISTA10T2 - 10.0.0.19 - 1 - 180 - 60 - - - ARISTA11T0 - 10.0.0.53 - sonic - 10.0.0.52 - 1 - 180 - 60 - - - sonic - 10.0.0.20 - ARISTA11T2 - 10.0.0.21 - 1 - 180 - 60 - - - ARISTA12T0 - 10.0.0.55 - sonic - 10.0.0.54 - 1 - 180 - 60 - - - sonic - 10.0.0.22 - ARISTA12T2 - 10.0.0.23 - 1 - 180 - 60 - - - ARISTA13T0 - 10.0.0.57 - sonic - 10.0.0.56 - 1 - 180 - 60 - - - sonic - 10.0.0.24 - ARISTA13T2 - 10.0.0.25 - 1 - 180 - 60 - - - ARISTA14T0 - 10.0.0.59 - sonic - 10.0.0.58 - 1 - 180 - 60 - - - sonic - 10.0.0.26 - ARISTA14T2 - 10.0.0.27 - 1 - 180 - 60 - - - ARISTA15T0 - 10.0.0.61 - sonic - 10.0.0.60 - 1 - 180 - 60 - - - sonic - 10.0.0.28 - ARISTA15T2 - 10.0.0.29 - 1 - 180 - 60 - - - ARISTA16T0 - 10.0.0.63 - sonic - 10.0.0.62 - 1 - 180 - 60 - - - sonic - 10.0.0.30 - ARISTA16T2 - 10.0.0.31 - 1 - 180 - 60 - - - - - 65100 - sonic - - -
10.0.0.33
- - -
- -
10.0.0.1
- - -
- -
10.0.0.35
- - -
- -
10.0.0.3
- - -
- -
10.0.0.37
- - -
- -
10.0.0.5
- - -
- -
10.0.0.39
- - -
- -
10.0.0.7
- - -
- -
10.0.0.41
- - -
- -
10.0.0.9
- - -
- -
10.0.0.43
- - -
- -
10.0.0.11
- - -
- -
10.0.0.45
- - -
- -
10.0.0.13
- - -
- -
10.0.0.47
- - -
- -
10.0.0.15
- - -
- -
10.0.0.49
- - -
- -
10.0.0.17
- - -
- -
10.0.0.51
- - -
- -
10.0.0.19
- - -
- -
10.0.0.53
- - -
- -
10.0.0.21
- - -
- -
10.0.0.55
- - -
- -
10.0.0.23
- - -
- -
10.0.0.57
- - -
- -
10.0.0.25
- - -
- -
10.0.0.59
- - -
- -
10.0.0.27
- - -
- -
10.0.0.61
- - -
- -
10.0.0.29
- - -
- -
10.0.0.63
- - -
- -
10.0.0.31
- - -
-
- -
- - 64001 - ARISTA01T0 - - - - 65200 - ARISTA01T2 - - - - 64002 - ARISTA02T0 - - - - 65200 - ARISTA02T2 - - - - 64003 - ARISTA03T0 - - - - 65200 - ARISTA03T2 - - - - 64004 - ARISTA04T0 - - - - 65200 - ARISTA04T2 - - - - 64005 - ARISTA05T0 - - - - 65200 - ARISTA05T2 - - - - 64006 - ARISTA06T0 - - - - 65200 - ARISTA06T2 - - - - 64007 - ARISTA07T0 - - - - 65200 - ARISTA07T2 - - - - 64008 - ARISTA08T0 - - - - 65200 - ARISTA08T2 - - - - 64009 - ARISTA09T0 - - - - 65200 - ARISTA09T2 - - - - 64010 - ARISTA10T0 - - - - 65200 - ARISTA10T2 - - - - 64011 - ARISTA11T0 - - - - 65200 - ARISTA11T2 - - - - 64012 - ARISTA12T0 - - - - 65200 - ARISTA12T2 - - - - 64013 - ARISTA13T0 - - - - 65200 - ARISTA13T2 - - - - 64014 - ARISTA14T0 - - - - 65200 - ARISTA14T2 - - - - 64015 - ARISTA15T0 - - - - 65200 - ARISTA15T2 - - - - 64016 - ARISTA16T0 - - - - 65200 - ARISTA16T2 - - -
-
- - - - - - HostIP - Loopback0 - - 10.1.0.32/32 - - 10.1.0.32/32 - - - - - - - - sonic - - - - - - Ethernet0 - 10.0.0.0/31 - - - - Ethernet4 - 10.0.0.2/31 - - - - Ethernet8 - 10.0.0.4/31 - - - - Ethernet12 - 10.0.0.6/31 - - - - Ethernet16 - 10.0.0.8/31 - - - - Ethernet20 - 10.0.0.10/31 - - - - Ethernet24 - 10.0.0.12/31 - - - - Ethernet28 - 10.0.0.14/31 - - - - Ethernet32 - 10.0.0.16/31 - - - - Ethernet36 - 10.0.0.18/31 - - - - Ethernet40 - 10.0.0.20/31 - - - - Ethernet44 - 10.0.0.22/31 - - - - Ethernet48 - 10.0.0.24/31 - - - - Ethernet52 - 10.0.0.26/31 - - - - Ethernet56 - 10.0.0.28/31 - - - - Ethernet60 - 10.0.0.30/31 - - - - Ethernet64 - 10.0.0.32/31 - - - - Ethernet68 - 10.0.0.34/31 - - - - Ethernet72 - 10.0.0.36/31 - - - - Ethernet76 - 10.0.0.38/31 - - - - Ethernet80 - 10.0.0.40/31 - - - - Ethernet84 - 10.0.0.42/31 - - - - Ethernet88 - 10.0.0.44/31 - - - - Ethernet92 - 10.0.0.46/31 - - - - Ethernet96 - 10.0.0.48/31 - - - - Ethernet100 - 10.0.0.50/31 - - - - Ethernet104 - 10.0.0.52/31 - - - - Ethernet108 - 10.0.0.54/31 - - - - Ethernet112 - 10.0.0.56/31 - - - - Ethernet116 - 10.0.0.58/31 - - - - Ethernet120 - 10.0.0.60/31 - - - - Ethernet124 - 10.0.0.62/31 - - - - - - - - - - - - DeviceInterfaceLink - sonic - Ethernet0 - ARISTA01T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet4 - ARISTA02T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet8 - ARISTA03T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet12 - ARISTA04T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet16 - ARISTA05T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet20 - ARISTA06T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet24 - ARISTA07T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet28 - ARISTA08T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet32 - ARISTA09T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet36 - ARISTA10T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet40 - ARISTA11T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet44 - ARISTA12T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet48 - ARISTA13T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet52 - ARISTA14T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet56 - ARISTA15T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet60 - ARISTA16T2 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet64 - ARISTA01T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet68 - ARISTA02T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet72 - ARISTA03T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet76 - ARISTA04T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet80 - ARISTA05T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet84 - ARISTA06T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet88 - ARISTA07T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet92 - ARISTA08T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet96 - ARISTA09T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet100 - ARISTA10T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet104 - ARISTA11T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet108 - ARISTA12T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet112 - ARISTA13T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet116 - ARISTA14T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet120 - ARISTA15T0 - Ethernet1 - - - DeviceInterfaceLink - sonic - Ethernet124 - ARISTA16T0 - Ethernet1 - - - - - sonic - E582-48x6q - - - - sonic - E582-48x6q -
diff --git a/device/centec/x86_64-centec_e582_48x6q-r0/plugins/eeprom.py b/device/centec/x86_64-centec_e582_48x6q-r0/plugins/eeprom.py new file mode 100644 index 000000000000..3fd55c63d8b7 --- /dev/null +++ b/device/centec/x86_64-centec_e582_48x6q-r0/plugins/eeprom.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python + +############################################################################# +# Centec E582-48X6Q +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +try: + import exceptions + import binascii + import time + import optparse + import warnings + import os + import sys + import subprocess + from sonic_eeprom import eeprom_base + from sonic_eeprom import eeprom_tlvinfo +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/class/i2c-adapter/i2c-0/0-0057/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/centec/x86_64-centec_e582_48x6q-r0/plugins/led_control.py b/device/centec/x86_64-centec_e582_48x6q-r0/plugins/led_control.py new file mode 100644 index 000000000000..d25bf6f8b473 --- /dev/null +++ b/device/centec/x86_64-centec_e582_48x6q-r0/plugins/led_control.py @@ -0,0 +1,153 @@ +#!/usr/bin/env python +# +# led_control.py +# +# Platform-specific LED control functionality for SONiC +# + +try: + from sonic_led.led_control_base import LedControlBase + import swsssdk + import threading + import os + import logging + import struct + import time + import syslog + from socket import * + from select import * +except ImportError, e: + raise ImportError(str(e) + " - required module not found") + + +def DBG_PRINT(str): + syslog.openlog("centec-led") + syslog.syslog(syslog.LOG_INFO, str) + syslog.closelog() + +class LedControl(LedControlBase): + """Platform specific LED control class""" + SONIC_PORT_NAME_PREFIX = "Ethernet" + LED_MODE_UP = [11, 1] + LED_MODE_DOWN = [7, 2] + + def _initSystemLed(self): + try: + with open(self.f_led.format("system"), 'w') as led_file: + led_file.write("5") + 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, ctlid, defmode) in self.led_mapping[1:59]: + data = struct.pack('=HHHBBH', 0, 7, 4, ctlid, defmode, port) + self.udpClient.sendto(data, ('localhost', 8101)) + + data = struct.pack('=HHHBB34B', 0, 3, 36, 34, 0, *[x[0] for x in self.led_mapping[1:35]]) + self.udpClient.sendto(data, ('localhost', 8101)) + data = struct.pack('=HHHBB24B', 0, 3, 26, 24, 1, *[x[0] for x in self.led_mapping[35:59]]) + self.udpClient.sendto(data, ('localhost', 8101)) + + data = struct.pack('=HHHB', 0, 5, 1, 1) + self.udpClient.sendto(data, ('localhost', 8101)) + + for idx in range(1, 55): + (port, ctlid, defmode) = self.led_mapping[idx] + with open(self.f_led.format("port{}".format(idx)), 'w') as led_file: + led_file.write(str(defmode)) + DBG_PRINT("init port{} led to mode={}".format(idx, defmode)) + + for idx in range(1, 55): + (port, ctlid, defmode) = self.led_mapping[idx] + with open(self.f_led.format("port{}".format(idx)), 'r') as led_file: + defmode = int(led_file.read()) + data = struct.pack('=HHHBBH', 0, 7, 4, ctlid, defmode, port) + self.udpClient.sendto(data, ('localhost', 8101)) + DBG_PRINT("init port{} led to mode={}".format(idx, defmode)) + + def _initDefaultConfig(self): + DBG_PRINT("start init led") + while True: + try: + r_sel = [self.udpClient] + echo_req = struct.pack('=HHH', 0, 1, 0) + self.udpClient.sendto(echo_req, ('localhost', 8101)) + result = select(r_sel, [], [], 1) + if self.udpClient in result[0]: + echo_rsp, srv_addr = self.udpClient.recvfrom(1024) + if echo_rsp: + break + DBG_PRINT("connect to sdk rpc server timeout, try again.") + except IOError as e: + DBG_PRINT(str(e)) + + DBG_PRINT("connect to sdk rpc server success.") + + self._initSystemLed() + self._initPanelLed() + + DBG_PRINT("init led done") + + + # Helper method to map SONiC port name to index + def _port_name_to_index(self, port_name): + # Strip "Ethernet" off port name + if not port_name.startswith(self.SONIC_PORT_NAME_PREFIX): + return -1 + + port_idx = int(port_name[len(self.SONIC_PORT_NAME_PREFIX):]) + return port_idx + + def _port_state_to_mode(self, port_idx, state): + if state == "up": + return self.LED_MODE_UP[0] if (port_idx < 49) else self.LED_MODE_UP[1] + else: + return self.LED_MODE_DOWN[0] if (port_idx < 49) else self.LED_MODE_DOWN[1] + + 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)) + (port, ctlid) = (self.led_mapping[port_idx][0], self.led_mapping[port_idx][1]) + data = struct.pack('=HHHBBH', 0, 7, 4, ctlid, ledMode, port) + self.udpClient.sendto(data, ('localhost', 8101)) + + # Concrete implementation of port_link_state_change() method + def port_link_state_change(self, portname, state): + port_idx = self._port_name_to_index(portname) + 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)) + + # Constructor + def __init__(self): + # [macid, ctlid, defaultmode] + self.led_mapping = [(0, 0, 0)] # resv + self.led_mapping.extend([(4, 0, 7), (5, 0, 7), (6, 0, 7), (8, 0, 7), (9, 0, 7), (10, 0, 7), (12, 0, 7), (13, 0, 7)]) # panel port 1~8 + self.led_mapping.extend([(14, 0, 7), (16, 0, 7), (17, 0, 7), (18, 0, 7), (20, 0, 7), (21, 0, 7), (22, 0, 7), (24, 0, 7)]) # panel port 9~16 + self.led_mapping.extend([(25, 0, 7), (26, 0, 7), (28, 0, 7), (30, 0, 7), (31, 0, 7), (32, 0, 7), (34, 0, 7), (35, 0, 7)]) # panel port 17~24 + self.led_mapping.extend([(48, 0, 7), (49, 0, 7), (51, 0, 7), (36, 0, 7), (37, 0, 7), (39, 0, 7), (55, 0, 7), (54, 0, 7)]) # panel port 25~32 + self.led_mapping.extend([(53, 0, 7), (52, 0, 7), (52, 1, 7), (53, 1, 7), (54, 1, 7), (55, 1, 7), (38, 1, 7), (37, 1, 7)]) # panel port 33~40 + self.led_mapping.extend([(36, 1, 7), (51, 1, 7), (50, 1, 7), (49, 1, 7), (48, 1, 7), (34, 1, 7), (33, 1, 7), (32, 1, 7)]) # panel port 41~48 + self.led_mapping.extend([(28, 1, 2), (24, 1, 2), (20, 1, 2), (12, 1, 2), (8, 1, 2), (4, 1, 2)]) # panel port 49~54 + self.led_mapping.extend([(0, 1, 2), (0, 1, 2), (0, 1, 2), (0, 1, 2), (0, 1, 2), (0, 1, 2)]) + + self.f_led = "/sys/class/leds/{}/brightness" + + self.udpClient = socket(AF_INET, SOCK_DGRAM) + + self._initDefaultConfig() + diff --git a/device/centec/x86_64-centec_e582_48x6q-r0/plugins/psuutil.py b/device/centec/x86_64-centec_e582_48x6q-r0/plugins/psuutil.py new file mode 100644 index 000000000000..5f8ba030c1f0 --- /dev/null +++ b/device/centec/x86_64-centec_e582_48x6q-r0/plugins/psuutil.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python + +############################################################################# +# Mellanox +# +# Module contains an implementation of SONiC PSU Base API and +# provides the PSUs status which are available in the platform +# +############################################################################# + +import os.path + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + + self.psu_path = "/sys/class/psu/psu{}/" + self.psu_presence = "psu_presence" + self.psu_oper_status = "psu_status" + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + + :return: An integer, the number of PSUs available on the device + """ + return 2 + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by 1-based index + + :param index: An integer, 1-based index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is faulty + """ + if index is None: + return False + + status = 0 + try: + with open(self.psu_path.format(index) + self.psu_oper_status, 'r') as power_status: + status = int(power_status.read()) + except IOError: + return False + + return status == 0 + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by 1-based index + + :param index: An integer, 1-based index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + if index is None: + return False + + status = 0 + try: + with open(self.psu_path.format(index) + self.psu_presence, 'r') as presence_status: + status = int(presence_status.read()) + except IOError: + return False + + return status == 0 diff --git a/device/centec/x86_64-centec_e582_48x6q-r0/plugins/sfputil.py b/device/centec/x86_64-centec_e582_48x6q-r0/plugins/sfputil.py new file mode 100644 index 000000000000..7bb1ac0d4192 --- /dev/null +++ b/device/centec/x86_64-centec_e582_48x6q-r0/plugins/sfputil.py @@ -0,0 +1,160 @@ +#!/usr/bin/env python + +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import time + import os + import logging + import struct + import syslog + from socket import * + from select import * + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + + +def DBG_PRINT(str): + print str + "\n" + + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + SONIC_PORT_NAME_PREFIX = "Ethernet" + PORT_START = 1 + PORT_END = 54 + PORTS_IN_BLOCK = 54 + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def qsfp_ports(self): + return range(49, self.PORTS_IN_BLOCK + 1) + + @property + def port_to_eeprom_mapping(self): + return self.eeprom_mapping + + def is_logical_port(self, port_name): + return True + + def get_logical_to_physical(self, port_name): + if not port_name.startswith(self.SONIC_PORT_NAME_PREFIX): + return None + + port_idx = int(port_name[len(self.SONIC_PORT_NAME_PREFIX):]) + + return [port_idx] + + def get_eeprom_data(self, port): + (ctlid, devid) = self.fiber_mapping[port] + offset = (128 if port in self.qsfp_ports else 0) + r_sel = [self.udpClient] + req = struct.pack('=HHHBBHIBBBBI', + 0, 9, 16, # lchip/msgtype/msglen + ctlid, # uint8 ctl_id + devid, # uint8 slave_dev_id + 0x50, # uint16 dev_addr + (1< self.port_end: + return False + try: + with open(self.f_sfp_present.format(port_num), '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): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + return False + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + return False + + def reset(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + return False + diff --git a/dockers/docker-orchagent/orchagent.sh b/dockers/docker-orchagent/orchagent.sh index 027c6d52a2fe..0b1c5dda8c7f 100755 --- a/dockers/docker-orchagent/orchagent.sh +++ b/dockers/docker-orchagent/orchagent.sh @@ -20,6 +20,11 @@ elif [ "$platform" == "cavium" ]; then ORCHAGENT_ARGS+="-m $MAC_ADDRESS" elif [ "$platform" == "nephos" ]; then ORCHAGENT_ARGS+="-m $MAC_ADDRESS" +elif [ "$platform" == "centec" ]; then + last_byte=$(python -c "print '$MAC_ADDRESS'[-2:]") + aligned_last_byte=$(python -c "print format(int(int('$last_byte', 16) + 1), '02x')") # put mask and take away the 0x prefix + ALIGNED_MAC_ADDRESS=$(python -c "print '$MAC_ADDRESS'[:-2] + '$aligned_last_byte'") # put aligned byte into the end of MAC + ORCHAGENT_ARGS+="-m $ALIGNED_MAC_ADDRESS" fi exec /usr/bin/orchagent ${ORCHAGENT_ARGS} diff --git a/platform/centec/one-image.mk b/platform/centec/one-image.mk index 7ad205dce521..42e78ab4df34 100644 --- a/platform/centec/one-image.mk +++ b/platform/centec/one-image.mk @@ -3,6 +3,6 @@ SONIC_ONE_IMAGE = sonic-centec.bin $(SONIC_ONE_IMAGE)_MACHINE = centec $(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie -$(SONIC_ONE_IMAGE)_INSTALLS += $(CENTEC_SDK_KERNEL) +$(SONIC_ONE_IMAGE)_INSTALLS += $(CENTEC_E582_48X6Q_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_IMAGES) SONIC_INSTALLERS += $(SONIC_ONE_IMAGE) diff --git a/platform/centec/platform-modules-centec-e582.mk b/platform/centec/platform-modules-centec-e582.mk new file mode 100644 index 000000000000..e86c428a7403 --- /dev/null +++ b/platform/centec/platform-modules-centec-e582.mk @@ -0,0 +1,19 @@ +# Centec E582-48X6Q Platform modules + + +CENTEC_E582_48X6Q_PLATFORM_MODULE_VERSION =1.1 +CENTEC_E582_48X2Q4Z_PLATFORM_MODULE_VERSION =1.1 + +export CENTEC_E582_48X6Q_PLATFORM_MODULE_VERSION +export CENTEC_E582_48X2Q4Z_PLATFORM_MODULE_VERSION + +CENTEC_E582_48X6Q_PLATFORM_MODULE = platform-modules-e582-48x6q_$(CENTEC_E582_48X6Q_PLATFORM_MODULE_VERSION)_amd64.deb + +$(CENTEC_E582_48X6Q_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-e582 +$(CENTEC_E582_48X6Q_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +$(CENTEC_E582_48X6Q_PLATFORM_MODULE)_PLATFORM = x86_64-centec_e582_48x6q-r0 +SONIC_DPKG_DEBS += $(CENTEC_E582_48X6Q_PLATFORM_MODULE) + +CENTEC_E582_48X2Q4Z_PLATFORM_MODULE = platform-modules-e582-48x2q4z_$(CENTEC_E582_48X2Q4Z_PLATFORM_MODULE_VERSION)_amd64.deb +$(CENTEC_E582_48X2Q4Z_PLATFORM_MODULE)_PLATFORM = x86_64-centec_e582_48x2q4z-r0 +$(eval $(call add_extra_package,$(CENTEC_E582_48X6Q_PLATFORM_MODULE),$(CENTEC_E582_48X2Q4Z_PLATFORM_MODULE))) diff --git a/platform/centec/rules.mk b/platform/centec/rules.mk index 8b676f87ece4..823144dc25ce 100644 --- a/platform/centec/rules.mk +++ b/platform/centec/rules.mk @@ -1,5 +1,5 @@ +include $(PLATFORM_PATH)/platform-modules-centec-e582.mk include $(PLATFORM_PATH)/sdk.mk -include $(PLATFORM_PATH)/sai.mk include $(PLATFORM_PATH)/docker-orchagent-centec.mk include $(PLATFORM_PATH)/docker-syncd-centec.mk include $(PLATFORM_PATH)/docker-syncd-centec-rpc.mk diff --git a/platform/centec/sai.mk b/platform/centec/sai.mk deleted file mode 100644 index 299b36a69ebf..000000000000 --- a/platform/centec/sai.mk +++ /dev/null @@ -1,5 +0,0 @@ -# Centec SAI -CENTEC_SAI = libsai_1.0.0_amd64.deb -$(CENTEC_SAI)_URL = https://github.com/CentecNetworks/goldengate-sai/raw/master/lib/SONiC_1.0/libsai_1.0.0_amd64.deb - -SONIC_ONLINE_DEBS += $(CENTEC_SAI) diff --git a/platform/centec/sdk.mk b/platform/centec/sdk.mk index e3ce05f6b742..ba2d1adbe6a8 100644 --- a/platform/centec/sdk.mk +++ b/platform/centec/sdk.mk @@ -1,4 +1,5 @@ -CENTEC_SDK_KERNEL = centec-gg-sdk3.5-modules-3.16.0-4-amd64.deb -$(CENTEC_SDK_KERNEL)_URL = "https://github.com/CentecNetworks/goldengate-sai/raw/master/lib/SONiC_1.0/centec-gg-sdk3.5-modules-3.16.0-4-amd64.deb" +# Centec SAI +CENTEC_SAI = libsai_1.2.4_amd64.deb +$(CENTEC_SAI)_URL = https://github.com/CentecNetworks/goldengate-sai/raw/master/lib/SONiC_1.2.4/libsai_1.2.4-1.0_amd64.deb -SONIC_ONLINE_DEBS += $(CENTEC_SDK_KERNEL) +SONIC_ONLINE_DEBS += $(CENTEC_SAI) diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/cfg/48x2q4z-modules.conf b/platform/centec/sonic-platform-modules-e582/48x2q4z/cfg/48x2q4z-modules.conf new file mode 100644 index 000000000000..5becd702a716 --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/48x2q4z/cfg/48x2q4z-modules.conf @@ -0,0 +1,17 @@ +# /etc/modules: kernel modules to load at boot time. +# +# This file contains the names of kernel modules that should be loaded +# at boot time, one per line. Lines beginning with "#" are ignored. + +i2c-i801 +i2c-dev +i2c-mux +i2c-smbus + +i2c-mux-pca954x +lm77 +adt7470 +tun +centec_e582_48x6q_platform +dal +centec_at24c64 diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/Makefile b/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/Makefile new file mode 100644 index 000000000000..d1ca9824aa9e --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/Makefile @@ -0,0 +1,2 @@ +obj-m := centec_e582_48x2q4z_platform.o dal.o centec_at24c64.o +dal-y := dal_kernel.o dal_mpool.o diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/centec_at24c64.c b/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/centec_at24c64.c new file mode 100644 index 000000000000..52b8d536d0e6 --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/centec_at24c64.c @@ -0,0 +1,657 @@ +/* + * at24.c - handle most I2C EEPROMs + * + * Copyright (C) 2005-2007 David Brownell + * Copyright (C) 2008 Wolfram Sang, Pengutronix + * + * 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * I2C EEPROMs from most vendors are inexpensive and mostly interchangeable. + * Differences between different vendor product lines (like Atmel AT24C or + * MicroChip 24LC, etc) won't much matter for typical read/write access. + * There are also I2C RAM chips, likewise interchangeable. One example + * would be the PCF8570, which acts like a 24c02 EEPROM (256 bytes). + * + * However, misconfiguration can lose data. "Set 16-bit memory address" + * to a part with 8-bit addressing will overwrite data. Writing with too + * big a page size also loses data. And it's not safe to assume that the + * conventional addresses 0x50..0x57 only hold eeproms; a PCF8563 RTC + * uses 0x51, for just one example. + * + * Accordingly, explicit board-specific configuration data should be used + * in almost all cases. (One partial exception is an SMBus used to access + * "SPD" data for DRAM sticks. Those only use 24c02 EEPROMs.) + * + * So this driver uses "new style" I2C driver binding, expecting to be + * told what devices exist. That may be in arch/X/mach-Y/board-Z.c or + * similar kernel-resident tables; or, configuration data coming from + * a bootloader. + * + * Other than binding model, current differences from "eeprom" driver are + * that this one handles write access and isn't restricted to 24c02 devices. + * It also handles larger devices (32 kbit and up) with two-byte addresses, + * which won't work on pure SMBus systems. + */ + +struct at24_data { + struct at24_platform_data chip; + struct memory_accessor macc; + int use_smbus; + + /* + * Lock protects against activities from other Linux tasks, + * but not from changes by other I2C masters. + */ + struct mutex lock; + struct bin_attribute bin; + + u8 *writebuf; + unsigned write_max; + unsigned num_addresses; + + /* + * Some chips tie up multiple I2C addresses; dummy devices reserve + * them for us, and we'll use them with SMBus calls. + */ + struct i2c_client *client[]; +}; + +/* + * This parameter is to help this driver avoid blocking other drivers out + * of I2C for potentially troublesome amounts of time. With a 100 kHz I2C + * clock, one 256 byte read takes about 1/43 second which is excessive; + * but the 1/170 second it takes at 400 kHz may be quite reasonable; and + * at 1 MHz (Fm+) a 1/430 second delay could easily be invisible. + * + * This value is forced to be a power of two so that writes align on pages. + */ +static unsigned io_limit = 128; +module_param(io_limit, uint, 0); +MODULE_PARM_DESC(io_limit, "Maximum bytes per I/O (default 128)"); + +/* + * Specs often allow 5 msec for a page write, sometimes 20 msec; + * it's important to recover from write timeouts. + */ +static unsigned write_timeout = 25; +module_param(write_timeout, uint, 0); +MODULE_PARM_DESC(write_timeout, "Time (in ms) to try writes (default 25)"); + +#define AT24_SIZE_BYTELEN 5 +#define AT24_SIZE_FLAGS 8 + +#define AT24_BITMASK(x) (BIT(x) - 1) + +/* create non-zero magic value for given eeprom parameters */ +#define AT24_DEVICE_MAGIC(_len, _flags) \ + ((1 << AT24_SIZE_FLAGS | (_flags)) \ + << AT24_SIZE_BYTELEN | ilog2(_len)) + +static const struct i2c_device_id at24_ctc_ids[] = { + { "24c64-ctc", AT24_DEVICE_MAGIC(65536 / 8, AT24_FLAG_ADDR16 | AT24_FLAG_READONLY | AT24_FLAG_IRUGO) }, + { /* END OF LIST */ } +}; +MODULE_DEVICE_TABLE(i2c, at24_ctc_ids); + +/*-------------------------------------------------------------------------*/ + +/* + * This routine supports chips which consume multiple I2C addresses. It + * computes the addressing information to be used for a given r/w request. + * Assumes that sanity checks for offset happened at sysfs-layer. + */ +static struct i2c_client *at24_translate_offset(struct at24_data *at24, + unsigned *offset) +{ + unsigned i; + + if (at24->chip.flags & AT24_FLAG_ADDR16) { + i = *offset >> 16; + *offset &= 0xffff; + } else { + i = *offset >> 8; + *offset &= 0xff; + } + + return at24->client[i]; +} + +static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf, + unsigned offset, size_t count) +{ + struct i2c_msg msg[2]; + struct i2c_client *client; + unsigned long timeout, read_time; + int status; + + memset(msg, 0, sizeof(msg)); + + /* + * REVISIT some multi-address chips don't rollover page reads to + * the next slave address, so we may need to truncate the count. + * Those chips might need another quirk flag. + * + * If the real hardware used four adjacent 24c02 chips and that + * were misconfigured as one 24c08, that would be a similar effect: + * one "eeprom" file not four, but larger reads would fail when + * they crossed certain pages. + */ + + /* + * Slave address and byte offset derive from the offset. Always + * set the byte address; on a multi-master board, another master + * may have changed the chip's "current" address pointer. + */ + client = at24_translate_offset(at24, &offset); + + if (count > io_limit) + count = io_limit; + + count = 1; + + /* + * Reads fail if the previous write didn't complete yet. We may + * loop a few times until this one succeeds, waiting at least + * long enough for one entire page write to work. + */ + timeout = jiffies + msecs_to_jiffies(write_timeout); + do { + read_time = jiffies; + + status = i2c_smbus_write_byte_data(client, (offset >> 8) & 0x0ff, offset & 0x0ff ); + status = i2c_smbus_read_byte(client); + if (status >= 0) { + buf[0] = status; + status = count; + } + + dev_dbg(&client->dev, "read %zu@%d --> %d (%ld)\n", + count, offset, status, jiffies); + + if (status == count) + return count; + + /* REVISIT: at HZ=100, this is sloooow */ + msleep(1); + } while (time_before(read_time, timeout)); + + return -ETIMEDOUT; +} + +static ssize_t at24_read(struct at24_data *at24, + char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) + return count; + + memset(buf, 0, count); + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&at24->lock); + + while (count) { + ssize_t status; + + status = at24_eeprom_read(at24, buf, off, count); + if (status <= 0) { + if (retval == 0) + retval = status; + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + //printk(KERN_ALERT "at24_read buf = %s, retval = %zu\n", buf, retval); + + mutex_unlock(&at24->lock); + + return retval; +} + +static ssize_t at24_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + struct at24_data *at24; + + at24 = dev_get_drvdata(container_of(kobj, struct device, kobj)); + return at24_read(at24, buf, off, count); +} + + +/* + * Note that if the hardware write-protect pin is pulled high, the whole + * chip is normally write protected. But there are plenty of product + * variants here, including OTP fuses and partial chip protect. + * + * We only use page mode writes; the alternative is sloooow. This routine + * writes at most one page. + */ +static ssize_t at24_eeprom_write(struct at24_data *at24, const char *buf, + unsigned offset, size_t count) +{ + struct i2c_client *client; + ssize_t status; + unsigned long timeout, write_time; + unsigned next_page; + + /* Get corresponding I2C address and adjust offset */ + client = at24_translate_offset(at24, &offset); + + /* write_max is at most a page */ + if (count > at24->write_max) + count = at24->write_max; + + /* Never roll over backwards, to the start of this page */ + next_page = roundup(offset + 1, at24->chip.page_size); + if (offset + count > next_page) + count = next_page - offset; + + /* + * Writes fail if the previous one didn't complete yet. We may + * loop a few times until this one succeeds, waiting at least + * long enough for one entire page write to work. + */ + timeout = jiffies + msecs_to_jiffies(write_timeout); + do { + write_time = jiffies; + + status = i2c_smbus_write_word_data(client, + (offset >> 8) & 0x0ff, (offset & 0xFF) | buf[0]); + if (status == 0) + status = count; + + dev_dbg(&client->dev, "write %zu@%d --> %zd (%ld)\n", + count, offset, status, jiffies); + + if (status == count) + return count; + + /* REVISIT: at HZ=100, this is sloooow */ + msleep(1); + } while (time_before(write_time, timeout)); + + return -ETIMEDOUT; +} + +static ssize_t at24_write(struct at24_data *at24, const char *buf, loff_t off, + size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) + return count; + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&at24->lock); + + while (count) { + ssize_t status; + + status = at24_eeprom_write(at24, buf, off, 1); /* only one-byte to write; TODO page wirte */ + if (status <= 0) { + if (retval == 0) + retval = status; + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&at24->lock); + + return retval; +} + +static ssize_t at24_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + struct at24_data *at24; + + if (unlikely(off >= attr->size)) + return -EFBIG; + + at24 = dev_get_drvdata(container_of(kobj, struct device, kobj)); + return at24_write(at24, buf, off, count); +} + +/*-------------------------------------------------------------------------*/ + +/* + * This lets other kernel code access the eeprom data. For example, it + * might hold a board's Ethernet address, or board-specific calibration + * data generated on the manufacturing floor. + */ + +static ssize_t at24_macc_read(struct memory_accessor *macc, char *buf, + off_t offset, size_t count) +{ + struct at24_data *at24 = container_of(macc, struct at24_data, macc); + + return at24_read(at24, buf, offset, count); +} + +static ssize_t at24_macc_write(struct memory_accessor *macc, const char *buf, + off_t offset, size_t count) +{ + struct at24_data *at24 = container_of(macc, struct at24_data, macc); + + return at24_write(at24, buf, offset, count); +} + +/*-------------------------------------------------------------------------*/ + +#ifdef CONFIG_OF +static void at24_get_ofdata(struct i2c_client *client, + struct at24_platform_data *chip) +{ + const __be32 *val; + struct device_node *node = client->dev.of_node; + + if (node) { + if (of_get_property(node, "read-only", NULL)) + chip->flags |= AT24_FLAG_READONLY; + val = of_get_property(node, "pagesize", NULL); + if (val) + chip->page_size = be32_to_cpup(val); + } +} +#else +static void at24_get_ofdata(struct i2c_client *client, + struct at24_platform_data *chip) +{ } +#endif /* CONFIG_OF */ + +static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct at24_platform_data chip; + bool writable; + int use_smbus = 0; + struct at24_data *at24; + int err; + unsigned i, num_addresses; + kernel_ulong_t magic; + + if (client->dev.platform_data) { + chip = *(struct at24_platform_data *)client->dev.platform_data; + } else { + if (!id->driver_data) + return -ENODEV; + + magic = id->driver_data; + chip.byte_len = BIT(magic & AT24_BITMASK(AT24_SIZE_BYTELEN)); + magic >>= AT24_SIZE_BYTELEN; + chip.flags = magic & AT24_BITMASK(AT24_SIZE_FLAGS); + + /* + * This is slow, but we can't know all eeproms, so we better + * play safe. Specifying custom eeprom-types via platform_data + * is recommended anyhow. + */ + chip.page_size = 1; + + /* update chipdata if OF is present */ + at24_get_ofdata(client, &chip); + + printk(KERN_ALERT "at24_probe chip.byte_len = 0x%x\n", chip.byte_len); + printk(KERN_ALERT "at24_probe chip.flags = 0x%x\n", chip.flags); + printk(KERN_ALERT "at24_probe chip.magic = 0x%lx\n", id->driver_data); + + chip.setup = NULL; + chip.context = NULL; + } + + if (!is_power_of_2(chip.byte_len)) + dev_warn(&client->dev, + "byte_len looks suspicious (no power of 2)!\n"); + if (!chip.page_size) { + dev_err(&client->dev, "page_size must not be 0!\n"); + return -EINVAL; + } + if (!is_power_of_2(chip.page_size)) + dev_warn(&client->dev, + "page_size looks suspicious (no power of 2)!\n"); + + /* Use I2C operations unless we're stuck with SMBus extensions. */ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { + use_smbus = I2C_SMBUS_I2C_BLOCK_DATA; + } else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_WORD_DATA)) { + use_smbus = I2C_SMBUS_WORD_DATA; + } else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_BYTE_DATA)) { + use_smbus = I2C_SMBUS_BYTE_DATA; + } else { + return -EPFNOSUPPORT; + } + use_smbus = I2C_SMBUS_BYTE_DATA; + printk(KERN_ALERT "at24_probe use_smbus --> %d\n", + use_smbus); + } + + if (chip.flags & AT24_FLAG_TAKE8ADDR) + num_addresses = 8; + else + num_addresses = DIV_ROUND_UP(chip.byte_len, + (chip.flags & AT24_FLAG_ADDR16) ? 65536 : 256); + + at24 = devm_kzalloc(&client->dev, sizeof(struct at24_data) + + num_addresses * sizeof(struct i2c_client *), GFP_KERNEL); + if (!at24) + return -ENOMEM; + + mutex_init(&at24->lock); + at24->use_smbus = use_smbus; + at24->chip = chip; + at24->num_addresses = num_addresses; + + /* + * Export the EEPROM bytes through sysfs, since that's convenient. + * By default, only root should see the data (maybe passwords etc) + */ + sysfs_bin_attr_init(&at24->bin); + at24->bin.attr.name = "eeprom"; + at24->bin.attr.mode = chip.flags & AT24_FLAG_IRUGO ? S_IRUGO : S_IRUSR; + at24->bin.read = at24_bin_read; + at24->bin.size = chip.byte_len; + + at24->macc.read = at24_macc_read; + + writable = !(chip.flags & AT24_FLAG_READONLY); + if (writable) { + if (!use_smbus || i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) { + + unsigned write_max = chip.page_size; + + at24->macc.write = at24_macc_write; + + at24->bin.write = at24_bin_write; + at24->bin.attr.mode |= S_IWUSR; + + if (write_max > io_limit) + write_max = io_limit; + if (use_smbus && write_max > I2C_SMBUS_BLOCK_MAX) + write_max = I2C_SMBUS_BLOCK_MAX; + at24->write_max = write_max; + + /* buffer (data + address at the beginning) */ + at24->writebuf = devm_kzalloc(&client->dev, + write_max + 2, GFP_KERNEL); + if (!at24->writebuf) + return -ENOMEM; + } else { + dev_warn(&client->dev, + "cannot write due to controller restrictions."); + } + } + + at24->client[0] = client; + + /* use dummy devices for multiple-address chips */ + for (i = 1; i < num_addresses; i++) { + at24->client[i] = i2c_new_dummy(client->adapter, + client->addr + i); + if (!at24->client[i]) { + dev_err(&client->dev, "address 0x%02x unavailable\n", + client->addr + i); + err = -EADDRINUSE; + goto err_clients; + } + } + + err = sysfs_create_bin_file(&client->dev.kobj, &at24->bin); + if (err) + goto err_clients; + + i2c_set_clientdata(client, at24); + + dev_info(&client->dev, "%zu byte %s EEPROM, %s, %u bytes/write\n", + at24->bin.size, client->name, + writable ? "writable" : "read-only", at24->write_max); + if (use_smbus == I2C_SMBUS_WORD_DATA || + use_smbus == I2C_SMBUS_BYTE_DATA) { + dev_notice(&client->dev, "Falling back to %s reads, " + "performance will suffer\n", use_smbus == + I2C_SMBUS_WORD_DATA ? "word" : "byte"); + } + + /* export data to kernel code */ + if (chip.setup) + chip.setup(&at24->macc, chip.context); + + return 0; + +err_clients: + for (i = 1; i < num_addresses; i++) + if (at24->client[i]) + i2c_unregister_device(at24->client[i]); + + return err; +} + +static int at24_remove(struct i2c_client *client) +{ + struct at24_data *at24; + int i; + + at24 = i2c_get_clientdata(client); + sysfs_remove_bin_file(&client->dev.kobj, &at24->bin); + + for (i = 1; i < at24->num_addresses; i++) + i2c_unregister_device(at24->client[i]); + + return 0; +} + +/*-------------------------------------------------------------------------*/ + +static struct i2c_board_info i2c_devs = { + I2C_BOARD_INFO("24c64-ctc", 0x57), +}; + +static struct i2c_adapter *adapter = NULL; +static struct i2c_client *client = NULL; + +static int ctc_at24c64_init(void) +{ + printk(KERN_ALERT "ctc_at24c64_init\n"); + + adapter = i2c_get_adapter(0); + if(adapter == NULL){ + printk(KERN_ALERT "i2c_get_adapter == NULL\n"); + return -1; + } + + client = i2c_new_device(adapter, &i2c_devs); + if(client == NULL){ + printk(KERN_ALERT "i2c_new_device == NULL\n"); + i2c_put_adapter(adapter); + adapter = NULL; + return -1; + } + + return 0; +} + +static void ctc_at24c64_exit(void) +{ + printk(KERN_ALERT "ctc_at24c64_exit\n"); + if(client){ + i2c_unregister_device(client); + } + if(adapter){ + i2c_put_adapter(adapter); + } +} + +static struct i2c_driver at24_ctc_driver = { + .driver = { + .name = "at24-ctc", + .owner = THIS_MODULE, + }, + .probe = at24_probe, + .remove = at24_remove, + .id_table = at24_ctc_ids, +}; + +static int __init at24_ctc_init(void) +{ + if (!io_limit) { + pr_err("at24_ctc: io_limit must not be 0!\n"); + return -EINVAL; + } + + io_limit = rounddown_pow_of_two(io_limit); + + ctc_at24c64_init(); + + return i2c_add_driver(&at24_ctc_driver); +} +module_init(at24_ctc_init); + +static void __exit at24_ctc_exit(void) +{ + ctc_at24c64_exit(); + i2c_del_driver(&at24_ctc_driver); +} +module_exit(at24_ctc_exit); + +MODULE_DESCRIPTION("Driver for most I2C EEPROMs"); +MODULE_AUTHOR("David Brownell and Wolfram Sang"); +MODULE_LICENSE("GPL"); diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/centec_e582_48x2q4z_platform.c b/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/centec_e582_48x2q4z_platform.c new file mode 100644 index 000000000000..003f9a80caf0 --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/centec_e582_48x2q4z_platform.c @@ -0,0 +1,142 @@ +#include +#include +#include +#include + +#define PCA9548_CHANNEL_NUM 8 +#define PCA9548_ADAPT_ID_START 10 + +static struct pca954x_platform_mode i2c_dev_pca9548_platform_mode[PCA9548_CHANNEL_NUM] = { + [0] = { + .adap_id = PCA9548_ADAPT_ID_START, + .deselect_on_exit = 1, + .class = 0, + }, + [1] = { + .adap_id = PCA9548_ADAPT_ID_START + 1, + .deselect_on_exit = 1, + .class = 0, + }, + [2] = { + .adap_id = PCA9548_ADAPT_ID_START + 2, + .deselect_on_exit = 1, + .class = 0, + }, + [3] = { + .adap_id = PCA9548_ADAPT_ID_START + 3, + .deselect_on_exit = 1, + .class = 0, + }, + [4] = { + .adap_id = PCA9548_ADAPT_ID_START + 4, + .deselect_on_exit = 1, + .class = 0, + }, + [5] = { + .adap_id = PCA9548_ADAPT_ID_START + 5, + .deselect_on_exit = 1, + .class = 0, + }, + [6] = { + .adap_id = PCA9548_ADAPT_ID_START + 6, + .deselect_on_exit = 1, + .class = 0, + }, + [7] = { + .adap_id = PCA9548_ADAPT_ID_START + 7, + .deselect_on_exit = 1, + .class = 0, + } +}; + +static struct pca954x_platform_data i2c_dev_pca9548_platform_data = { + .modes = i2c_dev_pca9548_platform_mode, + .num_modes = PCA9548_CHANNEL_NUM, +}; + +static struct i2c_board_info i2c_dev_pca9548 = { + I2C_BOARD_INFO("pca9548", 0x70), + .platform_data = &i2c_dev_pca9548_platform_data, +}; + +static struct i2c_board_info i2c_dev_adt7475 = { + I2C_BOARD_INFO("adt7470", 0x2F), +}; + +struct i2c_adapter *i2c_core_master = NULL; /* i2c-0-cpu */ +struct i2c_adapter *i2c_mux_channel_4 = NULL; /* pca9548x-channel 5 */ +struct i2c_client *i2c_client_pca9548x = NULL; +struct i2c_client *i2c_client_adt7475 = NULL; + +static int e582_48x6q_init(void) +{ + printk(KERN_INFO "install e582_48x6q board dirver...\n"); + + /* find i2c-core master */ + i2c_core_master = i2c_get_adapter(0); + if(i2c_core_master == NULL) + { + printk(KERN_CRIT "can't find i2c-core bus\n"); + goto err_i2c_core_master; + } + + /* install i2c-mux */ + i2c_client_pca9548x = i2c_new_device(i2c_core_master, &i2c_dev_pca9548); + if(i2c_client_pca9548x == NULL) + { + printk(KERN_INFO "install e582_48x6q board pca9548 failed\n"); + goto install_at24c64; + } + + /* install adt7475 */ + /* find i2c-mux-channel 15 */ + i2c_mux_channel_4 = i2c_get_adapter(PCA9548_ADAPT_ID_START + 4); + if(i2c_mux_channel_4 == NULL) + { + printk(KERN_INFO "install e582_48x6q board adt7470 failed\n"); + goto install_at24c64; + } + + i2c_client_adt7475 = i2c_new_device(i2c_mux_channel_4, &i2c_dev_adt7475); + if(i2c_client_adt7475 == NULL){ + printk(KERN_INFO "install e582_48x6q board adt7470 failed\n"); + goto install_at24c64; + } + +install_at24c64: + + printk(KERN_INFO "install e582_48x6q board dirver...ok\n"); + return 0; + +err_i2c_core_master: + return -1; +} + +static void e582_48x6q_exit(void) +{ + printk(KERN_INFO "uninstall e582_48x6q board dirver...\n"); + + /* uninstall adt7475 master */ + if(i2c_client_adt7475) { + i2c_unregister_device(i2c_client_adt7475); + } + if(i2c_mux_channel_4) { + i2c_put_adapter(i2c_mux_channel_4); + } + + /* uninstall i2c-core master */ + if(i2c_client_pca9548x) { + i2c_unregister_device(i2c_client_pca9548x); + } + + /* uninstall i2c-core master */ + if(i2c_core_master) { + i2c_put_adapter(i2c_core_master); + } +} + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_AUTHOR("xuwj centecNetworks, Inc"); +MODULE_DESCRIPTION("e582-48x6q board driver"); +module_init(e582_48x6q_init); +module_exit(e582_48x6q_exit); diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_kernel.c b/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_kernel.c new file mode 100644 index 000000000000..4c9a3da64e6e --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_kernel.c @@ -0,0 +1,1814 @@ +/** + @file dal_kernal.c + + @date 2012-10-18 + + @version v2.0 + + +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) +#include +#endif +#include "dal_kernel.h" +#include "dal_mpool.h" + +MODULE_AUTHOR("Centec Networks Inc."); +MODULE_DESCRIPTION("DAL kernel module"); +MODULE_LICENSE("GPL"); + +/* DMA memory pool size */ +static char* dma_pool_size; +module_param(dma_pool_size, charp, 0); +MODULE_PARM_DESC(dma_pool_size, + "Specify DMA memory pool size (default 4MB)"); + +/***************************************************************************** + * defines + *****************************************************************************/ +#define MB_SIZE 0x100000 +#define CTC_MAX_INTR_NUM 8 + +#define MEM_MAP_RESERVE SetPageReserved +#define MEM_MAP_UNRESERVE ClearPageReserved + +#define CTC_VENDOR_VID 0xc001 +#define CTC_HUMBER_DEVICE_ID 0x6048 +#define CTC_GOLDENGATE_DEVICE_ID 0xcb10 + +#define MEM_MAP_RESERVE SetPageReserved +#define MEM_MAP_UNRESERVE ClearPageReserved + +#define CTC_GREATBELT_DEVICE_ID 0x03e8 /* TBD */ +#define DAL_MAX_CHIP_NUM 8 /* [GB] used */ +#define VIRT_TO_PAGE(p) virt_to_page((p)) +#define DAL_UNTAG_BLOCK 0 +#define DAL_DISCARD_BLOCK 1 +#define DAL_MATCHED_BLOCK 2 +#define DAL_CUR_MATCH_BLOCk 3 +/***************************************************************************** + * typedef + *****************************************************************************/ +/* Control Data */ +typedef struct dal_isr_s +{ + int irq; + void (* isr)(void*); + void* isr_data; + int trigger; + int count; + wait_queue_head_t wqh; +} dal_isr_t; + +typedef struct dal_kernel_dev_s +{ + struct list_head list; + struct pci_dev* pci_dev; + + /* PCI I/O mapped base address */ + uintptr logic_address; + + /* Physical address */ + uintptr phys_address; +} dal_kern_dev_t; + +typedef struct _dma_segment +{ + struct list_head list; + unsigned long req_size; /* Requested DMA segment size */ + unsigned long blk_size; /* DMA block size */ + unsigned long blk_order; /* DMA block size in alternate format */ + unsigned long seg_size; /* Current DMA segment size */ + unsigned long seg_begin; /* Logical address of segment */ + unsigned long seg_end; /* Logical end address of segment */ + unsigned long* blk_ptr; /* Array of logical DMA block addresses */ + int blk_cnt_max; /* Maximum number of block to allocate */ + int blk_cnt; /* Current number of blocks allocated */ +} dma_segment_t; + +typedef irqreturn_t (*p_func) (int irq, void* dev_id); + +/*************************************************************************** + *declared + ***************************************************************************/ +static unsigned int linux_dal_poll0(struct file* filp, struct poll_table_struct* p); +static unsigned int linux_dal_poll1(struct file* filp, struct poll_table_struct* p); +static unsigned int linux_dal_poll2(struct file* filp, struct poll_table_struct* p); +static unsigned int linux_dal_poll3(struct file* filp, struct poll_table_struct* p); +static unsigned int linux_dal_poll4(struct file* filp, struct poll_table_struct* p); +static unsigned int linux_dal_poll5(struct file* filp, struct poll_table_struct* p); +static unsigned int linux_dal_poll6(struct file* filp, struct poll_table_struct* p); +static unsigned int linux_dal_poll7(struct file* filp, struct poll_table_struct* p); + +/***************************************************************************** + * global variables + *****************************************************************************/ +static dal_kern_dev_t dal_dev[DAL_MAX_CHIP_NUM]; +static dal_isr_t dal_isr[CTC_MAX_INTR_NUM]; +static int dal_chip_num = 0; +static int dal_version = 0; +static int dal_intr_num = 0; +static int use_high_memory = 0; +static unsigned int* dma_virt_base[DAL_MAX_CHIP_NUM]; +#ifndef DMA_MEM_MODE_PLATFORM +static unsigned int* dma_virt_base_tmp[DAL_MAX_CHIP_NUM]; +#endif +static uintptr dma_phy_base[DAL_MAX_CHIP_NUM]; +static unsigned int dma_mem_size = 0x800000; +static unsigned int msi_irq_base[DAL_MAX_CHIP_NUM]; +static unsigned int msi_irq_num[DAL_MAX_CHIP_NUM]; +static unsigned int msi_used = 0; +static struct class *dal_class; + +static LIST_HEAD(_dma_seg); +static int dal_debug = 0; +module_param(dal_debug, int, 0); +MODULE_PARM_DESC(dal_debug, "Set debug level (default 0)"); + +static struct pci_device_id dal_id_table[] = +{ + {PCI_DEVICE(CTC_VENDOR_VID, CTC_GREATBELT_DEVICE_ID)}, + {PCI_DEVICE(0xcb10, 0xc010)}, + {0, }, +}; + +static wait_queue_head_t poll_intr[CTC_MAX_INTR_NUM]; + +p_func intr_handler_fun[CTC_MAX_INTR_NUM]; + +static int poll_intr_trigger[CTC_MAX_INTR_NUM]; + +static struct file_operations dal_intr_fops[CTC_MAX_INTR_NUM] = +{ + { + .owner = THIS_MODULE, + .poll = linux_dal_poll0, + }, + { + .owner = THIS_MODULE, + .poll = linux_dal_poll1, + }, + { + .owner = THIS_MODULE, + .poll = linux_dal_poll2, + }, + { + .owner = THIS_MODULE, + .poll = linux_dal_poll3, + }, + { + .owner = THIS_MODULE, + .poll = linux_dal_poll4, + }, + { + .owner = THIS_MODULE, + .poll = linux_dal_poll5, + }, + { + .owner = THIS_MODULE, + .poll = linux_dal_poll6, + }, + { + .owner = THIS_MODULE, + .poll = linux_dal_poll7, + }, +}; + +/***************************************************************************** + * macros + *****************************************************************************/ +#define VERIFY_CHIP_INDEX(n) (n < dal_chip_num) + +#define _KERNEL_INTERUPT_PROCESS +static irqreturn_t +intr0_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + + if(poll_intr_trigger[0]) + { + return IRQ_HANDLED; + } + + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[0] = 1; + wake_up(&poll_intr[0]); + } + } + + return IRQ_HANDLED; +} + +static irqreturn_t +intr1_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + if(poll_intr_trigger[1]) + { + return IRQ_HANDLED; + } + + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[1] = 1; + wake_up(&poll_intr[1]); + } + } + + return IRQ_HANDLED; +} + +static irqreturn_t +intr2_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + if(poll_intr_trigger[2]) + { + return IRQ_HANDLED; + } + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[2] = 1; + wake_up(&poll_intr[2]); + } + } + + return IRQ_HANDLED; +} + +static irqreturn_t +intr3_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + if(poll_intr_trigger[3]) + { + return IRQ_HANDLED; + } + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[3] = 1; + wake_up(&poll_intr[3]); + } + } + + return IRQ_HANDLED; +} + +static irqreturn_t +intr4_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + if(poll_intr_trigger[4]) + { + return IRQ_HANDLED; + } + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[4] = 1; + wake_up(&poll_intr[4]); + } + } + + return IRQ_HANDLED; +} + +static irqreturn_t +intr5_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + if(poll_intr_trigger[5]) + { + return IRQ_HANDLED; + } + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[5] = 1; + wake_up(&poll_intr[5]); + } + } + + return IRQ_HANDLED; +} + +static irqreturn_t +intr6_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + if(poll_intr_trigger[6]) + { + return IRQ_HANDLED; + } + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[6] = 1; + wake_up(&poll_intr[6]); + } + } + + return IRQ_HANDLED; +} + +static irqreturn_t +intr7_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + if(poll_intr_trigger[7]) + { + return IRQ_HANDLED; + } + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[7] = 1; + wake_up(&poll_intr[7]); + } + } + + return IRQ_HANDLED; +} + +int +dal_interrupt_register(unsigned int irq, int prio, void (* isr)(void*), void* data) +{ + int ret; + unsigned char str[16]; + unsigned char* int_name = NULL; + unsigned int intr_num_tmp = 0; + unsigned int intr_num = CTC_MAX_INTR_NUM; + unsigned long irq_flags = 0; + + if (dal_intr_num >= CTC_MAX_INTR_NUM) + { + printk("Interrupt numbers exceeds max.\n"); + return -1; + } + + if (msi_used) + { + int_name = "dal_msi"; + } + else + { + int_name = "dal_intr"; + } + + + for (intr_num_tmp=0;intr_num_tmp < CTC_MAX_INTR_NUM; intr_num_tmp++) + { + if (irq == dal_isr[intr_num_tmp].irq) + { + dal_isr[intr_num_tmp].count++; + printk("Interrupt irq %d register count %d.\n", irq, dal_isr[intr_num_tmp].count); + return 0; + } + if ((0 == dal_isr[intr_num_tmp].irq) && (CTC_MAX_INTR_NUM == intr_num)) + { + intr_num = intr_num_tmp; + dal_isr[intr_num].count = 0; + } + } + dal_isr[intr_num].irq = irq; + dal_isr[intr_num].isr = isr; + dal_isr[intr_num].isr_data = data; + dal_isr[intr_num].count++; + + init_waitqueue_head(&poll_intr[intr_num]); + + /* only user mode */ + if ((NULL == isr) && (NULL == data)) + { + snprintf(str, 16, "%s%d", "dal_intr", intr_num); + ret = register_chrdev(DAL_DEV_INTR_MAJOR_BASE + intr_num, + str, &dal_intr_fops[intr_num]); + if (ret < 0) + { + printk("Register character device for irq %d failed, ret= %d", irq, ret); + return ret; + } + } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) + irq_flags = 0; +#else + irq_flags = IRQF_DISABLED; +#endif + if ((ret = request_irq(irq, + intr_handler_fun[intr_num], + irq_flags, + int_name, + &dal_isr[intr_num])) < 0) + { + printk("Cannot request irq %d, ret %d.\n", irq, ret); + unregister_chrdev(DAL_DEV_INTR_MAJOR_BASE + intr_num, str); + } + + if (0 == ret) + { + dal_intr_num++; + } + + return ret; +} + +int +dal_interrupt_unregister(unsigned int irq) +{ + unsigned char str[16]; + int intr_idx = 0; + int find_flag = 0; + + /* get intr device index */ + for (intr_idx = 0; intr_idx < CTC_MAX_INTR_NUM; intr_idx++) + { + if (dal_isr[intr_idx].irq == irq) + { + find_flag = 1; + break; + } + } + + if (find_flag == 0) + { + printk ("irq%d is not registered! unregister failed \n", irq); + return -1; + } + + dal_isr[intr_idx].count--; + if (0 != dal_isr[intr_idx].count) + { + printk("Interrupt irq %d unregister count %d.\n", irq, dal_isr[intr_idx].count); + return -1; + } + snprintf(str, 16, "%s%d", "dal_intr", intr_idx); + + unregister_chrdev(DAL_DEV_INTR_MAJOR_BASE + intr_idx, str); + + free_irq(irq, &dal_isr[intr_idx]); + + dal_isr[intr_idx].irq = 0; + + dal_intr_num--; + + return 0; +} + +int +dal_interrupt_set_en(unsigned int irq, unsigned int enable) +{ + enable ? enable_irq(irq) : disable_irq_nosync(irq); + return 0; +} + +static int +_dal_set_msi_enabe(unsigned int lchip, unsigned int irq_num) +{ + int ret = 0; + + if (irq_num == 1) + { + ret = pci_enable_msi(dal_dev[lchip].pci_dev); + if (ret) + { + printk ("msi enable failed!!! lchip = %d, irq_num = %d\n", lchip, irq_num); + pci_disable_msi(dal_dev[lchip].pci_dev); + msi_used = 0; + } + + msi_irq_base[lchip] = dal_dev[lchip].pci_dev->irq; + msi_irq_num[lchip] = 1; + } + else + { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 79)) + ret = pci_enable_msi_exact(dal_dev[lchip].pci_dev, irq_num); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 26, 32)) + ret = pci_enable_msi_block(dal_dev[lchip].pci_dev, irq_num); +#else + ret = -1; +#endif + if (ret) + { + printk ("msi enable failed!!! lchip = %d, irq_num = %d\n", lchip, irq_num); + pci_disable_msi(dal_dev[lchip].pci_dev); + msi_used = 0; + } + + msi_irq_base[lchip] = dal_dev[lchip].pci_dev->irq; + msi_irq_num[lchip] = irq_num; + } + + return ret; +} + +static int +_dal_set_msi_disable(unsigned int lchip) +{ + + pci_disable_msi(dal_dev[lchip].pci_dev); + + msi_irq_base[lchip] = 0; + msi_irq_num[lchip] = 0; + + return 0; +} + +int +dal_set_msi_cap(unsigned long arg) +{ + int ret = 0; + dal_msi_info_t msi_info; + + if (copy_from_user(&msi_info, (void*)arg, sizeof(dal_msi_info_t))) + { + return -EFAULT; + } + + printk("####dal_set_msi_cap lchip %d base %d num:%d\n", msi_info.lchip, msi_info.irq_base, msi_info.irq_num); + if (msi_info.irq_num > 0) + { + msi_used = 1; + ret = _dal_set_msi_enabe(msi_info.lchip, msi_info.irq_num); + } + else + { + msi_used = 0; + ret = _dal_set_msi_disable(msi_info.lchip); + } + + return ret; +} + +int +dal_user_interrupt_register(unsigned long arg) +{ + int irq = 0; + if (copy_from_user(&irq, (void*)arg, sizeof(int))) + { + return -EFAULT; + } + printk("####register interrupt irq:%d\n", irq); + return dal_interrupt_register(irq, 0, NULL, NULL); +} + +int +dal_user_interrupt_unregister(unsigned long arg) +{ + int irq = 0; + if (copy_from_user(&irq, (void*)arg, sizeof(int))) + { + return -EFAULT; + } + printk("####unregister interrupt irq:%d\n", irq); + return dal_interrupt_unregister(irq); +} + +int +dal_user_interrupt_set_en(unsigned long arg) +{ + dal_intr_parm_t dal_intr_parm; + + if (copy_from_user(&dal_intr_parm, (void*)arg, sizeof(dal_intr_parm_t))) + { + return -EFAULT; + } + + return dal_interrupt_set_en(dal_intr_parm.irq, dal_intr_parm.enable); +} + +/* + * Function: _dal_dma_segment_free + */ + +/* + * Function: _find_largest_segment + * + * Purpose: + * Find largest contiguous segment from a pool of DMA blocks. + * Parameters: + * dseg - DMA segment descriptor + * Returns: + * 0 on success, < 0 on error. + * Notes: + * Assembly stops if a segment of the requested segment size + * has been obtained. + * + * Lower address bits of the DMA blocks are used as follows: + * 0: Untagged + * 1: Discarded block + * 2: Part of largest contiguous segment + * 3: Part of current contiguous segment + */ +#ifndef DMA_MEM_MODE_PLATFORM +static int +_dal_find_largest_segment(dma_segment_t* dseg) +{ + int i, j, blks, found; + unsigned long seg_begin; + unsigned long seg_end; + unsigned long seg_tmp; + + blks = dseg->blk_cnt; + + /* Clear all block tags */ + for (i = 0; i < blks; i++) + { + dseg->blk_ptr[i] &= ~3; + } + + for (i = 0; i < blks && dseg->seg_size < dseg->req_size; i++) + { + /* First block must be an untagged block */ + if ((dseg->blk_ptr[i] & 3) == DAL_UNTAG_BLOCK) + { + /* Initial segment size is the block size */ + seg_begin = dseg->blk_ptr[i]; + seg_end = seg_begin + dseg->blk_size; + dseg->blk_ptr[i] |= DAL_CUR_MATCH_BLOCk; + + /* Loop looking for adjacent blocks */ + do + { + found = 0; + + for (j = i + 1; j < blks && (seg_end - seg_begin) < dseg->req_size; j++) + { + seg_tmp = dseg->blk_ptr[j]; + /* Check untagged blocks only */ + if ((seg_tmp & 3) == DAL_UNTAG_BLOCK) + { + if (seg_tmp == (seg_begin - dseg->blk_size)) + { + /* Found adjacent block below current segment */ + dseg->blk_ptr[j] |= DAL_CUR_MATCH_BLOCk; + seg_begin = seg_tmp; + found = 1; + } + else if (seg_tmp == seg_end) + { + /* Found adjacent block above current segment */ + dseg->blk_ptr[j] |= DAL_CUR_MATCH_BLOCk; + seg_end += dseg->blk_size; + found = 1; + } + } + } + } + while (found); + + if ((seg_end - seg_begin) > dseg->seg_size) + { + /* The current block is largest so far */ + dseg->seg_begin = seg_begin; + dseg->seg_end = seg_end; + dseg->seg_size = seg_end - seg_begin; + + /* Re-tag current and previous largest segment */ + for (j = 0; j < blks; j++) + { + if ((dseg->blk_ptr[j] & 3) == DAL_CUR_MATCH_BLOCk) + { + /* Tag current segment as the largest */ + dseg->blk_ptr[j] &= ~1; + } + else if ((dseg->blk_ptr[j] & 3) == DAL_MATCHED_BLOCK) + { + /* Discard previous largest segment */ + dseg->blk_ptr[j] ^= 3; + } + } + } + else + { + /* Discard all blocks in current segment */ + for (j = 0; j < blks; j++) + { + if ((dseg->blk_ptr[j] & 3) == DAL_CUR_MATCH_BLOCk) + { + dseg->blk_ptr[j] &= ~2; + } + } + } + } + } + + return 0; +} + +/* + * Function: _alloc_dma_blocks + */ +static int +_dal_alloc_dma_blocks(dma_segment_t* dseg, int blks) +{ + int i, start; + unsigned long addr; + + if (dseg->blk_cnt + blks > dseg->blk_cnt_max) + { + printk("No more DMA blocks\n"); + return -1; + } + + start = dseg->blk_cnt; + dseg->blk_cnt += blks; + + for (i = start; i < dseg->blk_cnt; i++) + { + addr = __get_free_pages(GFP_ATOMIC, dseg->blk_order); + if (addr) + { + dseg->blk_ptr[i] = addr; + } + else + { + printk("DMA allocation failed\n"); + return -1; + } + } + + return 0; +} + +/* + * Function: _dal_dma_segment_alloc + */ +static dma_segment_t* +_dal_dma_segment_alloc(unsigned int size, unsigned int blk_size) +{ + dma_segment_t* dseg; + int i, blk_ptr_size; + unsigned long page_addr; + struct sysinfo si; + + /* Sanity check */ + if (size == 0 || blk_size == 0) + { + return NULL; + } + + /* Allocate an initialize DMA segment descriptor */ + if ((dseg = kmalloc(sizeof(dma_segment_t), GFP_ATOMIC)) == NULL) + { + return NULL; + } + + memset(dseg, 0, sizeof(dma_segment_t)); + dseg->req_size = size; + dseg->blk_size = PAGE_ALIGN(blk_size); + + while ((PAGE_SIZE << dseg->blk_order) < dseg->blk_size) + { + dseg->blk_order++; + } + + si_meminfo(&si); + dseg->blk_cnt_max = (si.totalram << PAGE_SHIFT) / dseg->blk_size; + blk_ptr_size = dseg->blk_cnt_max * sizeof(unsigned long); + /* Allocate an initialize DMA block pool */ + dseg->blk_ptr = kmalloc(blk_ptr_size, GFP_KERNEL); + if (dseg->blk_ptr == NULL) + { + kfree(dseg); + return NULL; + } + + memset(dseg->blk_ptr, 0, blk_ptr_size); + /* Allocate minimum number of blocks */ + _dal_alloc_dma_blocks(dseg, dseg->req_size / dseg->blk_size); + + /* Allocate more blocks until we have a complete segment */ + do + { + _dal_find_largest_segment(dseg); + if (dseg->seg_size >= dseg->req_size) + { + break; + } + } + while (_dal_alloc_dma_blocks(dseg, 8) == 0); + + /* Reserve all pages in the DMA segment and free unused blocks */ + for (i = 0; i < dseg->blk_cnt; i++) + { + if ((dseg->blk_ptr[i] & 3) == 2) + { + dseg->blk_ptr[i] &= ~3; + + for (page_addr = dseg->blk_ptr[i]; + page_addr < dseg->blk_ptr[i] + dseg->blk_size; + page_addr += PAGE_SIZE) + { + MEM_MAP_RESERVE(VIRT_TO_PAGE((void*)page_addr)); + } + } + else if (dseg->blk_ptr[i]) + { + dseg->blk_ptr[i] &= ~3; + free_pages(dseg->blk_ptr[i], dseg->blk_order); + dseg->blk_ptr[i] = 0; + } + } + + return dseg; +} + +/* + * Function: _dal_dma_segment_free + */ +static void +_dal_dma_segment_free(dma_segment_t* dseg) +{ + int i; + unsigned long page_addr; + + if (dseg->blk_ptr) + { + for (i = 0; i < dseg->blk_cnt; i++) + { + if (dseg->blk_ptr[i]) + { + for (page_addr = dseg->blk_ptr[i]; + page_addr < dseg->blk_ptr[i] + dseg->blk_size; + page_addr += PAGE_SIZE) + { + MEM_MAP_UNRESERVE(VIRT_TO_PAGE(page_addr)); + } + + free_pages(dseg->blk_ptr[i], dseg->blk_order); + } + } + + kfree(dseg->blk_ptr); + kfree(dseg); + } +} + +/* + * Function: -dal_pgalloc + */ +static void* +_dal_pgalloc(unsigned int size) +{ + dma_segment_t* dseg; + unsigned int blk_size; + + blk_size = (size < DMA_BLOCK_SIZE) ? size : DMA_BLOCK_SIZE; + if ((dseg = _dal_dma_segment_alloc(size, blk_size)) == NULL) + { + return NULL; + } + + if (dseg->seg_size < size) + { + /* If we didn't get the full size then forget it */ + printk("Notice: Can not get enough memory for requset!!\n"); + printk("actual size:0x%lx, request size:0x%x\n", dseg->seg_size, size); + //-_dal_dma_segment_free(dseg); + //-return NULL; + } + + list_add(&dseg->list, &_dma_seg); + return (void*)dseg->seg_begin; +} + +/* + * Function: _dal_pgfree + */ +static int +_dal_pgfree(void* ptr) +{ + struct list_head* pos; + + list_for_each(pos, &_dma_seg) + { + dma_segment_t* dseg = list_entry(pos, dma_segment_t, list); + if (ptr == (void*)dseg->seg_begin) + { + list_del(&dseg->list); + _dal_dma_segment_free(dseg); + return 0; + } + } + return -1; +} +#endif +static void +dal_alloc_dma_pool(int lchip, int size) +{ + if (use_high_memory) + { + dma_phy_base[lchip] = virt_to_bus(high_memory); + dma_virt_base[lchip] = ioremap_nocache(dma_phy_base[lchip], size); + } + else + { +#ifdef DMA_MEM_MODE_PLATFORM + dma_virt_base[lchip] = dma_alloc_coherent(&(dal_dev[lchip].pci_dev->dev), dma_mem_size, + &dma_phy_base[lchip], GFP_KERNEL); + + printk(KERN_WARNING "########Using DMA_MEM_MODE_PLATFORM \n"); +#endif + +#ifndef DMA_MEM_MODE_PLATFORM + /* Get DMA memory from kernel */ + dma_virt_base_tmp[lchip] = _dal_pgalloc(size); + dma_phy_base[lchip] = virt_to_bus(dma_virt_base_tmp[lchip]); + dma_virt_base [lchip]= ioremap_nocache(dma_phy_base[lchip], size); +#endif + } +} + +static void +dal_free_dma_pool(int lchip) +{ + int ret = 0; + ret = ret; + if (use_high_memory) + { + iounmap(dma_virt_base[lchip]); + } + else + { +#ifdef DMA_MEM_MODE_PLATFORM + dma_free_coherent(&(dal_dev[lchip].pci_dev->dev), dma_mem_size, + dma_virt_base[lchip], dma_phy_base[lchip]); +#endif + +#ifndef DMA_MEM_MODE_PLATFORM + iounmap(dma_virt_base[lchip]); + ret = _dal_pgfree(dma_virt_base_tmp[lchip]); + if(ret<0) + { + printk("Dma free memory fail !!!!!! \n"); + } +#endif + } +} + +#define _KERNEL_DAL_IO +static int +_dal_pci_read(unsigned char lchip, unsigned int offset, unsigned int* value) +{ + if (!VERIFY_CHIP_INDEX(lchip)) + { + return -1; + } + + *value = *(volatile unsigned int*)(dal_dev[lchip].logic_address + offset); + return 0; +} + +int +dal_create_irq_mapping(unsigned long arg) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) + dal_irq_mapping_t irq_map; + + if (copy_from_user(&irq_map, (void*)arg, sizeof(dal_irq_mapping_t))) + { + return -EFAULT; + } + + irq_map.sw_irq = irq_create_mapping(NULL, irq_map.hw_irq); + if (irq_map.sw_irq == NO_IRQ) + { + printk("IRQ mapping fail !!!!!! \n"); + return -1; + } + + if (copy_to_user((dal_irq_mapping_t*)arg, (void*)&irq_map, sizeof(dal_irq_mapping_t))) + { + return -EFAULT; + } +#endif + return 0; +} + +int +dal_pci_read(unsigned long arg) +{ + dal_chip_parm_t cmdpara_chip; + + if (copy_from_user(&cmdpara_chip, (void*)arg, sizeof(dal_chip_parm_t))) + { + return -EFAULT; + } + + _dal_pci_read((unsigned char)cmdpara_chip.chip_id, (unsigned int)cmdpara_chip.reg_addr, + (unsigned int*)(&(cmdpara_chip.value))); + + if (copy_to_user((dal_chip_parm_t*)arg, (void*)&cmdpara_chip, sizeof(dal_chip_parm_t))) + { + return -EFAULT; + } + + return 0; +} + +static int +_dal_pci_write(unsigned char lchip, unsigned int offset, unsigned int value) +{ + if (!VERIFY_CHIP_INDEX(lchip)) + { + return -1; + } + + *(volatile unsigned int*)(dal_dev[lchip].logic_address + offset) = value; + return 0; +} + +int +dal_pci_write(unsigned long arg) +{ + dal_chip_parm_t cmdpara_chip; + + if (copy_from_user(&cmdpara_chip, (void*)arg, sizeof(dal_chip_parm_t))) + { + return -EFAULT; + } + + _dal_pci_write((unsigned char)cmdpara_chip.chip_id, (unsigned int)cmdpara_chip.reg_addr, + (unsigned int)cmdpara_chip.value); + + return 0; +} + +int +dal_pci_conf_read(unsigned char lchip, unsigned int offset, unsigned int* value) +{ + if (!VERIFY_CHIP_INDEX(lchip)) + { + return -1; + } + + pci_read_config_dword(dal_dev[lchip].pci_dev, offset, value); + return 0; +} + +int +dal_pci_conf_write(unsigned char lchip, unsigned int offset, unsigned int value) +{ + if (!VERIFY_CHIP_INDEX(lchip)) + { + return -1; + } + + pci_write_config_dword(dal_dev[lchip].pci_dev, offset, value); + return 0; +} +int +dal_user_read_pci_conf(unsigned long arg) +{ + dal_pci_cfg_ioctl_t dal_cfg; + + if (copy_from_user(&dal_cfg, (void*)arg, sizeof(dal_pci_cfg_ioctl_t))) + { + return -EFAULT; + } + + if (dal_pci_conf_read(dal_cfg.chip_id, dal_cfg.offset, &dal_cfg.value)) + { + printk("dal_pci_conf_read failed.\n"); + return -EFAULT; + } + + if (copy_to_user((dal_pci_cfg_ioctl_t*)arg, (void*)&dal_cfg, sizeof(dal_pci_cfg_ioctl_t))) + { + return -EFAULT; + } + + return 0; +} + +int +dal_user_write_pci_conf(unsigned long arg) +{ + dal_pci_cfg_ioctl_t dal_cfg; + + if (copy_from_user(&dal_cfg, (void*)arg, sizeof(dal_pci_cfg_ioctl_t))) + { + return -EFAULT; + } + + return dal_pci_conf_write(dal_cfg.chip_id, dal_cfg.offset, dal_cfg.value); +} + +static int +linux_get_device(unsigned long arg) +{ + dal_user_dev_t user_dev; + int chip_id = 0; + + if (copy_from_user(&user_dev, (void*)arg, sizeof(user_dev))) + { + return -EFAULT; + } + + user_dev.chip_num = dal_chip_num; + chip_id = user_dev.chip_id; + + if (chip_id < dal_chip_num) + { + user_dev.phy_base0 = (unsigned int)dal_dev[chip_id].phys_address; + #ifdef PHYS_ADDR_IS_64BIT + user_dev.phy_base1 = (unsigned int)(dal_dev[chip_id].phys_address >> 32); + #else + user_dev.phy_base1 = 0; + #endif + + user_dev.bus_no = dal_dev[chip_id].pci_dev->bus->number; + user_dev.dev_no = dal_dev[chip_id].pci_dev->device; + user_dev.fun_no = dal_dev[chip_id].pci_dev->devfn; + } + + if (copy_to_user((dal_user_dev_t*)arg, (void*)&user_dev, sizeof(user_dev))) + { + return -EFAULT; + } + + return 0; +} + +/* set dal version, copy to user */ +static int +linux_get_dal_version(unsigned long arg) +{ + int dal_ver = VERSION_1DOT2; /* set dal version */ + + if (copy_to_user((int*)arg, (void*)&dal_ver, sizeof(dal_ver))) + { + return -EFAULT; + } + + dal_version = dal_ver; /* up sw */ + + return 0; +} + +static int +linux_get_dma_info(unsigned long arg) +{ + dma_info_t dma_para; + + if (copy_from_user(&dma_para, (void*)arg, sizeof(dma_info_t))) + { + return -EFAULT; + } + + dma_para.phy_base = (unsigned int)dma_phy_base[dma_para.lchip]; + #ifdef PHYS_ADDR_IS_64BIT + dma_para.phy_base_hi = dma_phy_base[dma_para.lchip] >> 32; + #else + dma_para.phy_base_hi = 0; + #endif + dma_para.size = dma_mem_size; + + if (copy_to_user((dma_info_t*)arg, (void*)&dma_para, sizeof(dma_info_t))) + { + return -EFAULT; + } + + return 0; +} + +static int +dal_get_msi_info(unsigned long arg) +{ + dal_msi_info_t msi_para; + unsigned int lchip = 0; + + /* get lchip form user mode */ + if (copy_from_user(&msi_para, (void*)arg, sizeof(dal_msi_info_t))) + { + return -EFAULT; + } + lchip = msi_para.lchip; + + msi_para.irq_base = msi_irq_base[lchip]; + msi_para.irq_num = msi_irq_num[lchip]; + + /* send msi info to user mode */ + if (copy_to_user((dal_msi_info_t*)arg, (void*)&msi_para, sizeof(dal_msi_info_t))) + { + return -EFAULT; + } + + return 0; +} + + +static int +dal_get_intr_info(unsigned long arg) +{ + dal_intr_info_t intr_para; + unsigned int intr_num = 0; + + /* get lchip form user mode */ + if (copy_from_user(&intr_para, (void*)arg, sizeof(dal_intr_info_t))) + { + return -EFAULT; + } + + intr_para.irq_idx = CTC_MAX_INTR_NUM; + for (intr_num=0; intr_num< CTC_MAX_INTR_NUM; intr_num++) + { + if (intr_para.irq == dal_isr[intr_num].irq) + { + intr_para.irq_idx = intr_num; + break; + } + } + + if (CTC_MAX_INTR_NUM == intr_para.irq_idx) + { + printk("Interrupt %d cann't find.\n", intr_para.irq); + } + /* send msi info to user mode */ + if (copy_to_user((dal_intr_info_t*)arg, (void*)&intr_para, sizeof(dal_intr_info_t))) + { + return -EFAULT; + } + + return 0; +} + +static int +dal_cache_inval(unsigned long arg) +{ + dal_dma_cache_info_t intr_para; + + if (copy_from_user(&intr_para, (void*)arg, sizeof(dal_dma_cache_info_t))) + { + return -EFAULT; + } + +#if 0 + dma_cache_wback_inv((unsigned long)intr_para.ptr, intr_para.length); +#endif + +#if 0 + dma_sync_single_for_cpu(NULL, intr_para.ptr, intr_para.length, DMA_BIDIRECTIONAL); +#endif + + dma_cache_sync(NULL, (void*)intr_para.ptr, intr_para.length, DMA_BIDIRECTIONAL); + + return 0; +} + +static int +dal_cache_flush(unsigned long arg) +{ + dal_dma_cache_info_t intr_para; + + if (copy_from_user(&intr_para, (void*)arg, sizeof(dal_dma_cache_info_t))) + { + return -EFAULT; + } + +#if 0 + dma_cache_wback_inv(intr_para.ptr, intr_para.length); +#endif + +#if 0 + dma_sync_single_for_cpu(NULL, intr_para.ptr, intr_para.length, DMA_BIDIRECTIONAL); +#endif + + dma_cache_sync(NULL, (void*)intr_para.ptr, intr_para.length, DMA_BIDIRECTIONAL); + + return 0; +} + +int +linux_dal_probe(struct pci_dev* pdev, const struct pci_device_id* id) +{ + dal_kern_dev_t* dev = NULL; + int bar = 0; + int ret = 0; + unsigned int temp = 0; + unsigned int lchip = 0; + unsigned int chip_id = 0; + + printk(KERN_WARNING "********found dal device*****\n"); + + for (chip_id = 0; chip_id < DAL_MAX_CHIP_NUM; chip_id ++) + { + if (NULL == dal_dev[chip_id].pci_dev) + { + break; + } + } + + if (chip_id >= DAL_MAX_CHIP_NUM) + { + printk("Exceed max local chip num\n"); + return -1; + } + + dev = &dal_dev[chip_id]; + if (NULL == dev) + { + printk("Cannot obtain PCI resources\n"); + } + + lchip = chip_id; + dal_chip_num += 1; + + dev->pci_dev = pdev; + + if (pci_enable_device(pdev) < 0) + { + printk("Cannot enable PCI device: vendor id = %x, device id = %x\n", + pdev->vendor, pdev->device); + } + + ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); + if (ret) + { + ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (ret) + { + printk("Could not set PCI DMA Mask\n"); + return ret; + } + } + + if (pci_request_regions(pdev, DAL_NAME) < 0) + { + printk("Cannot obtain PCI resources\n"); + } + + dev->phys_address = pci_resource_start(pdev, bar); + dev->logic_address = (uintptr)ioremap_nocache(dev->phys_address, + pci_resource_len(dev->pci_dev, bar)); + + _dal_pci_read(lchip, 0x48, &temp); + if (((temp >> 8) & 0xffff) == 0x3412) + { + printk("Little endian Cpu detected!!! \n"); + _dal_pci_write(lchip, 0x48, 0xFFFFFFFF); + } + + pci_set_master(pdev); + + /* alloc dma_mem_size for every chip */ + if (dma_mem_size) + { + dal_alloc_dma_pool(lchip, dma_mem_size); + #ifdef PHYS_ADDR_IS_64BIT + + /*add check Dma memory pool cannot cross 4G space*/ + if ((0==(dma_phy_base[lchip]>>32)) && (0!=((dma_phy_base[lchip]+dma_mem_size)>>32))) + { + printk("Dma malloc memory cross 4G space!!!!!! \n"); + return -1; + } + #endif + } + + printk(KERN_WARNING "linux_dal_probe end*****\n"); + + return 0; +} + +void +linux_dal_remove(struct pci_dev* pdev) +{ + unsigned int chip_id = 0; + unsigned int flag = 0; + + for (chip_id = 0; chip_id < DAL_MAX_CHIP_NUM; chip_id ++) + { + if (pdev == dal_dev[chip_id].pci_dev) + { + flag = 1; + break; + } + } + + if (1 == flag) + { + dal_free_dma_pool(chip_id); + pci_release_regions(pdev); + pci_disable_device(pdev); + + dal_dev[chip_id].pci_dev = NULL; + dal_chip_num--; + } + + +} + +#ifdef CONFIG_COMPAT +static long +linux_dal_ioctl(struct file* file, + unsigned int cmd, unsigned long arg) +#else + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 13)) +static int +linux_dal_ioctl(struct file* file, + unsigned int cmd, unsigned long arg) +#else +static int +linux_dal_ioctl(struct inode* inode, struct file* file, + unsigned int cmd, unsigned long arg) +#endif + +#endif +{ + switch (cmd) + { + + case CMD_READ_CHIP: + return dal_pci_read(arg); + + case CMD_WRITE_CHIP: + return dal_pci_write(arg); + + case CMD_GET_DEVICES: + return linux_get_device(arg); + + case CMD_GET_DAL_VERSION: + return linux_get_dal_version(arg); + + case CMD_GET_DMA_INFO: + return linux_get_dma_info(arg); + + case CMD_PCI_CONFIG_READ: + return dal_user_read_pci_conf(arg); + + case CMD_PCI_CONFIG_WRITE: + return dal_user_write_pci_conf(arg); + + case CMD_REG_INTERRUPTS: + return dal_user_interrupt_register(arg); + + case CMD_UNREG_INTERRUPTS: + return dal_user_interrupt_unregister(arg); + + case CMD_EN_INTERRUPTS: + return dal_user_interrupt_set_en(arg); + + case CMD_SET_MSI_CAP: + return dal_set_msi_cap(arg); + + case CMD_GET_MSI_INFO: + return dal_get_msi_info(arg); + + case CMD_IRQ_MAPPING: + return dal_create_irq_mapping(arg); + + case CMD_GET_INTR_INFO: + return dal_get_intr_info(arg); + + case CMD_CACHE_INVAL: + return dal_cache_inval(arg); + + case CMD_CACHE_FLUSH: + return dal_cache_flush(arg); + + default: + break; + } + + return 0; +} + +static unsigned int +linux_dal_poll0(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[0], p); + local_irq_save(flags); + if (poll_intr_trigger[0]) + { + poll_intr_trigger[0] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static unsigned int +linux_dal_poll1(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[1], p); + local_irq_save(flags); + if (poll_intr_trigger[1]) + { + poll_intr_trigger[1] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static unsigned int +linux_dal_poll2(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[2], p); + local_irq_save(flags); + if (poll_intr_trigger[2]) + { + poll_intr_trigger[2] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static unsigned int +linux_dal_poll3(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[3], p); + local_irq_save(flags); + if (poll_intr_trigger[3]) + { + poll_intr_trigger[3] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static unsigned int +linux_dal_poll4(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[4], p); + local_irq_save(flags); + if (poll_intr_trigger[4]) + { + poll_intr_trigger[4] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static unsigned int +linux_dal_poll5(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[5], p); + local_irq_save(flags); + if (poll_intr_trigger[5]) + { + poll_intr_trigger[5] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static unsigned int +linux_dal_poll6(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[6], p); + local_irq_save(flags); + if (poll_intr_trigger[6]) + { + poll_intr_trigger[6] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static unsigned int +linux_dal_poll7(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[7], p); + local_irq_save(flags); + if (poll_intr_trigger[7]) + { + poll_intr_trigger[7] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static struct pci_driver linux_dal_driver = +{ + .name = DAL_NAME, + .id_table = dal_id_table, + .probe = linux_dal_probe, + .remove = linux_dal_remove, +}; + +static struct file_operations fops = +{ + .owner = THIS_MODULE, +#ifdef CONFIG_COMPAT + .compat_ioctl = linux_dal_ioctl, + .unlocked_ioctl = linux_dal_ioctl, +#else +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) + .unlocked_ioctl = linux_dal_ioctl, +#else + .ioctl = linux_dal_ioctl, +#endif +#endif +}; + + +static int __init +linux_dal_init(void) +{ + int ret = 0; + + /* Get DMA memory pool size form dal.ok input param, or use default dma_mem_size */ + if (dma_pool_size) + { + if ((dma_pool_size[strlen(dma_pool_size) - 1] & ~0x20) == 'M') + { + dma_mem_size = simple_strtoul(dma_pool_size, NULL, 0); + printk("dma_mem_size: 0x%x \n", dma_mem_size); + + dma_mem_size *= MB_SIZE; + } + else + { + printk("DMA memory pool size must be specified as e.g. dma_pool_size=8M\n"); + } + + if (dma_mem_size & (dma_mem_size - 1)) + { + printk("dma_mem_size must be a power of 2 (1M, 2M, 4M, 8M etc.)\n"); + dma_mem_size = 0; + } + } + + ret = register_chrdev(DAL_DEV_MAJOR, DAL_NAME, &fops); + if (ret < 0) + { + printk(KERN_WARNING "Register linux_dal device, ret %d\n", ret); + return ret; + } + + ret = pci_register_driver(&linux_dal_driver); + if (ret < 0) + { + printk(KERN_WARNING "Register ASIC PCI driver failed, ret %d\n", ret); + return ret; + } + + /* alloc /dev/linux_dal node */ + dal_class = class_create(THIS_MODULE, DAL_NAME); + device_create(dal_class, NULL, MKDEV(DAL_DEV_MAJOR, 0), NULL, DAL_NAME); + + /* init interrupt function */ + intr_handler_fun[0] = intr0_handler; + intr_handler_fun[1] = intr1_handler; + intr_handler_fun[2] = intr2_handler; + intr_handler_fun[3] = intr3_handler; + intr_handler_fun[4] = intr4_handler; + intr_handler_fun[5] = intr5_handler; + intr_handler_fun[6] = intr6_handler; + intr_handler_fun[7] = intr7_handler; + + return ret; +} + +static void __exit +linux_dal_exit(void) +{ + device_destroy(dal_class, MKDEV(DAL_DEV_MAJOR, 0)); + class_destroy(dal_class); + unregister_chrdev(DAL_DEV_MAJOR, "linux_dal"); + pci_unregister_driver(&linux_dal_driver); +} + +module_init(linux_dal_init); +module_exit(linux_dal_exit); + diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_kernel.h b/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_kernel.h new file mode 100644 index 000000000000..de39af67773b --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_kernel.h @@ -0,0 +1,170 @@ +/** + @file dal_kernel_io.h + + @author Copyright (C) 2012 Centec Networks Inc. All rights reserved. + + @date 2012-4-9 + + @version v2.0 + +*/ +#ifndef _DAL_KERNEL_H_ +#define _DAL_KERNEL_H_ +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(CONFIG_RESOURCES_64BIT) || defined(CONFIG_PHYS_ADDR_T_64BIT) +#define PHYS_ADDR_IS_64BIT +#endif + +#ifndef SDK_IN_USERMODE +#ifdef PHYS_ADDR_IS_64BIT +typedef long long intptr; +typedef unsigned long long uintptr; +#else +typedef int intptr; +typedef unsigned int uintptr; +#endif +#endif + +#define DAL_PCI_READ_ADDR 0x0 +#define DAL_PCI_READ_DATA 0xc +#define DAL_PCI_WRITE_ADDR 0x8 +#define DAL_PCI_WRITE_DATA 0x4 +#define DAL_PCI_STATUS 0x10 + +#define DAL_PCI_STATUS_IN_PROCESS 31 +#define DAL_PCI_STATUS_BAD_PARITY 5 +#define DAL_PCI_STATUS_CPU_ACCESS_ERR 4 +#define DAL_PCI_STATUS_READ_CMD 3 +#define DAL_PCI_STATUS_REGISTER_ERR 1 +#define DAL_PCI_STATUS_REGISTER_ACK 0 + +#define DAL_PCI_ACCESS_TIMEOUT 0x64 + +#define DAL_NAME "linux_dal" /* "linux_dal" */ + +#define DAL_DEV_MAJOR 198 + +#define DAL_DEV_INTR_MAJOR_BASE 200 + +#define DAL_DEV_NAME "/dev/" DAL_NAME +#define DAL_ONE_KB 1024 +#define DAL_ONE_MB (1024*1024) +struct dal_chip_parm_s +{ + unsigned int chip_id; /*tmp should be uint8*/ + unsigned int fpga_id; /*tmp add*/ + unsigned int reg_addr; + unsigned int value; +}; +typedef struct dal_chip_parm_s dal_chip_parm_t; + +struct dal_intr_parm_s +{ + unsigned int irq; + unsigned int enable; +}; +typedef struct dal_intr_parm_s dal_intr_parm_t; + +struct dal_irq_mapping_s +{ + unsigned int hw_irq; + unsigned int sw_irq; +}; +typedef struct dal_irq_mapping_s dal_irq_mapping_t; + +struct dal_user_dev_s +{ + unsigned int chip_num; /*output: local chip number*/ + unsigned int chip_id; /*input: local chip id*/ + unsigned int phy_base0; /* low 32bits physical base address */ + unsigned int phy_base1; /* high 32bits physical base address */ + unsigned int bus_no; + unsigned int dev_no; + unsigned int fun_no; + void* virt_base[2]; /* Virtual base address; this must be last member */ +}; +typedef struct dal_user_dev_s dal_user_dev_t; + +struct dma_info_s +{ + unsigned int lchip; + unsigned int phy_base; + unsigned int phy_base_hi; + unsigned int size; + unsigned int* virt_base; +}; +typedef struct dma_info_s dma_info_t; + +struct dal_pci_cfg_ioctl_s +{ + unsigned int chip_id; /* Device ID */ + unsigned int offset; + unsigned int value; +}; +typedef struct dal_pci_cfg_ioctl_s dal_pci_cfg_ioctl_t; + +struct dal_msi_info_s +{ + unsigned int lchip; + unsigned int irq_base; + unsigned int irq_num; +}; +typedef struct dal_msi_info_s dal_msi_info_t; + +struct dal_intr_info_s +{ + unsigned int irq; + unsigned int irq_idx; +}; +typedef struct dal_intr_info_s dal_intr_info_t; + +struct dal_dma_cache_info_s +{ + unsigned long ptr; + unsigned int length; +}; +typedef struct dal_dma_cache_info_s dal_dma_cache_info_t; + +#define CMD_MAGIC 'C' +#define CMD_WRITE_CHIP _IO(CMD_MAGIC, 0) /* for humber ioctrol*/ +#define CMD_READ_CHIP _IO(CMD_MAGIC, 1) /* for humber ioctrol*/ +#define CMD_GET_DEVICES _IO(CMD_MAGIC, 2) +#define CMD_GET_DAL_VERSION _IO(CMD_MAGIC, 3) +#define CMD_PCI_CONFIG_WRITE _IO(CMD_MAGIC, 4) +#define CMD_PCI_CONFIG_READ _IO(CMD_MAGIC, 5) +#define CMD_GET_DMA_INFO _IO(CMD_MAGIC, 6) +#define CMD_REG_INTERRUPTS _IO(CMD_MAGIC, 7) +#define CMD_UNREG_INTERRUPTS _IO(CMD_MAGIC, 8) +#define CMD_EN_INTERRUPTS _IO(CMD_MAGIC, 9) +#define CMD_I2C_READ _IO(CMD_MAGIC, 10) +#define CMD_I2C_WRITE _IO(CMD_MAGIC, 11) +#define CMD_GET_MSI_INFO _IO(CMD_MAGIC, 12) +#define CMD_SET_MSI_CAP _IO(CMD_MAGIC, 13) +#define CMD_IRQ_MAPPING _IO(CMD_MAGIC, 14) +#define CMD_GET_INTR_INFO _IO(CMD_MAGIC, 15) +#define CMD_CACHE_INVAL _IO(CMD_MAGIC, 16) +#define CMD_CACHE_FLUSH _IO(CMD_MAGIC, 17) + +enum dal_version_e +{ + VERSION_MIN, + VERSION_1DOT0, + VERSION_1DOT1, + VERSION_1DOT2, + + VERSION_MAX +}; +typedef enum dal_version_e dal_version_t; + +/* We try to assemble a contiguous segment from chunks of this size */ +#define DMA_BLOCK_SIZE (512 * DAL_ONE_KB) + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_mpool.c b/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_mpool.c new file mode 100644 index 000000000000..82d3b7a917a8 --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_mpool.c @@ -0,0 +1,343 @@ + +#include "dal_mpool.h" + +#ifdef __KERNEL__ +#include +#include + +#define DAL_MALLOC(x) kmalloc(x, GFP_ATOMIC) +#define DAL_FREE(x) kfree(x) + +static spinlock_t dal_mpool_lock; +#define MPOOL_LOCK_INIT() spin_lock_init(&dal_mpool_lock) +#define MPOOL_LOCK() unsigned long flags; spin_lock_irqsave(&dal_mpool_lock, flags) +#define MPOOL_UNLOCK() spin_unlock_irqrestore(&dal_mpool_lock, flags) +#define DAL_PRINT(fmt,arg...) printk(fmt,##arg) +#else /* !__KERNEL__*/ + +#include +#include "sal.h" +#define DAL_MALLOC(x) malloc(x) +#define DAL_FREE(x) free(x) +static sal_mutex_t* dal_mpool_lock; +#define MPOOL_LOCK_INIT() sal_mutex_create(&dal_mpool_lock) +#define MPOOL_LOCK() sal_mutex_lock(dal_mpool_lock) +#define MPOOL_UNLOCK() sal_mutex_unlock(dal_mpool_lock) +#define DAL_PRINT(fmt,arg...) sal_printf(fmt,##arg) + +#endif /* __KERNEL__ */ + +dal_mpool_mem_t* g_free_block_ptr = NULL; + +/* System cache line size */ +#ifndef DAL_CACHE_LINE_BYTES +#define DAL_CACHE_LINE_BYTES 256 +#endif + +static dal_mpool_mem_t* p_desc_pool = NULL; +static dal_mpool_mem_t* p_data_pool = NULL; + +int +dal_mpool_init(void) +{ + MPOOL_LOCK_INIT(); + return 0; +} + +dal_mpool_mem_t* +_dal_mpool_create(void* base, int size, int type) +{ + dal_mpool_mem_t* head = NULL; + dal_mpool_mem_t* tail = NULL; + + head = (dal_mpool_mem_t*)DAL_MALLOC(sizeof(dal_mpool_mem_t)); + if (head == NULL) + { + return NULL; + } + + tail = (dal_mpool_mem_t*)DAL_MALLOC(sizeof(dal_mpool_mem_t)); + if (tail == NULL) + { + DAL_FREE(head); + return NULL; + } + + head->size = tail->size = 0; + head->type = type; + head->address = base; + tail->address = head->address + size; + head->next = tail; + tail->next = NULL; + + return head; +} + +dal_mpool_mem_t* +dal_mpool_create(void* base, int size) +{ + dal_mpool_mem_t* head = NULL; + int mod = (int)(((unsigned long)base) & (DAL_CACHE_LINE_BYTES - 1)); + + MPOOL_LOCK(); + + if (mod) + { + base = (char*)base + (DAL_CACHE_LINE_BYTES - mod); + size -= (DAL_CACHE_LINE_BYTES - mod); + } + + size &= ~(DAL_CACHE_LINE_BYTES - 1); + + /* init for common linkptr, only used for GB */ + head = _dal_mpool_create(base, size, DAL_MPOOL_TYPE_USELESS); + if (NULL == head) + { + MPOOL_UNLOCK(); + return NULL; + } + + /* init for desc linkptr */ + p_desc_pool = _dal_mpool_create(base, DAL_MPOOL_MAX_DESX_SIZE, DAL_MPOOL_TYPE_DESC); + if (NULL == p_desc_pool) + { + MPOOL_UNLOCK(); + DAL_FREE(head->next); + DAL_FREE(head); + return NULL; + } + + /* init for data linkptr */ + p_data_pool = _dal_mpool_create(((char*)base+DAL_MPOOL_MAX_DESX_SIZE), (size - DAL_MPOOL_MAX_DESX_SIZE), DAL_MPOOL_TYPE_DATA); + if (NULL == p_data_pool) + { + MPOOL_UNLOCK(); + DAL_FREE(head->next); + DAL_FREE(head); + DAL_FREE(p_desc_pool->next); + DAL_FREE(p_desc_pool); + return NULL; + } + + MPOOL_UNLOCK(); + + return head; +} + +dal_mpool_mem_t* +_dal_mpool_alloc_comon(dal_mpool_mem_t* ptr, int size, int type) +{ + dal_mpool_mem_t* new_ptr = NULL; + + while (ptr && ptr->next) + { + if (ptr->next->address - (ptr->address + ptr->size) >= size) + { + break; + } + + ptr = ptr->next; + } + + if (!(ptr && ptr->next)) + { + return NULL; + } + + new_ptr = DAL_MALLOC(sizeof(dal_mpool_mem_t)); + if (!new_ptr) + { + return NULL; + } + + new_ptr->type = type; + new_ptr->address = ptr->address + ptr->size; + new_ptr->size = size; + new_ptr->next = ptr->next; + ptr->next = new_ptr; + + return new_ptr; +} + +void* +dal_mpool_alloc(dal_mpool_mem_t* pool, int size, int type) +{ + dal_mpool_mem_t* ptr = NULL; + dal_mpool_mem_t* new_ptr = NULL; + int mod; + + MPOOL_LOCK(); + + mod = size & (DAL_CACHE_LINE_BYTES - 1); + if (mod != 0) + { + size += (DAL_CACHE_LINE_BYTES - mod); + } + + switch(type) + { + case DAL_MPOOL_TYPE_USELESS: + ptr = pool; + new_ptr = _dal_mpool_alloc_comon(ptr, size, type); + if (NULL == new_ptr) + { + MPOOL_UNLOCK(); + return NULL; + } + break; + case DAL_MPOOL_TYPE_DESC: + ptr = p_desc_pool; + new_ptr = _dal_mpool_alloc_comon(ptr, size, type); + if (NULL == new_ptr) + { + MPOOL_UNLOCK(); + return NULL; + } + break; + case DAL_MPOOL_TYPE_DATA: + ptr = p_data_pool; + new_ptr = _dal_mpool_alloc_comon(ptr, size, type); + if (NULL == new_ptr) + { + MPOOL_UNLOCK(); + return NULL; + } + break; + default: + MPOOL_UNLOCK(); + return NULL; + break; + } + + MPOOL_UNLOCK(); + + return new_ptr->address; +} + +void +_dal_mpool_free(dal_mpool_mem_t* ptr, void* addr, int type) +{ + unsigned char* address = (unsigned char*)addr; + dal_mpool_mem_t* prev = NULL; + + while (ptr && ptr->next) + { + if (ptr->next->address == address) + { + break; + } + + ptr = ptr->next; + } + + if (ptr && ptr->next) + { + prev = ptr; + ptr = ptr->next; + prev->next = ptr->next; + DAL_FREE(ptr); + } + + return; +} + +void +dal_mpool_free(dal_mpool_mem_t* pool, void* addr) +{ + dal_mpool_mem_t* ptr = pool; + + MPOOL_LOCK(); + + switch(pool->type) + { + case DAL_MPOOL_TYPE_USELESS: + ptr = pool; + _dal_mpool_free(ptr, addr, DAL_MPOOL_TYPE_USELESS); + break; + case DAL_MPOOL_TYPE_DESC: + ptr = p_desc_pool; + _dal_mpool_free(ptr, addr, DAL_MPOOL_TYPE_DESC); + break; + case DAL_MPOOL_TYPE_DATA: + ptr = p_data_pool; + _dal_mpool_free(ptr, addr, DAL_MPOOL_TYPE_DATA); + break; + default: + break; + } + + MPOOL_UNLOCK(); + return; +} + +int +dal_mpool_destroy(dal_mpool_mem_t* pool) +{ + dal_mpool_mem_t* ptr, * next; + + MPOOL_LOCK(); + + for (ptr = pool; ptr; ptr = next) + { + next = ptr->next; + DAL_FREE(ptr); + } + + for (ptr = p_desc_pool; ptr; ptr = next) + { + next = ptr->next; + DAL_FREE(ptr); + } + + for (ptr = p_data_pool; ptr; ptr = next) + { + next = ptr->next; + DAL_FREE(ptr); + } + + MPOOL_UNLOCK(); + + return 0; +} + +int +dal_mpool_usage(dal_mpool_mem_t* pool, int type) +{ + int usage = 0; + dal_mpool_mem_t* ptr; + + MPOOL_LOCK(); + + for (ptr = pool; ptr; ptr = ptr->next) + { + if (ptr->type == type || ptr->type == -1) + { + usage += ptr->size; + } + } + + MPOOL_UNLOCK(); + + return usage; +} + +int +dal_mpool_debug(dal_mpool_mem_t* pool) +{ + dal_mpool_mem_t* ptr; + int index = 0; + + MPOOL_LOCK(); + + for (ptr = pool; ptr; ptr = ptr->next) + { +// DAL_PRINT("%2dst mpool block: address=0x%8x, size=0x%x \n", index, (unsigned int)ptr->address, ptr->size); + DAL_PRINT("%2dst mpool block: address=%p, size=0x%x \n", index, ptr->address, ptr->size); // note + index++; + } + + MPOOL_UNLOCK(); + + return 0; +} + diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_mpool.h b/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_mpool.h new file mode 100644 index 000000000000..a1fa37d05f82 --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/48x2q4z/modules/dal_mpool.h @@ -0,0 +1,71 @@ +/** + @file dal_mpool.h + + @author Copyright (C) 2011 Centec Networks Inc. All rights reserved. + + @date 2012-5-10 + + @version v2.0 + + This file contains the dma memory init, allocation and free APIs +*/ + +#ifndef _DMA_MPOOL_H +#define _DMA_MPOOL_H +#ifdef __cplusplus +extern "C" { +#endif + +#define DAL_MPOOL_MAX_DESX_SIZE (1024*1024) + +enum dal_mpool_type_e +{ + DAL_MPOOL_TYPE_USELESS, /* just compatible with GB */ + DAL_MPOOL_TYPE_DESC, /* dma mpool op for desc */ + DAL_MPOOL_TYPE_DATA /* dma mpool op for data */ +}; +typedef enum dal_mpool_type_e dal_mpool_type_t; + +struct dal_mpool_mem_s +{ + unsigned char* address; + int size; + int type; + struct dal_mpool_mem_s* next; +}; +typedef struct dal_mpool_mem_s dal_mpool_mem_t; + +/** + @brief This function is to alloc dma memory + + @param[in] size size of memory + + @return NULL + +*/ +extern int +dal_mpool_init(void); + +extern dal_mpool_mem_t* +dal_mpool_create(void* base_ptr, int size); + +extern void* +dal_mpool_alloc(dal_mpool_mem_t* pool, int size, int type); + +extern void +dal_mpool_free(dal_mpool_mem_t* pool, void* addr); + +extern int +dal_mpool_destroy(dal_mpool_mem_t* pool); + +extern int +dal_mpool_usage(dal_mpool_mem_t* pool, int type); + +extern int +dal_mpool_debug(dal_mpool_mem_t* pool); +#ifdef __cplusplus +} +#endif + +#endif /* !_DMA_MPOOL_H */ + diff --git a/platform/centec/sonic-platform-modules-e582/48x2q4z/scripts/48x2q4z_platform.sh b/platform/centec/sonic-platform-modules-e582/48x2q4z/scripts/48x2q4z_platform.sh new file mode 100755 index 000000000000..2caae94f03e7 --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/48x2q4z/scripts/48x2q4z_platform.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +#platform init script for centec e582-48x2q4z + +init_devnum() { + found=0 + for devnum in 0 1; do + devname=`cat /sys/bus/i2c/devices/i2c-${devnum}/name` + # I801 adapter can be at either dffd0000 or dfff0000 + if [[ $devname == 'SMBus I801 adapter at '* ]]; then + found=1 + break + fi + done + + [ $found -eq 0 ] && echo "cannot find I801" && exit 1 +} + +init_devnum + +if [ "$1" == "init" ]; then + depmod -a + modprobe i2c-dev + modprobe i2c-mux-pca954x force_deselect_on_exit=1 + modprobe centec_e582_48x2q4z_platform + modprobe dal + modprobe centec_at24c64 +elif [ "$1" == "deinit" ]; then + modprobe -r centec_at24c64 + modprobe -r dal + modprobe -r centec_e582_48x2q4z_platform + modprobe -r i2c-mux-pca954x + modprobe -r i2c-dev +else + echo "e582-48x2q4z_platform : Invalid option !" +fi diff --git a/platform/centec/sonic-platform-modules-e582/48x6q/cfg/48x6q-modules.conf b/platform/centec/sonic-platform-modules-e582/48x6q/cfg/48x6q-modules.conf new file mode 100644 index 000000000000..7a7881c8c0d3 --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/48x6q/cfg/48x6q-modules.conf @@ -0,0 +1,14 @@ +# /etc/modules: kernel modules to load at boot time. +# +# This file contains the names of kernel modules that should be loaded +# at boot time, one per line. Lines beginning with "#" are ignored. + +i2c-i801 +i2c-dev +i2c-mux +i2c-smbus + +i2c-mux-pca954x +lm77 +adt7470 +tun diff --git a/platform/centec/sonic-platform-modules-e582/48x6q/cfg/config_db.json b/platform/centec/sonic-platform-modules-e582/48x6q/cfg/config_db.json new file mode 100644 index 000000000000..c75eb1284f66 --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/48x6q/cfg/config_db.json @@ -0,0 +1,303 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "bgp_asn": 65100, + "deployment_id": null, + "hostname": "switch1", + "type": "LeafRouter", + "hwsku": "E582-48x6q" + + } + }, + "BGP_PEER_RANGE": {}, + "VLAN": {}, + "PORT": { + "Ethernet1": { + "alias": "Ethernet1", + "lanes": "4", + "speed": "1000" + }, + "Ethernet2": { + "alias": "Ethernet2", + "lanes": "5", + "speed": "1000" + }, + "Ethernet3": { + "alias": "Ethernet3", + "lanes": "6", + "speed": "1000" + }, + "Ethernet4": { + "alias": "Ethernet4", + "lanes": "8", + "speed": "1000" + }, + "Ethernet5": { + "alias": "Ethernet5", + "lanes": "9", + "speed": "1000" + }, + "Ethernet6": { + "alias": "Ethernet6", + "lanes": "10", + "speed": "1000" + }, + "Ethernet7": { + "alias": "Ethernet7", + "lanes": "12", + "speed": "1000" + }, + "Ethernet8": { + "alias": "Ethernet8", + "lanes": "13", + "speed": "1000" + }, + "Ethernet9": { + "alias": "Ethernet9", + "lanes": "14", + "speed": "1000" + }, + "Ethernet10": { + "alias": "Ethernet10", + "lanes": "16", + "speed": "1000" + }, + "Ethernet11": { + "alias": "Ethernet11", + "lanes": "17", + "speed": "1000" + }, + "Ethernet12": { + "alias": "Ethernet12", + "lanes": "18", + "speed": "1000" + }, + "Ethernet13": { + "alias": "Ethernet13", + "lanes": "20", + "speed": "10000" + }, + "Ethernet14": { + "alias": "Ethernet14", + "lanes": "21", + "speed": "10000" + }, + "Ethernet15": { + "alias": "Ethernet15", + "lanes": "22", + "speed": "10000" + }, + "Ethernet16": { + "alias": "Ethernet16", + "lanes": "24", + "speed": "10000" + }, + "Ethernet17": { + "alias": "Ethernet17", + "lanes": "25", + "speed": "10000" + }, + "Ethernet18": { + "alias": "Ethernet18", + "lanes": "26", + "speed": "10000" + }, + "Ethernet19": { + "alias": "Ethernet19", + "lanes": "28", + "speed": "10000" + }, + "Ethernet20": { + "alias": "Ethernet20", + "lanes": "30", + "speed": "10000" + }, + "Ethernet21": { + "alias": "Ethernet21", + "lanes": "31", + "speed": "10000" + }, + "Ethernet22": { + "alias": "Ethernet22", + "lanes": "32", + "speed": "10000" + }, + "Ethernet23": { + "alias": "Ethernet23", + "lanes": "34", + "speed": "10000" + }, + "Ethernet24": { + "alias": "Ethernet24", + "lanes": "35", + "speed": "10000" + }, + "Ethernet25": { + "alias": "Ethernet25", + "lanes": "40", + "speed": "10000" + }, + "Ethernet26": { + "alias": "Ethernet26", + "lanes": "41", + "speed": "10000" + }, + "Ethernet27": { + "alias": "Ethernet27", + "lanes": "43", + "speed": "10000" + }, + "Ethernet28": { + "alias": "Ethernet28", + "lanes": "36", + "speed": "10000" + }, + "Ethernet29": { + "alias": "Ethernet29", + "lanes": "37", + "speed": "10000" + }, + "Ethernet30": { + "alias": "Ethernet30", + "lanes": "39", + "speed": "10000" + }, + "Ethernet31": { + "alias": "Ethernet31", + "lanes": "44", + "speed": "10000" + }, + "Ethernet32": { + "alias": "Ethernet32", + "lanes": "45", + "speed": "10000" + }, + "Ethernet33": { + "alias": "Ethernet33", + "lanes": "46", + "speed": "10000" + }, + "Ethernet34": { + "alias": "Ethernet34", + "lanes": "47", + "speed": "10000" + }, + "Ethernet35": { + "alias": "Ethernet35", + "lanes": "80", + "speed": "10000" + }, + "Ethernet36": { + "alias": "Ethernet36", + "lanes": "81", + "speed": "10000" + }, + "Ethernet37": { + "alias": "Ethernet37", + "lanes": "82", + "speed": "10000" + }, + "Ethernet38": { + "alias": "Ethernet38", + "lanes": "88", + "speed": "10000" + }, + "Ethernet39": { + "alias": "Ethernet39", + "lanes": "89", + "speed": "10000" + }, + "Ethernet40": { + "alias": "Ethernet40", + "lanes": "90", + "speed": "10000" + }, + "Ethernet41": { + "alias": "Ethernet41", + "lanes": "84", + "speed": "10000" + }, + "Ethernet42": { + "alias": "Ethernet42", + "lanes": "85", + "speed": "10000" + }, + "Ethernet43": { + "alias": "Ethernet43", + "lanes": "86", + "speed": "10000" + }, + "Ethernet44": { + "alias": "Ethernet44", + "lanes": "87", + "speed": "10000" + }, + "Ethernet45": { + "alias": "Ethernet45", + "lanes": "92", + "speed": "10000" + }, + "Ethernet46": { + "alias": "Ethernet46", + "lanes": "93", + "speed": "10000" + }, + "Ethernet47": { + "alias": "Ethernet47", + "lanes": "94", + "speed": "10000" + }, + "Ethernet48": { + "alias": "Ethernet48", + "lanes": "95", + "speed": "10000" + }, + "Ethernet49": { + "alias": "Ethernet49", + "lanes": "52,53,54,55", + "speed": "40000" + }, + "Ethernet50": { + "alias": "Ethernet50", + "lanes": "56,57,58,59", + "speed": "40000" + }, + "Ethernet51": { + "alias": "Ethernet51", + "lanes": "60,61,62,63", + "speed": "40000" + }, + "Ethernet52": { + "alias": "Ethernet52", + "lanes": "68,69,70,71", + "speed": "40000" + }, + "Ethernet53": { + "alias": "Ethernet53", + "lanes": "72,73,74,75", + "speed": "40000" + }, + "Ethernet54": { + "alias": "Ethernet54", + "lanes": "76,77,78,79", + "speed": "40000" + } + }, + "SYSLOG_SERVER": {}, + "VLAN_INTERFACE": {}, + "PORTCHANNEL_INTERFACE": {}, + "PORTCHANNEL": {}, + "MGMT_INTERFACE": {}, + "DHCP_SERVER": {}, + "LOOPBACK_INTERFACE": { + "Loopback0|127.0.0.1/8": {} + }, + "ACL_TABLE": {}, + "INTERFACE": { + "Ethernet1|192.168.1.1/24": {}, + "Ethernet2|192.168.2.1/24": {}, + "Ethernet3|192.168.3.1/24": {}, + "Ethernet4|192.168.4.1/24": {} + } +} + diff --git a/platform/centec/sonic-platform-modules-e582/48x6q/cfg/config_db_l2l3.json b/platform/centec/sonic-platform-modules-e582/48x6q/cfg/config_db_l2l3.json new file mode 100644 index 000000000000..e9d9a3bb5e4b --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/48x6q/cfg/config_db_l2l3.json @@ -0,0 +1,610 @@ +{ + "QUEUE": { + "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|0-2": { + "wred_profile": "[WRED_PROFILE|AZURE_LOSSY]" + }, + "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|3-4": { + "wred_profile": "[WRED_PROFILE|AZURE_LOSSLESS]", + "scheduler": "[SCHEDULER|scheduler.0]" + }, + "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54|5-7": { + "wred_profile": "[WRED_PROFILE|AZURE_LOSSY]" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSLESS": { + "red_max_threshold": "32760", + "yellow_max_threshold": "32760", + "green_min_threshold": "4095", + "red_min_threshold": "4095", + "yellow_min_threshold": "4095", + "green_max_threshold": "32760", + "wred_yellow_enable": "true", + "wred_green_enable": "true" + }, + "AZURE_LOSSY": { + "red_max_threshold": "32760", + "yellow_max_threshold": "32760", + "green_min_threshold": "4095", + "red_min_threshold": "4095", + "yellow_min_threshold": "4095", + "green_max_threshold": "32760", + "wred_yellow_enable": "true", + "wred_green_enable": "true" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "56": "7", + "54": "6", + "28": "3", + "48": "6", + "29": "3", + "60": "7", + "61": "7", + "62": "7", + "63": "7", + "49": "6", + "34": "4", + "24": "3", + "25": "3", + "26": "3", + "27": "3", + "20": "2", + "21": "2", + "22": "2", + "23": "2", + "46": "5", + "47": "5", + "44": "5", + "45": "5", + "42": "5", + "43": "5", + "40": "5", + "41": "5", + "1": "0", + "0": "0", + "3": "0", + "2": "0", + "5": "0", + "4": "0", + "7": "0", + "6": "0", + "9": "1", + "8": "1", + "35": "4", + "13": "1", + "12": "1", + "15": "1", + "58": "7", + "11": "1", + "10": "1", + "39": "4", + "38": "4", + "59": "7", + "14": "1", + "17": "2", + "16": "2", + "19": "2", + "18": "2", + "31": "3", + "30": "3", + "51": "6", + "36": "4", + "53": "6", + "52": "6", + "33": "4", + "55": "6", + "37": "4", + "32": "4", + "57": "7", + "50": "6" + } + }, + "DEVICE_METADATA": { + "localhost": { + "hwsku": "E582-48x6q", + "hostname": "switch1", + "bgp_asn": "None", + "deployment_id": "None", + "type": "LeafRouter" + } + }, + "PORT": { + "Ethernet1": { + "alias": "Ethernet1", + "lanes": "4", + "speed": "1000" + }, + "Ethernet2": { + "alias": "Ethernet2", + "lanes": "5", + "speed": "1000" + }, + "Ethernet3": { + "alias": "Ethernet3", + "lanes": "6", + "speed": "1000" + }, + "Ethernet4": { + "alias": "Ethernet4", + "lanes": "8", + "speed": "1000" + }, + "Ethernet5": { + "alias": "Ethernet5", + "lanes": "9", + "speed": "1000" + }, + "Ethernet6": { + "alias": "Ethernet6", + "lanes": "10", + "speed": "1000" + }, + "Ethernet7": { + "alias": "Ethernet7", + "lanes": "12", + "speed": "1000" + }, + "Ethernet8": { + "alias": "Ethernet8", + "lanes": "13", + "speed": "1000" + }, + "Ethernet9": { + "alias": "Ethernet9", + "lanes": "14", + "speed": "1000" + }, + "Ethernet10": { + "alias": "Ethernet10", + "lanes": "16", + "speed": "1000" + }, + "Ethernet11": { + "alias": "Ethernet11", + "lanes": "17", + "speed": "1000" + }, + "Ethernet12": { + "alias": "Ethernet12", + "lanes": "18", + "speed": "1000" + }, + "Ethernet13": { + "alias": "Ethernet13", + "lanes": "20", + "speed": "10000" + }, + "Ethernet14": { + "alias": "Ethernet14", + "lanes": "21", + "speed": "10000" + }, + "Ethernet15": { + "alias": "Ethernet15", + "lanes": "22", + "speed": "10000" + }, + "Ethernet16": { + "alias": "Ethernet16", + "lanes": "24", + "speed": "10000" + }, + "Ethernet17": { + "alias": "Ethernet17", + "lanes": "25", + "speed": "10000" + }, + "Ethernet18": { + "alias": "Ethernet18", + "lanes": "26", + "speed": "10000" + }, + "Ethernet19": { + "alias": "Ethernet19", + "lanes": "28", + "speed": "10000" + }, + "Ethernet20": { + "alias": "Ethernet20", + "lanes": "30", + "speed": "10000" + }, + "Ethernet21": { + "alias": "Ethernet21", + "lanes": "31", + "speed": "10000" + }, + "Ethernet22": { + "alias": "Ethernet22", + "lanes": "32", + "speed": "10000" + }, + "Ethernet23": { + "alias": "Ethernet23", + "lanes": "34", + "speed": "10000" + }, + "Ethernet24": { + "alias": "Ethernet24", + "lanes": "35", + "speed": "10000" + }, + "Ethernet25": { + "alias": "Ethernet25", + "lanes": "40", + "speed": "10000" + }, + "Ethernet26": { + "alias": "Ethernet26", + "lanes": "41", + "speed": "10000" + }, + "Ethernet27": { + "alias": "Ethernet27", + "lanes": "43", + "speed": "10000" + }, + "Ethernet28": { + "alias": "Ethernet28", + "lanes": "36", + "speed": "10000" + }, + "Ethernet29": { + "alias": "Ethernet29", + "lanes": "37", + "speed": "10000" + }, + "Ethernet30": { + "alias": "Ethernet30", + "lanes": "39", + "speed": "10000" + }, + "Ethernet31": { + "alias": "Ethernet31", + "lanes": "44", + "speed": "10000" + }, + "Ethernet32": { + "alias": "Ethernet32", + "lanes": "45", + "speed": "10000" + }, + "Ethernet33": { + "alias": "Ethernet33", + "lanes": "46", + "speed": "10000" + }, + "Ethernet34": { + "alias": "Ethernet34", + "lanes": "47", + "speed": "10000" + }, + "Ethernet35": { + "alias": "Ethernet35", + "lanes": "80", + "speed": "10000" + }, + "Ethernet36": { + "alias": "Ethernet36", + "lanes": "81", + "speed": "10000" + }, + "Ethernet37": { + "alias": "Ethernet37", + "lanes": "82", + "speed": "10000" + }, + "Ethernet38": { + "alias": "Ethernet38", + "lanes": "88", + "speed": "10000" + }, + "Ethernet39": { + "alias": "Ethernet39", + "lanes": "89", + "speed": "10000" + }, + "Ethernet40": { + "alias": "Ethernet40", + "lanes": "90", + "speed": "10000" + }, + "Ethernet41": { + "alias": "Ethernet41", + "lanes": "84", + "speed": "10000" + }, + "Ethernet42": { + "alias": "Ethernet42", + "lanes": "85", + "speed": "10000" + }, + "Ethernet43": { + "alias": "Ethernet43", + "lanes": "86", + "speed": "10000" + }, + "Ethernet44": { + "alias": "Ethernet44", + "lanes": "87", + "speed": "10000" + }, + "Ethernet45": { + "alias": "Ethernet45", + "lanes": "92", + "speed": "10000" + }, + "Ethernet46": { + "alias": "Ethernet46", + "lanes": "93", + "speed": "10000" + }, + "Ethernet47": { + "alias": "Ethernet47", + "lanes": "94", + "speed": "10000" + }, + "Ethernet48": { + "alias": "Ethernet48", + "lanes": "95", + "speed": "10000" + }, + "Ethernet49": { + "alias": "Ethernet49", + "lanes": "52,53,54,55", + "speed": "40000" + }, + "Ethernet50": { + "alias": "Ethernet50", + "lanes": "56,57,58,59", + "speed": "40000" + }, + "Ethernet51": { + "alias": "Ethernet51", + "lanes": "60,61,62,63", + "speed": "40000" + }, + "Ethernet52": { + "alias": "Ethernet52", + "lanes": "68,69,70,71", + "speed": "40000" + }, + "Ethernet53": { + "alias": "Ethernet53", + "lanes": "72,73,74,75", + "speed": "40000" + }, + "Ethernet54": { + "alias": "Ethernet54", + "lanes": "76,77,78,79", + "speed": "40000" + } + }, + "PORT_QOS_MAP": { + "Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54": { + "pfc_enable": "3,4", + "dscp_to_tc_map": "[DSCP_TO_TC_MAP|AZURE]" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type": "DWRR", + "weight": "25" + }, + "scheduler.1": { + "type": "DWRR", + "weight": "30" + }, + "scheduler.2": { + "type": "DWRR", + "weight": "20" + } + }, + "VLAN": { + "Vlan500": { + "dhcp_servers": [ + "192.168.5.1", + "192.168.5.2", + "192.168.5.3", + "192.168.5.4" + ], + "members": [ + "Ethernet5", + "Ethernet6", + "Ethernet7", + "Ethernet8" + ], + "vlanid": "500" + }, + "Vlan600": { + "dhcp_servers": [ + "192.168.6.1", + "192.168.6.2", + "192.168.6.3", + "192.168.6.4" + ], + "members": [ + "Ethernet5", + "Ethernet6" + ], + "vlanid": "600" + }, + "Vlan700": { + "dhcp_servers": [ + "192.168.7.1", + "192.168.7.2", + "192.168.7.3", + "192.168.7.4" + ], + "members": [ + "Ethernet5", + "Ethernet7" + ], + "vlanid": "700" + }, + "Vlan800": { + "dhcp_servers": [ + "192.168.8.1", + "192.168.8.2", + "192.168.8.3", + "192.168.8.4" + ], + "members": [ + "Ethernet5", + "Ethernet8" + ], + "vlanid": "800" + } + }, + "VLAN_MEMBER": { + "Vlan500|Ethernet5": { + "tagging_mode": "tagged" + }, + "Vlan500|Ethernet6": { + "tagging_mode": "untagged" + }, + "Vlan500|Ethernet7": { + "tagging_mode": "untagged" + }, + "Vlan500|Ethernet8": { + "tagging_mode": "untagged" + }, + "Vlan600|Ethernet5": { + "tagging_mode": "tagged" + }, + "Vlan600|Ethernet6": { + "tagging_mode": "tagged" + }, + "Vlan700|Ethernet5": { + "tagging_mode": "tagged" + }, + "Vlan700|Ethernet7": { + "tagging_mode": "tagged" + }, + "Vlan800|Ethernet5": { + "tagging_mode": "tagged" + }, + "Vlan800|Ethernet8": { + "tagging_mode": "tagged" + } + }, + "INTERFACE": { + "Ethernet1|192.168.1.1/24": {}, + "Ethernet2|192.168.2.1/24": {}, + "Ethernet3|192.168.3.1/24": {}, + "Ethernet4|192.168.4.1/24": {} + }, + "VLAN_INTERFACE": { + "Vlan500|192.168.5.1/24": {}, + "Vlan600|192.168.6.1/24": {}, + "Vlan700|192.168.7.1/24": {}, + "Vlan800|192.168.8.1/24": {} + }, + "LOOPBACK_INTERFACE": { + "Loopback0|127.0.0.1/8": {} + }, + "CABLE_LENGTH": { + "AZURE": { + "Ethernet8": "40m", + "Ethernet9": "40m", + "Ethernet2": "40m", + "Ethernet3": "40m", + "Ethernet1": "40m", + "Ethernet6": "40m", + "Ethernet7": "40m", + "Ethernet4": "40m", + "Ethernet5": "40m", + "Ethernet22": "40m", + "Ethernet50": "40m", + "Ethernet51": "40m", + "Ethernet52": "40m", + "Ethernet53": "40m", + "Ethernet54": "40m", + "Ethernet38": "40m", + "Ethernet39": "40m", + "Ethernet18": "40m", + "Ethernet19": "40m", + "Ethernet14": "40m", + "Ethernet15": "40m", + "Ethernet16": "40m", + "Ethernet17": "40m", + "Ethernet10": "40m", + "Ethernet11": "40m", + "Ethernet12": "40m", + "Ethernet35": "40m", + "Ethernet37": "40m", + "Ethernet32": "40m", + "Ethernet33": "40m", + "Ethernet30": "40m", + "Ethernet31": "40m", + "Ethernet49": "40m", + "Ethernet48": "40m", + "Ethernet47": "40m", + "Ethernet36": "40m", + "Ethernet45": "40m", + "Ethernet44": "40m", + "Ethernet43": "40m", + "Ethernet42": "40m", + "Ethernet41": "40m", + "Ethernet40": "40m", + "Ethernet29": "40m", + "Ethernet28": "40m", + "Ethernet34": "40m", + "Ethernet46": "40m", + "Ethernet21": "40m", + "Ethernet20": "40m", + "Ethernet23": "40m", + "Ethernet13": "40m", + "Ethernet25": "40m", + "Ethernet24": "40m", + "Ethernet27": "40m", + "Ethernet26": "40m" + } + }, + "CRM": { + "Config": { + "acl_table_threshold_type": "percentage", + "nexthop_group_threshold_type": "percentage", + "fdb_entry_high_threshold": "85", + "acl_entry_threshold_type": "percentage", + "ipv6_neighbor_low_threshold": "70", + "nexthop_group_member_low_threshold": "70", + "acl_group_high_threshold": "85", + "ipv4_route_high_threshold": "85", + "acl_counter_high_threshold": "85", + "ipv4_route_low_threshold": "70", + "ipv4_route_threshold_type": "percentage", + "ipv4_neighbor_low_threshold": "70", + "acl_group_threshold_type": "percentage", + "ipv4_nexthop_high_threshold": "85", + "ipv6_route_threshold_type": "percentage", + "nexthop_group_low_threshold": "70", + "ipv4_neighbor_high_threshold": "85", + "ipv6_route_high_threshold": "85", + "ipv6_nexthop_threshold_type": "percentage", + "polling_interval": "300", + "ipv4_nexthop_threshold_type": "percentage", + "acl_group_low_threshold": "70", + "acl_entry_low_threshold": "70", + "nexthop_group_member_threshold_type": "percentage", + "ipv4_nexthop_low_threshold": "70", + "acl_counter_threshold_type": "percentage", + "ipv6_neighbor_high_threshold": "85", + "nexthop_group_member_high_threshold": "85", + "acl_table_low_threshold": "70", + "fdb_entry_threshold_type": "percentage", + "ipv6_neighbor_threshold_type": "percentage", + "acl_table_high_threshold": "85", + "ipv6_nexthop_low_threshold": "70", + "acl_counter_low_threshold": "70", + "ipv4_neighbor_threshold_type": "percentage", + "nexthop_group_high_threshold": "85", + "ipv6_route_low_threshold": "70", + "acl_entry_high_threshold": "85", + "fdb_entry_low_threshold": "70", + "ipv6_nexthop_high_threshold": "85" + } + } +} diff --git a/platform/centec/sonic-platform-modules-e582/48x6q/cfg/minigraph.xml b/platform/centec/sonic-platform-modules-e582/48x6q/cfg/minigraph.xml new file mode 100644 index 000000000000..fc313eb84635 --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/48x6q/cfg/minigraph.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + switch1 + + + + + + + + + + + + + switch1 + E582-48x6q + + + + switch1 + E582-48x6q + + diff --git a/platform/centec/sonic-platform-modules-e582/48x6q/modules/Makefile b/platform/centec/sonic-platform-modules-e582/48x6q/modules/Makefile new file mode 100644 index 000000000000..25df81bba426 --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/48x6q/modules/Makefile @@ -0,0 +1,2 @@ +obj-m := centec_e582_48x6q_platform.o dal.o centec_at24c64.o +dal-y := dal_kernel.o dal_mpool.o diff --git a/platform/centec/sonic-platform-modules-e582/48x6q/modules/centec_at24c64.c b/platform/centec/sonic-platform-modules-e582/48x6q/modules/centec_at24c64.c new file mode 100644 index 000000000000..7b551e71f79a --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/48x6q/modules/centec_at24c64.c @@ -0,0 +1,658 @@ +/* + * at24.c - handle most I2C EEPROMs + * + * Copyright (C) 2005-2007 David Brownell + * Copyright (C) 2008 Wolfram Sang, Pengutronix + * + * 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * I2C EEPROMs from most vendors are inexpensive and mostly interchangeable. + * Differences between different vendor product lines (like Atmel AT24C or + * MicroChip 24LC, etc) won't much matter for typical read/write access. + * There are also I2C RAM chips, likewise interchangeable. One example + * would be the PCF8570, which acts like a 24c02 EEPROM (256 bytes). + * + * However, misconfiguration can lose data. "Set 16-bit memory address" + * to a part with 8-bit addressing will overwrite data. Writing with too + * big a page size also loses data. And it's not safe to assume that the + * conventional addresses 0x50..0x57 only hold eeproms; a PCF8563 RTC + * uses 0x51, for just one example. + * + * Accordingly, explicit board-specific configuration data should be used + * in almost all cases. (One partial exception is an SMBus used to access + * "SPD" data for DRAM sticks. Those only use 24c02 EEPROMs.) + * + * So this driver uses "new style" I2C driver binding, expecting to be + * told what devices exist. That may be in arch/X/mach-Y/board-Z.c or + * similar kernel-resident tables; or, configuration data coming from + * a bootloader. + * + * Other than binding model, current differences from "eeprom" driver are + * that this one handles write access and isn't restricted to 24c02 devices. + * It also handles larger devices (32 kbit and up) with two-byte addresses, + * which won't work on pure SMBus systems. + */ + +struct at24_data { + struct at24_platform_data chip; + struct memory_accessor macc; + int use_smbus; + + /* + * Lock protects against activities from other Linux tasks, + * but not from changes by other I2C masters. + */ + struct mutex lock; + struct bin_attribute bin; + + u8 *writebuf; + unsigned write_max; + unsigned num_addresses; + + /* + * Some chips tie up multiple I2C addresses; dummy devices reserve + * them for us, and we'll use them with SMBus calls. + */ + struct i2c_client *client[]; +}; + +/* + * This parameter is to help this driver avoid blocking other drivers out + * of I2C for potentially troublesome amounts of time. With a 100 kHz I2C + * clock, one 256 byte read takes about 1/43 second which is excessive; + * but the 1/170 second it takes at 400 kHz may be quite reasonable; and + * at 1 MHz (Fm+) a 1/430 second delay could easily be invisible. + * + * This value is forced to be a power of two so that writes align on pages. + */ +static unsigned io_limit = 128; +module_param(io_limit, uint, 0); +MODULE_PARM_DESC(io_limit, "Maximum bytes per I/O (default 128)"); + +/* + * Specs often allow 5 msec for a page write, sometimes 20 msec; + * it's important to recover from write timeouts. + */ +static unsigned write_timeout = 25; +module_param(write_timeout, uint, 0); +MODULE_PARM_DESC(write_timeout, "Time (in ms) to try writes (default 25)"); + +#define AT24_SIZE_BYTELEN 5 +#define AT24_SIZE_FLAGS 8 + +#define AT24_BITMASK(x) (BIT(x) - 1) + +/* create non-zero magic value for given eeprom parameters */ +#define AT24_DEVICE_MAGIC(_len, _flags) \ + ((1 << AT24_SIZE_FLAGS | (_flags)) \ + << AT24_SIZE_BYTELEN | ilog2(_len)) + +static const struct i2c_device_id at24_ctc_ids[] = { + { "24c64-ctc", AT24_DEVICE_MAGIC(65536 / 8, AT24_FLAG_ADDR16 | AT24_FLAG_READONLY | AT24_FLAG_IRUGO) }, + { /* END OF LIST */ } +}; +MODULE_DEVICE_TABLE(i2c, at24_ctc_ids); + +/*-------------------------------------------------------------------------*/ + +/* + * This routine supports chips which consume multiple I2C addresses. It + * computes the addressing information to be used for a given r/w request. + * Assumes that sanity checks for offset happened at sysfs-layer. + */ +static struct i2c_client *at24_translate_offset(struct at24_data *at24, + unsigned *offset) +{ + unsigned i; + + if (at24->chip.flags & AT24_FLAG_ADDR16) { + i = *offset >> 16; + *offset &= 0xffff; + } else { + i = *offset >> 8; + *offset &= 0xff; + } + + return at24->client[i]; +} + +static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf, + unsigned offset, size_t count) +{ + struct i2c_msg msg[2]; + struct i2c_client *client; + unsigned long timeout, read_time; + int status; + + memset(msg, 0, sizeof(msg)); + + /* + * REVISIT some multi-address chips don't rollover page reads to + * the next slave address, so we may need to truncate the count. + * Those chips might need another quirk flag. + * + * If the real hardware used four adjacent 24c02 chips and that + * were misconfigured as one 24c08, that would be a similar effect: + * one "eeprom" file not four, but larger reads would fail when + * they crossed certain pages. + */ + + /* + * Slave address and byte offset derive from the offset. Always + * set the byte address; on a multi-master board, another master + * may have changed the chip's "current" address pointer. + */ + client = at24_translate_offset(at24, &offset); + + if (count > io_limit) + count = io_limit; + + count = 1; + + /* + * Reads fail if the previous write didn't complete yet. We may + * loop a few times until this one succeeds, waiting at least + * long enough for one entire page write to work. + */ + timeout = jiffies + msecs_to_jiffies(write_timeout); + do { + read_time = jiffies; + + status = i2c_smbus_write_byte_data(client, (offset >> 8) & 0x0ff, offset & 0x0ff ); + status = i2c_smbus_read_byte(client); + if (status >= 0) { + buf[0] = status; + status = count; + } + + dev_dbg(&client->dev, "read %zu@%d --> %d (%ld)\n", + count, offset, status, jiffies); + + if (status == count) + return count; + + /* REVISIT: at HZ=100, this is sloooow */ + msleep(1); + } while (time_before(read_time, timeout)); + + return -ETIMEDOUT; +} + +static ssize_t at24_read(struct at24_data *at24, + char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) + return count; + + memset(buf, 0, count); + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&at24->lock); + + while (count) { + ssize_t status; + + status = at24_eeprom_read(at24, buf, off, count); + if (status <= 0) { + if (retval == 0) + retval = status; + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + //printk(KERN_ALERT "at24_read buf = %s, retval = %zu\n", buf, retval); + + mutex_unlock(&at24->lock); + + return retval; +} + +static ssize_t at24_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + struct at24_data *at24; + + at24 = dev_get_drvdata(container_of(kobj, struct device, kobj)); + return at24_read(at24, buf, off, count); +} + + +/* + * Note that if the hardware write-protect pin is pulled high, the whole + * chip is normally write protected. But there are plenty of product + * variants here, including OTP fuses and partial chip protect. + * + * We only use page mode writes; the alternative is sloooow. This routine + * writes at most one page. + */ +static ssize_t at24_eeprom_write(struct at24_data *at24, const char *buf, + unsigned offset, size_t count) +{ + struct i2c_client *client; + ssize_t status; + unsigned long timeout, write_time; + unsigned next_page; + + /* Get corresponding I2C address and adjust offset */ + client = at24_translate_offset(at24, &offset); + + /* write_max is at most a page */ + if (count > at24->write_max) + count = at24->write_max; + + /* Never roll over backwards, to the start of this page */ + next_page = roundup(offset + 1, at24->chip.page_size); + if (offset + count > next_page) + count = next_page - offset; + + /* + * Writes fail if the previous one didn't complete yet. We may + * loop a few times until this one succeeds, waiting at least + * long enough for one entire page write to work. + */ + timeout = jiffies + msecs_to_jiffies(write_timeout); + do { + write_time = jiffies; + + status = i2c_smbus_write_word_data(client, + (offset >> 8) & 0x0ff, (offset & 0xFF) | buf[0]); + if (status == 0) + status = count; + + dev_dbg(&client->dev, "write %zu@%d --> %zd (%ld)\n", + count, offset, status, jiffies); + + if (status == count) + return count; + + /* REVISIT: at HZ=100, this is sloooow */ + msleep(1); + } while (time_before(write_time, timeout)); + + return -ETIMEDOUT; +} + +static ssize_t at24_write(struct at24_data *at24, const char *buf, loff_t off, + size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) + return count; + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&at24->lock); + + while (count) { + ssize_t status; + + status = at24_eeprom_write(at24, buf, off, 1); /* only one-byte to write; TODO page wirte */ + if (status <= 0) { + if (retval == 0) + retval = status; + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&at24->lock); + + return retval; +} + +static ssize_t at24_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + struct at24_data *at24; + + if (unlikely(off >= attr->size)) + return -EFBIG; + + at24 = dev_get_drvdata(container_of(kobj, struct device, kobj)); + return at24_write(at24, buf, off, count); +} + +/*-------------------------------------------------------------------------*/ + +/* + * This lets other kernel code access the eeprom data. For example, it + * might hold a board's Ethernet address, or board-specific calibration + * data generated on the manufacturing floor. + */ + +static ssize_t at24_macc_read(struct memory_accessor *macc, char *buf, + off_t offset, size_t count) +{ + struct at24_data *at24 = container_of(macc, struct at24_data, macc); + + return at24_read(at24, buf, offset, count); +} + +static ssize_t at24_macc_write(struct memory_accessor *macc, const char *buf, + off_t offset, size_t count) +{ + struct at24_data *at24 = container_of(macc, struct at24_data, macc); + + return at24_write(at24, buf, offset, count); +} + +/*-------------------------------------------------------------------------*/ + +#ifdef CONFIG_OF +static void at24_get_ofdata(struct i2c_client *client, + struct at24_platform_data *chip) +{ + const __be32 *val; + struct device_node *node = client->dev.of_node; + + if (node) { + if (of_get_property(node, "read-only", NULL)) + chip->flags |= AT24_FLAG_READONLY; + val = of_get_property(node, "pagesize", NULL); + if (val) + chip->page_size = be32_to_cpup(val); + } +} +#else +static void at24_get_ofdata(struct i2c_client *client, + struct at24_platform_data *chip) +{ } +#endif /* CONFIG_OF */ + +static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct at24_platform_data chip; + bool writable; + int use_smbus = 0; + struct at24_data *at24; + int err; + unsigned i, num_addresses; + kernel_ulong_t magic; + + if (client->dev.platform_data) { + chip = *(struct at24_platform_data *)client->dev.platform_data; + } else { + if (!id->driver_data) + return -ENODEV; + + magic = id->driver_data; + chip.byte_len = BIT(magic & AT24_BITMASK(AT24_SIZE_BYTELEN)); + magic >>= AT24_SIZE_BYTELEN; + chip.flags = magic & AT24_BITMASK(AT24_SIZE_FLAGS); + + /* + * This is slow, but we can't know all eeproms, so we better + * play safe. Specifying custom eeprom-types via platform_data + * is recommended anyhow. + */ + chip.page_size = 1; + + /* update chipdata if OF is present */ + at24_get_ofdata(client, &chip); + + printk(KERN_ALERT "at24_probe chip.byte_len = 0x%x\n", chip.byte_len); + printk(KERN_ALERT "at24_probe chip.flags = 0x%x\n", chip.flags); + printk(KERN_ALERT "at24_probe chip.magic = 0x%lx\n", id->driver_data); + + chip.setup = NULL; + chip.context = NULL; + } + + if (!is_power_of_2(chip.byte_len)) + dev_warn(&client->dev, + "byte_len looks suspicious (no power of 2)!\n"); + if (!chip.page_size) { + dev_err(&client->dev, "page_size must not be 0!\n"); + return -EINVAL; + } + if (!is_power_of_2(chip.page_size)) + dev_warn(&client->dev, + "page_size looks suspicious (no power of 2)!\n"); + + /* Use I2C operations unless we're stuck with SMBus extensions. */ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { + use_smbus = I2C_SMBUS_I2C_BLOCK_DATA; + } else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_WORD_DATA)) { + use_smbus = I2C_SMBUS_WORD_DATA; + } else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_BYTE_DATA)) { + use_smbus = I2C_SMBUS_BYTE_DATA; + } else { + return -EPFNOSUPPORT; + } + use_smbus = I2C_SMBUS_BYTE_DATA; + printk(KERN_ALERT "at24_probe use_smbus --> %d\n", + use_smbus); + } + + if (chip.flags & AT24_FLAG_TAKE8ADDR) + num_addresses = 8; + else + num_addresses = DIV_ROUND_UP(chip.byte_len, + (chip.flags & AT24_FLAG_ADDR16) ? 65536 : 256); + + at24 = devm_kzalloc(&client->dev, sizeof(struct at24_data) + + num_addresses * sizeof(struct i2c_client *), GFP_KERNEL); + if (!at24) + return -ENOMEM; + + mutex_init(&at24->lock); + at24->use_smbus = use_smbus; + at24->chip = chip; + at24->num_addresses = num_addresses; + + /* + * Export the EEPROM bytes through sysfs, since that's convenient. + * By default, only root should see the data (maybe passwords etc) + */ + sysfs_bin_attr_init(&at24->bin); + at24->bin.attr.name = "eeprom"; + at24->bin.attr.mode = chip.flags & AT24_FLAG_IRUGO ? S_IRUGO : S_IRUSR; + at24->bin.read = at24_bin_read; + at24->bin.size = chip.byte_len; + + at24->macc.read = at24_macc_read; + + writable = !(chip.flags & AT24_FLAG_READONLY); + if (writable) { + if (!use_smbus || i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) { + + unsigned write_max = chip.page_size; + + at24->macc.write = at24_macc_write; + + at24->bin.write = at24_bin_write; + at24->bin.attr.mode |= S_IWUSR; + + if (write_max > io_limit) + write_max = io_limit; + if (use_smbus && write_max > I2C_SMBUS_BLOCK_MAX) + write_max = I2C_SMBUS_BLOCK_MAX; + at24->write_max = write_max; + + /* buffer (data + address at the beginning) */ + at24->writebuf = devm_kzalloc(&client->dev, + write_max + 2, GFP_KERNEL); + if (!at24->writebuf) + return -ENOMEM; + } else { + dev_warn(&client->dev, + "cannot write due to controller restrictions."); + } + } + + at24->client[0] = client; + + /* use dummy devices for multiple-address chips */ + for (i = 1; i < num_addresses; i++) { + at24->client[i] = i2c_new_dummy(client->adapter, + client->addr + i); + if (!at24->client[i]) { + dev_err(&client->dev, "address 0x%02x unavailable\n", + client->addr + i); + err = -EADDRINUSE; + goto err_clients; + } + } + + err = sysfs_create_bin_file(&client->dev.kobj, &at24->bin); + if (err) + goto err_clients; + + i2c_set_clientdata(client, at24); + + dev_info(&client->dev, "%zu byte %s EEPROM, %s, %u bytes/write\n", + at24->bin.size, client->name, + writable ? "writable" : "read-only", at24->write_max); + if (use_smbus == I2C_SMBUS_WORD_DATA || + use_smbus == I2C_SMBUS_BYTE_DATA) { + dev_notice(&client->dev, "Falling back to %s reads, " + "performance will suffer\n", use_smbus == + I2C_SMBUS_WORD_DATA ? "word" : "byte"); + } + + /* export data to kernel code */ + if (chip.setup) + chip.setup(&at24->macc, chip.context); + + return 0; + +err_clients: + for (i = 1; i < num_addresses; i++) + if (at24->client[i]) + i2c_unregister_device(at24->client[i]); + + return err; +} + +static int at24_remove(struct i2c_client *client) +{ + struct at24_data *at24; + int i; + + at24 = i2c_get_clientdata(client); + sysfs_remove_bin_file(&client->dev.kobj, &at24->bin); + + for (i = 1; i < at24->num_addresses; i++) + i2c_unregister_device(at24->client[i]); + + return 0; +} + +/*-------------------------------------------------------------------------*/ + +static struct i2c_board_info i2c_devs = { + I2C_BOARD_INFO("24c64-ctc", 0x57), +}; + +static struct i2c_adapter *adapter = NULL; +static struct i2c_client *client = NULL; + +static int ctc_at24c64_init(void) +{ + printk(KERN_ALERT "ctc_at24c64_init\n"); + + adapter = i2c_get_adapter(0); + if(adapter == NULL){ + printk(KERN_ALERT "i2c_get_adapter == NULL\n"); + return -1; + } + + client = i2c_new_device(adapter, &i2c_devs); + if(client == NULL){ + printk(KERN_ALERT "i2c_new_device == NULL\n"); + i2c_put_adapter(adapter); + adapter = NULL; + return -1; + } + + return 0; +} + +static void ctc_at24c64_exit(void) +{ + printk(KERN_ALERT "ctc_at24c64_exit\n"); + if(client){ + i2c_unregister_device(client); + } + if(adapter){ + i2c_put_adapter(adapter); + } +} + +static struct i2c_driver at24_ctc_driver = { + .driver = { + .name = "at24-ctc", + .owner = THIS_MODULE, + }, + .probe = at24_probe, + .remove = at24_remove, + .id_table = at24_ctc_ids, +}; + +static int __init at24_ctc_init(void) +{ + if (!io_limit) { + pr_err("at24_ctc: io_limit must not be 0!\n"); + return -EINVAL; + } + + io_limit = rounddown_pow_of_two(io_limit); + + ctc_at24c64_init(); + + return i2c_add_driver(&at24_ctc_driver); +} +module_init(at24_ctc_init); + +static void __exit at24_ctc_exit(void) +{ + ctc_at24c64_exit(); + i2c_del_driver(&at24_ctc_driver); +} +module_exit(at24_ctc_exit); + +MODULE_DESCRIPTION("Driver for most I2C EEPROMs"); +MODULE_AUTHOR("David Brownell and Wolfram Sang"); +MODULE_LICENSE("GPL"); +/* XXX */ diff --git a/platform/centec/sonic-platform-modules-e582/48x6q/modules/centec_e582_48x6q_platform.c b/platform/centec/sonic-platform-modules-e582/48x6q/modules/centec_e582_48x6q_platform.c new file mode 100644 index 000000000000..4837335872e4 --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/48x6q/modules/centec_e582_48x6q_platform.c @@ -0,0 +1,1380 @@ +#include +#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 PCA9548_CHANNEL_NUM 8 +#define PCA9548_ADAPT_ID_START 10 +#define SFP_NUM 48 +#define QSFP_NUM 6 +#define PORT_NUM (SFP_NUM+QSFP_NUM) +#endif + +#if SEP("i2c:master") +static struct i2c_adapter *i2c_adp_master = NULL; /* i2c-0-cpu */ + +static int e582_48x6q_init_i2c_master(void) +{ + /* find i2c-core master */ + i2c_adp_master = i2c_get_adapter(0); + if(IS_INVALID_PTR(i2c_adp_master)) + { + i2c_adp_master = NULL; + printk(KERN_CRIT "e582_48x6q_init_i2c_master can't find i2c-core bus\n"); + return -1; + } + + return 0; +} + +static int e582_48x6q_exit_i2c_master(void) +{ + /* uninstall i2c-core master */ + if(IS_VALID_PTR(i2c_adp_master)) { + i2c_put_adapter(i2c_adp_master); + i2c_adp_master = NULL; + } + + return 0; +} +#endif + +#if SEP("i2c:pca9548") +static struct pca954x_platform_mode i2c_dev_pca9548_platform_mode[PCA9548_CHANNEL_NUM] = { + [0] = { + .adap_id = PCA9548_ADAPT_ID_START, + .deselect_on_exit = 1, + .class = 0, + }, + [1] = { + .adap_id = PCA9548_ADAPT_ID_START + 1, + .deselect_on_exit = 1, + .class = 0, + }, + [2] = { + .adap_id = PCA9548_ADAPT_ID_START + 2, + .deselect_on_exit = 1, + .class = 0, + }, + [3] = { + .adap_id = PCA9548_ADAPT_ID_START + 3, + .deselect_on_exit = 1, + .class = 0, + }, + [4] = { + .adap_id = PCA9548_ADAPT_ID_START + 4, + .deselect_on_exit = 1, + .class = 0, + }, + [5] = { + .adap_id = PCA9548_ADAPT_ID_START + 5, + .deselect_on_exit = 1, + .class = 0, + }, + [6] = { + .adap_id = PCA9548_ADAPT_ID_START + 6, + .deselect_on_exit = 1, + .class = 0, + }, + [7] = { + .adap_id = PCA9548_ADAPT_ID_START + 7, + .deselect_on_exit = 1, + .class = 0, + } +}; +static struct pca954x_platform_data i2c_dev_pca9548_platform_data = { + .modes = i2c_dev_pca9548_platform_mode, + .num_modes = PCA9548_CHANNEL_NUM, +}; +static struct i2c_board_info i2c_dev_pca9548 = { + I2C_BOARD_INFO("pca9548", 0x70), + .platform_data = &i2c_dev_pca9548_platform_data, +}; +static struct i2c_client *i2c_client_pca9548x = NULL; + +static int e582_48x6q_init_i2c_pca9548(void) +{ + if(IS_INVALID_PTR(i2c_adp_master)) + { + i2c_adp_master = NULL; + printk(KERN_CRIT "e582_48x6q_init_i2c_pca9548 can't find i2c-core bus\n"); + return -1; + } + + /* install i2c-mux */ + i2c_client_pca9548x = i2c_new_device(i2c_adp_master, &i2c_dev_pca9548); + if(IS_INVALID_PTR(i2c_client_pca9548x)) + { + i2c_client_pca9548x = NULL; + printk(KERN_CRIT "install e582_48x6q board pca9548 failed\n"); + return -1; + } + + return 0; +} + +static int e582_48x6q_exit_i2c_pca9548(void) +{ + /* uninstall i2c-core master */ + if(IS_VALID_PTR(i2c_client_pca9548x)) { + i2c_unregister_device(i2c_client_pca9548x); + i2c_client_pca9548x = NULL; + } + + return 0; +} +#endif + +#if SEP("i2c:adt7470") +static struct i2c_board_info i2c_dev_adt7470 = { + I2C_BOARD_INFO("adt7470", 0x2F), +}; +static struct i2c_adapter *i2c_adp_adt7470 = NULL; /* pca9548x-channel 5 */ +static struct i2c_client *i2c_client_adt7470 = NULL; + +static int e582_48x6q_init_i2c_adt7470(void) +{ + i2c_adp_adt7470 = i2c_get_adapter(PCA9548_ADAPT_ID_START + 5); + if(IS_INVALID_PTR(i2c_adp_adt7470)) + { + i2c_adp_adt7470 = NULL; + printk(KERN_CRIT "install e582_48x6q board adt7470 failed\n"); + return -1; + } + + i2c_client_adt7470 = i2c_new_device(i2c_adp_adt7470, &i2c_dev_adt7470); + if(IS_INVALID_PTR(i2c_client_adt7470)){ + i2c_client_adt7470 = NULL; + printk(KERN_CRIT "install e582_48x6q board adt7470 failed\n"); + return -1; + } + + return 0; +} + +static int e582_48x6q_exit_i2c_adt7470(void) +{ + if(IS_VALID_PTR(i2c_client_adt7470)) { + i2c_unregister_device(i2c_client_adt7470); + i2c_client_adt7470 = NULL; + } + + if(IS_VALID_PTR(i2c_adp_adt7470)) { + i2c_put_adapter(i2c_adp_adt7470); + i2c_adp_adt7470 = NULL; + } + + return 0; +} +#endif + +#if SEP("i2c:psu") +static struct i2c_adapter *i2c_adp_psu1 = NULL; /* psu1 channel 3 */ +static struct i2c_adapter *i2c_adp_psu2 = NULL; /* psu2 channel 1 */ +static struct i2c_board_info i2c_dev_psu1 = { + I2C_BOARD_INFO("i2c-psu1", 0x38), +}; +static struct i2c_board_info i2c_dev_psu2 = { + I2C_BOARD_INFO("i2c-psu2", 0x38), +}; +static struct i2c_client *i2c_client_psu1 = NULL; +static struct i2c_client *i2c_client_psu2 = NULL; + +static int e582_48x6q_init_i2c_psu(void) +{ + i2c_adp_psu1 = i2c_get_adapter(PCA9548_ADAPT_ID_START + 3); + if(IS_INVALID_PTR(i2c_adp_psu1)) + { + i2c_adp_psu1 = NULL; + printk(KERN_CRIT "get e582_48x6q psu1 i2c-adp failed\n"); + return -1; + } + + i2c_adp_psu2 = i2c_get_adapter(PCA9548_ADAPT_ID_START + 1); + if(IS_INVALID_PTR(i2c_adp_psu2)) + { + i2c_adp_psu2 = NULL; + printk(KERN_CRIT "get e582_48x6q psu2 i2c-adp failed\n"); + return -1; + } + + i2c_client_psu1 = i2c_new_device(i2c_adp_psu1, &i2c_dev_psu1); + if(IS_INVALID_PTR(i2c_client_psu1)){ + i2c_client_psu1 = NULL; + printk(KERN_CRIT "create e582_48x6q board i2c client psu1 failed\n"); + return -1; + } + + i2c_client_psu2 = i2c_new_device(i2c_adp_psu2, &i2c_dev_psu2); + if(IS_INVALID_PTR(i2c_client_psu2)){ + i2c_client_psu2 = NULL; + printk(KERN_CRIT "create e582_48x6q board i2c client psu2 failed\n"); + return -1; + } + + return 0; +} + +static int e582_48x6q_exit_i2c_psu(void) +{ + if(IS_VALID_PTR(i2c_client_psu1)) { + i2c_unregister_device(i2c_client_psu1); + i2c_client_psu1 = NULL; + } + + if(IS_VALID_PTR(i2c_client_psu2)) { + i2c_unregister_device(i2c_client_psu2); + i2c_client_psu2 = NULL; + } + + if(IS_VALID_PTR(i2c_adp_psu1)) + { + i2c_put_adapter(i2c_adp_psu1); + i2c_adp_psu1 = NULL; + } + + if(IS_VALID_PTR(i2c_adp_psu2)) + { + i2c_put_adapter(i2c_adp_psu2); + i2c_adp_psu2 = NULL; + } + + return 0; +} +#endif + +#if SEP("i2c:epld") +static struct i2c_board_info i2c_dev_epld = { + I2C_BOARD_INFO("i2c-epld", 0x58), +}; +static struct i2c_client *i2c_client_epld = NULL; + +static int e582_48x6q_init_i2c_epld(void) +{ + if (IS_INVALID_PTR(i2c_adp_master)) + { + printk(KERN_CRIT "e582_48x6q_init_i2c_epld can't find i2c-core bus\n"); + return -1; + } + + i2c_client_epld = i2c_new_device(i2c_adp_master, &i2c_dev_epld); + if(IS_INVALID_PTR(i2c_client_epld)) + { + i2c_client_epld = NULL; + printk(KERN_CRIT "create e582_48x6q board i2c client epld failed\n"); + return -1; + } + + return 0; +} + +static int e582_48x6q_exit_i2c_epld(void) +{ + if(IS_VALID_PTR(i2c_client_epld)) { + i2c_unregister_device(i2c_client_epld); + i2c_client_epld = NULL; + } + + return 0; +} +#endif + +#if SEP("i2c:gpio") +static struct i2c_board_info i2c_dev_gpio0 = { + I2C_BOARD_INFO("i2c-gpio0", 0x20), +}; +static struct i2c_board_info i2c_dev_gpio1 = { + I2C_BOARD_INFO("i2c-gpio1", 0x21), +}; +static struct i2c_board_info i2c_dev_gpio2 = { + I2C_BOARD_INFO("i2c-gpio2", 0x22), +}; +static struct i2c_board_info i2c_dev_gpio3 = { + I2C_BOARD_INFO("i2c-gpio3", 0x23), +}; +static struct i2c_board_info i2c_dev_gpio4 = { + I2C_BOARD_INFO("i2c-gpio4", 0x24), +}; +static struct i2c_client *i2c_client_gpio0 = NULL; +static struct i2c_client *i2c_client_gpio1 = NULL; +static struct i2c_client *i2c_client_gpio2 = NULL; +static struct i2c_client *i2c_client_gpio3 = NULL; +static struct i2c_client *i2c_client_gpio4 = NULL; + +static int e582_48x6q_init_i2c_gpio(void) +{ + if (IS_INVALID_PTR(i2c_adp_master)) + { + printk(KERN_CRIT "e582_48x6q_init_i2c_gpio can't find i2c-core bus\n"); + return -1; + } + + i2c_client_gpio0 = i2c_new_device(i2c_adp_master, &i2c_dev_gpio0); + if(IS_INVALID_PTR(i2c_client_gpio0)) + { + i2c_client_gpio0 = NULL; + printk(KERN_CRIT "create e582_48x6q board i2c client gpio0 failed\n"); + return -1; + } + + i2c_client_gpio1 = i2c_new_device(i2c_adp_master, &i2c_dev_gpio1); + if(IS_INVALID_PTR(i2c_client_gpio1)) + { + i2c_client_gpio1 = NULL; + printk(KERN_CRIT "create e582_48x6q board i2c client gpio1 failed\n"); + return -1; + } + + i2c_client_gpio2 = i2c_new_device(i2c_adp_master, &i2c_dev_gpio2); + if(IS_INVALID_PTR(i2c_client_gpio2)) + { + i2c_client_gpio2 = NULL; + printk(KERN_CRIT "create e582_48x6q board i2c client gpio2 failed\n"); + return -1; + } + + i2c_client_gpio3 = i2c_new_device(i2c_adp_master, &i2c_dev_gpio3); + if(IS_INVALID_PTR(i2c_client_gpio3)) + { + i2c_client_gpio3 = NULL; + printk(KERN_CRIT "create e582_48x6q board i2c client gpio3 failed\n"); + return -1; + } + + i2c_client_gpio4 = i2c_new_device(i2c_adp_master, &i2c_dev_gpio4); + if(IS_INVALID_PTR(i2c_client_gpio4)) + { + i2c_client_gpio4 = NULL; + printk(KERN_CRIT "create e582_48x6q board i2c client gpio4 failed\n"); + return -1; + } + + return 0; +} + +static int e582_48x6q_exit_i2c_gpio(void) +{ + if(IS_VALID_PTR(i2c_client_gpio0)) { + i2c_unregister_device(i2c_client_gpio0); + i2c_client_gpio0 = NULL; + } + + if((i2c_client_gpio1)) { + i2c_unregister_device(i2c_client_gpio1); + i2c_client_gpio1 = NULL; + } + + if(IS_VALID_PTR(i2c_client_gpio2)) { + i2c_unregister_device(i2c_client_gpio2); + i2c_client_gpio2 = NULL; + } + + if(IS_VALID_PTR(i2c_client_gpio3)) { + i2c_unregister_device(i2c_client_gpio3); + i2c_client_gpio3 = NULL; + } + + if(IS_VALID_PTR(i2c_client_gpio4)) { + i2c_unregister_device(i2c_client_gpio4); + i2c_client_gpio4 = NULL; + } + + return 0; +} +#endif + +#if SEP("i2c:smbus") +static int e582_48x6q_smbus_read_reg(struct i2c_client *client, unsigned char reg, unsigned char* value) +{ + int ret = 0; + + if (IS_INVALID_PTR(client)) + { + printk(KERN_CRIT "invalid i2c client"); + return -1; + } + + ret = i2c_smbus_read_byte_data(client, reg); + if (ret >= 0) { + *value = (unsigned char)ret; + } + else + { + *value = 0; + printk(KERN_CRIT "i2c_smbus op failed: ret=%d reg=%d\n",ret ,reg); + return ret; + } + + return 0; +} + +static int e582_48x6q_smbus_write_reg(struct i2c_client *client, unsigned char reg, unsigned char value) +{ + int ret = 0; + + if (IS_INVALID_PTR(client)) + { + printk(KERN_CRIT "invalid i2c client"); + return -1; + } + + ret = i2c_smbus_write_byte_data(client, reg, value); + if (ret != 0) + { + printk(KERN_CRIT "i2c_smbus op failed: ret=%d reg=%d\n",ret ,reg); + return ret; + } + + return 0; +} +#endif + +#if SEP("drivers:psu") +static struct class* psu_class = NULL; +static struct device* psu_dev_psu1 = NULL; +static struct device* psu_dev_psu2 = NULL; + +static ssize_t e582_48x6q_psu_read_presence(struct device *dev, struct device_attribute *attr, char *buf) +{ + int ret = 0; + unsigned char present_no = 0; + unsigned char present = 0; + unsigned char value = 0; + struct i2c_client *i2c_psu_client = NULL; + + if (psu_dev_psu1 == dev) + { + i2c_psu_client = i2c_client_gpio0; + present_no = 17; + } + else if (psu_dev_psu2 == dev) + { + i2c_psu_client = i2c_client_gpio0; + present_no = 9; + } + else + { + return sprintf(buf, "Error: unknown psu device\n"); + } + + if (IS_INVALID_PTR(i2c_psu_client)) + { + return sprintf(buf, "Error: psu i2c-adapter invalid\n"); + } + + ret = e582_48x6q_smbus_read_reg(i2c_psu_client, present_no/8, &present); + if (ret != 0) + { + return sprintf(buf, "Error: read psu data:%s failed\n", attr->attr.name); + } + + value = ((present & (1<<(present_no%8))) ? 1 : 0 ); + + return sprintf(buf, "%d\n", value); +} + +static ssize_t e582_48x6q_psu_read_status(struct device *dev, struct device_attribute *attr, char *buf) +{ + int ret = 0; + unsigned char workstate_no = 0; + unsigned char workstate = 0; + unsigned char value = 0; + struct i2c_client *i2c_psu_client = NULL; + + if (psu_dev_psu1 == dev) + { + i2c_psu_client = i2c_client_gpio0; + workstate_no = 21; + } + else if (psu_dev_psu2 == dev) + { + i2c_psu_client = i2c_client_gpio0; + workstate_no = 13; + } + else + { + return sprintf(buf, "Error: unknown psu device\n"); + } + + if (IS_INVALID_PTR(i2c_psu_client)) + { + return sprintf(buf, "Error: psu i2c-adapter invalid\n"); + } + + ret = e582_48x6q_smbus_read_reg(i2c_psu_client, workstate_no/8, &workstate); + if (ret != 0) + { + return sprintf(buf, "Error: read psu data:%s failed\n", attr->attr.name); + } + + if (ret != 0) + { + return sprintf(buf, "Error: read psu data:%s failed\n", attr->attr.name); + } + + value = ((workstate & (1<<(workstate_no%8))) ? 1 : 0 ); + + return sprintf(buf, "%d\n", value); +} + +static DEVICE_ATTR(psu_presence, S_IRUGO, e582_48x6q_psu_read_presence, NULL); +static DEVICE_ATTR(psu_status, S_IRUGO, e582_48x6q_psu_read_status, NULL); + +static int e582_48x6q_init_psu(void) +{ + int ret = 0; + + psu_class = class_create(THIS_MODULE, "psu"); + if (IS_INVALID_PTR(psu_class)) + { + psu_class = NULL; + printk(KERN_CRIT "create e582_48x6q class psu failed\n"); + return -1; + } + + psu_dev_psu1 = device_create(psu_class, NULL, MKDEV(222,0), NULL, "psu1"); + if (IS_INVALID_PTR(psu_dev_psu1)) + { + psu_dev_psu1 = NULL; + printk(KERN_CRIT "create e582_48x6q psu1 device failed\n"); + return -1; + } + + psu_dev_psu2 = device_create(psu_class, NULL, MKDEV(222,1), NULL, "psu2"); + if (IS_INVALID_PTR(psu_dev_psu2)) + { + psu_dev_psu2 = NULL; + printk(KERN_CRIT "create e582_48x6q psu2 device failed\n"); + return -1; + } + + ret = device_create_file(psu_dev_psu1, &dev_attr_psu_presence); + if (ret != 0) + { + printk(KERN_CRIT "create e582_48x6q psu1 device attr:presence failed\n"); + return -1; + } + + ret = device_create_file(psu_dev_psu1, &dev_attr_psu_status); + if (ret != 0) + { + printk(KERN_CRIT "create e582_48x6q psu1 device attr:status failed\n"); + return -1; + } + + ret = device_create_file(psu_dev_psu2, &dev_attr_psu_presence); + if (ret != 0) + { + printk(KERN_CRIT "create e582_48x6q psu2 device attr:presence failed\n"); + return -1; + } + + ret = device_create_file(psu_dev_psu2, &dev_attr_psu_status); + if (ret != 0) + { + printk(KERN_CRIT "create e582_48x6q psu2 device attr:status failed\n"); + return -1; + } + + return 0; +} + +static int e582_48x6q_exit_psu(void) +{ + if (IS_VALID_PTR(psu_dev_psu1)) + { + device_remove_file(psu_dev_psu1, &dev_attr_psu_presence); + device_remove_file(psu_dev_psu1, &dev_attr_psu_status); + device_destroy(psu_class, MKDEV(222,0)); + } + + if (IS_VALID_PTR(psu_dev_psu2)) + { + device_remove_file(psu_dev_psu2, &dev_attr_psu_presence); + device_remove_file(psu_dev_psu2, &dev_attr_psu_status); + device_destroy(psu_class, MKDEV(222,1)); + } + + if (IS_VALID_PTR(psu_class)) + { + class_destroy(psu_class); + psu_class = NULL; + } + + return 0; +} +#endif + +#if SEP("drivers:leds") +extern void e582_48x6q_led_set(struct led_classdev *led_cdev, enum led_brightness set_value); +extern enum led_brightness e582_48x6q_led_get(struct led_classdev *led_cdev); +extern void e582_48x6q_led_port_set(struct led_classdev *led_cdev, enum led_brightness set_value); +extern enum led_brightness e582_48x6q_led_port_get(struct led_classdev *led_cdev); + +static struct led_classdev led_dev_system = { + .name = "system", + .brightness_set = e582_48x6q_led_set, + .brightness_get = e582_48x6q_led_get, +}; +static struct led_classdev led_dev_idn = { + .name = "idn", + .brightness_set = e582_48x6q_led_set, + .brightness_get = e582_48x6q_led_get, +}; +static struct led_classdev led_dev_fan1 = { + .name = "fan1", + .brightness_set = e582_48x6q_led_set, + .brightness_get = e582_48x6q_led_get, +}; +static struct led_classdev led_dev_fan2 = { + .name = "fan2", + .brightness_set = e582_48x6q_led_set, + .brightness_get = e582_48x6q_led_get, +}; +static struct led_classdev led_dev_fan3 = { + .name = "fan3", + .brightness_set = e582_48x6q_led_set, + .brightness_get = e582_48x6q_led_get, +}; +static struct led_classdev led_dev_fan4 = { + .name = "fan4", + .brightness_set = e582_48x6q_led_set, + .brightness_get = e582_48x6q_led_get, +}; +static struct led_classdev led_dev_psu1 = { + .name = "psu1", + .brightness_set = e582_48x6q_led_set, + .brightness_get = e582_48x6q_led_get, +}; +static struct led_classdev led_dev_psu2 = { + .name = "psu2", + .brightness_set = e582_48x6q_led_set, + .brightness_get = e582_48x6q_led_get, +}; +static struct led_classdev led_dev_port[PORT_NUM] = { +{ .name = "port1", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port2", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port3", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port4", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port5", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port6", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port7", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port8", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port9", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port10", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port11", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port12", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port13", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port14", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port15", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port16", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port17", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port18", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port19", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port20", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port21", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port22", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port23", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port24", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port25", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port26", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port27", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port28", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port29", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port30", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port31", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port32", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port33", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port34", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port35", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port36", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port37", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port38", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port39", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port40", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port41", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port42", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port43", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port44", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port45", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port46", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port47", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port48", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port49", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port50", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port51", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port52", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port53", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,}, +{ .name = "port54", .brightness_set = e582_48x6q_led_port_set, .brightness_get = e582_48x6q_led_port_get,} +}; +static unsigned char port_led_mode[PORT_NUM] = {0}; + +void e582_48x6q_led_set(struct led_classdev *led_cdev, enum led_brightness set_value) +{ + int ret = 0; + unsigned char reg = 0; + unsigned char mask = 0; + unsigned char shift = 0; + unsigned char led_value = 0; + struct i2c_client *i2c_led_client = i2c_client_epld; + + if (0 == strcmp(led_dev_system.name, led_cdev->name)) + { + reg = 0x2; + mask = 0x0F; + shift = 4; + } + else if (0 == strcmp(led_dev_idn.name, led_cdev->name)) + { + reg = 0x3; + mask = 0xFE; + shift = 0; + } + else if (0 == strcmp(led_dev_fan1.name, led_cdev->name)) + { + goto not_support; + } + else if (0 == strcmp(led_dev_fan2.name, led_cdev->name)) + { + goto not_support; + } + else if (0 == strcmp(led_dev_fan3.name, led_cdev->name)) + { + goto not_support; + } + else if (0 == strcmp(led_dev_fan4.name, led_cdev->name)) + { + goto not_support; + } + else if (0 == strcmp(led_dev_psu1.name, led_cdev->name)) + { + goto not_support; + } + else if (0 == strcmp(led_dev_psu2.name, led_cdev->name)) + { + goto not_support; + } + else + { + goto not_support; + } + + ret = e582_48x6q_smbus_read_reg(i2c_led_client, reg, &led_value); + if (ret != 0) + { + printk(KERN_CRIT "Error: read %s led attr failed\n", led_cdev->name); + return; + } + + led_value = ((led_value & mask) | ((set_value << shift) & (~mask))); + + ret = e582_48x6q_smbus_write_reg(i2c_led_client, reg, led_value); + if (ret != 0) + { + printk(KERN_CRIT "Error: write %s led attr failed\n", led_cdev->name); + return; + } + + return; + +not_support: + + printk(KERN_INFO "Error: not support device:%s\n", led_cdev->name); + return; +} + +enum led_brightness e582_48x6q_led_get(struct led_classdev *led_cdev) +{ + int ret = 0; + unsigned char reg = 0; + unsigned char mask = 0; + unsigned char shift = 0; + unsigned char led_value = 0; + struct i2c_client *i2c_led_client = i2c_client_epld; + + if (0 == strcmp(led_dev_system.name, led_cdev->name)) + { + reg = 0x2; + mask = 0xF0; + shift = 4; + } + else if (0 == strcmp(led_dev_idn.name, led_cdev->name)) + { + reg = 0x3; + mask = 0x01; + shift = 0; + } + else if (0 == strcmp(led_dev_fan1.name, led_cdev->name)) + { + goto not_support; + } + else if (0 == strcmp(led_dev_fan2.name, led_cdev->name)) + { + goto not_support; + } + else if (0 == strcmp(led_dev_fan3.name, led_cdev->name)) + { + goto not_support; + } + else if (0 == strcmp(led_dev_fan4.name, led_cdev->name)) + { + goto not_support; + } + else if (0 == strcmp(led_dev_psu1.name, led_cdev->name)) + { + goto not_support; + } + else if (0 == strcmp(led_dev_psu2.name, led_cdev->name)) + { + goto not_support; + } + else + { + goto not_support; + } + + ret = e582_48x6q_smbus_read_reg(i2c_led_client, reg, &led_value); + if (ret != 0) + { + printk(KERN_CRIT "Error: read %s led attr failed\n", led_cdev->name); + return; + } + + led_value = ((led_value & mask) >> shift); + + return led_value; + +not_support: + + printk(KERN_INFO "Error: not support device:%s\n", led_cdev->name); + return 0; +} + +void e582_48x6q_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-1] = set_value; + + return; +} + +enum led_brightness e582_48x6q_led_port_get(struct led_classdev *led_cdev) +{ + int portNum = 0; + + sscanf(led_cdev->name, "port%d", &portNum); + + return port_led_mode[portNum-1]; +} + +static int e582_48x6q_init_led(void) +{ + int ret = 0; + int i = 0; + + ret = led_classdev_register(NULL, &led_dev_system); + if (ret != 0) + { + printk(KERN_CRIT "create e582_48x6q led_dev_system device failed\n"); + return -1; + } + + ret = led_classdev_register(NULL, &led_dev_idn); + if (ret != 0) + { + printk(KERN_CRIT "create e582_48x6q led_dev_idn device failed\n"); + return -1; + } + + ret = led_classdev_register(NULL, &led_dev_fan1); + if (ret != 0) + { + printk(KERN_CRIT "create e582_48x6q led_dev_fan1 device failed\n"); + return -1; + } + + ret = led_classdev_register(NULL, &led_dev_fan2); + if (ret != 0) + { + printk(KERN_CRIT "create e582_48x6q led_dev_fan2 device failed\n"); + return -1; + } + + ret = led_classdev_register(NULL, &led_dev_fan3); + if (ret != 0) + { + printk(KERN_CRIT "create e582_48x6q led_dev_fan3 device failed\n"); + return -1; + } + + ret = led_classdev_register(NULL, &led_dev_fan4); + if (ret != 0) + { + printk(KERN_CRIT "create e582_48x6q led_dev_fan4 device failed\n"); + return -1; + } + + ret = led_classdev_register(NULL, &led_dev_psu1); + if (ret != 0) + { + printk(KERN_CRIT "create e582_48x6q led_dev_psu1 device failed\n"); + return -1; + } + + ret = led_classdev_register(NULL, &led_dev_psu2); + if (ret != 0) + { + printk(KERN_CRIT "create e582_48x6q led_dev_psu2 device failed\n"); + return -1; + } + + for (i=0; i PORT_NUM)) + { + printk(KERN_CRIT "sfp read presence, invalid port number!\n"); + value = 0; + } + + if ((portNum >= 1) && (portNum <= 8)) + { + reg_no = portNum + 31;/*32-39*/ + i2c_sfp_client = i2c_client_gpio0; + } + else if ((portNum >= 9) && (portNum <= 16)) + { + reg_no = portNum + 7;/*16-23*/ + i2c_sfp_client = i2c_client_gpio1; + } + else if ((portNum >= 17) && (portNum <= 24)) + { + reg_no = portNum - 17;/*0-7*/ + i2c_sfp_client = i2c_client_gpio2; + } + else if ((portNum >= 25) && (portNum <= 32)) + { + reg_no = portNum - 1;/*24-31*/ + i2c_sfp_client = i2c_client_gpio2; + } + else if ((portNum >= 33) && (portNum <= 40)) + { + reg_no = portNum - 25;/*8-15*/ + i2c_sfp_client = i2c_client_gpio3; + } + else if ((portNum >= 41) && (portNum <= 48)) + { + reg_no = portNum - 9;/*32-39*/ + i2c_sfp_client = i2c_client_gpio3; + } + else if ((portNum >= 49) && (portNum <= 54)) + { + reg_no = portNum - 25;/*24-29*/ + i2c_sfp_client = i2c_client_gpio4; + } + + dir_bank = (reg_no/8) + 0x18; + ret = e582_48x6q_smbus_write_reg(i2c_sfp_client, dir_bank, 0xff); + if (ret != 0) + { + return sprintf(buf, "Error: read sfp data:%s set dir-ctl failed\n", attr->attr.name); + } + + input_bank = (reg_no/8) + 0x0; + ret = e582_48x6q_smbus_read_reg(i2c_sfp_client, input_bank, &value); + if (ret != 0) + { + return sprintf(buf, "Error: read sfp data:%s failed\n", attr->attr.name); + } + + value = ((value & (1<<(reg_no%8))) ? 0 : 1 );/*1:PRESENT 0:ABSENT*/ + + return sprintf(buf, "%d\n", value); +} + +static ssize_t e582_48x6q_sfp_read_enable(struct device *dev, struct device_attribute *attr, char *buf) +{ + int ret = 0; + unsigned char value = 0; + unsigned char reg_no = 0; + unsigned char dir_bank = 0; + unsigned char input_bank = 0; + int portNum = 0; + const char *name = dev_name(dev); + struct i2c_client *i2c_sfp_client = NULL; + + sscanf(name, "sfp%d", &portNum); + + if ((portNum < 1) || (portNum > PORT_NUM)) + { + printk(KERN_CRIT "sfp read presence, invalid port number!\n"); + value = 0; + } + + if ((portNum >= 1) && (portNum <= 8)) + { + reg_no = portNum + 23;/*24-31*/ + i2c_sfp_client = i2c_client_gpio0; + } + else if ((portNum >= 9) && (portNum <= 16)) + { + reg_no = portNum - 1;/*8-15*/ + i2c_sfp_client = i2c_client_gpio1; + } + else if ((portNum >= 17) && (portNum <= 24)) + { + reg_no = portNum + 15;/*32-39*/ + i2c_sfp_client = i2c_client_gpio1; + } + else if ((portNum >= 25) && (portNum <= 32)) + { + reg_no = portNum - 9;/*16-23*/ + i2c_sfp_client = i2c_client_gpio2; + } + else if ((portNum >= 33) && (portNum <= 40)) + { + reg_no = portNum - 33;/*0-7*/ + i2c_sfp_client = i2c_client_gpio3; + } + else if ((portNum >= 41) && (portNum <= 48)) + { + reg_no = portNum - 17;/*24-31*/ + i2c_sfp_client = i2c_client_gpio3; + } + else if ((portNum >= 49) && (portNum <= 54)) + { + printk(KERN_INFO "%s not supported!\n", name); + return sprintf(buf, "%d\n", 0); + } + + dir_bank = (reg_no/8) + 0x18; + ret = e582_48x6q_smbus_write_reg(i2c_sfp_client, dir_bank, 0xff); + if (ret != 0) + { + return sprintf(buf, "Error: read sfp data:%s set dir-ctl failed\n", attr->attr.name); + } + + input_bank = (reg_no/8) + 0x8; + ret = e582_48x6q_smbus_read_reg(i2c_sfp_client, input_bank, &value); + if (ret != 0) + { + return sprintf(buf, "Error: read sfp data:%s failed\n", attr->attr.name); + } + + value = ((value & (1<<(reg_no%8))) ? 0 : 1 ); + + return sprintf(buf, "%d\n", value); +} + +static ssize_t e582_48x6q_sfp_write_enable(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + int ret = 0; + unsigned char value = 0; + unsigned char set_value = simple_strtol(buf, NULL, 10); + unsigned char reg_no = 0; + unsigned char dir_bank = 0; + unsigned char input_bank = 0; + unsigned char output_bank = 0; + int portNum = 0; + const char *name = dev_name(dev); + struct i2c_client *i2c_sfp_client = NULL; + + sscanf(name, "sfp%d", &portNum); + + if ((portNum < 1) || (portNum > PORT_NUM)) + { + printk(KERN_CRIT "sfp read presence, invalid port number!\n"); + return size; + } + + if ((portNum >= 1) && (portNum <= 8)) + { + reg_no = portNum + 23;/*24-31*/ + i2c_sfp_client = i2c_client_gpio0; + } + else if ((portNum >= 9) && (portNum <= 16)) + { + reg_no = portNum - 1;/*8-15*/ + i2c_sfp_client = i2c_client_gpio1; + } + else if ((portNum >= 17) && (portNum <= 24)) + { + reg_no = portNum + 15;/*32-39*/ + i2c_sfp_client = i2c_client_gpio1; + } + else if ((portNum >= 25) && (portNum <= 32)) + { + reg_no = portNum - 9;/*16-23*/ + i2c_sfp_client = i2c_client_gpio2; + } + else if ((portNum >= 33) && (portNum <= 40)) + { + reg_no = portNum - 33;/*0-7*/ + i2c_sfp_client = i2c_client_gpio3; + } + else if ((portNum >= 41) && (portNum <= 48)) + { + reg_no = portNum - 17;/*24-31*/ + i2c_sfp_client = i2c_client_gpio3; + } + else if ((portNum >= 49) && (portNum <= 54)) + { + printk(KERN_INFO "%s not supported!\n", name); + return size; + } + + set_value = ((set_value > 0) ? 0 : 1 ); + + dir_bank = (reg_no/8) + 0x18; + ret = e582_48x6q_smbus_write_reg(i2c_sfp_client, dir_bank, 0x0); + if (ret != 0) + { + return sprintf(buf, "Error: read sfp data:%s set dir-ctl failed\n", attr->attr.name); + } + + input_bank = (reg_no/8) + 0x8; + ret = e582_48x6q_smbus_read_reg(i2c_sfp_client, input_bank, &value); + if (ret != 0) + { + printk(KERN_CRIT "Error: read %s presence failed\n", name); + return size; + } + + if (set_value) + { + value = (value | (1<<(reg_no % 8))); + } + else + { + value = (value & (~(1<<(reg_no % 8)))); + } + + output_bank = (reg_no/8) + 0x8; + ret = e582_48x6q_smbus_write_reg(i2c_sfp_client, output_bank, value); + if (ret != 0) + { + printk(KERN_CRIT "Error: write %s presence failed\n", name); + return size; + } + + return size; +} + +static DEVICE_ATTR(sfp_presence, S_IRUGO, e582_48x6q_sfp_read_presence, NULL); +static DEVICE_ATTR(sfp_enable, S_IRUGO|S_IWUGO, e582_48x6q_sfp_read_enable, e582_48x6q_sfp_write_enable); +static int e582_48x6q_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 e582_48x6q class sfp failed\n"); + return -1; + } + + for (i=1; i<=PORT_NUM; i++) + { + 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 e582_48x6q 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 e582_48x6q 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 e582_48x6q sfp[%d] device attr:enable failed\n", i); + continue; + } + } + + return ret; +} + +static int e582_48x6q_exit_sfp(void) +{ + int i = 0; + + for (i=1; i<=PORT_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_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 e582_48x6q_init(void) +{ + int ret = 0; + int failed = 0; + + printk(KERN_ALERT "install e582_48x6q board dirver...\n"); + + ret = e582_48x6q_init_i2c_master(); + if (ret != 0) + { + failed = 1; + } + + ret = e582_48x6q_init_i2c_pca9548(); + if (ret != 0) + { + failed = 1; + } + + ret = e582_48x6q_init_i2c_adt7470(); + if (ret != 0) + { + failed = 1; + } + + ret = e582_48x6q_init_i2c_psu(); + if (ret != 0) + { + failed = 1; + } + + ret = e582_48x6q_init_i2c_epld(); + if (ret != 0) + { + failed = 1; + } + + ret = e582_48x6q_init_i2c_gpio(); + if (ret != 0) + { + failed = 1; + } + + ret = e582_48x6q_init_psu(); + if (ret != 0) + { + failed = 1; + } + + ret = e582_48x6q_init_led(); + if (ret != 0) + { + failed = 1; + } + + ret = e582_48x6q_init_sfp(); + if (ret != 0) + { + failed = 1; + } + + if (failed) + printk(KERN_INFO "install e582_48x6q board driver failed\n"); + else + printk(KERN_ALERT "install e582_48x6q board dirver...ok\n"); + + return 0; +} + +static void e582_48x6q_exit(void) +{ + printk(KERN_INFO "uninstall e582_48x6q board dirver...\n"); + + e582_48x6q_exit_sfp(); + e582_48x6q_exit_led(); + e582_48x6q_exit_psu(); + e582_48x6q_exit_i2c_gpio(); + e582_48x6q_exit_i2c_epld(); + e582_48x6q_exit_i2c_psu(); + e582_48x6q_exit_i2c_adt7470(); + e582_48x6q_exit_i2c_pca9548(); + e582_48x6q_exit_i2c_master(); +} + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_AUTHOR("yangbs centecNetworks, Inc"); +MODULE_DESCRIPTION("e582-48x6q board driver"); +module_init(e582_48x6q_init); +module_exit(e582_48x6q_exit); + diff --git a/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_kernel.c b/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_kernel.c new file mode 100644 index 000000000000..a1315a97159b --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_kernel.c @@ -0,0 +1,1822 @@ +/** + @file dal_kernal.c + + @date 2012-10-18 + + @version v2.0 + + +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) +#include +#endif +#include "dal_kernel.h" +#include "dal_mpool.h" + +MODULE_AUTHOR("Centec Networks Inc."); +MODULE_DESCRIPTION("DAL kernel module"); +MODULE_LICENSE("GPL"); + +/* DMA memory pool size */ +static char* dma_pool_size; +module_param(dma_pool_size, charp, 0); +MODULE_PARM_DESC(dma_pool_size, + "Specify DMA memory pool size (default 4MB)"); + +/***************************************************************************** + * defines + *****************************************************************************/ +#define MB_SIZE 0x100000 +#define CTC_MAX_INTR_NUM 8 + +#define MEM_MAP_RESERVE SetPageReserved +#define MEM_MAP_UNRESERVE ClearPageReserved + +#define CTC_VENDOR_VID 0xc001 +#define CTC_HUMBER_DEVICE_ID 0x6048 +#define CTC_GOLDENGATE_DEVICE_ID 0xcb10 + +#define MEM_MAP_RESERVE SetPageReserved +#define MEM_MAP_UNRESERVE ClearPageReserved + +#define CTC_GREATBELT_DEVICE_ID 0x03e8 /* TBD */ +#define DAL_MAX_CHIP_NUM 8 /* [GB] used */ +#define VIRT_TO_PAGE(p) virt_to_page((p)) +#define DAL_UNTAG_BLOCK 0 +#define DAL_DISCARD_BLOCK 1 +#define DAL_MATCHED_BLOCK 2 +#define DAL_CUR_MATCH_BLOCk 3 +/***************************************************************************** + * typedef + *****************************************************************************/ +/* Control Data */ +typedef struct dal_isr_s +{ + int irq; + void (* isr)(void*); + void* isr_data; + int trigger; + int count; + wait_queue_head_t wqh; +} dal_isr_t; + +typedef struct dal_kernel_dev_s +{ + struct list_head list; + struct pci_dev* pci_dev; + + /* PCI I/O mapped base address */ + uintptr logic_address; + + /* Physical address */ + uintptr phys_address; +} dal_kern_dev_t; + +typedef struct _dma_segment +{ + struct list_head list; + unsigned long req_size; /* Requested DMA segment size */ + unsigned long blk_size; /* DMA block size */ + unsigned long blk_order; /* DMA block size in alternate format */ + unsigned long seg_size; /* Current DMA segment size */ + unsigned long seg_begin; /* Logical address of segment */ + unsigned long seg_end; /* Logical end address of segment */ + unsigned long* blk_ptr; /* Array of logical DMA block addresses */ + int blk_cnt_max; /* Maximum number of block to allocate */ + int blk_cnt; /* Current number of blocks allocated */ +} dma_segment_t; + +typedef irqreturn_t (*p_func) (int irq, void* dev_id); + +/*************************************************************************** + *declared + ***************************************************************************/ +static unsigned int linux_dal_poll0(struct file* filp, struct poll_table_struct* p); +static unsigned int linux_dal_poll1(struct file* filp, struct poll_table_struct* p); +static unsigned int linux_dal_poll2(struct file* filp, struct poll_table_struct* p); +static unsigned int linux_dal_poll3(struct file* filp, struct poll_table_struct* p); +static unsigned int linux_dal_poll4(struct file* filp, struct poll_table_struct* p); +static unsigned int linux_dal_poll5(struct file* filp, struct poll_table_struct* p); +static unsigned int linux_dal_poll6(struct file* filp, struct poll_table_struct* p); +static unsigned int linux_dal_poll7(struct file* filp, struct poll_table_struct* p); + +/***************************************************************************** + * global variables + *****************************************************************************/ +static dal_kern_dev_t dal_dev[DAL_MAX_CHIP_NUM]; +static dal_isr_t dal_isr[CTC_MAX_INTR_NUM]; +static int dal_chip_num = 0; +static int dal_version = 0; +static int dal_intr_num = 0; +static int use_high_memory = 0; +static unsigned int* dma_virt_base[DAL_MAX_CHIP_NUM]; +#ifndef DMA_MEM_MODE_PLATFORM +static unsigned int* dma_virt_base_tmp[DAL_MAX_CHIP_NUM]; +#endif +static uintptr dma_phy_base[DAL_MAX_CHIP_NUM]; +static unsigned int dma_mem_size = 0x800000; +static unsigned int msi_irq_base[DAL_MAX_CHIP_NUM]; +static unsigned int msi_irq_num[DAL_MAX_CHIP_NUM]; +static unsigned int msi_used = 0; +static struct class *dal_class; + +static LIST_HEAD(_dma_seg); +static int dal_debug = 0; +module_param(dal_debug, int, 0); +MODULE_PARM_DESC(dal_debug, "Set debug level (default 0)"); + +static struct pci_device_id dal_id_table[] = +{ + {PCI_DEVICE(CTC_VENDOR_VID, CTC_GREATBELT_DEVICE_ID)}, + {PCI_DEVICE(0xcb10, 0xc010)}, + {0, }, +}; + +static wait_queue_head_t poll_intr[CTC_MAX_INTR_NUM]; + +p_func intr_handler_fun[CTC_MAX_INTR_NUM]; + +static int poll_intr_trigger[CTC_MAX_INTR_NUM]; + +static struct file_operations dal_intr_fops[CTC_MAX_INTR_NUM] = +{ + { + .owner = THIS_MODULE, + .poll = linux_dal_poll0, + }, + { + .owner = THIS_MODULE, + .poll = linux_dal_poll1, + }, + { + .owner = THIS_MODULE, + .poll = linux_dal_poll2, + }, + { + .owner = THIS_MODULE, + .poll = linux_dal_poll3, + }, + { + .owner = THIS_MODULE, + .poll = linux_dal_poll4, + }, + { + .owner = THIS_MODULE, + .poll = linux_dal_poll5, + }, + { + .owner = THIS_MODULE, + .poll = linux_dal_poll6, + }, + { + .owner = THIS_MODULE, + .poll = linux_dal_poll7, + }, +}; + +/***************************************************************************** + * macros + *****************************************************************************/ +#define VERIFY_CHIP_INDEX(n) (n < dal_chip_num) + +#define _KERNEL_INTERUPT_PROCESS +static irqreturn_t +intr0_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + + if(poll_intr_trigger[0]) + { + return IRQ_HANDLED; + } + + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[0] = 1; + wake_up(&poll_intr[0]); + } + } + + return IRQ_HANDLED; +} + +static irqreturn_t +intr1_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + if(poll_intr_trigger[1]) + { + return IRQ_HANDLED; + } + + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[1] = 1; + wake_up(&poll_intr[1]); + } + } + + return IRQ_HANDLED; +} + +static irqreturn_t +intr2_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + if(poll_intr_trigger[2]) + { + return IRQ_HANDLED; + } + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[2] = 1; + wake_up(&poll_intr[2]); + } + } + + return IRQ_HANDLED; +} + +static irqreturn_t +intr3_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + if(poll_intr_trigger[3]) + { + return IRQ_HANDLED; + } + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[3] = 1; + wake_up(&poll_intr[3]); + } + } + + return IRQ_HANDLED; +} + +static irqreturn_t +intr4_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + if(poll_intr_trigger[4]) + { + return IRQ_HANDLED; + } + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[4] = 1; + wake_up(&poll_intr[4]); + } + } + + return IRQ_HANDLED; +} + +static irqreturn_t +intr5_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + if(poll_intr_trigger[5]) + { + return IRQ_HANDLED; + } + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[5] = 1; + wake_up(&poll_intr[5]); + } + } + + return IRQ_HANDLED; +} + +static irqreturn_t +intr6_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + if(poll_intr_trigger[6]) + { + return IRQ_HANDLED; + } + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[6] = 1; + wake_up(&poll_intr[6]); + } + } + + return IRQ_HANDLED; +} + +static irqreturn_t +intr7_handler(int irq, void* dev_id) +{ + dal_isr_t* p_dal_isr = (dal_isr_t*)dev_id; + if(poll_intr_trigger[7]) + { + return IRQ_HANDLED; + } + disable_irq_nosync(irq); + + if (p_dal_isr) + { + if (p_dal_isr->isr) + { + /* kernel mode interrupt handler */ + p_dal_isr->isr(p_dal_isr->isr_data); + } + else if ((NULL == p_dal_isr->isr) && (NULL == p_dal_isr->isr_data)) + { + /* user mode interrupt handler */ + poll_intr_trigger[7] = 1; + wake_up(&poll_intr[7]); + } + } + + return IRQ_HANDLED; +} + +int +dal_interrupt_register(unsigned int irq, int prio, void (* isr)(void*), void* data) +{ + int ret; + unsigned char str[16]; + unsigned char* int_name = NULL; + unsigned int intr_num_tmp = 0; + unsigned int intr_num = CTC_MAX_INTR_NUM; + unsigned long irq_flags = 0; + + if (dal_intr_num >= CTC_MAX_INTR_NUM) + { + printk("Interrupt numbers exceeds max.\n"); + return -1; + } + + if (msi_used) + { + int_name = "dal_msi"; + } + else + { + int_name = "dal_intr"; + } + + + for (intr_num_tmp=0;intr_num_tmp < CTC_MAX_INTR_NUM; intr_num_tmp++) + { + if (irq == dal_isr[intr_num_tmp].irq) + { + dal_isr[intr_num_tmp].count++; + printk("Interrupt irq %d register count %d.\n", irq, dal_isr[intr_num_tmp].count); + return 0; + } + if ((0 == dal_isr[intr_num_tmp].irq) && (CTC_MAX_INTR_NUM == intr_num)) + { + intr_num = intr_num_tmp; + dal_isr[intr_num].count = 0; + } + } + dal_isr[intr_num].irq = irq; + dal_isr[intr_num].isr = isr; + dal_isr[intr_num].isr_data = data; + dal_isr[intr_num].count++; + + init_waitqueue_head(&poll_intr[intr_num]); + + /* only user mode */ + if ((NULL == isr) && (NULL == data)) + { + snprintf(str, 16, "%s%d", "dal_intr", intr_num); + ret = register_chrdev(DAL_DEV_INTR_MAJOR_BASE + intr_num, + str, &dal_intr_fops[intr_num]); + if (ret < 0) + { + printk("Register character device for irq %d failed, ret= %d", irq, ret); + return ret; + } + } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) + irq_flags = 0; +#else + irq_flags = IRQF_DISABLED; +#endif + if ((ret = request_irq(irq, + intr_handler_fun[intr_num], + irq_flags, + int_name, + &dal_isr[intr_num])) < 0) + { + printk("Cannot request irq %d, ret %d.\n", irq, ret); + unregister_chrdev(DAL_DEV_INTR_MAJOR_BASE + intr_num, str); + } + + if (0 == ret) + { + dal_intr_num++; + } + + return ret; +} + +int +dal_interrupt_unregister(unsigned int irq) +{ + unsigned char str[16]; + int intr_idx = 0; + int find_flag = 0; + + /* get intr device index */ + for (intr_idx = 0; intr_idx < CTC_MAX_INTR_NUM; intr_idx++) + { + if (dal_isr[intr_idx].irq == irq) + { + find_flag = 1; + break; + } + } + + if (find_flag == 0) + { + printk ("irq%d is not registered! unregister failed \n", irq); + return -1; + } + + dal_isr[intr_idx].count--; + if (0 != dal_isr[intr_idx].count) + { + printk("Interrupt irq %d unregister count %d.\n", irq, dal_isr[intr_idx].count); + return -1; + } + snprintf(str, 16, "%s%d", "dal_intr", intr_idx); + + unregister_chrdev(DAL_DEV_INTR_MAJOR_BASE + intr_idx, str); + + free_irq(irq, &dal_isr[intr_idx]); + + dal_isr[intr_idx].irq = 0; + + dal_intr_num--; + + return 0; +} + +int +dal_interrupt_set_en(unsigned int irq, unsigned int enable) +{ + enable ? enable_irq(irq) : disable_irq_nosync(irq); + return 0; +} + +static int +_dal_set_msi_enabe(unsigned int lchip, unsigned int irq_num) +{ + int ret = 0; + + if (irq_num == 1) + { + if (msi_irq_base[lchip]) + { + dal_interrupt_unregister(msi_irq_base[lchip]); + pci_disable_msi(dal_dev[lchip].pci_dev); + msi_used = 0; + msi_irq_base[lchip] = 0; + msi_irq_num[lchip] = 0; + } + ret = pci_enable_msi(dal_dev[lchip].pci_dev); + if (ret) + { + printk ("msi enable failed!!! lchip = %d, irq_num = %d\n", lchip, irq_num); + pci_disable_msi(dal_dev[lchip].pci_dev); + msi_used = 0; + } + + msi_irq_base[lchip] = dal_dev[lchip].pci_dev->irq; + msi_irq_num[lchip] = 1; + } + else + { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 79)) + ret = pci_enable_msi_exact(dal_dev[lchip].pci_dev, irq_num); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 26, 32)) + ret = pci_enable_msi_block(dal_dev[lchip].pci_dev, irq_num); +#else + ret = -1; +#endif + if (ret) + { + printk ("msi enable failed!!! lchip = %d, irq_num = %d\n", lchip, irq_num); + pci_disable_msi(dal_dev[lchip].pci_dev); + msi_used = 0; + } + + msi_irq_base[lchip] = dal_dev[lchip].pci_dev->irq; + msi_irq_num[lchip] = irq_num; + } + + return ret; +} + +static int +_dal_set_msi_disable(unsigned int lchip) +{ + + pci_disable_msi(dal_dev[lchip].pci_dev); + + msi_irq_base[lchip] = 0; + msi_irq_num[lchip] = 0; + + return 0; +} + +int +dal_set_msi_cap(unsigned long arg) +{ + int ret = 0; + dal_msi_info_t msi_info; + + if (copy_from_user(&msi_info, (void*)arg, sizeof(dal_msi_info_t))) + { + return -EFAULT; + } + + printk("####dal_set_msi_cap lchip %d base %d num:%d\n", msi_info.lchip, msi_info.irq_base, msi_info.irq_num); + if (msi_info.irq_num > 0) + { + msi_used = 1; + ret = _dal_set_msi_enabe(msi_info.lchip, msi_info.irq_num); + } + else + { + msi_used = 0; + ret = _dal_set_msi_disable(msi_info.lchip); + } + + return ret; +} + +int +dal_user_interrupt_register(unsigned long arg) +{ + int irq = 0; + if (copy_from_user(&irq, (void*)arg, sizeof(int))) + { + return -EFAULT; + } + printk("####register interrupt irq:%d\n", irq); + return dal_interrupt_register(irq, 0, NULL, NULL); +} + +int +dal_user_interrupt_unregister(unsigned long arg) +{ + int irq = 0; + if (copy_from_user(&irq, (void*)arg, sizeof(int))) + { + return -EFAULT; + } + printk("####unregister interrupt irq:%d\n", irq); + return dal_interrupt_unregister(irq); +} + +int +dal_user_interrupt_set_en(unsigned long arg) +{ + dal_intr_parm_t dal_intr_parm; + + if (copy_from_user(&dal_intr_parm, (void*)arg, sizeof(dal_intr_parm_t))) + { + return -EFAULT; + } + + return dal_interrupt_set_en(dal_intr_parm.irq, dal_intr_parm.enable); +} + +/* + * Function: _dal_dma_segment_free + */ + +/* + * Function: _find_largest_segment + * + * Purpose: + * Find largest contiguous segment from a pool of DMA blocks. + * Parameters: + * dseg - DMA segment descriptor + * Returns: + * 0 on success, < 0 on error. + * Notes: + * Assembly stops if a segment of the requested segment size + * has been obtained. + * + * Lower address bits of the DMA blocks are used as follows: + * 0: Untagged + * 1: Discarded block + * 2: Part of largest contiguous segment + * 3: Part of current contiguous segment + */ +#ifndef DMA_MEM_MODE_PLATFORM +static int +_dal_find_largest_segment(dma_segment_t* dseg) +{ + int i, j, blks, found; + unsigned long seg_begin; + unsigned long seg_end; + unsigned long seg_tmp; + + blks = dseg->blk_cnt; + + /* Clear all block tags */ + for (i = 0; i < blks; i++) + { + dseg->blk_ptr[i] &= ~3; + } + + for (i = 0; i < blks && dseg->seg_size < dseg->req_size; i++) + { + /* First block must be an untagged block */ + if ((dseg->blk_ptr[i] & 3) == DAL_UNTAG_BLOCK) + { + /* Initial segment size is the block size */ + seg_begin = dseg->blk_ptr[i]; + seg_end = seg_begin + dseg->blk_size; + dseg->blk_ptr[i] |= DAL_CUR_MATCH_BLOCk; + + /* Loop looking for adjacent blocks */ + do + { + found = 0; + + for (j = i + 1; j < blks && (seg_end - seg_begin) < dseg->req_size; j++) + { + seg_tmp = dseg->blk_ptr[j]; + /* Check untagged blocks only */ + if ((seg_tmp & 3) == DAL_UNTAG_BLOCK) + { + if (seg_tmp == (seg_begin - dseg->blk_size)) + { + /* Found adjacent block below current segment */ + dseg->blk_ptr[j] |= DAL_CUR_MATCH_BLOCk; + seg_begin = seg_tmp; + found = 1; + } + else if (seg_tmp == seg_end) + { + /* Found adjacent block above current segment */ + dseg->blk_ptr[j] |= DAL_CUR_MATCH_BLOCk; + seg_end += dseg->blk_size; + found = 1; + } + } + } + } + while (found); + + if ((seg_end - seg_begin) > dseg->seg_size) + { + /* The current block is largest so far */ + dseg->seg_begin = seg_begin; + dseg->seg_end = seg_end; + dseg->seg_size = seg_end - seg_begin; + + /* Re-tag current and previous largest segment */ + for (j = 0; j < blks; j++) + { + if ((dseg->blk_ptr[j] & 3) == DAL_CUR_MATCH_BLOCk) + { + /* Tag current segment as the largest */ + dseg->blk_ptr[j] &= ~1; + } + else if ((dseg->blk_ptr[j] & 3) == DAL_MATCHED_BLOCK) + { + /* Discard previous largest segment */ + dseg->blk_ptr[j] ^= 3; + } + } + } + else + { + /* Discard all blocks in current segment */ + for (j = 0; j < blks; j++) + { + if ((dseg->blk_ptr[j] & 3) == DAL_CUR_MATCH_BLOCk) + { + dseg->blk_ptr[j] &= ~2; + } + } + } + } + } + + return 0; +} + +/* + * Function: _alloc_dma_blocks + */ +static int +_dal_alloc_dma_blocks(dma_segment_t* dseg, int blks) +{ + int i, start; + unsigned long addr; + + if (dseg->blk_cnt + blks > dseg->blk_cnt_max) + { + printk("No more DMA blocks\n"); + return -1; + } + + start = dseg->blk_cnt; + dseg->blk_cnt += blks; + + for (i = start; i < dseg->blk_cnt; i++) + { + addr = __get_free_pages(GFP_ATOMIC, dseg->blk_order); + if (addr) + { + dseg->blk_ptr[i] = addr; + } + else + { + printk("DMA allocation failed\n"); + return -1; + } + } + + return 0; +} + +/* + * Function: _dal_dma_segment_alloc + */ +static dma_segment_t* +_dal_dma_segment_alloc(unsigned int size, unsigned int blk_size) +{ + dma_segment_t* dseg; + int i, blk_ptr_size; + unsigned long page_addr; + struct sysinfo si; + + /* Sanity check */ + if (size == 0 || blk_size == 0) + { + return NULL; + } + + /* Allocate an initialize DMA segment descriptor */ + if ((dseg = kmalloc(sizeof(dma_segment_t), GFP_ATOMIC)) == NULL) + { + return NULL; + } + + memset(dseg, 0, sizeof(dma_segment_t)); + dseg->req_size = size; + dseg->blk_size = PAGE_ALIGN(blk_size); + + while ((PAGE_SIZE << dseg->blk_order) < dseg->blk_size) + { + dseg->blk_order++; + } + + si_meminfo(&si); + dseg->blk_cnt_max = (si.totalram << PAGE_SHIFT) / dseg->blk_size; + blk_ptr_size = dseg->blk_cnt_max * sizeof(unsigned long); + /* Allocate an initialize DMA block pool */ + dseg->blk_ptr = kmalloc(blk_ptr_size, GFP_KERNEL); + if (dseg->blk_ptr == NULL) + { + kfree(dseg); + return NULL; + } + + memset(dseg->blk_ptr, 0, blk_ptr_size); + /* Allocate minimum number of blocks */ + _dal_alloc_dma_blocks(dseg, dseg->req_size / dseg->blk_size); + + /* Allocate more blocks until we have a complete segment */ + do + { + _dal_find_largest_segment(dseg); + if (dseg->seg_size >= dseg->req_size) + { + break; + } + } + while (_dal_alloc_dma_blocks(dseg, 8) == 0); + + /* Reserve all pages in the DMA segment and free unused blocks */ + for (i = 0; i < dseg->blk_cnt; i++) + { + if ((dseg->blk_ptr[i] & 3) == 2) + { + dseg->blk_ptr[i] &= ~3; + + for (page_addr = dseg->blk_ptr[i]; + page_addr < dseg->blk_ptr[i] + dseg->blk_size; + page_addr += PAGE_SIZE) + { + MEM_MAP_RESERVE(VIRT_TO_PAGE((void*)page_addr)); + } + } + else if (dseg->blk_ptr[i]) + { + dseg->blk_ptr[i] &= ~3; + free_pages(dseg->blk_ptr[i], dseg->blk_order); + dseg->blk_ptr[i] = 0; + } + } + + return dseg; +} + +/* + * Function: _dal_dma_segment_free + */ +static void +_dal_dma_segment_free(dma_segment_t* dseg) +{ + int i; + unsigned long page_addr; + + if (dseg->blk_ptr) + { + for (i = 0; i < dseg->blk_cnt; i++) + { + if (dseg->blk_ptr[i]) + { + for (page_addr = dseg->blk_ptr[i]; + page_addr < dseg->blk_ptr[i] + dseg->blk_size; + page_addr += PAGE_SIZE) + { + MEM_MAP_UNRESERVE(VIRT_TO_PAGE(page_addr)); + } + + free_pages(dseg->blk_ptr[i], dseg->blk_order); + } + } + + kfree(dseg->blk_ptr); + kfree(dseg); + } +} + +/* + * Function: -dal_pgalloc + */ +static void* +_dal_pgalloc(unsigned int size) +{ + dma_segment_t* dseg; + unsigned int blk_size; + + blk_size = (size < DMA_BLOCK_SIZE) ? size : DMA_BLOCK_SIZE; + if ((dseg = _dal_dma_segment_alloc(size, blk_size)) == NULL) + { + return NULL; + } + + if (dseg->seg_size < size) + { + /* If we didn't get the full size then forget it */ + printk("Notice: Can not get enough memory for requset!!\n"); + printk("actual size:0x%lx, request size:0x%x\n", dseg->seg_size, size); + //-_dal_dma_segment_free(dseg); + //-return NULL; + } + + list_add(&dseg->list, &_dma_seg); + return (void*)dseg->seg_begin; +} + +/* + * Function: _dal_pgfree + */ +static int +_dal_pgfree(void* ptr) +{ + struct list_head* pos; + + list_for_each(pos, &_dma_seg) + { + dma_segment_t* dseg = list_entry(pos, dma_segment_t, list); + if (ptr == (void*)dseg->seg_begin) + { + list_del(&dseg->list); + _dal_dma_segment_free(dseg); + return 0; + } + } + return -1; +} +#endif +static void +dal_alloc_dma_pool(int lchip, int size) +{ + if (use_high_memory) + { + dma_phy_base[lchip] = virt_to_bus(high_memory); + dma_virt_base[lchip] = ioremap_nocache(dma_phy_base[lchip], size); + } + else + { +#ifdef DMA_MEM_MODE_PLATFORM + dma_virt_base[lchip] = dma_alloc_coherent(&(dal_dev[lchip].pci_dev->dev), dma_mem_size, + &dma_phy_base[lchip], GFP_KERNEL); + + printk(KERN_WARNING "########Using DMA_MEM_MODE_PLATFORM \n"); +#endif + +#ifndef DMA_MEM_MODE_PLATFORM + /* Get DMA memory from kernel */ + dma_virt_base_tmp[lchip] = _dal_pgalloc(size); + dma_phy_base[lchip] = virt_to_bus(dma_virt_base_tmp[lchip]); + dma_virt_base [lchip]= ioremap_nocache(dma_phy_base[lchip], size); +#endif + } +} + +static void +dal_free_dma_pool(int lchip) +{ + int ret = 0; + ret = ret; + if (use_high_memory) + { + iounmap(dma_virt_base[lchip]); + } + else + { +#ifdef DMA_MEM_MODE_PLATFORM + dma_free_coherent(&(dal_dev[lchip].pci_dev->dev), dma_mem_size, + dma_virt_base[lchip], dma_phy_base[lchip]); +#endif + +#ifndef DMA_MEM_MODE_PLATFORM + iounmap(dma_virt_base[lchip]); + ret = _dal_pgfree(dma_virt_base_tmp[lchip]); + if(ret<0) + { + printk("Dma free memory fail !!!!!! \n"); + } +#endif + } +} + +#define _KERNEL_DAL_IO +static int +_dal_pci_read(unsigned char lchip, unsigned int offset, unsigned int* value) +{ + if (!VERIFY_CHIP_INDEX(lchip)) + { + return -1; + } + + *value = *(volatile unsigned int*)(dal_dev[lchip].logic_address + offset); + return 0; +} + +int +dal_create_irq_mapping(unsigned long arg) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) + dal_irq_mapping_t irq_map; + + if (copy_from_user(&irq_map, (void*)arg, sizeof(dal_irq_mapping_t))) + { + return -EFAULT; + } + + irq_map.sw_irq = irq_create_mapping(NULL, irq_map.hw_irq); + if (irq_map.sw_irq == NO_IRQ) + { + printk("IRQ mapping fail !!!!!! \n"); + return -1; + } + + if (copy_to_user((dal_irq_mapping_t*)arg, (void*)&irq_map, sizeof(dal_irq_mapping_t))) + { + return -EFAULT; + } +#endif + return 0; +} + +int +dal_pci_read(unsigned long arg) +{ + dal_chip_parm_t cmdpara_chip; + + if (copy_from_user(&cmdpara_chip, (void*)arg, sizeof(dal_chip_parm_t))) + { + return -EFAULT; + } + + _dal_pci_read((unsigned char)cmdpara_chip.chip_id, (unsigned int)cmdpara_chip.reg_addr, + (unsigned int*)(&(cmdpara_chip.value))); + + if (copy_to_user((dal_chip_parm_t*)arg, (void*)&cmdpara_chip, sizeof(dal_chip_parm_t))) + { + return -EFAULT; + } + + return 0; +} + +static int +_dal_pci_write(unsigned char lchip, unsigned int offset, unsigned int value) +{ + if (!VERIFY_CHIP_INDEX(lchip)) + { + return -1; + } + + *(volatile unsigned int*)(dal_dev[lchip].logic_address + offset) = value; + return 0; +} + +int +dal_pci_write(unsigned long arg) +{ + dal_chip_parm_t cmdpara_chip; + + if (copy_from_user(&cmdpara_chip, (void*)arg, sizeof(dal_chip_parm_t))) + { + return -EFAULT; + } + + _dal_pci_write((unsigned char)cmdpara_chip.chip_id, (unsigned int)cmdpara_chip.reg_addr, + (unsigned int)cmdpara_chip.value); + + return 0; +} + +int +dal_pci_conf_read(unsigned char lchip, unsigned int offset, unsigned int* value) +{ + if (!VERIFY_CHIP_INDEX(lchip)) + { + return -1; + } + + pci_read_config_dword(dal_dev[lchip].pci_dev, offset, value); + return 0; +} + +int +dal_pci_conf_write(unsigned char lchip, unsigned int offset, unsigned int value) +{ + if (!VERIFY_CHIP_INDEX(lchip)) + { + return -1; + } + + pci_write_config_dword(dal_dev[lchip].pci_dev, offset, value); + return 0; +} +int +dal_user_read_pci_conf(unsigned long arg) +{ + dal_pci_cfg_ioctl_t dal_cfg; + + if (copy_from_user(&dal_cfg, (void*)arg, sizeof(dal_pci_cfg_ioctl_t))) + { + return -EFAULT; + } + + if (dal_pci_conf_read(dal_cfg.chip_id, dal_cfg.offset, &dal_cfg.value)) + { + printk("dal_pci_conf_read failed.\n"); + return -EFAULT; + } + + if (copy_to_user((dal_pci_cfg_ioctl_t*)arg, (void*)&dal_cfg, sizeof(dal_pci_cfg_ioctl_t))) + { + return -EFAULT; + } + + return 0; +} + +int +dal_user_write_pci_conf(unsigned long arg) +{ + dal_pci_cfg_ioctl_t dal_cfg; + + if (copy_from_user(&dal_cfg, (void*)arg, sizeof(dal_pci_cfg_ioctl_t))) + { + return -EFAULT; + } + + return dal_pci_conf_write(dal_cfg.chip_id, dal_cfg.offset, dal_cfg.value); +} + +static int +linux_get_device(unsigned long arg) +{ + dal_user_dev_t user_dev; + int chip_id = 0; + + if (copy_from_user(&user_dev, (void*)arg, sizeof(user_dev))) + { + return -EFAULT; + } + + user_dev.chip_num = dal_chip_num; + chip_id = user_dev.chip_id; + + if (chip_id < dal_chip_num) + { + user_dev.phy_base0 = (unsigned int)dal_dev[chip_id].phys_address; + #ifdef PHYS_ADDR_IS_64BIT + user_dev.phy_base1 = (unsigned int)(dal_dev[chip_id].phys_address >> 32); + #else + user_dev.phy_base1 = 0; + #endif + + user_dev.bus_no = dal_dev[chip_id].pci_dev->bus->number; + user_dev.dev_no = dal_dev[chip_id].pci_dev->device; + user_dev.fun_no = dal_dev[chip_id].pci_dev->devfn; + } + + if (copy_to_user((dal_user_dev_t*)arg, (void*)&user_dev, sizeof(user_dev))) + { + return -EFAULT; + } + + return 0; +} + +/* set dal version, copy to user */ +static int +linux_get_dal_version(unsigned long arg) +{ + int dal_ver = VERSION_1DOT2; /* set dal version */ + + if (copy_to_user((int*)arg, (void*)&dal_ver, sizeof(dal_ver))) + { + return -EFAULT; + } + + dal_version = dal_ver; /* up sw */ + + return 0; +} + +static int +linux_get_dma_info(unsigned long arg) +{ + dma_info_t dma_para; + + if (copy_from_user(&dma_para, (void*)arg, sizeof(dma_info_t))) + { + return -EFAULT; + } + + dma_para.phy_base = (unsigned int)dma_phy_base[dma_para.lchip]; + #ifdef PHYS_ADDR_IS_64BIT + dma_para.phy_base_hi = dma_phy_base[dma_para.lchip] >> 32; + #else + dma_para.phy_base_hi = 0; + #endif + dma_para.size = dma_mem_size; + + if (copy_to_user((dma_info_t*)arg, (void*)&dma_para, sizeof(dma_info_t))) + { + return -EFAULT; + } + + return 0; +} + +static int +dal_get_msi_info(unsigned long arg) +{ + dal_msi_info_t msi_para; + unsigned int lchip = 0; + + /* get lchip form user mode */ + if (copy_from_user(&msi_para, (void*)arg, sizeof(dal_msi_info_t))) + { + return -EFAULT; + } + lchip = msi_para.lchip; + + msi_para.irq_base = msi_irq_base[lchip]; + msi_para.irq_num = msi_irq_num[lchip]; + + /* send msi info to user mode */ + if (copy_to_user((dal_msi_info_t*)arg, (void*)&msi_para, sizeof(dal_msi_info_t))) + { + return -EFAULT; + } + + return 0; +} + + +static int +dal_get_intr_info(unsigned long arg) +{ + dal_intr_info_t intr_para; + unsigned int intr_num = 0; + + /* get lchip form user mode */ + if (copy_from_user(&intr_para, (void*)arg, sizeof(dal_intr_info_t))) + { + return -EFAULT; + } + + intr_para.irq_idx = CTC_MAX_INTR_NUM; + for (intr_num=0; intr_num< CTC_MAX_INTR_NUM; intr_num++) + { + if (intr_para.irq == dal_isr[intr_num].irq) + { + intr_para.irq_idx = intr_num; + break; + } + } + + if (CTC_MAX_INTR_NUM == intr_para.irq_idx) + { + printk("Interrupt %d cann't find.\n", intr_para.irq); + } + /* send msi info to user mode */ + if (copy_to_user((dal_intr_info_t*)arg, (void*)&intr_para, sizeof(dal_intr_info_t))) + { + return -EFAULT; + } + + return 0; +} + +static int +dal_cache_inval(unsigned long arg) +{ + dal_dma_cache_info_t intr_para; + + if (copy_from_user(&intr_para, (void*)arg, sizeof(dal_dma_cache_info_t))) + { + return -EFAULT; + } + +#if 0 + dma_cache_wback_inv((unsigned long)intr_para.ptr, intr_para.length); +#endif + +#if 0 + dma_sync_single_for_cpu(NULL, intr_para.ptr, intr_para.length, DMA_BIDIRECTIONAL); +#endif + + dma_cache_sync(NULL, (void*)intr_para.ptr, intr_para.length, DMA_BIDIRECTIONAL); + + return 0; +} + +static int +dal_cache_flush(unsigned long arg) +{ + dal_dma_cache_info_t intr_para; + + if (copy_from_user(&intr_para, (void*)arg, sizeof(dal_dma_cache_info_t))) + { + return -EFAULT; + } + +#if 0 + dma_cache_wback_inv(intr_para.ptr, intr_para.length); +#endif + +#if 0 + dma_sync_single_for_cpu(NULL, intr_para.ptr, intr_para.length, DMA_BIDIRECTIONAL); +#endif + + dma_cache_sync(NULL, (void*)intr_para.ptr, intr_para.length, DMA_BIDIRECTIONAL); + + return 0; +} + +int +linux_dal_probe(struct pci_dev* pdev, const struct pci_device_id* id) +{ + dal_kern_dev_t* dev = NULL; + int bar = 0; + int ret = 0; + unsigned int temp = 0; + unsigned int lchip = 0; + unsigned int chip_id = 0; + + printk(KERN_WARNING "********found dal device*****\n"); + + for (chip_id = 0; chip_id < DAL_MAX_CHIP_NUM; chip_id ++) + { + if (NULL == dal_dev[chip_id].pci_dev) + { + break; + } + } + + if (chip_id >= DAL_MAX_CHIP_NUM) + { + printk("Exceed max local chip num\n"); + return -1; + } + + dev = &dal_dev[chip_id]; + if (NULL == dev) + { + printk("Cannot obtain PCI resources\n"); + } + + lchip = chip_id; + dal_chip_num += 1; + + dev->pci_dev = pdev; + + if (pci_enable_device(pdev) < 0) + { + printk("Cannot enable PCI device: vendor id = %x, device id = %x\n", + pdev->vendor, pdev->device); + } + + ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); + if (ret) + { + ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (ret) + { + printk("Could not set PCI DMA Mask\n"); + return ret; + } + } + + if (pci_request_regions(pdev, DAL_NAME) < 0) + { + printk("Cannot obtain PCI resources\n"); + } + + dev->phys_address = pci_resource_start(pdev, bar); + dev->logic_address = (uintptr)ioremap_nocache(dev->phys_address, + pci_resource_len(dev->pci_dev, bar)); + + _dal_pci_read(lchip, 0x48, &temp); + if (((temp >> 8) & 0xffff) == 0x3412) + { + printk("Little endian Cpu detected!!! \n"); + _dal_pci_write(lchip, 0x48, 0xFFFFFFFF); + } + + pci_set_master(pdev); + + /* alloc dma_mem_size for every chip */ + if (dma_mem_size) + { + dal_alloc_dma_pool(lchip, dma_mem_size); + #ifdef PHYS_ADDR_IS_64BIT + + /*add check Dma memory pool cannot cross 4G space*/ + if ((0==(dma_phy_base[lchip]>>32)) && (0!=((dma_phy_base[lchip]+dma_mem_size)>>32))) + { + printk("Dma malloc memory cross 4G space!!!!!! \n"); + return -1; + } + #endif + } + + printk(KERN_WARNING "linux_dal_probe end*****\n"); + + return 0; +} + +void +linux_dal_remove(struct pci_dev* pdev) +{ + unsigned int chip_id = 0; + unsigned int flag = 0; + + for (chip_id = 0; chip_id < DAL_MAX_CHIP_NUM; chip_id ++) + { + if (pdev == dal_dev[chip_id].pci_dev) + { + flag = 1; + break; + } + } + + if (1 == flag) + { + dal_free_dma_pool(chip_id); + pci_release_regions(pdev); + pci_disable_device(pdev); + + dal_dev[chip_id].pci_dev = NULL; + dal_chip_num--; + } + + +} + +#ifdef CONFIG_COMPAT +static long +linux_dal_ioctl(struct file* file, + unsigned int cmd, unsigned long arg) +#else + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 13)) +static int +linux_dal_ioctl(struct file* file, + unsigned int cmd, unsigned long arg) +#else +static int +linux_dal_ioctl(struct inode* inode, struct file* file, + unsigned int cmd, unsigned long arg) +#endif + +#endif +{ + switch (cmd) + { + + case CMD_READ_CHIP: + return dal_pci_read(arg); + + case CMD_WRITE_CHIP: + return dal_pci_write(arg); + + case CMD_GET_DEVICES: + return linux_get_device(arg); + + case CMD_GET_DAL_VERSION: + return linux_get_dal_version(arg); + + case CMD_GET_DMA_INFO: + return linux_get_dma_info(arg); + + case CMD_PCI_CONFIG_READ: + return dal_user_read_pci_conf(arg); + + case CMD_PCI_CONFIG_WRITE: + return dal_user_write_pci_conf(arg); + + case CMD_REG_INTERRUPTS: + return dal_user_interrupt_register(arg); + + case CMD_UNREG_INTERRUPTS: + return dal_user_interrupt_unregister(arg); + + case CMD_EN_INTERRUPTS: + return dal_user_interrupt_set_en(arg); + + case CMD_SET_MSI_CAP: + return dal_set_msi_cap(arg); + + case CMD_GET_MSI_INFO: + return dal_get_msi_info(arg); + + case CMD_IRQ_MAPPING: + return dal_create_irq_mapping(arg); + + case CMD_GET_INTR_INFO: + return dal_get_intr_info(arg); + + case CMD_CACHE_INVAL: + return dal_cache_inval(arg); + + case CMD_CACHE_FLUSH: + return dal_cache_flush(arg); + + default: + break; + } + + return 0; +} + +static unsigned int +linux_dal_poll0(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[0], p); + local_irq_save(flags); + if (poll_intr_trigger[0]) + { + poll_intr_trigger[0] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static unsigned int +linux_dal_poll1(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[1], p); + local_irq_save(flags); + if (poll_intr_trigger[1]) + { + poll_intr_trigger[1] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static unsigned int +linux_dal_poll2(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[2], p); + local_irq_save(flags); + if (poll_intr_trigger[2]) + { + poll_intr_trigger[2] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static unsigned int +linux_dal_poll3(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[3], p); + local_irq_save(flags); + if (poll_intr_trigger[3]) + { + poll_intr_trigger[3] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static unsigned int +linux_dal_poll4(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[4], p); + local_irq_save(flags); + if (poll_intr_trigger[4]) + { + poll_intr_trigger[4] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static unsigned int +linux_dal_poll5(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[5], p); + local_irq_save(flags); + if (poll_intr_trigger[5]) + { + poll_intr_trigger[5] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static unsigned int +linux_dal_poll6(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[6], p); + local_irq_save(flags); + if (poll_intr_trigger[6]) + { + poll_intr_trigger[6] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static unsigned int +linux_dal_poll7(struct file* filp, struct poll_table_struct* p) +{ + unsigned int mask = 0; + unsigned long flags; + + poll_wait(filp, &poll_intr[7], p); + local_irq_save(flags); + if (poll_intr_trigger[7]) + { + poll_intr_trigger[7] = 0; + mask |= POLLIN | POLLRDNORM; + } + + local_irq_restore(flags); + + return mask; +} + +static struct pci_driver linux_dal_driver = +{ + .name = DAL_NAME, + .id_table = dal_id_table, + .probe = linux_dal_probe, + .remove = linux_dal_remove, +}; + +static struct file_operations fops = +{ + .owner = THIS_MODULE, +#ifdef CONFIG_COMPAT + .compat_ioctl = linux_dal_ioctl, + .unlocked_ioctl = linux_dal_ioctl, +#else +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) + .unlocked_ioctl = linux_dal_ioctl, +#else + .ioctl = linux_dal_ioctl, +#endif +#endif +}; + + +static int __init +linux_dal_init(void) +{ + int ret = 0; + + /* Get DMA memory pool size form dal.ok input param, or use default dma_mem_size */ + if (dma_pool_size) + { + if ((dma_pool_size[strlen(dma_pool_size) - 1] & ~0x20) == 'M') + { + dma_mem_size = simple_strtoul(dma_pool_size, NULL, 0); + printk("dma_mem_size: 0x%x \n", dma_mem_size); + + dma_mem_size *= MB_SIZE; + } + else + { + printk("DMA memory pool size must be specified as e.g. dma_pool_size=8M\n"); + } + + if (dma_mem_size & (dma_mem_size - 1)) + { + printk("dma_mem_size must be a power of 2 (1M, 2M, 4M, 8M etc.)\n"); + dma_mem_size = 0; + } + } + + ret = register_chrdev(DAL_DEV_MAJOR, DAL_NAME, &fops); + if (ret < 0) + { + printk(KERN_WARNING "Register linux_dal device, ret %d\n", ret); + return ret; + } + + ret = pci_register_driver(&linux_dal_driver); + if (ret < 0) + { + printk(KERN_WARNING "Register ASIC PCI driver failed, ret %d\n", ret); + return ret; + } + + /* alloc /dev/linux_dal node */ + dal_class = class_create(THIS_MODULE, DAL_NAME); + device_create(dal_class, NULL, MKDEV(DAL_DEV_MAJOR, 0), NULL, DAL_NAME); + + /* init interrupt function */ + intr_handler_fun[0] = intr0_handler; + intr_handler_fun[1] = intr1_handler; + intr_handler_fun[2] = intr2_handler; + intr_handler_fun[3] = intr3_handler; + intr_handler_fun[4] = intr4_handler; + intr_handler_fun[5] = intr5_handler; + intr_handler_fun[6] = intr6_handler; + intr_handler_fun[7] = intr7_handler; + + return ret; +} + +static void __exit +linux_dal_exit(void) +{ + device_destroy(dal_class, MKDEV(DAL_DEV_MAJOR, 0)); + class_destroy(dal_class); + unregister_chrdev(DAL_DEV_MAJOR, "linux_dal"); + pci_unregister_driver(&linux_dal_driver); +} + +module_init(linux_dal_init); +module_exit(linux_dal_exit); + diff --git a/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_kernel.h b/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_kernel.h new file mode 100644 index 000000000000..de39af67773b --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_kernel.h @@ -0,0 +1,170 @@ +/** + @file dal_kernel_io.h + + @author Copyright (C) 2012 Centec Networks Inc. All rights reserved. + + @date 2012-4-9 + + @version v2.0 + +*/ +#ifndef _DAL_KERNEL_H_ +#define _DAL_KERNEL_H_ +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(CONFIG_RESOURCES_64BIT) || defined(CONFIG_PHYS_ADDR_T_64BIT) +#define PHYS_ADDR_IS_64BIT +#endif + +#ifndef SDK_IN_USERMODE +#ifdef PHYS_ADDR_IS_64BIT +typedef long long intptr; +typedef unsigned long long uintptr; +#else +typedef int intptr; +typedef unsigned int uintptr; +#endif +#endif + +#define DAL_PCI_READ_ADDR 0x0 +#define DAL_PCI_READ_DATA 0xc +#define DAL_PCI_WRITE_ADDR 0x8 +#define DAL_PCI_WRITE_DATA 0x4 +#define DAL_PCI_STATUS 0x10 + +#define DAL_PCI_STATUS_IN_PROCESS 31 +#define DAL_PCI_STATUS_BAD_PARITY 5 +#define DAL_PCI_STATUS_CPU_ACCESS_ERR 4 +#define DAL_PCI_STATUS_READ_CMD 3 +#define DAL_PCI_STATUS_REGISTER_ERR 1 +#define DAL_PCI_STATUS_REGISTER_ACK 0 + +#define DAL_PCI_ACCESS_TIMEOUT 0x64 + +#define DAL_NAME "linux_dal" /* "linux_dal" */ + +#define DAL_DEV_MAJOR 198 + +#define DAL_DEV_INTR_MAJOR_BASE 200 + +#define DAL_DEV_NAME "/dev/" DAL_NAME +#define DAL_ONE_KB 1024 +#define DAL_ONE_MB (1024*1024) +struct dal_chip_parm_s +{ + unsigned int chip_id; /*tmp should be uint8*/ + unsigned int fpga_id; /*tmp add*/ + unsigned int reg_addr; + unsigned int value; +}; +typedef struct dal_chip_parm_s dal_chip_parm_t; + +struct dal_intr_parm_s +{ + unsigned int irq; + unsigned int enable; +}; +typedef struct dal_intr_parm_s dal_intr_parm_t; + +struct dal_irq_mapping_s +{ + unsigned int hw_irq; + unsigned int sw_irq; +}; +typedef struct dal_irq_mapping_s dal_irq_mapping_t; + +struct dal_user_dev_s +{ + unsigned int chip_num; /*output: local chip number*/ + unsigned int chip_id; /*input: local chip id*/ + unsigned int phy_base0; /* low 32bits physical base address */ + unsigned int phy_base1; /* high 32bits physical base address */ + unsigned int bus_no; + unsigned int dev_no; + unsigned int fun_no; + void* virt_base[2]; /* Virtual base address; this must be last member */ +}; +typedef struct dal_user_dev_s dal_user_dev_t; + +struct dma_info_s +{ + unsigned int lchip; + unsigned int phy_base; + unsigned int phy_base_hi; + unsigned int size; + unsigned int* virt_base; +}; +typedef struct dma_info_s dma_info_t; + +struct dal_pci_cfg_ioctl_s +{ + unsigned int chip_id; /* Device ID */ + unsigned int offset; + unsigned int value; +}; +typedef struct dal_pci_cfg_ioctl_s dal_pci_cfg_ioctl_t; + +struct dal_msi_info_s +{ + unsigned int lchip; + unsigned int irq_base; + unsigned int irq_num; +}; +typedef struct dal_msi_info_s dal_msi_info_t; + +struct dal_intr_info_s +{ + unsigned int irq; + unsigned int irq_idx; +}; +typedef struct dal_intr_info_s dal_intr_info_t; + +struct dal_dma_cache_info_s +{ + unsigned long ptr; + unsigned int length; +}; +typedef struct dal_dma_cache_info_s dal_dma_cache_info_t; + +#define CMD_MAGIC 'C' +#define CMD_WRITE_CHIP _IO(CMD_MAGIC, 0) /* for humber ioctrol*/ +#define CMD_READ_CHIP _IO(CMD_MAGIC, 1) /* for humber ioctrol*/ +#define CMD_GET_DEVICES _IO(CMD_MAGIC, 2) +#define CMD_GET_DAL_VERSION _IO(CMD_MAGIC, 3) +#define CMD_PCI_CONFIG_WRITE _IO(CMD_MAGIC, 4) +#define CMD_PCI_CONFIG_READ _IO(CMD_MAGIC, 5) +#define CMD_GET_DMA_INFO _IO(CMD_MAGIC, 6) +#define CMD_REG_INTERRUPTS _IO(CMD_MAGIC, 7) +#define CMD_UNREG_INTERRUPTS _IO(CMD_MAGIC, 8) +#define CMD_EN_INTERRUPTS _IO(CMD_MAGIC, 9) +#define CMD_I2C_READ _IO(CMD_MAGIC, 10) +#define CMD_I2C_WRITE _IO(CMD_MAGIC, 11) +#define CMD_GET_MSI_INFO _IO(CMD_MAGIC, 12) +#define CMD_SET_MSI_CAP _IO(CMD_MAGIC, 13) +#define CMD_IRQ_MAPPING _IO(CMD_MAGIC, 14) +#define CMD_GET_INTR_INFO _IO(CMD_MAGIC, 15) +#define CMD_CACHE_INVAL _IO(CMD_MAGIC, 16) +#define CMD_CACHE_FLUSH _IO(CMD_MAGIC, 17) + +enum dal_version_e +{ + VERSION_MIN, + VERSION_1DOT0, + VERSION_1DOT1, + VERSION_1DOT2, + + VERSION_MAX +}; +typedef enum dal_version_e dal_version_t; + +/* We try to assemble a contiguous segment from chunks of this size */ +#define DMA_BLOCK_SIZE (512 * DAL_ONE_KB) + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_mpool.c b/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_mpool.c new file mode 100644 index 000000000000..82d3b7a917a8 --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_mpool.c @@ -0,0 +1,343 @@ + +#include "dal_mpool.h" + +#ifdef __KERNEL__ +#include +#include + +#define DAL_MALLOC(x) kmalloc(x, GFP_ATOMIC) +#define DAL_FREE(x) kfree(x) + +static spinlock_t dal_mpool_lock; +#define MPOOL_LOCK_INIT() spin_lock_init(&dal_mpool_lock) +#define MPOOL_LOCK() unsigned long flags; spin_lock_irqsave(&dal_mpool_lock, flags) +#define MPOOL_UNLOCK() spin_unlock_irqrestore(&dal_mpool_lock, flags) +#define DAL_PRINT(fmt,arg...) printk(fmt,##arg) +#else /* !__KERNEL__*/ + +#include +#include "sal.h" +#define DAL_MALLOC(x) malloc(x) +#define DAL_FREE(x) free(x) +static sal_mutex_t* dal_mpool_lock; +#define MPOOL_LOCK_INIT() sal_mutex_create(&dal_mpool_lock) +#define MPOOL_LOCK() sal_mutex_lock(dal_mpool_lock) +#define MPOOL_UNLOCK() sal_mutex_unlock(dal_mpool_lock) +#define DAL_PRINT(fmt,arg...) sal_printf(fmt,##arg) + +#endif /* __KERNEL__ */ + +dal_mpool_mem_t* g_free_block_ptr = NULL; + +/* System cache line size */ +#ifndef DAL_CACHE_LINE_BYTES +#define DAL_CACHE_LINE_BYTES 256 +#endif + +static dal_mpool_mem_t* p_desc_pool = NULL; +static dal_mpool_mem_t* p_data_pool = NULL; + +int +dal_mpool_init(void) +{ + MPOOL_LOCK_INIT(); + return 0; +} + +dal_mpool_mem_t* +_dal_mpool_create(void* base, int size, int type) +{ + dal_mpool_mem_t* head = NULL; + dal_mpool_mem_t* tail = NULL; + + head = (dal_mpool_mem_t*)DAL_MALLOC(sizeof(dal_mpool_mem_t)); + if (head == NULL) + { + return NULL; + } + + tail = (dal_mpool_mem_t*)DAL_MALLOC(sizeof(dal_mpool_mem_t)); + if (tail == NULL) + { + DAL_FREE(head); + return NULL; + } + + head->size = tail->size = 0; + head->type = type; + head->address = base; + tail->address = head->address + size; + head->next = tail; + tail->next = NULL; + + return head; +} + +dal_mpool_mem_t* +dal_mpool_create(void* base, int size) +{ + dal_mpool_mem_t* head = NULL; + int mod = (int)(((unsigned long)base) & (DAL_CACHE_LINE_BYTES - 1)); + + MPOOL_LOCK(); + + if (mod) + { + base = (char*)base + (DAL_CACHE_LINE_BYTES - mod); + size -= (DAL_CACHE_LINE_BYTES - mod); + } + + size &= ~(DAL_CACHE_LINE_BYTES - 1); + + /* init for common linkptr, only used for GB */ + head = _dal_mpool_create(base, size, DAL_MPOOL_TYPE_USELESS); + if (NULL == head) + { + MPOOL_UNLOCK(); + return NULL; + } + + /* init for desc linkptr */ + p_desc_pool = _dal_mpool_create(base, DAL_MPOOL_MAX_DESX_SIZE, DAL_MPOOL_TYPE_DESC); + if (NULL == p_desc_pool) + { + MPOOL_UNLOCK(); + DAL_FREE(head->next); + DAL_FREE(head); + return NULL; + } + + /* init for data linkptr */ + p_data_pool = _dal_mpool_create(((char*)base+DAL_MPOOL_MAX_DESX_SIZE), (size - DAL_MPOOL_MAX_DESX_SIZE), DAL_MPOOL_TYPE_DATA); + if (NULL == p_data_pool) + { + MPOOL_UNLOCK(); + DAL_FREE(head->next); + DAL_FREE(head); + DAL_FREE(p_desc_pool->next); + DAL_FREE(p_desc_pool); + return NULL; + } + + MPOOL_UNLOCK(); + + return head; +} + +dal_mpool_mem_t* +_dal_mpool_alloc_comon(dal_mpool_mem_t* ptr, int size, int type) +{ + dal_mpool_mem_t* new_ptr = NULL; + + while (ptr && ptr->next) + { + if (ptr->next->address - (ptr->address + ptr->size) >= size) + { + break; + } + + ptr = ptr->next; + } + + if (!(ptr && ptr->next)) + { + return NULL; + } + + new_ptr = DAL_MALLOC(sizeof(dal_mpool_mem_t)); + if (!new_ptr) + { + return NULL; + } + + new_ptr->type = type; + new_ptr->address = ptr->address + ptr->size; + new_ptr->size = size; + new_ptr->next = ptr->next; + ptr->next = new_ptr; + + return new_ptr; +} + +void* +dal_mpool_alloc(dal_mpool_mem_t* pool, int size, int type) +{ + dal_mpool_mem_t* ptr = NULL; + dal_mpool_mem_t* new_ptr = NULL; + int mod; + + MPOOL_LOCK(); + + mod = size & (DAL_CACHE_LINE_BYTES - 1); + if (mod != 0) + { + size += (DAL_CACHE_LINE_BYTES - mod); + } + + switch(type) + { + case DAL_MPOOL_TYPE_USELESS: + ptr = pool; + new_ptr = _dal_mpool_alloc_comon(ptr, size, type); + if (NULL == new_ptr) + { + MPOOL_UNLOCK(); + return NULL; + } + break; + case DAL_MPOOL_TYPE_DESC: + ptr = p_desc_pool; + new_ptr = _dal_mpool_alloc_comon(ptr, size, type); + if (NULL == new_ptr) + { + MPOOL_UNLOCK(); + return NULL; + } + break; + case DAL_MPOOL_TYPE_DATA: + ptr = p_data_pool; + new_ptr = _dal_mpool_alloc_comon(ptr, size, type); + if (NULL == new_ptr) + { + MPOOL_UNLOCK(); + return NULL; + } + break; + default: + MPOOL_UNLOCK(); + return NULL; + break; + } + + MPOOL_UNLOCK(); + + return new_ptr->address; +} + +void +_dal_mpool_free(dal_mpool_mem_t* ptr, void* addr, int type) +{ + unsigned char* address = (unsigned char*)addr; + dal_mpool_mem_t* prev = NULL; + + while (ptr && ptr->next) + { + if (ptr->next->address == address) + { + break; + } + + ptr = ptr->next; + } + + if (ptr && ptr->next) + { + prev = ptr; + ptr = ptr->next; + prev->next = ptr->next; + DAL_FREE(ptr); + } + + return; +} + +void +dal_mpool_free(dal_mpool_mem_t* pool, void* addr) +{ + dal_mpool_mem_t* ptr = pool; + + MPOOL_LOCK(); + + switch(pool->type) + { + case DAL_MPOOL_TYPE_USELESS: + ptr = pool; + _dal_mpool_free(ptr, addr, DAL_MPOOL_TYPE_USELESS); + break; + case DAL_MPOOL_TYPE_DESC: + ptr = p_desc_pool; + _dal_mpool_free(ptr, addr, DAL_MPOOL_TYPE_DESC); + break; + case DAL_MPOOL_TYPE_DATA: + ptr = p_data_pool; + _dal_mpool_free(ptr, addr, DAL_MPOOL_TYPE_DATA); + break; + default: + break; + } + + MPOOL_UNLOCK(); + return; +} + +int +dal_mpool_destroy(dal_mpool_mem_t* pool) +{ + dal_mpool_mem_t* ptr, * next; + + MPOOL_LOCK(); + + for (ptr = pool; ptr; ptr = next) + { + next = ptr->next; + DAL_FREE(ptr); + } + + for (ptr = p_desc_pool; ptr; ptr = next) + { + next = ptr->next; + DAL_FREE(ptr); + } + + for (ptr = p_data_pool; ptr; ptr = next) + { + next = ptr->next; + DAL_FREE(ptr); + } + + MPOOL_UNLOCK(); + + return 0; +} + +int +dal_mpool_usage(dal_mpool_mem_t* pool, int type) +{ + int usage = 0; + dal_mpool_mem_t* ptr; + + MPOOL_LOCK(); + + for (ptr = pool; ptr; ptr = ptr->next) + { + if (ptr->type == type || ptr->type == -1) + { + usage += ptr->size; + } + } + + MPOOL_UNLOCK(); + + return usage; +} + +int +dal_mpool_debug(dal_mpool_mem_t* pool) +{ + dal_mpool_mem_t* ptr; + int index = 0; + + MPOOL_LOCK(); + + for (ptr = pool; ptr; ptr = ptr->next) + { +// DAL_PRINT("%2dst mpool block: address=0x%8x, size=0x%x \n", index, (unsigned int)ptr->address, ptr->size); + DAL_PRINT("%2dst mpool block: address=%p, size=0x%x \n", index, ptr->address, ptr->size); // note + index++; + } + + MPOOL_UNLOCK(); + + return 0; +} + diff --git a/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_mpool.h b/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_mpool.h new file mode 100644 index 000000000000..a1fa37d05f82 --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/48x6q/modules/dal_mpool.h @@ -0,0 +1,71 @@ +/** + @file dal_mpool.h + + @author Copyright (C) 2011 Centec Networks Inc. All rights reserved. + + @date 2012-5-10 + + @version v2.0 + + This file contains the dma memory init, allocation and free APIs +*/ + +#ifndef _DMA_MPOOL_H +#define _DMA_MPOOL_H +#ifdef __cplusplus +extern "C" { +#endif + +#define DAL_MPOOL_MAX_DESX_SIZE (1024*1024) + +enum dal_mpool_type_e +{ + DAL_MPOOL_TYPE_USELESS, /* just compatible with GB */ + DAL_MPOOL_TYPE_DESC, /* dma mpool op for desc */ + DAL_MPOOL_TYPE_DATA /* dma mpool op for data */ +}; +typedef enum dal_mpool_type_e dal_mpool_type_t; + +struct dal_mpool_mem_s +{ + unsigned char* address; + int size; + int type; + struct dal_mpool_mem_s* next; +}; +typedef struct dal_mpool_mem_s dal_mpool_mem_t; + +/** + @brief This function is to alloc dma memory + + @param[in] size size of memory + + @return NULL + +*/ +extern int +dal_mpool_init(void); + +extern dal_mpool_mem_t* +dal_mpool_create(void* base_ptr, int size); + +extern void* +dal_mpool_alloc(dal_mpool_mem_t* pool, int size, int type); + +extern void +dal_mpool_free(dal_mpool_mem_t* pool, void* addr); + +extern int +dal_mpool_destroy(dal_mpool_mem_t* pool); + +extern int +dal_mpool_usage(dal_mpool_mem_t* pool, int type); + +extern int +dal_mpool_debug(dal_mpool_mem_t* pool); +#ifdef __cplusplus +} +#endif + +#endif /* !_DMA_MPOOL_H */ + diff --git a/platform/centec/sonic-platform-modules-e582/48x6q/scripts/48x6q_platform.sh b/platform/centec/sonic-platform-modules-e582/48x6q/scripts/48x6q_platform.sh new file mode 100755 index 000000000000..e8f81a20d9d1 --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/48x6q/scripts/48x6q_platform.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +#platform init script for centec e582-48x6q + +init_devnum() { + found=0 + for devnum in 0 1; do + devname=`cat /sys/bus/i2c/devices/i2c-${devnum}/name` + # I801 adapter can be at either dffd0000 or dfff0000 + if [[ $devname == 'SMBus I801 adapter at '* ]]; then + found=1 + break + fi + done + + [ $found -eq 0 ] && echo "cannot find I801" && exit 1 +} + +init_devnum + +if [ "$1" == "init" ]; then + #install drivers and dependencies + depmod -a + modprobe i2c-i801 + modprobe i2c-dev + modprobe i2c-mux + modprobe i2c-smbus + modprobe i2c-mux-pca954x force_deselect_on_exit=1 + i2cset -y 0 0x58 0x8 0x3f + i2cset -y 0 0x20 0x1b 0x0 + i2cset -y 0 0x20 0xb 0x0 + i2cset -y 0 0x21 0x19 0x0 + i2cset -y 0 0x21 0x9 0x0 + i2cset -y 0 0x21 0x1c 0x0 + i2cset -y 0 0x21 0xc 0x0 + i2cset -y 0 0x22 0x1a 0x0 + i2cset -y 0 0x22 0xa 0x0 + i2cset -y 0 0x23 0x18 0x0 + i2cset -y 0 0x23 0x8 0x0 + i2cset -y 0 0x23 0x1b 0x0 + i2cset -y 0 0x23 0xb 0x0 + modprobe lm77 + modprobe tun + modprobe dal + modprobe centec_at24c64 + modprobe centec_e582_48x6q_platform + + #start platform monitor + rm -rf /usr/bin/platform_monitor + ln -s /usr/bin/48x6q_platform_monitor.py /usr/bin/platform_monitor + python /usr/bin/platform_monitor & +elif [ "$1" == "deinit" ]; then + kill -9 $(pidof platform_monitor) > /dev/null 2>&1 + rm -rf /usr/bin/platform_monitor + modprobe -r centec_e582_48x6q_platform + modprobe -r centec_at24c64 + modprobe -r dal + modprobe -r i2c-mux-pca954x + modprobe -r i2c-dev +else + echo "e582-48x6q_platform : Invalid option !" +fi diff --git a/platform/centec/sonic-platform-modules-e582/48x6q/scripts/48x6q_platform_monitor.py b/platform/centec/sonic-platform-modules-e582/48x6q/scripts/48x6q_platform_monitor.py new file mode 100644 index 000000000000..d08802a35f3b --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/48x6q/scripts/48x6q_platform_monitor.py @@ -0,0 +1,217 @@ +#!/usr/bin/env python + +############################################################################# +# Centec +# +# Module contains an implementation of sfp presence scan logic +# +############################################################################# + +try: + import os + import os.path + import threading + import time + import logging + import struct + import syslog + import swsssdk + from socket import * + from select import * +except ImportError, e: + raise ImportError(str(e) + " - required module not found") + + +def DBG_PRINT(str): + syslog.openlog("centec-pmon") + syslog.syslog(syslog.LOG_INFO, str) + syslog.closelog() + +PORT_NUMBER = (48+6) + +class PlatformMonitor: + + """init board platform default config""" + def __init__(self): + """[ctlid, slavedevid]""" + self.fiber_mapping = [(0, 0)] # res + self.fiber_mapping.extend([(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7)]) # panel port 1~8 + self.fiber_mapping.extend([(0, 14), (0, 13), (0, 15), (0, 12), (0, 8), (0, 11), (0, 9), (0, 10)]) # panel port 9~16 + self.fiber_mapping.extend([(0, 22), (0, 21), (0, 23), (0, 20), (0, 16), (0, 19), (0, 17), (0, 18)]) # panel port 17~24 + self.fiber_mapping.extend([(1, 4), (1, 3), (1, 5), (1, 2), (1, 6), (1, 1), (1, 7), (1, 0)]) # panel port 25~32 + self.fiber_mapping.extend([(1, 8), (1, 15), (1, 9), (1, 14), (1, 10), (1, 13), (1, 11), (1, 12)]) # panel port 33~40 + self.fiber_mapping.extend([(1, 22), (1, 21), (1, 23), (1, 20), (1, 16), (1, 19), (1, 17), (1, 18)]) # panel port 41~48 + self.fiber_mapping.extend([(1, 28), (1, 29), (1, 26), (1, 27), (1, 24), (1, 25)]) # panel port 49~54 + + self.udpClient = socket(AF_INET, SOCK_DGRAM) + self.sfp_present = [0]*(PORT_NUMBER+1) + self.sfp_enable = [0]*(PORT_NUMBER+1) + self.f_sfp_present = "/sys/class/sfp/sfp{}/sfp_presence" + self.f_sfp_enable = "/sys/class/sfp/sfp{}/sfp_enable" + self.sfp_scan_timer = 0 + + def is_qsfp(self, port): + if port <= 48: + return False + else: + return True + + def get_sfp_present(self, port): + with open(self.f_sfp_present.format(port), 'r') as sfp_file: + return int(sfp_file.read()) + + def set_sfp_present(self, port, present): + self.sfp_present[port] = present + + def set_sfp_enable(self, port, enable): + if self.is_qsfp(port): + if enable: + with open(self.f_sfp_enable.format(port), 'w') as sfp_file: + sfp_file.write("1") + self.sfp_enable[port] = 1 + else: + with open(self.f_sfp_enable.format(port), 'w') as sfp_file: + sfp_file.write("0") + self.sfp_enable[port] = 0 + else: + (ctlid, devid) = self.fiber_mapping[port] + req = struct.pack('=HHHBBHIBBBBI', 0, 9, 16, ctlid, devid, 0x50, 0, 0x56, 1, 0xf, 0, 1) + self.udpClient.sendto(req, ('localhost', 8101)) + rsp, addr = self.udpClient.recvfrom(1024) + rsp_data = struct.unpack('=HHHBBHIBBBBIi512B', rsp) + enable_v = rsp_data[13] + if enable: + enable_v &= 0xf0 + else: + enable_v |= 0x0f + data = struct.pack('=HHHBBHBBBB', 0, 11, 8, ctlid, 0x56, 0x50, devid, enable_v, 0xf, 0) + self.udpClient.sendto(data, ('localhost', 8101)) + DBG_PRINT("set sfp{} to {}".format(port, ("enable" if enable else "disable"))) + + def initialize_configdb(self): + try: + f_mac = os.popen('ip link show eth0 | grep ether | awk \'{print $2}\'') + mac_addr = f_mac.read(17) + last_byte = mac_addr[-2:] + aligned_last_byte = format(int(int(str(last_byte), 16) + 1), '02x') + mac_addr = mac_addr[:-2] + aligned_last_byte + DBG_PRINT("start connect swss config-db to set device mac-address") + swss = swsssdk.SonicV2Connector() + swss.connect(swss.CONFIG_DB) + swss.set(swss.CONFIG_DB, "DEVICE_METADATA|localhost", 'mac', mac_addr) + mac_addr = swss.get(swss.CONFIG_DB, "DEVICE_METADATA|localhost", 'mac') + DBG_PRINT("set device mac-address: %s" % mac_addr) + except IOError as e: + DBG_PRINT(str(e)) + + def initialize_rpc(self): + while True: + try: + r_sel = [self.udpClient] + echo_req = struct.pack('=HHH', 0, 1, 0) + self.udpClient.sendto(echo_req, ('localhost', 8101)) + result = select(r_sel, [], [], 1) + if self.udpClient in result[0]: + echo_rsp, srv_addr = self.udpClient.recvfrom(1024) + if echo_rsp: + break + DBG_PRINT("connect to sdk rpc server timeout, try again.") + except IOError as e: + DBG_PRINT(str(e)) + + DBG_PRINT("connect to sdk rpc server success.") + + def initialize_gpio(self): + # set gpio 1,2,3,4,5,6,7,8 output mode + gpio_init = struct.pack('=HHHBBB', 0, 13, 3, 1, 1, 1) + self.udpClient.sendto(gpio_init, ('localhost', 8101)) + gpio_init = struct.pack('=HHHBBB', 0, 13, 3, 1, 2, 1) + self.udpClient.sendto(gpio_init, ('localhost', 8101)) + gpio_init = struct.pack('=HHHBBB', 0, 13, 3, 1, 3, 1) + self.udpClient.sendto(gpio_init, ('localhost', 8101)) + gpio_init = struct.pack('=HHHBBB', 0, 13, 3, 1, 4, 1) + self.udpClient.sendto(gpio_init, ('localhost', 8101)) + gpio_init = struct.pack('=HHHBBB', 0, 13, 3, 1, 5, 1) + self.udpClient.sendto(gpio_init, ('localhost', 8101)) + gpio_init = struct.pack('=HHHBBB', 0, 13, 3, 1, 6, 1) + self.udpClient.sendto(gpio_init, ('localhost', 8101)) + gpio_init = struct.pack('=HHHBBB', 0, 13, 3, 1, 7, 1) + self.udpClient.sendto(gpio_init, ('localhost', 8101)) + gpio_init = struct.pack('=HHHBBB', 0, 13, 3, 1, 8, 1) + self.udpClient.sendto(gpio_init, ('localhost', 8101)) + # set gpio 1,2,3,4,5,6,7,8 output 0 to reset i2c bridge + gpio_init = struct.pack('=HHHBBB', 0, 13, 3, 2, 1, 0) + self.udpClient.sendto(gpio_init, ('localhost', 8101)) + gpio_init = struct.pack('=HHHBBB', 0, 13, 3, 2, 2, 0) + self.udpClient.sendto(gpio_init, ('localhost', 8101)) + gpio_init = struct.pack('=HHHBBB', 0, 13, 3, 2, 3, 0) + self.udpClient.sendto(gpio_init, ('localhost', 8101)) + gpio_init = struct.pack('=HHHBBB', 0, 13, 3, 2, 4, 0) + self.udpClient.sendto(gpio_init, ('localhost', 8101)) + gpio_init = struct.pack('=HHHBBB', 0, 13, 3, 2, 5, 0) + self.udpClient.sendto(gpio_init, ('localhost', 8101)) + gpio_init = struct.pack('=HHHBBB', 0, 13, 3, 2, 6, 0) + self.udpClient.sendto(gpio_init, ('localhost', 8101)) + gpio_init = struct.pack('=HHHBBB', 0, 13, 3, 2, 7, 0) + self.udpClient.sendto(gpio_init, ('localhost', 8101)) + gpio_init = struct.pack('=HHHBBB', 0, 13, 3, 2, 8, 0) + self.udpClient.sendto(gpio_init, ('localhost', 8101)) + # set gpio 1,2,3,4,5,6,7,8 output 1 to release i2c bridge + gpio_init = struct.pack('=HHHBBB', 0, 13, 3, 2, 1, 1) + self.udpClient.sendto(gpio_init, ('localhost', 8101)) + gpio_init = struct.pack('=HHHBBB', 0, 13, 3, 2, 2, 1) + self.udpClient.sendto(gpio_init, ('localhost', 8101)) + gpio_init = struct.pack('=HHHBBB', 0, 13, 3, 2, 3, 1) + self.udpClient.sendto(gpio_init, ('localhost', 8101)) + gpio_init = struct.pack('=HHHBBB', 0, 13, 3, 2, 4, 1) + self.udpClient.sendto(gpio_init, ('localhost', 8101)) + gpio_init = struct.pack('=HHHBBB', 0, 13, 3, 2, 5, 1) + self.udpClient.sendto(gpio_init, ('localhost', 8101)) + gpio_init = struct.pack('=HHHBBB', 0, 13, 3, 2, 6, 1) + self.udpClient.sendto(gpio_init, ('localhost', 8101)) + gpio_init = struct.pack('=HHHBBB', 0, 13, 3, 2, 7, 1) + self.udpClient.sendto(gpio_init, ('localhost', 8101)) + gpio_init = struct.pack('=HHHBBB', 0, 13, 3, 2, 8, 1) + self.udpClient.sendto(gpio_init, ('localhost', 8101)) + DBG_PRINT("config ctc chip gpio done.") + + def initialize_sfp(self): + try: + for port in range(1, PORT_NUMBER+1): + if self.get_sfp_present(port): + self.set_sfp_present(port, 1) + self.set_sfp_enable(port, 1) + else: + self.set_sfp_present(port, 0) + self.set_sfp_enable(port, 0) + except IOError as e: + DBG_PRINT(str(e)) + + def initialize(self): + DBG_PRINT("start connect to sdk rpc server.") + + self.initialize_configdb() + self.initialize_rpc() + self.initialize_gpio() + self.initialize_sfp() + + def sfp_scan(self): + try: + for port in range(1, PORT_NUMBER+1): + cur_present = self.get_sfp_present(port) + if self.sfp_present[port] != cur_present: + self.set_sfp_present(port, cur_present) + self.set_sfp_enable(port, cur_present) + except IOError as e: + DBG_PRINT(str(e)) + + def start(self): + while True: + self.sfp_scan() + time.sleep(1) + +if __name__ == "__main__": + monitor = PlatformMonitor() + monitor.initialize() + monitor.start() + diff --git a/platform/centec/sonic-platform-modules-e582/LICENSE b/platform/centec/sonic-platform-modules-e582/LICENSE new file mode 100644 index 000000000000..99228517bae7 --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/LICENSE @@ -0,0 +1,15 @@ +Copyright (C) 2017 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-e582/README.md b/platform/centec/sonic-platform-modules-e582/README.md new file mode 100644 index 000000000000..61b3ef6c87f4 --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/README.md @@ -0,0 +1 @@ +platform drivers for Centec E582 for the SONiC project diff --git a/platform/centec/sonic-platform-modules-e582/debian/changelog b/platform/centec/sonic-platform-modules-e582/debian/changelog new file mode 100644 index 000000000000..d6f8d9ed26d4 --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/debian/changelog @@ -0,0 +1,11 @@ +sonic-centec-platform-modules (1.1) unstable; urgency=low + + * Add support for centec e582-48x2q4z + + -- xuwj Thus, 25 Jan 2018 13:43:40 +0800 + +sonic-centec-platform-modules (1.0) unstable; urgency=low + + * Initial release + + -- xuwj Mon, 22 Jan 2018 13:43:40 +0800 diff --git a/platform/centec/sonic-platform-modules-e582/debian/compat b/platform/centec/sonic-platform-modules-e582/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/debian/compat @@ -0,0 +1 @@ +9 diff --git a/platform/centec/sonic-platform-modules-e582/debian/control b/platform/centec/sonic-platform-modules-e582/debian/control new file mode 100644 index 000000000000..103b6eca242d --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/debian/control @@ -0,0 +1,17 @@ +Source: sonic-centec-platform-modules +Section: main +Priority: extra +Maintainer: yangbs +Build-Depends: debhelper (>= 8.0.0), bzip2 +Standards-Version: 3.9.3 + +Package: platform-modules-e582-48x2q4z +Architecture: amd64 +Depends: linux-image-3.16.0-5-amd64 +Description: kernel modules for platform devices such as fan, led, sfp + +Package: platform-modules-e582-48x6q +Architecture: amd64 +Depends: linux-image-3.16.0-5-amd64 +Description: kernel modules for platform devices such as fan, led, sfp + diff --git a/platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x2q4z.init b/platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x2q4z.init new file mode 100755 index 000000000000..3ef5e7e30b6d --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x2q4z.init @@ -0,0 +1,38 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup e582-48x2q4z board. +### END INIT INFO + +case "$1" in +start) + echo -n "Setting up board... " + /usr/bin/48x2q4z_platform.sh init + + echo "done." + ;; + +stop) + /usr/bin/48x2q4z_platform.sh deinit + echo "done." + + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: service platform-modules-e582-48x2q4z {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x2q4z.install b/platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x2q4z.install new file mode 100644 index 000000000000..86569b323b1a --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x2q4z.install @@ -0,0 +1,2 @@ +48x2q4z/cfg/48x2q4z-modules.conf etc/modules-load.d +48x2q4z/scripts/48x2q4z_platform.sh usr/bin diff --git a/platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x6q.init b/platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x6q.init new file mode 100755 index 000000000000..1c5b0c1c4978 --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x6q.init @@ -0,0 +1,38 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup e582-48x6q board. +### END INIT INFO + +case "$1" in +start) + echo -n "Setting up board... " + /usr/bin/48x6q_platform.sh init + + echo "done." + ;; + +stop) + /usr/bin/48x6q_platform.sh deinit + echo "done." + + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: service platform-modules-e582-48x6q {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x6q.install b/platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x6q.install new file mode 100644 index 000000000000..7ec21f33784d --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/debian/platform-modules-e582-48x6q.install @@ -0,0 +1,6 @@ +48x6q/cfg/48x6q-modules.conf etc/modules-load.d +48x6q/cfg/minigraph.xml etc/sonic +48x6q/cfg/config_db.json etc/sonic +48x6q/cfg/config_db_l2l3.json etc/sonic +48x6q/scripts/48x6q_platform.sh usr/bin +48x6q/scripts/48x6q_platform_monitor.py usr/bin diff --git a/platform/centec/sonic-platform-modules-e582/debian/rules b/platform/centec/sonic-platform-modules-e582/debian/rules new file mode 100755 index 000000000000..9f5d67b1af5c --- /dev/null +++ b/platform/centec/sonic-platform-modules-e582/debian/rules @@ -0,0 +1,35 @@ +#!/usr/bin/make -f + +export INSTALL_MOD_DIR:=extra + +KVERSION ?= $(shell uname -r) +KERNEL_SRC := /lib/modules/$(KVERSION) +MOD_SRC_DIR:= $(shell pwd) +MODULE_DIRS:= 48x6q 48x2q4z + +%: + dh $@ + +override_dh_auto_build: + (for mod in $(MODULE_DIRS); do \ + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ + done) + +override_dh_auto_install: + (for mod in $(MODULE_DIRS); do \ + dh_installdirs -pplatform-modules-e582-$${mod} \ + $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp -f $(MOD_SRC_DIR)/$${mod}/modules/*.ko \ + debian/platform-modules-e582-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + done) + +override_dh_usrlocal: + +override_dh_clean: + dh_clean + (for mod in $(MODULE_DIRS); do \ + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules clean; \ + rm -rf $(MOD_SRC_DIR)/$${mod}/modules/*.ko; \ + rm -rf debian/platform-modules-e582-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR)/*.ko; \ + done) + From 511eada57bf7b20824c82f984a0b674b89c45c40 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Fri, 17 Aug 2018 09:49:12 +0000 Subject: [PATCH 123/219] [broadcom]: fix delay to load led proc init (#1940) led start bcm cmd triggers link state notifications. This is quick fix to avoid such fake link state notifications. Signed-off-by: Guohan Lu --- platform/broadcom/docker-syncd-brcm/start.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform/broadcom/docker-syncd-brcm/start.sh b/platform/broadcom/docker-syncd-brcm/start.sh index cc82e1ba33a8..fe08e1bfa1ff 100755 --- a/platform/broadcom/docker-syncd-brcm/start.sh +++ b/platform/broadcom/docker-syncd-brcm/start.sh @@ -28,11 +28,13 @@ wait_syncd() { fi sleep 1 done + + # wait until bcm sdk is ready to get a request + sleep 3 } # If this platform has an initialization file for the Broadcom LED microprocessor, load it if [ -r ${PLATFORM_DIR}/led_proc_init.soc ]; then wait_syncd - sleep 60 # wait until bcm sdk is ready to get a request /usr/bin/bcmcmd -t 60 "rcload ${PLATFORM_DIR}/led_proc_init.soc" fi From 5817dcf72e2a81534c9ddf42240220b137f9358e Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 9 Aug 2018 23:56:41 -0700 Subject: [PATCH 124/219] Download newer version (8.23.0-2) of rsyslog from jessie-backports in hopes of eliminating memory leaks (#1912) --- build_debian.sh | 5 ++++- dockers/docker-base/Dockerfile.j2 | 5 ++++- dockers/docker-base/sources.list | 1 + files/apt/sources.list | 1 + .../debian_archive_trafficmanager_net_debian.list | 1 + sonic-slave/Dockerfile | 2 +- 6 files changed, 12 insertions(+), 3 deletions(-) diff --git a/build_debian.sh b/build_debian.sh index b1026c7bf3c2..d1da9b9ea937 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -204,7 +204,6 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in openssh-server \ python \ python-setuptools \ - rsyslog \ monit \ python-apt \ traceroute \ @@ -227,6 +226,10 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in grub2-common \ ethtool +# Install a newer version of rsyslog from jessie-backports in hopes of +# eliminating memory leaks +sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y -t jessie-backports install rsyslog + sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y download \ grub-pc-bin diff --git a/dockers/docker-base/Dockerfile.j2 b/dockers/docker-base/Dockerfile.j2 index ff52cf88e7d3..43ae42a11e69 100644 --- a/dockers/docker-base/Dockerfile.j2 +++ b/dockers/docker-base/Dockerfile.j2 @@ -24,12 +24,15 @@ RUN apt-get update # Pre-install fundamental packages RUN apt-get -y install \ - rsyslog \ vim-tiny \ perl \ python \ less +# Install a newer version of rsyslog from jessie-backports in hopes of +# eliminating memory leaks +RUN apt-get -y -t jessie-backports install rsyslog + COPY ["etc/rsyslog.conf", "/etc/rsyslog.conf"] COPY ["etc/rsyslog.d/*", "/etc/rsyslog.d/"] COPY ["root/.vimrc", "/root/.vimrc"] diff --git a/dockers/docker-base/sources.list b/dockers/docker-base/sources.list index 2ed195cff416..7121d6fd8c2d 100644 --- a/dockers/docker-base/sources.list +++ b/dockers/docker-base/sources.list @@ -5,3 +5,4 @@ deb http://debian-archive.trafficmanager.net/debian/ jessie main contrib non-fre deb-src http://debian-archive.trafficmanager.net/debian/ jessie main contrib non-free deb http://debian-archive.trafficmanager.net/debian-security/ jessie/updates main contrib non-free deb-src http://debian-archive.trafficmanager.net/debian-security/ jessie/updates main contrib non-free +deb http://debian-archive.trafficmanager.net/debian/ jessie-backports main contrib non-free diff --git a/files/apt/sources.list b/files/apt/sources.list index 2ed195cff416..7121d6fd8c2d 100644 --- a/files/apt/sources.list +++ b/files/apt/sources.list @@ -5,3 +5,4 @@ deb http://debian-archive.trafficmanager.net/debian/ jessie main contrib non-fre deb-src http://debian-archive.trafficmanager.net/debian/ jessie main contrib non-free deb http://debian-archive.trafficmanager.net/debian-security/ jessie/updates main contrib non-free deb-src http://debian-archive.trafficmanager.net/debian-security/ jessie/updates main contrib non-free +deb http://debian-archive.trafficmanager.net/debian/ jessie-backports main contrib non-free diff --git a/files/image_config/apt/sources.list.d/debian_archive_trafficmanager_net_debian.list b/files/image_config/apt/sources.list.d/debian_archive_trafficmanager_net_debian.list index d5ecf56d4069..4daa3ccba677 100644 --- a/files/image_config/apt/sources.list.d/debian_archive_trafficmanager_net_debian.list +++ b/files/image_config/apt/sources.list.d/debian_archive_trafficmanager_net_debian.list @@ -1,2 +1,3 @@ deb http://debian-archive.trafficmanager.net/debian/ jessie main contrib non-free deb http://debian-archive.trafficmanager.net/debian-security/ jessie/updates main contrib non-free +deb http://debian-archive.trafficmanager.net/debian/ jessie-backports main contrib non-free diff --git a/sonic-slave/Dockerfile b/sonic-slave/Dockerfile index cb4529e67aa4..dd526a898e8d 100644 --- a/sonic-slave/Dockerfile +++ b/sonic-slave/Dockerfile @@ -6,7 +6,7 @@ RUN echo "deb http://debian-archive.trafficmanager.net/debian/ jessie main contr echo "deb-src http://debian-archive.trafficmanager.net/debian/ jessie main contrib non-free" >> /etc/apt/sources.list && \ echo "deb http://debian-archive.trafficmanager.net/debian-security/ jessie/updates main contrib non-free" >> /etc/apt/sources.list && \ echo "deb-src http://debian-archive.trafficmanager.net/debian-security/ jessie/updates main contrib non-free" >> /etc/apt/sources.list && \ - echo 'deb http://debian-archive.trafficmanager.net/debian jessie-backports main' >> /etc/apt/sources.list + echo "deb http://debian-archive.trafficmanager.net/debian/ jessie-backports main contrib non-free" >> /etc/apt/sources.list ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive From cd8f6c8195f697405ade70190ea0eaf77d7c17de Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sun, 19 Aug 2018 21:32:56 +0000 Subject: [PATCH 125/219] [sonic-swss]: support dynamic configuration of ecn on/off, threshold, prob Upgrade to libsai 3.1.3.4-16 to support dynamic configuration Signed-off-by: Guohan Lu --- platform/broadcom/sai.mk | 8 ++++---- src/sonic-swss | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 5cda170b3391..2099fbb6b90b 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,9 +1,9 @@ -BRCM_SAI = libsaibcm_3.1.3.4-15_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm_3.1.3.4-15_amd64.deb?sv=2015-04-05&sr=b&sig=7CIkdlBB%2BY6Xjae0vc1QBnlAVedRkreJRhWM93SyHOI%3D&se=2032-02-29T18%3A31%3A54Z&sp=r" +BRCM_SAI = libsaibcm_3.1.3.5-6_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/libsaibcm_3.1.3.5-6_amd64.deb?sv=2015-04-05&sr=b&sig=Srm9zk6mYTYpqaifRwrMwQ9%2Bqf2b0HqrkS9okhSA%2Bq0%3D&se=2155-07-11T19%3A40%3A27Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.1.3.4-15_amd64.deb +BRCM_SAI_DEV = libsaibcm-dev_3.1.3.5-6_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm-dev_3.1.3.4-15_amd64.deb?sv=2015-04-05&sr=b&sig=rBOT802o1o%2BAcogaXq%2FgqyuTAmSlFKhtPzYM%2BtXlIdM%3D&se=2032-02-29T18%3A34%3A10Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/libsaibcm-dev_3.1.3.5-6_amd64.deb?sv=2015-04-05&sr=b&sig=xqMANzXnUJli4hcggZ8wJpepxfCaWedW2%2Fyx3X%2BXDH4%3D&se=2155-07-11T19%3A40%3A50Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) diff --git a/src/sonic-swss b/src/sonic-swss index 8f52e297e83a..6ea4ea351fa7 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 8f52e297e83acc3e5d8ce82ef67285ee730e0ea4 +Subproject commit 6ea4ea351fa78cea6e2390a4f2211d9ddca0187c From 275b583c1cf62d790220925ddc13c3dcb1c8b48a Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Sun, 19 Aug 2018 14:36:25 -0700 Subject: [PATCH 126/219] Mitigate CVE-2018-5391 by sysctl (#1948) Signed-off-by: Qi Luo --- build_debian.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build_debian.sh b/build_debian.sh index d1da9b9ea937..1080a5847a20 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -272,6 +272,7 @@ check system $HOST EOF ## Config sysctl +## TODO: ipfrag* are for mitigating CVE-2018-5391, remove after kernel upgraded sudo mkdir -p $FILESYSTEM_ROOT/var/core sudo augtool --autosave " set /files/etc/sysctl.conf/kernel.core_pattern '|/usr/bin/coredump-compress %e %t %p' @@ -309,6 +310,9 @@ set /files/etc/sysctl.conf/net.ipv6.conf.eth0.accept_ra_defrtr 0 set /files/etc/sysctl.conf/net.core.rmem_max 2097152 set /files/etc/sysctl.conf/net.core.wmem_max 2097152 + +set /files/etc/sysctl.conf/net.ipv4.ipfrag_high_thresh 262144 +set /files/etc/sysctl.conf/net.ipv4.ipfrag_low_thresh 196608 " -r $FILESYSTEM_ROOT ## docker-py is needed by Ansible docker module From e7a213253077962c24bf5b8b75b4fef7fa995a73 Mon Sep 17 00:00:00 2001 From: Wenda Ni Date: Thu, 16 Aug 2018 23:11:20 -0700 Subject: [PATCH 127/219] [devices/a7050]: Separate ECN/WRED profile per queue to maintain a consistent view among CONFIG_DB get commands (#1941) for ecn on/off operations, which are conducted at per queue all interfaces granularity. TODO: Ideally, we should have ECN/WRED profile applied at per interface per queue granularity, and we should do it for all hwskus under the device directory, not just 7050. Signed-off-by: Wenda Ni --- .../x86_64-arista_7050_qx32s/Arista-7050-QX-32S/qos.json | 7 ++++++- .../dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/qos.json | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/qos.json b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/qos.json index 926911ab59d0..698811c610ff 100644 --- a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/qos.json +++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/qos.json @@ -130,7 +130,12 @@ }, "QUEUE": { "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3-4" : { - "scheduler" : "[SCHEDULER|scheduler.0]", + "scheduler" : "[SCHEDULER|scheduler.0]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3" : { + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|4" : { "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0" : { diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/qos.json b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/qos.json index 926911ab59d0..698811c610ff 100644 --- a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/qos.json +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/qos.json @@ -130,7 +130,12 @@ }, "QUEUE": { "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3-4" : { - "scheduler" : "[SCHEDULER|scheduler.0]", + "scheduler" : "[SCHEDULER|scheduler.0]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3" : { + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|4" : { "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0" : { From 47c28c2ee2ab19736f366d0361dc5101a24d5e6f Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sun, 19 Aug 2018 23:15:45 +0000 Subject: [PATCH 128/219] [sonic-utilities]: add ecnconfig command Signed-off-by: Guohan Lu --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 47c2bee08c89..b86cb86fc817 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 47c2bee08c894c0ff4458e3fbb01e25868d2da11 +Subproject commit b86cb86fc817b37ecd5e56ccec6a79865c7e68d6 From ff91c0511cd4c0de11ad1d942749c90aa58a3bd0 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Mon, 20 Aug 2018 04:43:05 +0000 Subject: [PATCH 129/219] [broadcom]: update sai to 3.1.3.4-16 Signed-off-by: Guohan Lu --- platform/broadcom/sai.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 2099fbb6b90b..68742dea25b9 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,9 +1,9 @@ -BRCM_SAI = libsaibcm_3.1.3.5-6_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/libsaibcm_3.1.3.5-6_amd64.deb?sv=2015-04-05&sr=b&sig=Srm9zk6mYTYpqaifRwrMwQ9%2Bqf2b0HqrkS9okhSA%2Bq0%3D&se=2155-07-11T19%3A40%3A27Z&sp=r" +BRCM_SAI = libsaibcm_3.1.3.4-16_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/libsaibcm_3.1.3.4-16_amd64.deb?sv=2015-04-05&sr=b&sig=p7e4USdBWxIKYxP22t7yb%2BKtzlWBidZxQF1HZ%2FDs16I%3D&se=2155-07-13T04%3A43%3A02Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.1.3.5-6_amd64.deb +BRCM_SAI_DEV = libsaibcm-dev_3.1.3.4-16_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/libsaibcm-dev_3.1.3.5-6_amd64.deb?sv=2015-04-05&sr=b&sig=xqMANzXnUJli4hcggZ8wJpepxfCaWedW2%2Fyx3X%2BXDH4%3D&se=2155-07-11T19%3A40%3A50Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/libsaibcm-dev_3.1.3.4-16_amd64.deb?sv=2015-04-05&sr=b&sig=80iUtmr%2BbdWg7p5Zst%2FQrWuukgSx0TME2fRPPIhfLMQ%3D&se=2155-07-12T21%3A32%3A56Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) From 73d99d20b338d813f17db664bcde45c22603ce5c Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Mon, 20 Aug 2018 19:00:21 +0000 Subject: [PATCH 130/219] [submodules]: update sonic-platform-common 1e61b29 [sonic_eeprom] If reading from what appears to be a corrupt cache file, delete file and read directly from EEPROM (#10) Signed-off-by: Guohan Lu --- src/sonic-platform-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-common b/src/sonic-platform-common index 10bef06fd66b..1e61b2922762 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit 10bef06fd66b233b8e3fdecb19809dedee9f0e75 +Subproject commit 1e61b2922762cea085c584436e28031b4092a507 From 9f401166053b5ec1add211c1f0c8d17d138df6d1 Mon Sep 17 00:00:00 2001 From: Volodymyr Samotiy Date: Tue, 21 Aug 2018 10:56:59 +0300 Subject: [PATCH 131/219] [mellanox]: Fix problem with system EEPROM in "hw-mgmt" (#1952) Signed-off-by: Volodymyr Samotiy --- .../Add-modprobe-config-for-at24-module.patch | 21 +++++++++++++++++++ platform/mellanox/hw-management/Makefile | 1 + 2 files changed, 22 insertions(+) create mode 100644 platform/mellanox/hw-management/Add-modprobe-config-for-at24-module.patch diff --git a/platform/mellanox/hw-management/Add-modprobe-config-for-at24-module.patch b/platform/mellanox/hw-management/Add-modprobe-config-for-at24-module.patch new file mode 100644 index 000000000000..37d57da4e937 --- /dev/null +++ b/platform/mellanox/hw-management/Add-modprobe-config-for-at24-module.patch @@ -0,0 +1,21 @@ +From 2f70f5df445820fb86e3bd7f95707e0fb97b553f Mon Sep 17 00:00:00 2001 +From: Volodymyr Samotiy +Date: Thu, 16 Aug 2018 17:21:37 +0300 +Subject: Add modprobe config for "at24" module + +Signed-off-by: Volodymyr Samotiy +--- + usr/etc/modprobe.d/mellanox-system-whitelist.conf | 1 + + 1 file changed, 1 insertion(+) + create mode 100644 usr/etc/modprobe.d/mellanox-system-whitelist.conf + +diff --git a/usr/etc/modprobe.d/mellanox-system-whitelist.conf b/usr/etc/modprobe.d/mellanox-system-whitelist.conf +new file mode 100644 +index 0000000..a3eef57 +--- /dev/null ++++ b/usr/etc/modprobe.d/mellanox-system-whitelist.conf +@@ -0,0 +1 @@ ++options at24 io_limit=32 +-- +1.9.1 + diff --git a/platform/mellanox/hw-management/Makefile b/platform/mellanox/hw-management/Makefile index ee2899d07c39..4fa5d2cf328c 100644 --- a/platform/mellanox/hw-management/Makefile +++ b/platform/mellanox/hw-management/Makefile @@ -10,6 +10,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # build pushd hw-management + git am ../*.patch sed "s~@SED_VERSION@~$(MLNX_HW_MANAGEMENT_VERSION)~" -i debian/changelog chmod +x ./debian/rules sudo ./debian/rules binary KVERSION=$(KVERSION) From 35f4c68bc00e2bdaf420a6a3355c2032c8054dc4 Mon Sep 17 00:00:00 2001 From: Wenda Ni Date: Wed, 22 Aug 2018 13:06:01 -0700 Subject: [PATCH 132/219] [mellanox]: Enable WRED red color profile on mellanox platform (#1971) Signed-off-by: Wenda Ni --- device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/qos.json | 2 ++ device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/qos.json | 2 ++ device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/qos.json | 2 ++ device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/qos.json | 2 ++ .../x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/qos.json | 2 ++ 5 files changed, 10 insertions(+) diff --git a/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/qos.json b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/qos.json index 3e01af3f2c64..df3d29c636e3 100644 --- a/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/qos.json +++ b/device/mellanox/x86_64-mlnx_lssn2700-r0/LS-SN2700/qos.json @@ -127,6 +127,7 @@ "AZURE_LOSSY": { "wred_green_enable":"true", "wred_yellow_enable":"true", + "wred_red_enable":"true", "ecn":"ecn_all", "red_max_threshold":"516096", "red_min_threshold":"516096", @@ -138,6 +139,7 @@ "AZURE_LOSSLESS": { "wred_green_enable":"true", "wred_yellow_enable":"true", + "wred_red_enable":"true", "ecn":"ecn_all", "red_max_threshold":"516096", "red_min_threshold":"516096", diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/qos.json b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/qos.json index 74045469dbfd..2ea9b9dc019d 100644 --- a/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/qos.json +++ b/device/mellanox/x86_64-mlnx_msn2100-r0/ACS-MSN2100/qos.json @@ -127,6 +127,7 @@ "AZURE_LOSSY": { "wred_green_enable":"true", "wred_yellow_enable":"true", + "wred_red_enable":"true", "ecn":"ecn_all", "red_max_threshold":"516096", "red_min_threshold":"516096", @@ -138,6 +139,7 @@ "AZURE_LOSSLESS": { "wred_green_enable":"true", "wred_yellow_enable":"true", + "wred_red_enable":"true", "ecn":"ecn_all", "red_max_threshold":"516096", "red_min_threshold":"516096", diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/qos.json b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/qos.json index 95652cf96f4e..0d01a3f1cbad 100644 --- a/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/qos.json +++ b/device/mellanox/x86_64-mlnx_msn2410-r0/ACS-MSN2410/qos.json @@ -127,6 +127,7 @@ "AZURE_LOSSY": { "wred_green_enable":"true", "wred_yellow_enable":"true", + "wred_red_enable":"true", "ecn":"ecn_all", "red_max_threshold":"516096", "red_min_threshold":"516096", @@ -138,6 +139,7 @@ "AZURE_LOSSLESS": { "wred_green_enable":"true", "wred_yellow_enable":"true", + "wred_red_enable":"true", "ecn":"ecn_all", "red_max_threshold":"516096", "red_min_threshold":"516096", diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/qos.json b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/qos.json index 3e01af3f2c64..df3d29c636e3 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/qos.json +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/qos.json @@ -127,6 +127,7 @@ "AZURE_LOSSY": { "wred_green_enable":"true", "wred_yellow_enable":"true", + "wred_red_enable":"true", "ecn":"ecn_all", "red_max_threshold":"516096", "red_min_threshold":"516096", @@ -138,6 +139,7 @@ "AZURE_LOSSLESS": { "wred_green_enable":"true", "wred_yellow_enable":"true", + "wred_red_enable":"true", "ecn":"ecn_all", "red_max_threshold":"516096", "red_min_threshold":"516096", diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/qos.json b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/qos.json index d35f614de635..03c89438ab68 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/qos.json +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/qos.json @@ -127,6 +127,7 @@ "AZURE_LOSSY": { "wred_green_enable":"true", "wred_yellow_enable":"true", + "wred_red_enable":"true", "ecn":"ecn_all", "red_max_threshold":"516096", "red_min_threshold":"516096", @@ -138,6 +139,7 @@ "AZURE_LOSSLESS": { "wred_green_enable":"true", "wred_yellow_enable":"true", + "wred_red_enable":"true", "ecn":"ecn_all", "red_max_threshold":"516096", "red_min_threshold":"516096", From 2f12abe9ed1e79770304b457460a40e08e7391e9 Mon Sep 17 00:00:00 2001 From: Wenda Ni Date: Thu, 23 Aug 2018 00:39:20 -0700 Subject: [PATCH 133/219] [arista]: Buffers & qos config change on a7050 (#1973) * Enable WRED red color profile on mellanox platform Signed-off-by: Wenda Ni * Change ingress alpha to 2^(-3) on a7050 * a7050: Add dscp 46 mapping to pg 5 and queue 5; link pg 5 and queue 5 to lossy profile; Make ecn off by default on queues Signed-off-by: Wenda --- .../Arista-7050-QX32/buffers.json.j2 | 8 ++++- .../Arista-7050-QX32/qos.json | 29 ++++++++--------- .../Arista-7050-QX-32S/buffers.json.j2 | 8 ++++- .../Arista-7050-QX-32S/qos.json | 32 +++++++------------ 4 files changed, 39 insertions(+), 38 deletions(-) diff --git a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers.json.j2 b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers.json.j2 index 551f73ca0477..782dc528f71e 100644 --- a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers.json.j2 +++ b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers.json.j2 @@ -90,7 +90,7 @@ "xon":"18432", "xoff":"40560", "size":"41808", - "dynamic_th":"-4", + "dynamic_th":"-3", "xon_offset":"2496" }, "ingress_lossy_profile": { @@ -115,6 +115,9 @@ }, "{{ port_names }}|0-1": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "{{ port_names }}|5": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" } }, "BUFFER_QUEUE": { @@ -123,6 +126,9 @@ }, "{{ port_names }}|0-1": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "{{ port_names }}|5": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" } } } diff --git a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/qos.json b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/qos.json index 926911ab59d0..6cb1e880ab10 100644 --- a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/qos.json +++ b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/qos.json @@ -4,7 +4,8 @@ "0": "0", "1": "1", "3": "3", - "4": "4" + "4": "4", + "5": "5" } }, "MAP_PFC_PRIORITY_TO_QUEUE": { @@ -12,7 +13,8 @@ "0": "0", "1": "1", "3": "3", - "4": "4" + "4": "4", + "5": "5" } }, "TC_TO_QUEUE_MAP": { @@ -20,7 +22,8 @@ "0": "0", "1": "1", "3": "3", - "4": "4" + "4": "4", + "5": "5" } }, "DSCP_TO_TC_MAP": { @@ -71,7 +74,7 @@ "43":"0", "44":"0", "45":"0", - "46":"0", + "46":"5", "47":"0", "48":"0", "49":"0", @@ -93,14 +96,6 @@ }, "SCHEDULER": { "scheduler.0" : { - "type":"DWRR", - "weight": "25" - }, - "scheduler.1" : { - "type":"DWRR", - "weight": "30" - }, - "scheduler.2" : { "type":"DWRR", "weight": "20" } @@ -130,14 +125,16 @@ }, "QUEUE": { "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3-4" : { - "scheduler" : "[SCHEDULER|scheduler.0]", - "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" + "scheduler" : "[SCHEDULER|scheduler.0]" }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0" : { - "scheduler" : "[SCHEDULER|scheduler.1]" + "scheduler" : "[SCHEDULER|scheduler.0]" }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|1" : { - "scheduler" : "[SCHEDULER|scheduler.2]" + "scheduler" : "[SCHEDULER|scheduler.0]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|5" : { + "scheduler" : "[SCHEDULER|scheduler.0]" } } } diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/buffers.json.j2 b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/buffers.json.j2 index 551f73ca0477..782dc528f71e 100644 --- a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/buffers.json.j2 +++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/buffers.json.j2 @@ -90,7 +90,7 @@ "xon":"18432", "xoff":"40560", "size":"41808", - "dynamic_th":"-4", + "dynamic_th":"-3", "xon_offset":"2496" }, "ingress_lossy_profile": { @@ -115,6 +115,9 @@ }, "{{ port_names }}|0-1": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "{{ port_names }}|5": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" } }, "BUFFER_QUEUE": { @@ -123,6 +126,9 @@ }, "{{ port_names }}|0-1": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "{{ port_names }}|5": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" } } } diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/qos.json b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/qos.json index 698811c610ff..6cb1e880ab10 100644 --- a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/qos.json +++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/qos.json @@ -4,7 +4,8 @@ "0": "0", "1": "1", "3": "3", - "4": "4" + "4": "4", + "5": "5" } }, "MAP_PFC_PRIORITY_TO_QUEUE": { @@ -12,7 +13,8 @@ "0": "0", "1": "1", "3": "3", - "4": "4" + "4": "4", + "5": "5" } }, "TC_TO_QUEUE_MAP": { @@ -20,7 +22,8 @@ "0": "0", "1": "1", "3": "3", - "4": "4" + "4": "4", + "5": "5" } }, "DSCP_TO_TC_MAP": { @@ -71,7 +74,7 @@ "43":"0", "44":"0", "45":"0", - "46":"0", + "46":"5", "47":"0", "48":"0", "49":"0", @@ -93,14 +96,6 @@ }, "SCHEDULER": { "scheduler.0" : { - "type":"DWRR", - "weight": "25" - }, - "scheduler.1" : { - "type":"DWRR", - "weight": "30" - }, - "scheduler.2" : { "type":"DWRR", "weight": "20" } @@ -132,17 +127,14 @@ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3-4" : { "scheduler" : "[SCHEDULER|scheduler.0]" }, - "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3" : { - "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" - }, - "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|4" : { - "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" - }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0" : { - "scheduler" : "[SCHEDULER|scheduler.1]" + "scheduler" : "[SCHEDULER|scheduler.0]" }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|1" : { - "scheduler" : "[SCHEDULER|scheduler.2]" + "scheduler" : "[SCHEDULER|scheduler.0]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|5" : { + "scheduler" : "[SCHEDULER|scheduler.0]" } } } From 5d299c496c4a5cc19643b6233c077677a64e198d Mon Sep 17 00:00:00 2001 From: Shuotian Cheng Date: Wed, 29 Aug 2018 17:32:16 -0700 Subject: [PATCH 134/219] [Dell]: Update sonic-platform-modules-dell submodule (#1999) Fix depmod -a issue on 201803 branch Signed-off-by: Shu0T1an ChenG --- platform/broadcom/sonic-platform-modules-dell | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/broadcom/sonic-platform-modules-dell b/platform/broadcom/sonic-platform-modules-dell index 8bc799d26011..811e6207330e 160000 --- a/platform/broadcom/sonic-platform-modules-dell +++ b/platform/broadcom/sonic-platform-modules-dell @@ -1 +1 @@ -Subproject commit 8bc799d26011622be07e03f888b4dd4c6b014d38 +Subproject commit 811e6207330e05ba68d950d4a19ccc573e7b9ee4 From 2f0a3c63fa8683bb092428777de9dd5de5496260 Mon Sep 17 00:00:00 2001 From: Taoyu Li Date: Tue, 11 Sep 2018 21:26:51 -0700 Subject: [PATCH 135/219] Don't reuse init_cfg.json from old image during upgrade (#2036) --- files/image_config/updategraph/updategraph | 3 --- 1 file changed, 3 deletions(-) diff --git a/files/image_config/updategraph/updategraph b/files/image_config/updategraph/updategraph index f0cea0894a9c..df1a5db6129a 100755 --- a/files/image_config/updategraph/updategraph +++ b/files/image_config/updategraph/updategraph @@ -44,9 +44,6 @@ if [ -f /tmp/pending_config_migration ]; then if [ "$enabled" = "true" ]; then echo "Use minigraph.xml from old system..." cp /etc/sonic/old_config/minigraph.xml /etc/sonic/ - if [ -f /etc/sonic/old_config/init_cfg.json ]; then - cp /etc/sonic/old_config/init_cfg.json /etc/sonic/ - fi if [ -f /etc/sonic/old_config/snmp.yml ]; then cp /etc/sonic/old_config/snmp.yml /etc/sonic/ fi From 09a61f18469a3a6313522427380e036680b91665 Mon Sep 17 00:00:00 2001 From: Wenda Ni Date: Tue, 11 Sep 2018 22:15:09 -0700 Subject: [PATCH 136/219] [devices]: Buffers & qos config change on a6100 and a7050 (#2037) * a7050 & a6100 ecn profile th_min = 1MB = 1048576 bytes, th_max = 2MB = 2097152 bytes, pmax = 5% a6100 dscp 46 -> 5; apply lossy traffic profile dwrr equal weight on 5 queues ingress lossless alpha 2^(-3) Signed-off-by: Wenda Ni * Adjust config format for wred profile on a7050 & a6100 Signed-off-by: Wenda * Update sonic-utilities submodule reference point Signed-off-by: Wenda --- .../Arista-7050-QX32/qos.json | 18 ++++--- .../Arista-7050-QX-32S/qos.json | 18 ++++--- .../Force10-S6100/pg_profile_lookup.ini | 30 +++++------ .../Force10-S6100/qos.json | 50 +++++++------------ files/build_templates/buffers_config.j2 | 6 +++ src/sonic-utilities | 2 +- 6 files changed, 62 insertions(+), 62 deletions(-) diff --git a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/qos.json b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/qos.json index 6cb1e880ab10..88d872d5dc70 100644 --- a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/qos.json +++ b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/qos.json @@ -115,17 +115,21 @@ "wred_yellow_enable":"true", "wred_red_enable":"true", "ecn":"ecn_all", - "red_max_threshold":"312000", - "red_min_threshold":"104000", - "yellow_max_threshold":"312000", - "yellow_min_threshold":"104000", - "green_max_threshold":"312000", - "green_min_threshold":"104000" + "red_max_threshold":"2097152", + "red_min_threshold":"1048576", + "yellow_max_threshold":"2097152", + "yellow_min_threshold":"1048576", + "green_max_threshold":"2097152", + "green_min_threshold":"1048576", + "green_drop_probability":"5", + "yellow_drop_probability":"5", + "red_drop_probability":"5" } }, "QUEUE": { "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3-4" : { - "scheduler" : "[SCHEDULER|scheduler.0]" + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0" : { "scheduler" : "[SCHEDULER|scheduler.0]" diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/qos.json b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/qos.json index 6cb1e880ab10..88d872d5dc70 100644 --- a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/qos.json +++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/qos.json @@ -115,17 +115,21 @@ "wred_yellow_enable":"true", "wred_red_enable":"true", "ecn":"ecn_all", - "red_max_threshold":"312000", - "red_min_threshold":"104000", - "yellow_max_threshold":"312000", - "yellow_min_threshold":"104000", - "green_max_threshold":"312000", - "green_min_threshold":"104000" + "red_max_threshold":"2097152", + "red_min_threshold":"1048576", + "yellow_max_threshold":"2097152", + "yellow_min_threshold":"1048576", + "green_max_threshold":"2097152", + "green_min_threshold":"1048576", + "green_drop_probability":"5", + "yellow_drop_probability":"5", + "red_drop_probability":"5" } }, "QUEUE": { "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3-4" : { - "scheduler" : "[SCHEDULER|scheduler.0]" + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0" : { "scheduler" : "[SCHEDULER|scheduler.0]" diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/pg_profile_lookup.ini b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/pg_profile_lookup.ini index 3b2a417cebcd..aedda37a8878 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/pg_profile_lookup.ini +++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/pg_profile_lookup.ini @@ -1,17 +1,17 @@ # PG lossless profiles. # speed cable size xon xoff threshold xon_offset - 10000 5m 1248 2288 35776 -4 2288 - 25000 5m 1248 2288 53248 -4 2288 - 40000 5m 1248 2288 66560 -4 2288 - 50000 5m 1248 2288 90272 -4 2288 - 100000 5m 1248 2288 165568 -4 2288 - 10000 40m 1248 2288 37024 -4 2288 - 25000 40m 1248 2288 53248 -4 2288 - 40000 40m 1248 2288 71552 -4 2288 - 50000 40m 1248 2288 96096 -4 2288 - 100000 40m 1248 2288 177632 -4 2288 - 10000 300m 1248 2288 46176 -4 2288 - 25000 300m 1248 2288 79040 -4 2288 - 40000 300m 1248 2288 108160 -4 2288 - 50000 300m 1248 2288 141856 -4 2288 - 100000 300m 1248 2288 268736 -4 2288 + 10000 5m 1248 2288 35776 -3 2288 + 25000 5m 1248 2288 53248 -3 2288 + 40000 5m 1248 2288 66560 -3 2288 + 50000 5m 1248 2288 90272 -3 2288 + 100000 5m 1248 2288 165568 -3 2288 + 10000 40m 1248 2288 37024 -3 2288 + 25000 40m 1248 2288 53248 -3 2288 + 40000 40m 1248 2288 71552 -3 2288 + 50000 40m 1248 2288 96096 -3 2288 + 100000 40m 1248 2288 177632 -3 2288 + 10000 300m 1248 2288 46176 -3 2288 + 25000 300m 1248 2288 79040 -3 2288 + 40000 300m 1248 2288 108160 -3 2288 + 50000 300m 1248 2288 141856 -3 2288 + 100000 300m 1248 2288 268736 -3 2288 diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json index 99642cf8cf4c..cf6992853f2b 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json +++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json @@ -83,7 +83,7 @@ "43":"0", "44":"0", "45":"0", - "46":"0", + "46":"5", "47":"0", "48":"0", "49":"0", @@ -105,14 +105,6 @@ }, "SCHEDULER": { "scheduler.0" : { - "type":"DWRR", - "weight": "25" - }, - "scheduler.1" : { - "type":"DWRR", - "weight": "30" - }, - "scheduler.2" : { "type":"DWRR", "weight": "20" } @@ -127,41 +119,35 @@ } }, "WRED_PROFILE": { - "AZURE_LOSSY" : { - "wred_green_enable":"true", - "wred_yellow_enable":"true", - "ecn":"ecn_all", - "red_max_threshold":"512000", - "red_min_threshold":"512000", - "yellow_max_threshold":"512000", - "yellow_min_threshold":"512000", - "green_max_threshold": "184320", - "green_min_threshold": "184320" - }, "AZURE_LOSSLESS" : { "wred_green_enable":"true", "wred_yellow_enable":"true", + "wred_red_enable":"true", "ecn":"ecn_all", - "red_max_threshold":"512000", - "red_min_threshold":"512000", - "yellow_max_threshold":"512000", - "yellow_min_threshold":"512000", - "green_max_threshold": "184320", - "green_min_threshold": "184320" + "red_max_threshold":"2097152", + "red_min_threshold":"1048576", + "yellow_max_threshold":"2097152", + "yellow_min_threshold":"1048576", + "green_max_threshold":"2097152", + "green_min_threshold":"1048576", + "green_drop_probability":"5", + "yellow_drop_probability":"5", + "red_drop_probability":"5" } }, "QUEUE": { - "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63|0-1" : { - "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]" - }, "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63|3-4" : { - "scheduler" : "[SCHEDULER|scheduler.0]" + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63|0" : { - "scheduler" : "[SCHEDULER|scheduler.1]" + "scheduler" : "[SCHEDULER|scheduler.0]" }, "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63|1" : { - "scheduler" : "[SCHEDULER|scheduler.2]" + "scheduler" : "[SCHEDULER|scheduler.0]" + }, + "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63|5" : { + "scheduler" : "[SCHEDULER|scheduler.0]" } } } diff --git a/files/build_templates/buffers_config.j2 b/files/build_templates/buffers_config.j2 index 20019d20afae..f4d2fd3a6d2d 100644 --- a/files/build_templates/buffers_config.j2 +++ b/files/build_templates/buffers_config.j2 @@ -121,6 +121,9 @@ def "BUFFER_PG": { "{{ port_names_all }}|0-1": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "{{ port_names_all }}|5": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" } }, {% endif %} @@ -134,6 +137,9 @@ def }, "{{ port_names_all }}|0-1": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "{{ port_names_all }}|5": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" } } {% endif %} diff --git a/src/sonic-utilities b/src/sonic-utilities index b86cb86fc817..f49ee3ff5ef1 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit b86cb86fc817b37ecd5e56ccec6a79865c7e68d6 +Subproject commit f49ee3ff5ef17df4f525ac9fcc9e638f73dbc9ac From 964bf9d0053ba63a52d60c380969452bcc46e0a5 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Thu, 13 Sep 2018 07:45:22 +0000 Subject: [PATCH 137/219] [submodule]: update sonic-utilities 958f2d3 2018-09-13 | Fix pfcwd start_default (#317) (origin/201803) [Wenda Ni] Signed-off-by: Guohan Lu --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index f49ee3ff5ef1..958f2d326bf0 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit f49ee3ff5ef17df4f525ac9fcc9e638f73dbc9ac +Subproject commit 958f2d326bf067cac0734373cc99499ad5362725 From 1fa607c36ab67ac4d6fba1b7986819e5be07d6b7 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Fri, 14 Sep 2018 09:01:07 +0000 Subject: [PATCH 138/219] [submodules]: update sonic-utilities d5f2877 Fix pfcwd start_default: Use config_db to get the active port list. (#319) Signed-off-by: Guohan Lu --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 958f2d326bf0..d5f2877fd5b9 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 958f2d326bf067cac0734373cc99499ad5362725 +Subproject commit d5f2877fd5b98f62c0dad0d972aeb67041a6ad26 From 33dbfd279ae55734b91d616387a5206a9d46a8e2 Mon Sep 17 00:00:00 2001 From: zhenggen-xu Date: Fri, 21 Sep 2018 03:04:53 -0700 Subject: [PATCH 139/219] Move all platform submodule code into sonic-buildimage (#2063) * Remove all platform submodules * Add all platform code into sonic-buildimage --- .gitmodules | 27 - .../broadcom/sonic-platform-modules-accton | 1 - .../sonic-platform-modules-accton/.gitignore | 33 + .../sonic-platform-modules-accton/LICENSE | 16 + .../sonic-platform-modules-accton/README.md | 1 + .../as5712-54x/classes/__init__.py | 0 .../as5712-54x/classes/fanutil.py | 238 ++ .../as5712-54x/classes/thermalutil.py | 121 + .../as5712-54x/modules/Makefile | 17 + .../modules/accton_as5712_54x_fan.c | 437 ++++ .../modules/accton_as5712_54x_psu.c | 371 +++ .../modules/accton_as5712_54x_sfp.c | 825 +++++++ .../as5712-54x/modules/cpr_4011_4mxx.c | 400 ++++ .../modules/i2c-mux-accton_as5712_54x_cpld.c | 1517 ++++++++++++ .../modules/leds-accton_as5712_54x.c | 594 +++++ .../as5712-54x/modules/ym2651y.c | 683 ++++++ .../service/as5712-platform-monitor.service | 17 + .../as5712-54x/setup.py | 16 + .../as5712-54x/utils/README | 117 + .../as5712-54x/utils/accton_as5712_monitor.py | 195 ++ .../as5712-54x/utils/accton_as5712_util.py | 602 +++++ .../as5812-54t/modules/Makefile | 4 + .../as5812-54t/modules/accton_i2c_cpld.c | 330 +++ .../modules/x86-64-accton-as5812-54t-fan.c | 442 ++++ .../modules/x86-64-accton-as5812-54t-leds.c | 601 +++++ .../modules/x86-64-accton-as5812-54t-psu.c | 372 +++ .../modules/x86-64-accton-as5812-54t-sfp.c | 318 +++ .../as5812-54t/modules/ym2651y.c | 680 ++++++ .../service/as5812-platform-init.service | 13 + .../as5812-54t/utils/README | 60 + .../utils/accton_as5812_54t_util.py | 565 +++++ .../as7312-54x/classes/__init__.py | 0 .../as7312-54x/classes/fanutil.py | 255 +++ .../as7312-54x/classes/thermalutil.py | 124 + .../as7312-54x/modules/Makefile | 17 + .../modules/accton_as7312_54x_fan.c | 815 +++++++ .../modules/accton_as7312_54x_leds.c | 438 ++++ .../modules/accton_as7312_54x_psu.c | 277 +++ .../modules/accton_as7312_54x_sfp.c | 1972 ++++++++++++++++ .../as7312-54x/modules/accton_i2c_cpld.c | 1219 ++++++++++ .../as7312-54x/modules/ym2651y.c | 1 + .../service/as7312-platform-monitor.service | 17 + .../as7312-54x/setup.py | 16 + .../as7312-54x/utils/README | 117 + .../as7312-54x/utils/accton_as7312_monitor.py | 208 ++ .../as7312-54x/utils/accton_as7312_util.py | 588 +++++ .../as7326-56x/classes/__init__.py | 0 .../as7326-56x/classes/fanutil.py | 254 +++ .../as7326-56x/classes/thermalutil.py | 124 + .../as7326-56x/modules/Makefile | 17 + .../modules/accton_as7326_56x_fan.c | 815 +++++++ .../modules/accton_as7326_56x_leds.c | 438 ++++ .../modules/accton_as7326_56x_psu.c | 277 +++ .../as7326-56x/modules/accton_i2c_cpld.c | 1080 +++++++++ .../as7326-56x/modules/ym2651y.c | 1 + .../service/as7326-platform-monitor.service | 17 + .../as7326-56x/setup.py | 16 + .../as7326-56x/utils/README | 74 + .../as7326-56x/utils/accton_as7326_monitor.py | 208 ++ .../as7326-56x/utils/accton_as7326_util.py | 577 +++++ .../as7712-32x/classes/__init__.py | 0 .../as7712-32x/modules/Makefile | 2 + .../modules/accton_as7712_32x_fan.c | 776 +++++++ .../modules/accton_as7712_32x_psu.c | 288 +++ .../modules/accton_as7712_32x_sfp.c | 1171 ++++++++++ .../as7712-32x/modules/accton_i2c_cpld.c | 1 + .../as7712-32x/modules/accton_pmbus_3y.c | 1 + .../modules/leds-accton_as7712_32x.c | 690 ++++++ .../as7712-32x/modules/pmbus.h | 1 + .../as7712-32x/modules/ym2651y.c | 1 + .../service/as7712-platform-init.service | 13 + .../as7712-32x/setup.py | 16 + .../as7712-32x/utils/README | 60 + .../as7712-32x/utils/accton_as7712_util.py | 569 +++++ .../as7716-32x/classes/__init__.py | 0 .../as7716-32x/classes/fanutil.py | 254 +++ .../as7716-32x/classes/thermalutil.py | 123 + .../as7716-32x/modules/Makefile | 21 + .../modules/accton_as7716_32x_cpld1.c | 781 +++++++ .../modules/accton_as7716_32x_fan.c | 794 +++++++ .../modules/accton_as7716_32x_leds.c | 442 ++++ .../modules/accton_as7716_32x_psu.c | 381 ++++ .../modules/accton_as7716_32x_sfp.c | 365 +++ .../as7716-32x/modules/accton_i2c_cpld.c | 259 +++ .../as7716-32x/modules/cpr_4011_4mxx.c | 400 ++++ .../as7716-32x/modules/optoe.c | 1148 ++++++++++ .../as7716-32x/modules/ym2651y.c | 603 +++++ .../service/as7716-platform-monitor.service | 17 + .../as7716-32x/setup.py | 16 + .../as7716-32x/utils/README | 117 + .../as7716-32x/utils/accton_as7716_monitor.py | 207 ++ .../as7716-32x/utils/accton_as7716_util.py | 595 +++++ .../as7716-32xb/classes/__init__.py | 0 .../as7716-32xb/classes/fanutil.py | 263 +++ .../as7716-32xb/classes/thermalutil.py | 124 + .../as7716-32xb/modules/Makefile | 17 + .../modules/accton_as7716_32xb_cpld1.c | 1021 +++++++++ .../modules/accton_as7716_32xb_fan.c | 969 ++++++++ .../modules/accton_as7716_32xb_leds.c | 443 ++++ .../modules/accton_as7716_32xb_oom.c | 267 +++ .../modules/accton_as7716_32xb_pmbus.c | 444 ++++ .../modules/accton_as7716_32xb_psu.c | 355 +++ .../modules/accton_as7716_32xb_sfp.c | 365 +++ .../modules/accton_as7716_32xb_sys.c | 243 ++ .../modules/accton_as7716_32xb_thermal.c | 214 ++ .../as7716-32xb/modules/accton_i2c_cpld.c | 259 +++ .../as7716_32xb-platform-monitor.service | 17 + .../as7716-32xb/setup.py | 16 + .../as7716-32xb/utils/README | 117 + .../utils/accton_as7716_32xb_drv_handler.py | 443 ++++ .../utils/accton_as7716_32xb_monitor.py | 227 ++ .../utils/accton_as7716_32xb_util.py | 616 +++++ .../as7816-64x/classes/__init__.py | 0 .../as7816-64x/classes/fanutil.py | 0 .../as7816-64x/classes/thermalutil.py | 0 .../as7816-64x/modules/Makefile | 2 + .../as7816-64x/modules/accton_i2c_cpld.c | 1 + .../modules/x86-64-accton-as7816-64x-fan.c | 466 ++++ .../modules/x86-64-accton-as7816-64x-leds.c | 460 ++++ .../modules/x86-64-accton-as7816-64x-psu.c | 239 ++ .../modules/x86-64-accton-as7816-64x-sfp.c | 1576 +++++++++++++ .../as7816-64x/modules/ym2651y.c | 1 + .../service/as7816-platform-init.service | 13 + .../as7816-64x/setup.py | 16 + .../as7816-64x/utils/README | 60 + .../as7816-64x/utils/accton_as7816_util.py | 523 +++++ .../common/modules/accton_i2c_cpld.c | 887 +++++++ .../common/modules/accton_pmbus_3y.c | 1978 ++++++++++++++++ .../common/modules/cpr_4011_4mxx.c | 402 ++++ .../common/modules/pmbus.h | 389 ++++ .../common/modules/ym2651y.c | 619 +++++ .../debian/changelog | 18 + .../debian/compat | 1 + .../debian/control | 41 + .../debian/rules | 86 + .../broadcom/sonic-platform-modules-arista | 1 - .../sonic-platform-modules-arista/.gitignore | 21 + .../sonic-platform-modules-arista/LICENSE | 1016 +++++++++ .../sonic-platform-modules-arista/Makefile | 17 + .../sonic-platform-modules-arista/README.md | 250 ++ .../arista/__init__.py | 0 .../arista/components/__init__.py | 0 .../arista/components/common.py | 109 + .../arista/components/ds125br.py | 84 + .../arista/components/ds460.py | 37 + .../arista/components/scd.py | 473 ++++ .../arista/core/__init__.py | 0 .../arista/core/component.py | 109 + .../arista/core/driver.py | 106 + .../arista/core/inventory.py | 101 + .../arista/core/platform.py | 125 + .../arista/core/prefdl.py | 225 ++ .../arista/core/types.py | 29 + .../arista/core/utils.py | 129 ++ .../arista/platforms/__init__.py | 5 + .../arista/platforms/a7050qx32.py | 94 + .../arista/platforms/a7050qx32s.py | 116 + .../arista/platforms/a7060cx32s.py | 102 + .../arista/platforms/a7260cx364.py | 106 + .../arista/utils/__init__.py | 0 .../arista/utils/sonic_eeprom.py | 67 + .../arista/utils/sonic_leds.py | 99 + .../arista/utils/sonic_psu.py | 34 + .../arista/utils/sonic_sfputil.py | 95 + .../confs/arista-drivers.service | 14 + .../confs/gardena-watchdog-stop.service | 18 + .../debian/changelog | 5 + .../debian/compat | 1 + .../debian/control | 54 + .../debian/copyright | 1016 +++++++++ .../debian/files | 4 + .../debian/rules | 54 + .../debian/sonic-platform-arista.init | 47 + .../sonic-platform-modules-arista/setup.py | 18 + .../src/Makefile | 9 + .../src/crow-fan-driver.c | 505 ++++ .../src/gpio-kversfix.h | 70 + .../src/raven-fan-driver.c | 527 +++++ .../src/rook-fan-cpld.c | 963 ++++++++ .../src/rook-led-driver.c | 296 +++ .../src/scd-hwmon.c | 1595 +++++++++++++ .../src/scd-hwmon.h | 15 + .../sonic-platform-modules-arista/src/scd.c | 1697 ++++++++++++++ .../sonic-platform-modules-arista/src/scd.h | 61 + .../src/sonic-support-driver.c | 1270 +++++++++++ .../src/sonic-support-driver.h | 19 + .../tests/all-platforms.sh | 52 + .../utils/98-scd-uio.rules | 6 + .../utils/arista | 233 ++ .../utils/arista-gardena-watchdog | 144 ++ .../utils/boot-eos | 207 ++ .../sonic-platform-modules-arista/utils/boot0 | 122 + .../sonic-platform-modules-arista/utils/reset | 180 ++ platform/broadcom/sonic-platform-modules-cel | 1 - .../sonic-platform-modules-cel/.gitignore | 33 + .../sonic-platform-modules-cel/LICENSE | 15 + .../sonic-platform-modules-cel/README.md | 1 + .../debian/changelog | 44 + .../sonic-platform-modules-cel/debian/compat | 1 + .../sonic-platform-modules-cel/debian/control | 12 + .../debian/platform-modules-dx010.init | 147 ++ .../debian/platform-modules-dx010.install | 2 + .../sonic-platform-modules-cel/debian/rules | 33 + .../dx010/cfg/dx010-modules.conf | 15 + .../dx010/modules/Makefile | 1 + .../dx010/modules/dx010_cpld.c | 506 ++++ .../dx010/modules/dx010_wdt.c | 215 ++ .../dx010/modules/emc2305.c | 886 +++++++ .../dx010/modules/leds-dx010.c | 289 +++ .../dx010/modules/lm75.c | 553 +++++ .../dx010/modules/lm75.h | 49 + .../dx010/modules/mc24lc64t.c | 142 ++ .../dx010/scripts/dx010_check_qsfp.sh | 7 + platform/broadcom/sonic-platform-modules-dell | 1 - .../sonic-platform-modules-dell/.gitignore | 33 + .../sonic-platform-modules-dell/LICENSE | 16 + .../sonic-platform-modules-dell/README.md | 1 + .../common/dell_i2c_utils.sh | 62 + .../common/dell_pmc.c | 1919 ++++++++++++++++ .../common/fstrim.service | 6 + .../common/fstrim.timer | 12 + .../debian/changelog | 11 + .../sonic-platform-modules-dell/debian/compat | 1 + .../debian/control | 17 + .../debian/platform-modules-s6100.init | 40 + .../debian/platform-modules-s6100.install | 9 + .../debian/platform-modules-s6100.postinst | 7 + .../debian/platform-modules-z9100.init | 40 + .../debian/platform-modules-z9100.install | 8 + .../debian/platform-modules-z9100.postinst | 7 + .../sonic-platform-modules-dell/debian/rules | 45 + .../s6100/modules/Makefile | 2 + .../s6100/modules/dell_s6100_iom_cpld.c | 266 +++ .../s6100/scripts/README | 146 ++ .../s6100/scripts/io_rd_wr.py | 93 + .../s6100/scripts/iom_power_off.sh | 16 + .../s6100/scripts/iom_power_on.sh | 17 + .../s6100/scripts/platform_sensors.py | 322 +++ .../s6100/scripts/s6100_platform.sh | 205 ++ .../s6100/scripts/sensors | 7 + .../z9100/cfg/z9100-modules.conf | 15 + .../z9100/modules/Makefile | 2 + .../z9100/modules/dell_z9100_cpld.c | 273 +++ .../z9100/scripts/check_qsfp.sh | 60 + .../z9100/scripts/platform_sensors.py | 324 +++ .../z9100/scripts/sensors | 7 + .../z9100/scripts/z9100_platform.sh | 169 ++ .../broadcom/sonic-platform-modules-ingrasys | 1 - .../.gitignore | 33 + .../sonic-platform-modules-ingrasys/LICENSE | 674 ++++++ .../debian/changelog | 22 + .../debian/compat | 1 + .../debian/control | 26 + .../debian/rules | 80 + .../sonic-platform-ingrasys-s8810-32q.dirs | 3 + .../sonic-platform-ingrasys-s8810-32q.install | 3 + ...sonic-platform-ingrasys-s8810-32q.postinst | 43 + .../sonic-platform-ingrasys-s8810-32q.postrm | 38 + .../sonic-platform-ingrasys-s8810-32q.prerm | 17 + .../sonic-platform-ingrasys-s8810-32q.upstart | 6 + .../sonic-platform-ingrasys-s8900-54xc.dirs | 3 + ...sonic-platform-ingrasys-s8900-54xc.install | 3 + ...onic-platform-ingrasys-s8900-54xc.postinst | 43 + .../sonic-platform-ingrasys-s8900-54xc.postrm | 38 + .../sonic-platform-ingrasys-s8900-54xc.prerm | 17 + ...sonic-platform-ingrasys-s8900-54xc.upstart | 6 + .../sonic-platform-ingrasys-s8900-64xc.dirs | 3 + ...sonic-platform-ingrasys-s8900-64xc.install | 3 + ...onic-platform-ingrasys-s8900-64xc.postinst | 42 + .../sonic-platform-ingrasys-s8900-64xc.postrm | 38 + .../sonic-platform-ingrasys-s8900-64xc.prerm | 15 + ...sonic-platform-ingrasys-s8900-64xc.upstart | 6 + .../debian/sonic-platform-ingrasys-s9100.dirs | 3 + .../sonic-platform-ingrasys-s9100.install | 3 + .../sonic-platform-ingrasys-s9100.postinst | 43 + .../sonic-platform-ingrasys-s9100.postrm | 38 + .../sonic-platform-ingrasys-s9100.prerm | 17 + .../sonic-platform-ingrasys-s9100.upstart | 6 + .../sonic-platform-ingrasys-s9200-64x.dirs | 3 + .../sonic-platform-ingrasys-s9200-64x.install | 3 + ...sonic-platform-ingrasys-s9200-64x.postinst | 43 + .../sonic-platform-ingrasys-s9200-64x.postrm | 38 + .../sonic-platform-ingrasys-s9200-64x.prerm | 17 + .../sonic-platform-ingrasys-s9200-64x.upstart | 6 + .../s8810-32q/README.md | 185 ++ .../s8810-32q/modules/Makefile | 2 + .../s8810-32q/modules/eeprom_mb.c | 212 ++ .../modules/ingrasys_s8810_32q_platform.h | 148 ++ .../modules/ingrasys_s8810_32q_psu.c | 393 ++++ .../s8810-32q/service/qsfp-monitor.service | 15 + .../service/s8810-32q-monitor.service | 19 + .../s8810-32q/utils/i2c_utils.sh | 1452 ++++++++++++ .../s8810-32q/utils/qsfp_monitor.sh | 104 + .../s8810-32q/utils/s8810_32q_monitor.sh | 39 + .../s8900-54xc/README.md | 185 ++ .../s8900-54xc/modules/Makefile | 2 + .../s8900-54xc/modules/eeprom_mb.c | 212 ++ .../s8900-54xc/modules/i2c_cpld.c | 448 ++++ .../s8900-54xc/modules/i2c_cpld.h | 197 ++ .../s8900-54xc/service/qsfp-monitor.service | 15 + .../service/s8900-54xc-monitor.service | 18 + .../s8900-54xc/utils/i2c_utils.sh | 1485 ++++++++++++ .../s8900-54xc/utils/qsfp_monitor.sh | 106 + .../s8900-54xc/utils/qsfp_si_cfg.sh | 331 +++ .../s8900-54xc/utils/s8900_54xc_monitor.sh | 39 + .../s8900-64xc/README.md | 185 ++ .../s8900-64xc/modules/Makefile | 4 + .../s8900-64xc/modules/eeprom_mb.c | 212 ++ .../s8900-64xc/modules/i2c_cpld.c | 448 ++++ .../s8900-64xc/modules/i2c_cpld.h | 197 ++ .../s8900-64xc/modules/qsfp_cpld.c | 1771 ++++++++++++++ .../s8900-64xc/service/qsfp-monitor.service | 15 + .../service/s8900-64xc-monitor.service | 18 + .../s8900-64xc/utils/i2c_utils.sh | 1157 ++++++++++ .../s8900-64xc/utils/qsfp_monitor.sh | 106 + .../s8900-64xc/utils/qsfp_si_cfg.sh | 409 ++++ .../s8900-64xc/utils/s8900_64xc_monitor.sh | 39 + .../s9100/README.md | 185 ++ .../s9100/modules/Makefile | 2 + .../s9100/modules/eeprom_mb.c | 212 ++ .../s9100/modules/i2c_cpld.c | 448 ++++ .../s9100/modules/i2c_cpld.h | 197 ++ .../s9100/service/qsfp-monitor.service | 15 + .../s9100/service/s9100-monitor.service | 19 + .../s9100/utils/i2c_utils.sh | 1518 ++++++++++++ .../s9100/utils/qsfp_monitor.sh | 104 + .../s9100/utils/qsfp_si_cfg.sh | 339 +++ .../s9100/utils/s9100_monitor.sh | 39 + .../s9200-64x/README.md | 184 ++ .../s9200-64x/modules/Makefile | 3 + .../s9200-64x/modules/cpld.c | 498 ++++ .../s9200-64x/modules/eeprom_mb.c | 267 +++ .../modules/ingrasys_s9200_64x_platform.h | 148 ++ .../modules/ingrasys_s9200_64x_psu.c | 389 ++++ .../s9200-64x/service/qsfp-monitor.service | 15 + .../service/s9200-64x-monitor.service | 19 + .../s9200-64x/utils/i2c_utils.sh | 1942 ++++++++++++++++ .../s9200-64x/utils/qsfp_monitor.sh | 104 + .../s9200-64x/utils/qsfp_si_cfg.sh | 230 ++ .../s9200-64x/utils/s9200_64x_monitor.sh | 39 + .../broadcom/sonic-platform-modules-mitac | 1 - .../sonic-platform-modules-mitac/.gitignore | 17 + .../sonic-platform-modules-mitac/LICENSE | 16 + .../sonic-platform-modules-mitac/README.md | 1 + .../debian/changelog | 5 + .../debian/compat | 1 + .../debian/control | 12 + .../sonic-platform-modules-mitac/debian/rules | 41 + .../sonic-platform-mitac-ly1200-32x.init | 56 + .../sonic-platform-mitac-ly1200-32x.upstart | 5 + .../ly1200-32x/etc/init.d/fan-ctrld | 35 + .../ly1200-32x/etc/init.d/gpe | 39 + .../ly1200-32x/etc/init.d/i2c_init | 231 ++ .../ly1200-32x/etc/init.d/sys_polld | 48 + .../ly1200-32x/etc/init.d/sys_servd | 28 + .../ly1200-32x/etc/init.d/xcvr_servd | 28 + .../ly1200-32x/modules/Makefile | 5 + .../ly1200-32x/modules/bms_i2c.h | 26 + .../ly1200-32x/modules/master_cpld_reg.h | 275 +++ .../ly1200-32x/modules/master_cpld_sysfs.h | 226 ++ .../modules/mitac_ly1200_32x_cb_i2c.c | 163 ++ .../modules/mitac_ly1200_32x_fb_i2c.c | 153 ++ .../modules/mitac_ly1200_32x_fb_module_i2c.c | 138 ++ .../modules/mitac_ly1200_32x_fse000.c | 1787 +++++++++++++++ .../ly1200-32x/modules/mitac_ly1200_32x_gpe.c | 93 + .../modules/mitac_ly1200_32x_master_cpld.c | 503 ++++ .../modules/mitac_ly1200_32x_pb_i2c.c | 137 ++ .../modules/mitac_ly1200_32x_sb_i2c.c | 514 +++++ .../modules/mitac_ly1200_32x_slave_cpld.c | 427 ++++ .../modules/mitac_ly1200_32x_system_cpld.c | 541 +++++ .../ly1200-32x/modules/pmbus.h | 366 +++ .../ly1200-32x/modules/slave_cpld_reg.h | 192 ++ .../ly1200-32x/modules/slave_cpld_sysfs.h | 155 ++ .../ly1200-32x/modules/system_cpld_reg.h | 107 + .../ly1200-32x/modules/system_cpld_sysfs.h | 76 + .../ly1200-32x/opt/fan-ctrl/fan-ctrl | 679 ++++++ .../opt/fan-ctrl/fan-zone-thermal_B2F.conf | 13 + .../opt/fan-ctrl/fan-zone-thermal_F2B.conf | 12 + .../ly1200-32x/opt/fan-ctrl/fan-zone_B2F.conf | 38 + .../ly1200-32x/opt/fan-ctrl/fan-zone_F2B.conf | 38 + .../ly1200-32x/opt/fan-ctrl/funcs.sh | 22 + .../ly1200-32x/opt/fan-ctrl/init.sh | 26 + .../ly1200-32x/opt/script/funcs.sh | 23 + .../ly1200-32x/opt/script/start_service.sh | 162 ++ .../ly1200-32x/opt/script/start_watchdog.sh | 32 + .../ly1200-32x/opt/sys-serv/sys-servd | Bin 0 -> 56280 bytes .../opt/system-check/system-check.sh | 55 + .../ly1200-32x/opt/watchdog/watchdog.conf | 45 + .../ly1200-32x/opt/xcvr-serv/xcvr-servd | Bin 0 -> 31456 bytes .../broadcom/sonic-platform-modules-quanta | 1 - .../sonic-platform-modules-quanta/.gitignore | 37 + .../sonic-platform-modules-quanta/LICENSE | 16 + .../sonic-platform-modules-quanta/README.md | 2 + .../debian/changelog | 6 + .../debian/compat | 1 + .../debian/control | 12 + .../debian/rules | 86 + .../ix1b-32x/classes/__init__.py | 0 .../ix1b-32x/modules/Makefile | 3 + .../ix1b-32x/modules/pmbus.h | 387 ++++ .../ix1b-32x/modules/qci_cpld_qsfp28.c | 409 ++++ .../ix1b-32x/modules/qci_platform.h | 64 + .../ix1b-32x/modules/qci_platform_ix1b.c | 491 ++++ .../ix1b-32x/modules/qci_pmbus.c | 487 ++++ .../service/ix1b-platform-init.service | 13 + .../ix1b-32x/setup.py | 16 + .../ix1b-32x/utils/quanta_ix1b_util.py | 203 ++ .../broadcom/sonic-platform-modules-s6000 | 1 - .../sonic-platform-modules-s6000/LICENSE | 15 + .../sonic-platform-modules-s6000/MAINTAINERS | 7 + .../sonic-platform-modules-s6000/README.md | 2 + .../debian/changelog | 5 + .../debian/compat | 1 + .../debian/control | 12 + .../debian/copyright | 16 + .../debian/platform-modules-s6000.init | 45 + .../sonic-platform-modules-s6000/debian/rules | 32 + .../modules/Makefile | 1 + .../modules/dell_s6000_platform.c | 2031 +++++++++++++++++ .../scripts/reset-qsfp | 25 + .../scripts/set-fan-speed | 58 + .../nephos/sonic-platform-modules-ingrasys | 1 - .../.gitignore | 52 + .../sonic-platform-modules-ingrasys/LICENSE | 674 ++++++ .../debian/changelog | 11 + .../debian/compat | 1 + .../debian/control | 15 + .../debian/rules | 82 + .../sonic-platform-ingrasys-s9130-32x.dirs | 3 + .../sonic-platform-ingrasys-s9130-32x.install | 3 + .../sonic-platform-ingrasys-s9130-32x.links | 1 + ...sonic-platform-ingrasys-s9130-32x.postinst | 44 + .../sonic-platform-ingrasys-s9130-32x.postrm | 38 + .../sonic-platform-ingrasys-s9130-32x.prerm | 17 + .../sonic-platform-ingrasys-s9130-32x.upstart | 6 + .../sonic-platform-ingrasys-s9230-64x.dirs | 3 + .../sonic-platform-ingrasys-s9230-64x.install | 3 + .../sonic-platform-ingrasys-s9230-64x.links | 1 + ...sonic-platform-ingrasys-s9230-64x.postinst | 45 + .../sonic-platform-ingrasys-s9230-64x.postrm | 38 + .../sonic-platform-ingrasys-s9230-64x.prerm | 17 + .../sonic-platform-ingrasys-s9230-64x.upstart | 6 + .../s9130-32x/README.md | 167 ++ .../s9130-32x/modules/Makefile | 2 + .../s9130-32x/modules/eeprom_mb.c | 267 +++ .../modules/ingrasys_s9130_32x_platform.h | 148 ++ .../modules/ingrasys_s9130_32x_psu.c | 407 ++++ .../s9130-32x/service/qsfp-monitor.service | 15 + .../service/s9130-32x-monitor.service | 19 + .../s9130-32x/utils/i2c_utils.sh | 1685 ++++++++++++++ .../s9130-32x/utils/qsfp_monitor.sh | 104 + .../s9130-32x/utils/s9130_32x_monitor.sh | 39 + .../s9230-64x/README.md | 182 ++ .../s9230-64x/modules/Makefile | 3 + .../s9230-64x/modules/eeprom_mb.c | 267 +++ .../modules/ingrasys_s9230_64x_i2c_cpld.c | 1259 ++++++++++ .../modules/ingrasys_s9230_64x_i2c_cpld.h | 223 ++ .../modules/ingrasys_s9230_64x_platform.h | 148 ++ .../modules/ingrasys_s9230_64x_psu.c | 407 ++++ .../s9230-64x/service/qsfp-monitor.service | 15 + .../service/s9230-64x-monitor.service | 19 + .../s9230-64x/utils/i2c_utils.sh | 1850 +++++++++++++++ .../s9230-64x/utils/qsfp_monitor.sh | 105 + .../s9230-64x/utils/s9230_64x_monitor.sh | 39 + 464 files changed, 102689 insertions(+), 36 deletions(-) delete mode 160000 platform/broadcom/sonic-platform-modules-accton create mode 100644 platform/broadcom/sonic-platform-modules-accton/.gitignore create mode 100644 platform/broadcom/sonic-platform-modules-accton/LICENSE create mode 100644 platform/broadcom/sonic-platform-modules-accton/README.md create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5712-54x/classes/__init__.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5712-54x/classes/fanutil.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5712-54x/classes/thermalutil.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/Makefile create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/accton_as5712_54x_fan.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/accton_as5712_54x_psu.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/accton_as5712_54x_sfp.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/cpr_4011_4mxx.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/i2c-mux-accton_as5712_54x_cpld.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/leds-accton_as5712_54x.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/ym2651y.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5712-54x/service/as5712-platform-monitor.service create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5712-54x/setup.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/README create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_monitor.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_util.py create mode 100644 platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/accton_i2c_cpld.c create mode 100644 platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-fan.c create mode 100644 platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-leds.c create mode 100644 platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-psu.c create mode 100644 platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-sfp.c create mode 100644 platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/ym2651y.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5812-54t/service/as5812-platform-init.service create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/README create mode 100755 platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_54t_util.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7312-54x/classes/__init__.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7312-54x/classes/fanutil.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7312-54x/classes/thermalutil.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/Makefile create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_fan.c create mode 100644 platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_leds.c create mode 100644 platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_psu.c create mode 100644 platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_sfp.c create mode 100644 platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_i2c_cpld.c create mode 120000 platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/ym2651y.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7312-54x/service/as7312-platform-monitor.service create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7312-54x/setup.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/README create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/accton_as7312_monitor.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/accton_as7312_util.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7326-56x/classes/__init__.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7326-56x/classes/fanutil.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7326-56x/classes/thermalutil.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/Makefile create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_fan.c create mode 100644 platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_leds.c create mode 100644 platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_psu.c create mode 100644 platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_i2c_cpld.c create mode 120000 platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/ym2651y.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7326-56x/service/as7326-platform-monitor.service create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7326-56x/setup.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/README create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_monitor.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_util.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7712-32x/classes/__init__.py create mode 100644 platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/accton_as7712_32x_fan.c create mode 100644 platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/accton_as7712_32x_psu.c create mode 100644 platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/accton_as7712_32x_sfp.c create mode 120000 platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/accton_i2c_cpld.c create mode 120000 platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/accton_pmbus_3y.c create mode 100644 platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/leds-accton_as7712_32x.c create mode 120000 platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/pmbus.h create mode 120000 platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/ym2651y.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7712-32x/service/as7712-platform-init.service create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7712-32x/setup.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7712-32x/utils/README create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7712-32x/utils/accton_as7712_util.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32x/classes/__init__.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32x/classes/fanutil.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32x/classes/thermalutil.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/Makefile create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_cpld1.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_fan.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_leds.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_psu.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_sfp.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_i2c_cpld.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/cpr_4011_4mxx.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/optoe.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/ym2651y.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32x/service/as7716-platform-monitor.service create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32x/setup.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/README create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/accton_as7716_monitor.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/accton_as7716_util.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32xb/classes/__init__.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32xb/classes/fanutil.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32xb/classes/thermalutil.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/Makefile create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_cpld1.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_fan.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_leds.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_oom.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_pmbus.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_psu.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_sfp.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_sys.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_thermal.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_i2c_cpld.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32xb/service/as7716_32xb-platform-monitor.service create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32xb/setup.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/README create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_drv_handler.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_monitor.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_util.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7816-64x/classes/__init__.py create mode 100644 platform/broadcom/sonic-platform-modules-accton/as7816-64x/classes/fanutil.py create mode 100644 platform/broadcom/sonic-platform-modules-accton/as7816-64x/classes/thermalutil.py create mode 100644 platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/Makefile create mode 120000 platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/accton_i2c_cpld.c create mode 100644 platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/x86-64-accton-as7816-64x-fan.c create mode 100644 platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/x86-64-accton-as7816-64x-leds.c create mode 100644 platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/x86-64-accton-as7816-64x-psu.c create mode 100644 platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/x86-64-accton-as7816-64x-sfp.c create mode 120000 platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/ym2651y.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7816-64x/service/as7816-platform-init.service create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7816-64x/setup.py create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/README create mode 100755 platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/accton_as7816_util.py create mode 100644 platform/broadcom/sonic-platform-modules-accton/common/modules/accton_i2c_cpld.c create mode 100644 platform/broadcom/sonic-platform-modules-accton/common/modules/accton_pmbus_3y.c create mode 100644 platform/broadcom/sonic-platform-modules-accton/common/modules/cpr_4011_4mxx.c create mode 100644 platform/broadcom/sonic-platform-modules-accton/common/modules/pmbus.h create mode 100644 platform/broadcom/sonic-platform-modules-accton/common/modules/ym2651y.c create mode 100755 platform/broadcom/sonic-platform-modules-accton/debian/changelog create mode 100644 platform/broadcom/sonic-platform-modules-accton/debian/compat create mode 100755 platform/broadcom/sonic-platform-modules-accton/debian/control create mode 100755 platform/broadcom/sonic-platform-modules-accton/debian/rules delete mode 160000 platform/broadcom/sonic-platform-modules-arista create mode 100644 platform/broadcom/sonic-platform-modules-arista/.gitignore create mode 100644 platform/broadcom/sonic-platform-modules-arista/LICENSE create mode 100644 platform/broadcom/sonic-platform-modules-arista/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-arista/README.md create mode 100644 platform/broadcom/sonic-platform-modules-arista/arista/__init__.py create mode 100644 platform/broadcom/sonic-platform-modules-arista/arista/components/__init__.py create mode 100644 platform/broadcom/sonic-platform-modules-arista/arista/components/common.py create mode 100644 platform/broadcom/sonic-platform-modules-arista/arista/components/ds125br.py create mode 100644 platform/broadcom/sonic-platform-modules-arista/arista/components/ds460.py create mode 100644 platform/broadcom/sonic-platform-modules-arista/arista/components/scd.py create mode 100644 platform/broadcom/sonic-platform-modules-arista/arista/core/__init__.py create mode 100644 platform/broadcom/sonic-platform-modules-arista/arista/core/component.py create mode 100644 platform/broadcom/sonic-platform-modules-arista/arista/core/driver.py create mode 100644 platform/broadcom/sonic-platform-modules-arista/arista/core/inventory.py create mode 100644 platform/broadcom/sonic-platform-modules-arista/arista/core/platform.py create mode 100755 platform/broadcom/sonic-platform-modules-arista/arista/core/prefdl.py create mode 100644 platform/broadcom/sonic-platform-modules-arista/arista/core/types.py create mode 100644 platform/broadcom/sonic-platform-modules-arista/arista/core/utils.py create mode 100644 platform/broadcom/sonic-platform-modules-arista/arista/platforms/__init__.py create mode 100644 platform/broadcom/sonic-platform-modules-arista/arista/platforms/a7050qx32.py create mode 100644 platform/broadcom/sonic-platform-modules-arista/arista/platforms/a7050qx32s.py create mode 100644 platform/broadcom/sonic-platform-modules-arista/arista/platforms/a7060cx32s.py create mode 100644 platform/broadcom/sonic-platform-modules-arista/arista/platforms/a7260cx364.py create mode 100644 platform/broadcom/sonic-platform-modules-arista/arista/utils/__init__.py create mode 100644 platform/broadcom/sonic-platform-modules-arista/arista/utils/sonic_eeprom.py create mode 100644 platform/broadcom/sonic-platform-modules-arista/arista/utils/sonic_leds.py create mode 100644 platform/broadcom/sonic-platform-modules-arista/arista/utils/sonic_psu.py create mode 100644 platform/broadcom/sonic-platform-modules-arista/arista/utils/sonic_sfputil.py create mode 100644 platform/broadcom/sonic-platform-modules-arista/confs/arista-drivers.service create mode 100644 platform/broadcom/sonic-platform-modules-arista/confs/gardena-watchdog-stop.service create mode 100755 platform/broadcom/sonic-platform-modules-arista/debian/changelog create mode 100755 platform/broadcom/sonic-platform-modules-arista/debian/compat create mode 100755 platform/broadcom/sonic-platform-modules-arista/debian/control create mode 100644 platform/broadcom/sonic-platform-modules-arista/debian/copyright create mode 100644 platform/broadcom/sonic-platform-modules-arista/debian/files create mode 100755 platform/broadcom/sonic-platform-modules-arista/debian/rules create mode 100755 platform/broadcom/sonic-platform-modules-arista/debian/sonic-platform-arista.init create mode 100755 platform/broadcom/sonic-platform-modules-arista/setup.py create mode 100644 platform/broadcom/sonic-platform-modules-arista/src/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-arista/src/crow-fan-driver.c create mode 100644 platform/broadcom/sonic-platform-modules-arista/src/gpio-kversfix.h create mode 100644 platform/broadcom/sonic-platform-modules-arista/src/raven-fan-driver.c create mode 100644 platform/broadcom/sonic-platform-modules-arista/src/rook-fan-cpld.c create mode 100644 platform/broadcom/sonic-platform-modules-arista/src/rook-led-driver.c create mode 100644 platform/broadcom/sonic-platform-modules-arista/src/scd-hwmon.c create mode 100644 platform/broadcom/sonic-platform-modules-arista/src/scd-hwmon.h create mode 100644 platform/broadcom/sonic-platform-modules-arista/src/scd.c create mode 100644 platform/broadcom/sonic-platform-modules-arista/src/scd.h create mode 100644 platform/broadcom/sonic-platform-modules-arista/src/sonic-support-driver.c create mode 100644 platform/broadcom/sonic-platform-modules-arista/src/sonic-support-driver.h create mode 100755 platform/broadcom/sonic-platform-modules-arista/tests/all-platforms.sh create mode 100644 platform/broadcom/sonic-platform-modules-arista/utils/98-scd-uio.rules create mode 100755 platform/broadcom/sonic-platform-modules-arista/utils/arista create mode 100644 platform/broadcom/sonic-platform-modules-arista/utils/arista-gardena-watchdog create mode 100755 platform/broadcom/sonic-platform-modules-arista/utils/boot-eos create mode 100755 platform/broadcom/sonic-platform-modules-arista/utils/boot0 create mode 100755 platform/broadcom/sonic-platform-modules-arista/utils/reset delete mode 160000 platform/broadcom/sonic-platform-modules-cel create mode 100644 platform/broadcom/sonic-platform-modules-cel/.gitignore create mode 100644 platform/broadcom/sonic-platform-modules-cel/LICENSE create mode 100644 platform/broadcom/sonic-platform-modules-cel/README.md create mode 100644 platform/broadcom/sonic-platform-modules-cel/debian/changelog create mode 100644 platform/broadcom/sonic-platform-modules-cel/debian/compat create mode 100644 platform/broadcom/sonic-platform-modules-cel/debian/control create mode 100644 platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init create mode 100644 platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install create mode 100644 platform/broadcom/sonic-platform-modules-cel/debian/rules create mode 100644 platform/broadcom/sonic-platform-modules-cel/dx010/cfg/dx010-modules.conf create mode 100644 platform/broadcom/sonic-platform-modules-cel/dx010/modules/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010_cpld.c create mode 100644 platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010_wdt.c create mode 100644 platform/broadcom/sonic-platform-modules-cel/dx010/modules/emc2305.c create mode 100644 platform/broadcom/sonic-platform-modules-cel/dx010/modules/leds-dx010.c create mode 100644 platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.c create mode 100644 platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.h create mode 100644 platform/broadcom/sonic-platform-modules-cel/dx010/modules/mc24lc64t.c create mode 100644 platform/broadcom/sonic-platform-modules-cel/dx010/scripts/dx010_check_qsfp.sh delete mode 160000 platform/broadcom/sonic-platform-modules-dell create mode 100644 platform/broadcom/sonic-platform-modules-dell/.gitignore create mode 100644 platform/broadcom/sonic-platform-modules-dell/LICENSE create mode 100644 platform/broadcom/sonic-platform-modules-dell/README.md create mode 100755 platform/broadcom/sonic-platform-modules-dell/common/dell_i2c_utils.sh create mode 100644 platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c create mode 100644 platform/broadcom/sonic-platform-modules-dell/common/fstrim.service create mode 100644 platform/broadcom/sonic-platform-modules-dell/common/fstrim.timer create mode 100644 platform/broadcom/sonic-platform-modules-dell/debian/changelog create mode 100644 platform/broadcom/sonic-platform-modules-dell/debian/compat create mode 100644 platform/broadcom/sonic-platform-modules-dell/debian/control create mode 100755 platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.init create mode 100644 platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install create mode 100644 platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.postinst create mode 100755 platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.init create mode 100644 platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install create mode 100644 platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.postinst create mode 100755 platform/broadcom/sonic-platform-modules-dell/debian/rules create mode 100644 platform/broadcom/sonic-platform-modules-dell/s6100/modules/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-dell/s6100/modules/dell_s6100_iom_cpld.c create mode 100644 platform/broadcom/sonic-platform-modules-dell/s6100/scripts/README create mode 100755 platform/broadcom/sonic-platform-modules-dell/s6100/scripts/io_rd_wr.py create mode 100755 platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_off.sh create mode 100755 platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_on.sh create mode 100755 platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_sensors.py create mode 100755 platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh create mode 100755 platform/broadcom/sonic-platform-modules-dell/s6100/scripts/sensors create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9100/cfg/z9100-modules.conf create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9100/modules/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9100/modules/dell_z9100_cpld.c create mode 100755 platform/broadcom/sonic-platform-modules-dell/z9100/scripts/check_qsfp.sh create mode 100755 platform/broadcom/sonic-platform-modules-dell/z9100/scripts/platform_sensors.py create mode 100755 platform/broadcom/sonic-platform-modules-dell/z9100/scripts/sensors create mode 100755 platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh delete mode 160000 platform/broadcom/sonic-platform-modules-ingrasys create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/.gitignore create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/LICENSE create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/changelog create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/compat create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/control create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/rules create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8810-32q.dirs create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8810-32q.install create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8810-32q.postinst create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8810-32q.postrm create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8810-32q.prerm create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8810-32q.upstart create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-54xc.dirs create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-54xc.install create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-54xc.postinst create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-54xc.postrm create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-54xc.prerm create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-54xc.upstart create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-64xc.dirs create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-64xc.install create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-64xc.postinst create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-64xc.postrm create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-64xc.prerm create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-64xc.upstart create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9100.dirs create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9100.install create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9100.postinst create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9100.postrm create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9100.prerm create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9100.upstart create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9200-64x.dirs create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9200-64x.install create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9200-64x.postinst create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9200-64x.postrm create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9200-64x.prerm create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9200-64x.upstart create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/README.md create mode 100755 platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/modules/Makefile create mode 100755 platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/modules/eeprom_mb.c create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/modules/ingrasys_s8810_32q_platform.h create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/modules/ingrasys_s8810_32q_psu.c create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/service/qsfp-monitor.service create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/service/s8810-32q-monitor.service create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/i2c_utils.sh create mode 100755 platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/qsfp_monitor.sh create mode 100755 platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/s8810_32q_monitor.sh create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/README.md create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/modules/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/modules/eeprom_mb.c create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/modules/i2c_cpld.c create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/modules/i2c_cpld.h create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/service/qsfp-monitor.service create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/service/s8900-54xc-monitor.service create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/i2c_utils.sh create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_monitor.sh create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_si_cfg.sh create mode 100755 platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/s8900_54xc_monitor.sh create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/README.md create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/modules/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/modules/eeprom_mb.c create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/modules/i2c_cpld.c create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/modules/i2c_cpld.h create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/modules/qsfp_cpld.c create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/service/qsfp-monitor.service create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/service/s8900-64xc-monitor.service create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/i2c_utils.sh create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_monitor.sh create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_si_cfg.sh create mode 100755 platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/s8900_64xc_monitor.sh create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s9100/README.md create mode 100755 platform/broadcom/sonic-platform-modules-ingrasys/s9100/modules/Makefile create mode 100755 platform/broadcom/sonic-platform-modules-ingrasys/s9100/modules/eeprom_mb.c create mode 100755 platform/broadcom/sonic-platform-modules-ingrasys/s9100/modules/i2c_cpld.c create mode 100755 platform/broadcom/sonic-platform-modules-ingrasys/s9100/modules/i2c_cpld.h create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s9100/service/qsfp-monitor.service create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s9100/service/s9100-monitor.service create mode 100755 platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/i2c_utils.sh create mode 100755 platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_monitor.sh create mode 100755 platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_si_cfg.sh create mode 100755 platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/s9100_monitor.sh create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/README.md create mode 100755 platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/modules/Makefile create mode 100755 platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/modules/cpld.c create mode 100755 platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/modules/eeprom_mb.c create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/modules/ingrasys_s9200_64x_platform.h create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/modules/ingrasys_s9200_64x_psu.c create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/service/qsfp-monitor.service create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/service/s9200-64x-monitor.service create mode 100644 platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/i2c_utils.sh create mode 100755 platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_monitor.sh create mode 100755 platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_si_cfg.sh create mode 100755 platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/s9200_64x_monitor.sh delete mode 160000 platform/broadcom/sonic-platform-modules-mitac create mode 100644 platform/broadcom/sonic-platform-modules-mitac/.gitignore create mode 100644 platform/broadcom/sonic-platform-modules-mitac/LICENSE create mode 100644 platform/broadcom/sonic-platform-modules-mitac/README.md create mode 100644 platform/broadcom/sonic-platform-modules-mitac/debian/changelog create mode 100644 platform/broadcom/sonic-platform-modules-mitac/debian/compat create mode 100644 platform/broadcom/sonic-platform-modules-mitac/debian/control create mode 100755 platform/broadcom/sonic-platform-modules-mitac/debian/rules create mode 100644 platform/broadcom/sonic-platform-modules-mitac/debian/sonic-platform-mitac-ly1200-32x.init create mode 100644 platform/broadcom/sonic-platform-modules-mitac/debian/sonic-platform-mitac-ly1200-32x.upstart create mode 100755 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/etc/init.d/fan-ctrld create mode 100755 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/etc/init.d/gpe create mode 100755 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/etc/init.d/i2c_init create mode 100755 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/etc/init.d/sys_polld create mode 100755 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/etc/init.d/sys_servd create mode 100755 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/etc/init.d/xcvr_servd create mode 100644 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/bms_i2c.h create mode 100644 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/master_cpld_reg.h create mode 100644 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/master_cpld_sysfs.h create mode 100644 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_cb_i2c.c create mode 100644 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_fb_i2c.c create mode 100644 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_fb_module_i2c.c create mode 100644 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_fse000.c create mode 100644 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_gpe.c create mode 100644 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_master_cpld.c create mode 100644 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_pb_i2c.c create mode 100644 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_sb_i2c.c create mode 100644 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_slave_cpld.c create mode 100644 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_system_cpld.c create mode 100644 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/pmbus.h create mode 100644 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/slave_cpld_reg.h create mode 100644 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/slave_cpld_sysfs.h create mode 100644 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/system_cpld_reg.h create mode 100644 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/system_cpld_sysfs.h create mode 100755 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/fan-ctrl/fan-ctrl create mode 100644 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/fan-ctrl/fan-zone-thermal_B2F.conf create mode 100644 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/fan-ctrl/fan-zone-thermal_F2B.conf create mode 100644 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/fan-ctrl/fan-zone_B2F.conf create mode 100644 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/fan-ctrl/fan-zone_F2B.conf create mode 100755 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/fan-ctrl/funcs.sh create mode 100755 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/fan-ctrl/init.sh create mode 100755 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/script/funcs.sh create mode 100755 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/script/start_service.sh create mode 100755 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/script/start_watchdog.sh create mode 100755 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/sys-serv/sys-servd create mode 100755 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/system-check/system-check.sh create mode 100644 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/watchdog/watchdog.conf create mode 100755 platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/xcvr-serv/xcvr-servd delete mode 160000 platform/broadcom/sonic-platform-modules-quanta create mode 100755 platform/broadcom/sonic-platform-modules-quanta/.gitignore create mode 100755 platform/broadcom/sonic-platform-modules-quanta/LICENSE create mode 100644 platform/broadcom/sonic-platform-modules-quanta/README.md create mode 100755 platform/broadcom/sonic-platform-modules-quanta/debian/changelog create mode 100755 platform/broadcom/sonic-platform-modules-quanta/debian/compat create mode 100755 platform/broadcom/sonic-platform-modules-quanta/debian/control create mode 100755 platform/broadcom/sonic-platform-modules-quanta/debian/rules create mode 100755 platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/classes/__init__.py create mode 100755 platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/Makefile create mode 100755 platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/pmbus.h create mode 100755 platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_cpld_qsfp28.c create mode 100755 platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_platform.h create mode 100755 platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_platform_ix1b.c create mode 100755 platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_pmbus.c create mode 100755 platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/service/ix1b-platform-init.service create mode 100755 platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/setup.py create mode 100755 platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/utils/quanta_ix1b_util.py delete mode 160000 platform/broadcom/sonic-platform-modules-s6000 create mode 100644 platform/broadcom/sonic-platform-modules-s6000/LICENSE create mode 100644 platform/broadcom/sonic-platform-modules-s6000/MAINTAINERS create mode 100644 platform/broadcom/sonic-platform-modules-s6000/README.md create mode 100644 platform/broadcom/sonic-platform-modules-s6000/debian/changelog create mode 100644 platform/broadcom/sonic-platform-modules-s6000/debian/compat create mode 100644 platform/broadcom/sonic-platform-modules-s6000/debian/control create mode 100644 platform/broadcom/sonic-platform-modules-s6000/debian/copyright create mode 100755 platform/broadcom/sonic-platform-modules-s6000/debian/platform-modules-s6000.init create mode 100755 platform/broadcom/sonic-platform-modules-s6000/debian/rules create mode 100644 platform/broadcom/sonic-platform-modules-s6000/modules/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-s6000/modules/dell_s6000_platform.c create mode 100755 platform/broadcom/sonic-platform-modules-s6000/scripts/reset-qsfp create mode 100755 platform/broadcom/sonic-platform-modules-s6000/scripts/set-fan-speed delete mode 160000 platform/nephos/sonic-platform-modules-ingrasys create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/.gitignore create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/LICENSE create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/debian/changelog create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/debian/compat create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/debian/control create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/debian/rules create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9130-32x.dirs create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9130-32x.install create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9130-32x.links create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9130-32x.postinst create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9130-32x.postrm create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9130-32x.prerm create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9130-32x.upstart create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9230-64x.dirs create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9230-64x.install create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9230-64x.links create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9230-64x.postinst create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9230-64x.postrm create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9230-64x.prerm create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9230-64x.upstart create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/README.md create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/modules/Makefile create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/modules/eeprom_mb.c create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/modules/ingrasys_s9130_32x_platform.h create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/modules/ingrasys_s9130_32x_psu.c create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/service/qsfp-monitor.service create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/service/s9130-32x-monitor.service create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/i2c_utils.sh create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/qsfp_monitor.sh create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/s9130_32x_monitor.sh create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/README.md create mode 100755 platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/modules/Makefile create mode 100755 platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/modules/eeprom_mb.c create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/modules/ingrasys_s9230_64x_i2c_cpld.c create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/modules/ingrasys_s9230_64x_i2c_cpld.h create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/modules/ingrasys_s9230_64x_platform.h create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/modules/ingrasys_s9230_64x_psu.c create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/service/qsfp-monitor.service create mode 100644 platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/service/s9230-64x-monitor.service create mode 100755 platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/i2c_utils.sh create mode 100755 platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/qsfp_monitor.sh create mode 100755 platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/s9230_64x_monitor.sh diff --git a/.gitmodules b/.gitmodules index e0cfc0869d05..cbe82c215f7c 100755 --- a/.gitmodules +++ b/.gitmodules @@ -35,30 +35,12 @@ [submodule "src/sonic-utilities"] path = src/sonic-utilities url = https://github.com/Azure/sonic-utilities -[submodule "platform/broadcom/sonic-platform-modules-s6000"] - path = platform/broadcom/sonic-platform-modules-s6000 - url = https://github.com/Azure/sonic-platform-modules-s6000 -[submodule "platform/broadcom/sonic-platform-modules-arista"] - path = platform/broadcom/sonic-platform-modules-arista - url = https://github.com/aristanetworks/sonic -[submodule "platform/broadcom/sonic-platform-modules-dell"] - path = platform/broadcom/sonic-platform-modules-dell - url = https://github.com/Azure/sonic-platform-modules-dell -[submodule "platform/broadcom/sonic-platform-modules-ingrasys"] - path = platform/broadcom/sonic-platform-modules-ingrasys - url = https://github.com/Ingrasys-sonic/sonic-platform-modules-ingrasys [submodule "src/sonic-platform-common"] path = src/sonic-platform-common url = https://github.com/Azure/sonic-platform-common [submodule "src/sonic-platform-daemons"] path = src/sonic-platform-daemons url = https://github.com/Azure/sonic-platform-daemons -[submodule "platform/broadcom/sonic-platform-modules-accton"] - path = platform/broadcom/sonic-platform-modules-accton - url = https://github.com/edge-core/sonic-platform-modules-accton.git -[submodule "platform/broadcom/sonic-platform-modules-cel"] - path = platform/broadcom/sonic-platform-modules-cel - url = https://github.com/celestica-Inc/sonic-platform-modules-cel.git [submodule "src/sonic-frr/frr"] path = src/sonic-frr/frr url = https://github.com/FRRouting/frr.git @@ -68,12 +50,3 @@ [submodule "platform/p4/SAI-P4-BM"] path = platform/p4/SAI-P4-BM url = https://github.com/Mellanox/SAI-P4-BM.git -[submodule "platform/nephos/sonic-platform-modules-ingrasys"] - path = platform/nephos/sonic-platform-modules-ingrasys - url = https://github.com/Ingrasys-sonic/sonic-platform-modules-ingrasys-nephos.git -[submodule "platform/broadcom/sonic-platform-modules-quanta"] - path = platform/broadcom/sonic-platform-modules-quanta - url = https://github.com/QuantaSwitchONIE/sonic-platform-modules-quanta.git -[submodule "platform/broadcom/sonic-platform-modules-mitac"] - path = platform/broadcom/sonic-platform-modules-mitac - url = https://github.com/MiTAC-EBU/sonic-platform-modules-mitac.git diff --git a/platform/broadcom/sonic-platform-modules-accton b/platform/broadcom/sonic-platform-modules-accton deleted file mode 160000 index 406c4e675ea7..000000000000 --- a/platform/broadcom/sonic-platform-modules-accton +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 406c4e675ea73d52827b520958c9956551a94e8e diff --git a/platform/broadcom/sonic-platform-modules-accton/.gitignore b/platform/broadcom/sonic-platform-modules-accton/.gitignore new file mode 100644 index 000000000000..f805e810e5c6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/.gitignore @@ -0,0 +1,33 @@ +# Object files +*.o +*.ko +*.obj +*.elf + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su diff --git a/platform/broadcom/sonic-platform-modules-accton/LICENSE b/platform/broadcom/sonic-platform-modules-accton/LICENSE new file mode 100644 index 000000000000..bc693f7a4c40 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/LICENSE @@ -0,0 +1,16 @@ +Copyright (C) 2016 Microsoft, Inc +Copyright (C) 2017 Accton Technology Corporation + +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/broadcom/sonic-platform-modules-accton/README.md b/platform/broadcom/sonic-platform-modules-accton/README.md new file mode 100644 index 000000000000..0ff20bb2d21b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/README.md @@ -0,0 +1 @@ +platform drivers of Accton products for the SONiC project diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/classes/__init__.py b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/classes/__init__.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/classes/fanutil.py b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/classes/fanutil.py new file mode 100755 index 000000000000..c16771e214e4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/classes/fanutil.py @@ -0,0 +1,238 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 Accton Technology Corporation +# +# 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 3 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, see . + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 11/13/2017: Polly Hsu, Create +# +# ------------------------------------------------------------------ + +try: + import time + import logging + from collections import namedtuple +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + + +class FanUtil(object): + """Platform-specific FanUtil class""" + + FAN_NUM_ON_MAIN_BROAD = 5 + FAN_NUM_1_IDX = 1 + FAN_NUM_2_IDX = 2 + FAN_NUM_3_IDX = 3 + FAN_NUM_4_IDX = 4 + FAN_NUM_5_IDX = 5 + + FAN_NODE_NUM_OF_MAP = 6 + FAN_NODE_FAULT_IDX_OF_MAP = 1 + FAN_NODE_SPEED_IDX_OF_MAP = 2 + FAN_NODE_DIR_IDX_OF_MAP = 3 + FAN_NODE_DUTY_IDX_OF_MAP = 4 + FANR_NODE_FAULT_IDX_OF_MAP = 5 + FANR_NODE_SPEED_IDX_OF_MAP = 6 + + BASE_VAL_PATH = '/sys/devices/platform/as5712_54x_fan/{0}' + + #logfile = '' + #loglevel = logging.INFO + + """ Dictionary where + key1 = fan id index (integer) starting from 1 + key2 = fan node index (interger) starting from 1 + value = path to fan device file (string) """ + _fan_to_device_path_mapping = {} + + _fan_to_device_node_mapping = { + (FAN_NUM_1_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan1_fault', + (FAN_NUM_1_IDX, FAN_NODE_SPEED_IDX_OF_MAP): 'fan1_speed_rpm', + (FAN_NUM_1_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan1_direction', + (FAN_NUM_1_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan1_duty_cycle_percentage', + (FAN_NUM_1_IDX, FANR_NODE_FAULT_IDX_OF_MAP): 'fanr1_fault', + (FAN_NUM_1_IDX, FANR_NODE_SPEED_IDX_OF_MAP): 'fanr1_speed_rpm', + + (FAN_NUM_2_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan2_fault', + (FAN_NUM_2_IDX, FAN_NODE_SPEED_IDX_OF_MAP): 'fan2_speed_rpm', + (FAN_NUM_2_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan2_direction', + (FAN_NUM_2_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan2_duty_cycle_percentage', + (FAN_NUM_2_IDX, FANR_NODE_FAULT_IDX_OF_MAP): 'fanr2_fault', + (FAN_NUM_2_IDX, FANR_NODE_SPEED_IDX_OF_MAP): 'fanr2_speed_rpm', + + (FAN_NUM_3_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan3_fault', + (FAN_NUM_3_IDX, FAN_NODE_SPEED_IDX_OF_MAP): 'fan3_speed_rpm', + (FAN_NUM_3_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan3_direction', + (FAN_NUM_3_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan3_duty_cycle_percentage', + (FAN_NUM_3_IDX, FANR_NODE_FAULT_IDX_OF_MAP): 'fanr3_fault', + (FAN_NUM_3_IDX, FANR_NODE_SPEED_IDX_OF_MAP): 'fanr3_speed_rpm', + + (FAN_NUM_4_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan4_fault', + (FAN_NUM_4_IDX, FAN_NODE_SPEED_IDX_OF_MAP): 'fan4_speed_rpm', + (FAN_NUM_4_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan4_direction', + (FAN_NUM_4_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan4_duty_cycle_percentage', + (FAN_NUM_4_IDX, FANR_NODE_FAULT_IDX_OF_MAP): 'fanr4_fault', + (FAN_NUM_4_IDX, FANR_NODE_SPEED_IDX_OF_MAP): 'fanr4_speed_rpm', + + (FAN_NUM_5_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan5_fault', + (FAN_NUM_5_IDX, FAN_NODE_SPEED_IDX_OF_MAP): 'fan5_speed_rpm', + (FAN_NUM_5_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan5_direction', + (FAN_NUM_5_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan5_duty_cycle_percentage', + (FAN_NUM_5_IDX, FANR_NODE_FAULT_IDX_OF_MAP): 'fanr5_fault', + (FAN_NUM_5_IDX, FANR_NODE_SPEED_IDX_OF_MAP): 'fanr5_speed_rpm', + } + + def _get_fan_to_device_node(self, fan_num, node_num): + return self._fan_to_device_node_mapping[(fan_num, node_num)] + + def _get_fan_node_val(self, fan_num, node_num): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. fan_num:%d', fan_num) + return None + + if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP: + logging.debug('GET. Parameter error. node_num:%d', node_num) + return None + + device_path = self.get_fan_to_device_path(fan_num, node_num) + try: + val_file = open(device_path, 'r') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None + + content = val_file.readline().rstrip() + + if content == '': + logging.debug('GET. content is NULL. device_path:%s', device_path) + return None + + try: + val_file.close() + except: + logging.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return int(content) + + def _set_fan_node_val(self, fan_num, node_num, val): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. fan_num:%d', fan_num) + return None + + if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP: + logging.debug('GET. Parameter error. node_num:%d', node_num) + return None + + content = str(val) + if content == '': + logging.debug('GET. content is NULL. device_path:%s', device_path) + return None + + device_path = self.get_fan_to_device_path(fan_num, node_num) + try: + val_file = open(device_path, 'w') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None + + val_file.write(content) + + try: + val_file.close() + except: + logging.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return True + + def __init__(self): + fan_path = self.BASE_VAL_PATH + + for fan_num in range(self.FAN_NUM_1_IDX, self.FAN_NUM_ON_MAIN_BROAD+1): + for node_num in range(self.FAN_NODE_FAULT_IDX_OF_MAP, self.FAN_NODE_NUM_OF_MAP+1): + self._fan_to_device_path_mapping[(fan_num, node_num)] = fan_path.format( + self._fan_to_device_node_mapping[(fan_num, node_num)]) + + def get_num_fans(self): + return self.FAN_NUM_ON_MAIN_BROAD + + def get_idx_fan_start(self): + return self.FAN_NUM_1_IDX + + def get_num_nodes(self): + return self.FAN_NODE_NUM_OF_MAP + + def get_idx_node_start(self): + return self.FAN_NODE_FAULT_IDX_OF_MAP + + def get_size_node_map(self): + return len(self._fan_to_device_node_mapping) + + def get_size_path_map(self): + return len(self._fan_to_device_path_mapping) + + def get_fan_to_device_path(self, fan_num, node_num): + return self._fan_to_device_path_mapping[(fan_num, node_num)] + + def get_fan_fault(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_FAULT_IDX_OF_MAP) + + def get_fan_speed(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_SPEED_IDX_OF_MAP) + + def get_fan_dir(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_DIR_IDX_OF_MAP) + + def get_fan_duty_cycle(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_DUTY_IDX_OF_MAP) + + def set_fan_duty_cycle(self, fan_num, val): + return self._set_fan_node_val(fan_num, self.FAN_NODE_DUTY_IDX_OF_MAP, val) + + def get_fanr_fault(self, fan_num): + return self._get_fan_node_val(fan_num, self.FANR_NODE_FAULT_IDX_OF_MAP) + + def get_fanr_speed(self, fan_num): + return self._get_fan_node_val(fan_num, self.FANR_NODE_SPEED_IDX_OF_MAP) + + def get_fan_status(self, fan_num): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. fan_num, %d', fan_num) + return None + + if self.get_fan_fault(fan_num) is not None and self.get_fan_fault(fan_num) > 0: + logging.debug('GET. FAN fault. fan_num, %d', fan_num) + return False + + if self.get_fanr_fault(fan_num) is not None and self.get_fanr_fault(fan_num) > 0: + logging.debug('GET. FANR fault. fan_num, %d', fan_num) + return False + + return True + +#def main(): +# fan = FanUtil() +# +# print 'get_size_node_map : %d' % fan.get_size_node_map() +# print 'get_size_path_map : %d' % fan.get_size_path_map() +# for x in range(fan.get_idx_fan_start(), fan.get_num_fans()+1): +# for y in range(fan.get_idx_node_start(), fan.get_num_nodes()+1): +# print fan.get_fan_to_device_path(x, y) +# +#if __name__ == '__main__': +# main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/classes/thermalutil.py b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/classes/thermalutil.py new file mode 100755 index 000000000000..5b8f890e8819 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/classes/thermalutil.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 Accton Technology Corporation +# +# 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 3 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, see . + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 11/13/2017: Polly Hsu, Create +# +# ------------------------------------------------------------------ + +try: + import time + import logging + import glob + from collections import namedtuple +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + + +class ThermalUtil(object): + """Platform-specific ThermalUtil class""" + + THERMAL_NUM_ON_MAIN_BROAD = 3 + THERMAL_NUM_1_IDX = 1 # 1_ON_MAIN_BROAD + THERMAL_NUM_2_IDX = 2 # 2_ON_MAIN_BROAD + THERMAL_NUM_3_IDX = 3 # 3_ON_MAIN_BROAD + + BASE_VAL_PATH = '/sys/bus/i2c/devices/{0}-00{1}/hwmon/hwmon*/temp1_input' + + """ Dictionary where + key1 = thermal id index (integer) starting from 1 + value = path to fan device file (string) """ + _thermal_to_device_path_mapping = {} + + _thermal_to_device_node_mapping = { + THERMAL_NUM_1_IDX: ['61', '48'], + THERMAL_NUM_2_IDX: ['62', '49'], + THERMAL_NUM_3_IDX: ['63', '4a'], + } + + def __init__(self): + thermal_path = self.BASE_VAL_PATH + + for x in range(self.THERMAL_NUM_1_IDX, self.THERMAL_NUM_ON_MAIN_BROAD+1): + self._thermal_to_device_path_mapping[x] = thermal_path.format( + self._thermal_to_device_node_mapping[x][0], + self._thermal_to_device_node_mapping[x][1]) + + def _get_thermal_node_val(self, thermal_num): + if thermal_num < self.THERMAL_NUM_1_IDX or thermal_num > self.THERMAL_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. thermal_num, %d', thermal_num) + return None + + device_path = self.get_thermal_to_device_path(thermal_num) + for filename in glob.glob(device_path): + try: + val_file = open(filename, 'r') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None + + content = val_file.readline().rstrip() + + if content == '': + logging.debug('GET. content is NULL. device_path:%s', device_path) + return None + + try: + val_file.close() + except: + logging.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return int(content) + + + def get_num_thermals(self): + return self.THERMAL_NUM_ON_MAIN_BROAD + + def get_idx_thermal_start(self): + return self.THERMAL_NUM_1_IDX + + def get_size_node_map(self): + return len(self._thermal_to_device_node_mapping) + + def get_size_path_map(self): + return len(self._thermal_to_device_path_mapping) + + def get_thermal_to_device_path(self, thermal_num): + return self._thermal_to_device_path_mapping[thermal_num] + + def get_thermal_1_val(self): + return self._get_thermal_node_val(self.THERMAL_NUM_1_IDX) + + def get_thermal_2_val(self): + return self._get_thermal_node_val(self.THERMAL_NUM_2_IDX) + +#def main(): +# thermal = ThermalUtil() +# +# print 'get_size_node_map : %d' % thermal.get_size_node_map() +# print 'get_size_path_map : %d' % thermal.get_size_path_map() +# for x in range(thermal.get_idx_thermal_start(), thermal.get_num_thermals()+1): +# print thermal.get_thermal_to_device_path(x) +# +#if __name__ == '__main__': +# main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/Makefile b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/Makefile new file mode 100755 index 000000000000..39fe78bf8cae --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/Makefile @@ -0,0 +1,17 @@ +ifneq ($(KERNELRELEASE),) +obj-m:= i2c-mux-accton_as5712_54x_cpld.o \ + accton_as5712_54x_fan.o leds-accton_as5712_54x.o accton_as5712_54x_psu.o \ + cpr_4011_4mxx.o ym2651y.o + +else +ifeq (,$(KERNEL_SRC)) +$(error KERNEL_SRC is not defined) +else +KERNELDIR:=$(KERNEL_SRC) +endif +PWD:=$(shell pwd) +default: + $(MAKE) -C $(KERNELDIR) M=$(PWD) modules +clean: + rm -rf *.o *.mod.o *.mod.o *.ko .*cmd .tmp_versions Module.markers Module.symvers modules.order +endif diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/accton_as5712_54x_fan.c b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/accton_as5712_54x_fan.c new file mode 100755 index 000000000000..db81a1a8ca97 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/accton_as5712_54x_fan.c @@ -0,0 +1,437 @@ +/* + * A hwmon driver for the Accton as5710 54x fan contrl + * + * Copyright (C) 2013 Accton Technology Corporation. + * Brandon Chuang + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define FAN_MAX_NUMBER 5 +#define FAN_SPEED_CPLD_TO_RPM_STEP 150 +#define FAN_SPEED_PRECENT_TO_CPLD_STEP 5 +#define FAN_DUTY_CYCLE_MIN 0 /* 10% ??*/ +#define FAN_DUTY_CYCLE_MAX 100 /* 100% */ + +#define CPLD_REG_FAN_STATUS_OFFSET 0xC +#define CPLD_REG_FANR_STATUS_OFFSET 0x1F +#define CPLD_REG_FAN_DIRECTION_OFFSET 0x1E + +#define CPLD_FAN1_REG_SPEED_OFFSET 0x10 +#define CPLD_FAN2_REG_SPEED_OFFSET 0x11 +#define CPLD_FAN3_REG_SPEED_OFFSET 0x12 +#define CPLD_FAN4_REG_SPEED_OFFSET 0x13 +#define CPLD_FAN5_REG_SPEED_OFFSET 0x14 + +#define CPLD_FANR1_REG_SPEED_OFFSET 0x18 +#define CPLD_FANR2_REG_SPEED_OFFSET 0x19 +#define CPLD_FANR3_REG_SPEED_OFFSET 0x1A +#define CPLD_FANR4_REG_SPEED_OFFSET 0x1B +#define CPLD_FANR5_REG_SPEED_OFFSET 0x1C + +#define CPLD_REG_FAN_PWM_CYCLE_OFFSET 0xD + +#define CPLD_FAN1_INFO_BIT_MASK 0x1 +#define CPLD_FAN2_INFO_BIT_MASK 0x2 +#define CPLD_FAN3_INFO_BIT_MASK 0x4 +#define CPLD_FAN4_INFO_BIT_MASK 0x8 +#define CPLD_FAN5_INFO_BIT_MASK 0x10 + +#define PROJECT_NAME + +#define LOCAL_DEBUG 0 + +static struct accton_as5712_54x_fan *fan_data = NULL; + +struct accton_as5712_54x_fan { + struct platform_device *pdev; + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 status[FAN_MAX_NUMBER]; /* inner first fan status */ + u32 speed[FAN_MAX_NUMBER]; /* inner first fan speed */ + u8 direction[FAN_MAX_NUMBER]; /* reconrd the direction of inner first and second fans */ + u32 duty_cycle[FAN_MAX_NUMBER]; /* control the speed of inner first and second fans */ + u8 r_status[FAN_MAX_NUMBER]; /* inner second fan status */ + u32 r_speed[FAN_MAX_NUMBER]; /* inner second fan speed */ +}; + +/*******************/ +#define MAKE_FAN_MASK_OR_REG(name,type) \ + CPLD_FAN##type##1_##name, \ + CPLD_FAN##type##2_##name, \ + CPLD_FAN##type##3_##name, \ + CPLD_FAN##type##4_##name, \ + CPLD_FAN##type##5_##name, + +/* fan related data + */ +static const u8 fan_info_mask[] = { + MAKE_FAN_MASK_OR_REG(INFO_BIT_MASK,) +}; + +static const u8 fan_speed_reg[] = { + MAKE_FAN_MASK_OR_REG(REG_SPEED_OFFSET,) +}; + +static const u8 fanr_speed_reg[] = { + MAKE_FAN_MASK_OR_REG(REG_SPEED_OFFSET,R) +}; + +/*******************/ +#define DEF_FAN_SET(id) \ + FAN##id##_FAULT, \ + FAN##id##_SPEED, \ + FAN##id##_DUTY_CYCLE, \ + FAN##id##_DIRECTION, \ + FANR##id##_FAULT, \ + FANR##id##_SPEED, + +enum sysfs_fan_attributes { + DEF_FAN_SET(1) + DEF_FAN_SET(2) + DEF_FAN_SET(3) + DEF_FAN_SET(4) + DEF_FAN_SET(5) +}; +/*******************/ +static void accton_as5712_54x_fan_update_device(struct device *dev); +static int accton_as5712_54x_fan_read_value(u8 reg); +static int accton_as5712_54x_fan_write_value(u8 reg, u8 value); + +static ssize_t fan_set_duty_cycle(struct device *dev, + struct device_attribute *da,const char *buf, size_t count); +static ssize_t fan_show_value(struct device *dev, + struct device_attribute *da, char *buf); + +extern int as5712_54x_cpld_read(unsigned short cpld_addr, u8 reg); +extern int as5712_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + + +/*******************/ +#define _MAKE_SENSOR_DEVICE_ATTR(prj, id) \ + static SENSOR_DEVICE_ATTR(prj##fan##id##_fault, S_IRUGO, fan_show_value, NULL, FAN##id##_FAULT); \ + static SENSOR_DEVICE_ATTR(prj##fan##id##_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##id##_SPEED); \ + static SENSOR_DEVICE_ATTR(prj##fan##id##_duty_cycle_percentage, S_IWUSR | S_IRUGO, fan_show_value, \ + fan_set_duty_cycle, FAN##id##_DUTY_CYCLE); \ + static SENSOR_DEVICE_ATTR(prj##fan##id##_direction, S_IRUGO, fan_show_value, NULL, FAN##id##_DIRECTION); \ + static SENSOR_DEVICE_ATTR(prj##fanr##id##_fault, S_IRUGO, fan_show_value, NULL, FANR##id##_FAULT); \ + static SENSOR_DEVICE_ATTR(prj##fanr##id##_speed_rpm, S_IRUGO, fan_show_value, NULL, FANR##id##_SPEED); + +#define MAKE_SENSOR_DEVICE_ATTR(prj,id) _MAKE_SENSOR_DEVICE_ATTR(prj,id) + +MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 1) +MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 2) +MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 3) +MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 4) +MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 5) +/*******************/ + +#define _MAKE_FAN_ATTR(prj, id) \ + &sensor_dev_attr_##prj##fan##id##_fault.dev_attr.attr, \ + &sensor_dev_attr_##prj##fan##id##_speed_rpm.dev_attr.attr, \ + &sensor_dev_attr_##prj##fan##id##_duty_cycle_percentage.dev_attr.attr,\ + &sensor_dev_attr_##prj##fan##id##_direction.dev_attr.attr, \ + &sensor_dev_attr_##prj##fanr##id##_fault.dev_attr.attr, \ + &sensor_dev_attr_##prj##fanr##id##_speed_rpm.dev_attr.attr, + +#define MAKE_FAN_ATTR(prj, id) _MAKE_FAN_ATTR(prj, id) + +static struct attribute *accton_as5712_54x_fan_attributes[] = { + /* fan related attributes */ + MAKE_FAN_ATTR(PROJECT_NAME,1) + MAKE_FAN_ATTR(PROJECT_NAME,2) + MAKE_FAN_ATTR(PROJECT_NAME,3) + MAKE_FAN_ATTR(PROJECT_NAME,4) + MAKE_FAN_ATTR(PROJECT_NAME,5) + NULL +}; +/*******************/ + +/* fan related functions + */ +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + ssize_t ret = 0; + int data_index, type_index; + + accton_as5712_54x_fan_update_device(dev); + + if (fan_data->valid == 0) { + return ret; + } + + type_index = attr->index%FAN2_FAULT; + data_index = attr->index/FAN2_FAULT; + + switch (type_index) { + case FAN1_FAULT: + ret = sprintf(buf, "%d\n", fan_data->status[data_index]); + if (LOCAL_DEBUG) + printk ("[Check !!][%s][%d][type->index=%d][data->index=%d]\n", __FUNCTION__, __LINE__, type_index, data_index); + break; + case FAN1_SPEED: + ret = sprintf(buf, "%d\n", fan_data->speed[data_index]); + if (LOCAL_DEBUG) + printk ("[Check !!][%s][%d][type->index=%d][data->index=%d]\n", __FUNCTION__, __LINE__, type_index, data_index); + break; + case FAN1_DUTY_CYCLE: + ret = sprintf(buf, "%d\n", fan_data->duty_cycle[data_index]); + if (LOCAL_DEBUG) + printk ("[Check !!][%s][%d][type->index=%d][data->index=%d]\n", __FUNCTION__, __LINE__, type_index, data_index); + break; + case FAN1_DIRECTION: + ret = sprintf(buf, "%d\n", fan_data->direction[data_index]); /* presnet, need to modify*/ + if (LOCAL_DEBUG) + printk ("[Check !!][%s][%d][type->index=%d][data->index=%d]\n", __FUNCTION__, __LINE__, type_index, data_index); + break; + case FANR1_FAULT: + ret = sprintf(buf, "%d\n", fan_data->r_status[data_index]); + if (LOCAL_DEBUG) + printk ("[Check !!][%s][%d][type->index=%d][data->index=%d]\n", __FUNCTION__, __LINE__, type_index, data_index); + break; + case FANR1_SPEED: + ret = sprintf(buf, "%d\n", fan_data->r_speed[data_index]); + if (LOCAL_DEBUG) + printk ("[Check !!][%s][%d][type->index=%d][data->index=%d]\n", __FUNCTION__, __LINE__, type_index, data_index); + break; + default: + if (LOCAL_DEBUG) + printk ("[Check !!][%s][%d] \n", __FUNCTION__, __LINE__); + break; + } + + return ret; +} +/*******************/ +static ssize_t fan_set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) { + + int error, value; + + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (value < FAN_DUTY_CYCLE_MIN || value > FAN_DUTY_CYCLE_MAX) + return -EINVAL; + + accton_as5712_54x_fan_write_value(CPLD_REG_FAN_PWM_CYCLE_OFFSET, value/FAN_SPEED_PRECENT_TO_CPLD_STEP); + + fan_data->valid = 0; + + return count; +} + +static const struct attribute_group accton_as5712_54x_fan_group = { + .attrs = accton_as5712_54x_fan_attributes, +}; + +static int accton_as5712_54x_fan_read_value(u8 reg) +{ + return as5712_54x_cpld_read(0x60, reg); +} + +static int accton_as5712_54x_fan_write_value(u8 reg, u8 value) +{ + return as5712_54x_cpld_write(0x60, reg, value); +} + +static void accton_as5712_54x_fan_update_device(struct device *dev) +{ + int speed, r_speed, fault, r_fault, ctrl_speed, direction; + int i; + + mutex_lock(&fan_data->update_lock); + + if (LOCAL_DEBUG) + printk ("Starting accton_as5712_54x_fan update \n"); + + if (!(time_after(jiffies, fan_data->last_updated + HZ + HZ / 2) || !fan_data->valid)) { + /* do nothing */ + goto _exit; + } + + fan_data->valid = 0; + + if (LOCAL_DEBUG) + printk ("Starting accton_as5712_54x_fan update 2 \n"); + + fault = accton_as5712_54x_fan_read_value(CPLD_REG_FAN_STATUS_OFFSET); + r_fault = accton_as5712_54x_fan_read_value(CPLD_REG_FANR_STATUS_OFFSET); + direction = accton_as5712_54x_fan_read_value(CPLD_REG_FAN_DIRECTION_OFFSET); + ctrl_speed = accton_as5712_54x_fan_read_value(CPLD_REG_FAN_PWM_CYCLE_OFFSET); + + if ( (fault < 0) || (r_fault < 0) || (direction < 0) || (ctrl_speed < 0) ) + { + if (LOCAL_DEBUG) + printk ("[Error!!][%s][%d] \n", __FUNCTION__, __LINE__); + goto _exit; /* error */ + } + + if (LOCAL_DEBUG) + printk ("[fan:] fault:%d, r_fault=%d, direction=%d, ctrl_speed=%d \n",fault, r_fault, direction, ctrl_speed); + + for (i=0; istatus[i] = (fault & fan_info_mask[i]) >> i; + if (LOCAL_DEBUG) + printk ("[fan%d:] fail=%d \n",i, fan_data->status[i]); + + fan_data->r_status[i] = (r_fault & fan_info_mask[i]) >> i; + fan_data->direction[i] = (direction & fan_info_mask[i]) >> i; + fan_data->duty_cycle[i] = ctrl_speed * FAN_SPEED_PRECENT_TO_CPLD_STEP; + + /* fan speed + */ + speed = accton_as5712_54x_fan_read_value(fan_speed_reg[i]); + r_speed = accton_as5712_54x_fan_read_value(fanr_speed_reg[i]); + if ( (speed < 0) || (r_speed < 0) ) + { + if (LOCAL_DEBUG) + printk ("[Error!!][%s][%d] \n", __FUNCTION__, __LINE__); + goto _exit; /* error */ + } + + if (LOCAL_DEBUG) + printk ("[fan%d:] speed:%d, r_speed=%d \n", i, speed, r_speed); + + fan_data->speed[i] = speed * FAN_SPEED_CPLD_TO_RPM_STEP; + fan_data->r_speed[i] = r_speed * FAN_SPEED_CPLD_TO_RPM_STEP; + } + + /* finish to update */ + fan_data->last_updated = jiffies; + fan_data->valid = 1; + +_exit: + mutex_unlock(&fan_data->update_lock); +} + +static int accton_as5712_54x_fan_probe(struct platform_device *pdev) +{ + int status = -1; + + /* Register sysfs hooks */ + status = sysfs_create_group(&pdev->dev.kobj, &accton_as5712_54x_fan_group); + if (status) { + goto exit; + + } + + fan_data->hwmon_dev = hwmon_device_register(&pdev->dev); + if (IS_ERR(fan_data->hwmon_dev)) { + status = PTR_ERR(fan_data->hwmon_dev); + goto exit_remove; + } + + dev_info(&pdev->dev, "accton_as5712_54x_fan\n"); + + return 0; + +exit_remove: + sysfs_remove_group(&pdev->dev.kobj, &accton_as5712_54x_fan_group); +exit: + return status; +} + +static int accton_as5712_54x_fan_remove(struct platform_device *pdev) +{ + hwmon_device_unregister(fan_data->hwmon_dev); + sysfs_remove_group(&fan_data->pdev->dev.kobj, &accton_as5712_54x_fan_group); + + return 0; +} + +#define DRVNAME "as5712_54x_fan" + +static struct platform_driver accton_as5712_54x_fan_driver = { + .probe = accton_as5712_54x_fan_probe, + .remove = accton_as5712_54x_fan_remove, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +static int __init accton_as5712_54x_fan_init(void) +{ + int ret; + + ret = platform_driver_register(&accton_as5712_54x_fan_driver); + if (ret < 0) { + goto exit; + } + + fan_data = kzalloc(sizeof(struct accton_as5712_54x_fan), GFP_KERNEL); + if (!fan_data) { + ret = -ENOMEM; + platform_driver_unregister(&accton_as5712_54x_fan_driver); + goto exit; + } + + mutex_init(&fan_data->update_lock); + fan_data->valid = 0; + + fan_data->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(fan_data->pdev)) { + ret = PTR_ERR(fan_data->pdev); + platform_driver_unregister(&accton_as5712_54x_fan_driver); + kfree(fan_data); + goto exit; + } + +exit: + return ret; +} + +static void __exit accton_as5712_54x_fan_exit(void) +{ + platform_device_unregister(fan_data->pdev); + platform_driver_unregister(&accton_as5712_54x_fan_driver); + kfree(fan_data); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton_as5712_54x_fan driver"); +MODULE_LICENSE("GPL"); + +module_init(accton_as5712_54x_fan_init); +module_exit(accton_as5712_54x_fan_exit); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/accton_as5712_54x_psu.c b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/accton_as5712_54x_psu.c new file mode 100755 index 000000000000..9a0d1dae58ba --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/accton_as5712_54x_psu.c @@ -0,0 +1,371 @@ +/* + * An hwmon driver for accton as5712_54x Power Module + * + * Copyright (C) 2015 Accton Technology Corporation. + * Copyright (C) Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#if 0 +#define DEBUG +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define PSU_STATUS_I2C_ADDR 0x60 +#define PSU_STATUS_I2C_REG_OFFSET 0x2 + +#define IS_POWER_GOOD(id, value) (!!(value & BIT(id*4 + 1))) +#define IS_PRESENT(id, value) (!(value & BIT(id*4))) + +static ssize_t show_index(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_model_name(struct device *dev, struct device_attribute *da, char *buf); +static int as5712_54x_psu_read_block(struct i2c_client *client, u8 command, u8 *data,int data_len); +extern int as5712_54x_cpld_read(unsigned short cpld_addr, u8 reg); +static int as5712_54x_psu_model_name_get(struct device *dev); + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +/* Each client has this additional data + */ +struct as5712_54x_psu_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 index; /* PSU index */ + u8 status; /* Status(present/power_good) register read from CPLD */ + char model_name[14]; /* Model name, read from eeprom */ +}; + +static struct as5712_54x_psu_data *as5712_54x_psu_update_device(struct device *dev); + +enum as5712_54x_psu_sysfs_attributes { + PSU_INDEX, + PSU_PRESENT, + PSU_MODEL_NAME, + PSU_POWER_GOOD +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(psu_index, S_IRUGO, show_index, NULL, PSU_INDEX); +static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, show_status, NULL, PSU_PRESENT); +static SENSOR_DEVICE_ATTR(psu_model_name, S_IRUGO, show_model_name,NULL, PSU_MODEL_NAME); +static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_status, NULL, PSU_POWER_GOOD); + +static struct attribute *as5712_54x_psu_attributes[] = { + &sensor_dev_attr_psu_index.dev_attr.attr, + &sensor_dev_attr_psu_present.dev_attr.attr, + &sensor_dev_attr_psu_model_name.dev_attr.attr, + &sensor_dev_attr_psu_power_good.dev_attr.attr, + NULL +}; + +static ssize_t show_index(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as5712_54x_psu_data *data = i2c_get_clientdata(client); + + return sprintf(buf, "%d\n", data->index); +} + +static ssize_t show_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct as5712_54x_psu_data *data = as5712_54x_psu_update_device(dev); + u8 status = 0; + + if (!data->valid) { + return sprintf(buf, "0\n"); + } + + if (attr->index == PSU_PRESENT) { + status = IS_PRESENT(data->index, data->status); + } + else { /* PSU_POWER_GOOD */ + status = IS_POWER_GOOD(data->index, data->status); + } + + return sprintf(buf, "%d\n", status); +} + +static ssize_t show_model_name(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct as5712_54x_psu_data *data = as5712_54x_psu_update_device(dev); + + if (!data->valid) { + return 0; + } + + if (!IS_PRESENT(data->index, data->status)) { + return 0; + } + + if (as5712_54x_psu_model_name_get(dev) < 0) { + return -ENXIO; + } + + return sprintf(buf, "%s\n", data->model_name); +} + +static const struct attribute_group as5712_54x_psu_group = { + .attrs = as5712_54x_psu_attributes, +}; + +static int as5712_54x_psu_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct as5712_54x_psu_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct as5712_54x_psu_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + data->index = dev_id->driver_data; + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as5712_54x_psu_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as5712_54x_psu_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as5712_54x_psu_remove(struct i2c_client *client) +{ + struct as5712_54x_psu_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as5712_54x_psu_group); + kfree(data); + + return 0; +} + +enum psu_index +{ + as5712_54x_psu1, + as5712_54x_psu2 +}; + +static const struct i2c_device_id as5712_54x_psu_id[] = { + { "as5712_54x_psu1", as5712_54x_psu1 }, + { "as5712_54x_psu2", as5712_54x_psu2 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, as5712_54x_psu_id); + +static struct i2c_driver as5712_54x_psu_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "as5712_54x_psu", + }, + .probe = as5712_54x_psu_probe, + .remove = as5712_54x_psu_remove, + .id_table = as5712_54x_psu_id, + .address_list = normal_i2c, +}; + +static int as5712_54x_psu_read_block(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ + int result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + + if (unlikely(result < 0)) + goto abort; + if (unlikely(result != data_len)) { + result = -EIO; + goto abort; + } + + result = 0; + +abort: + return result; +} + +enum psu_type { + PSU_YM_2401_JCR, /* AC110V - F2B */ + PSU_YM_2401_JDR, /* AC110V - B2F */ + PSU_CPR_4011_4M11, /* AC110V - F2B */ + PSU_CPR_4011_4M21, /* AC110V - B2F */ + PSU_CPR_6011_2M11, /* AC110V - F2B */ + PSU_CPR_6011_2M21, /* AC110V - B2F */ + PSU_UM400D_01G, /* DC48V - F2B */ + PSU_UM400D01_01G /* DC48V - B2F */ +}; + +struct model_name_info { + enum psu_type type; + u8 offset; + u8 length; + char* model_name; +}; + +struct model_name_info models[] = { +{PSU_YM_2401_JCR, 0x20, 11, "YM-2401JCR"}, +{PSU_YM_2401_JDR, 0x20, 11, "YM-2401JDR"}, +{PSU_CPR_4011_4M11, 0x26, 13, "CPR-4011-4M11"}, +{PSU_CPR_4011_4M21, 0x26, 13, "CPR-4011-4M21"}, +{PSU_CPR_6011_2M11, 0x26, 13, "CPR-6011-2M11"}, +{PSU_CPR_6011_2M21, 0x26, 13, "CPR-6011-2M21"}, +{PSU_UM400D_01G, 0x50, 9, "um400d01G"}, +{PSU_UM400D01_01G, 0x50, 12, "um400d01-01G"}, +}; + +static int as5712_54x_psu_model_name_get(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as5712_54x_psu_data *data = i2c_get_clientdata(client); + int i, status; + + for (i = 0; i < ARRAY_SIZE(models); i++) { + memset(data->model_name, 0, sizeof(data->model_name)); + + status = as5712_54x_psu_read_block(client, models[i].offset, + data->model_name, models[i].length); + if (status < 0) { + data->model_name[0] = '\0'; + dev_dbg(&client->dev, "unable to read model name from (0x%x) offset(0x%x)\n", + client->addr, models[i].offset); + return status; + } + else { + data->model_name[models[i].length] = '\0'; + } + + if (i == PSU_YM_2401_JCR || i == PSU_YM_2401_JDR) { + /* Skip the meaningless data byte 8*/ + data->model_name[8] = data->model_name[9]; + data->model_name[9] = data->model_name[10]; + data->model_name[10] = '\0'; + } + + /* Determine if the model name is known, if not, read next index + */ + if (strncmp(data->model_name, models[i].model_name, models[i].length) == 0) { + return 0; + } + else { + data->model_name[0] = '\0'; + } + } + + return -ENODATA; +} + +static struct as5712_54x_psu_data *as5712_54x_psu_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as5712_54x_psu_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int status = -1; + + dev_dbg(&client->dev, "Starting as5712_54x update\n"); + data->valid = 0; + + + /* Read psu status */ + status = as5712_54x_cpld_read(PSU_STATUS_I2C_ADDR, PSU_STATUS_I2C_REG_OFFSET); + + if (status < 0) { + dev_dbg(&client->dev, "cpld reg (0x%x) err %d\n", PSU_STATUS_I2C_ADDR, status); + goto exit; + } + else { + data->status = status; + } + + data->last_updated = jiffies; + data->valid = 1; + } + +exit: + mutex_unlock(&data->update_lock); + + return data; +} + +static int __init as5712_54x_psu_init(void) +{ + return i2c_add_driver(&as5712_54x_psu_driver); +} + +static void __exit as5712_54x_psu_exit(void) +{ + i2c_del_driver(&as5712_54x_psu_driver); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton as5712_54x_psu driver"); +MODULE_LICENSE("GPL"); + +module_init(as5712_54x_psu_init); +module_exit(as5712_54x_psu_exit); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/accton_as5712_54x_sfp.c b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/accton_as5712_54x_sfp.c new file mode 100755 index 000000000000..d236057c4e59 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/accton_as5712_54x_sfp.c @@ -0,0 +1,825 @@ +/* + * An hwmon driver for accton as5712_54x sfp + * + * Copyright (C) Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#if 0 +#define DEBUG +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NUM_OF_SFF_PORT 54 +#define SFP_PORT_MAX 48 +#define I2C_ADDR_CPLD1 0x60 +#define I2C_ADDR_CPLD2 0x61 +#define I2C_ADDR_CPLD3 0x62 +#define CPLD3_OFFSET_QSFP_MOD_RST 0x15 +#define CPLD3_OFFSET_QSFP_LPMODE 0x16 + + +#define BIT_INDEX(i) (1ULL << (i)) + +#if 0 +static ssize_t show_status(struct device *dev, struct device_attribute *da,char *buf); +static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_eeprom(struct device *dev, struct device_attribute *da, char *buf); +static int as5712_54x_sfp_read_block(struct i2c_client *client, u8 command, u8 *data,int data_len); +extern int as5712_54x_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int as5712_54x_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); +#endif + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { 0x50, I2C_CLIENT_END }; + +/* Each client has this additional data + */ +struct as5712_54x_sfp_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + int port; /* Front port index */ + char eeprom[256]; /* eeprom data */ + u64 status[4]; /* bit0:port0, bit1:port1 and so on */ + /* index 0 => is_present + 1 => tx_fail + 2 => tx_disable + 3 => rx_loss */ +}; + +/* The table maps active port to cpld port. + * Array index 0 is for active port 1, + * index 1 for active port 2, and so on. + * The array content implies cpld port index. + */ +static const u8 cpld_to_front_port_table[] = +{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 52, 50, 53, 51, 54}; + +#define CPLD_PORT_TO_FRONT_PORT(port) (cpld_to_front_port_table[port]) + +static struct as5712_54x_sfp_data *as5712_54x_sfp_update_device(struct device *dev, int update_eeprom); +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_eeprom(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t get_lp_mode(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t set_lp_mode(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t get_mode_reset(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t set_mode_reset(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +extern int as5712_54x_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int as5712_54x_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +enum as5712_54x_sfp_sysfs_attributes { + SFP_IS_PRESENT, + SFP_TX_FAULT, + SFP_TX_DISABLE, + SFP_RX_LOSS, + SFP_PORT_NUMBER, + SFP_EEPROM, + SFP_RX_LOS_ALL, + SFP_IS_PRESENT_ALL, + SFP_LP_MODE, + SFP_MOD_RST, +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(sfp_is_present, S_IRUGO, show_status, NULL, SFP_IS_PRESENT); +static SENSOR_DEVICE_ATTR(sfp_tx_fault, S_IRUGO, show_status, NULL, SFP_TX_FAULT); +static SENSOR_DEVICE_ATTR(sfp_tx_disable, S_IWUSR | S_IRUGO, show_status, set_tx_disable, SFP_TX_DISABLE); +static SENSOR_DEVICE_ATTR(sfp_rx_loss, S_IRUGO, show_status,NULL, SFP_RX_LOSS); +static SENSOR_DEVICE_ATTR(sfp_port_number, S_IRUGO, show_port_number, NULL, SFP_PORT_NUMBER); +static SENSOR_DEVICE_ATTR(sfp_eeprom, S_IRUGO, show_eeprom, NULL, SFP_EEPROM); +static SENSOR_DEVICE_ATTR(sfp_rx_los_all, S_IRUGO, show_status,NULL, SFP_RX_LOS_ALL); +static SENSOR_DEVICE_ATTR(sfp_is_present_all, S_IRUGO, show_status,NULL, SFP_IS_PRESENT_ALL); +static SENSOR_DEVICE_ATTR(sfp_lp_mode, S_IWUSR | S_IRUGO, get_lp_mode, set_lp_mode, SFP_LP_MODE); +static SENSOR_DEVICE_ATTR(sfp_mod_rst, S_IWUSR | S_IRUGO, get_mode_reset, set_mode_reset, SFP_MOD_RST); + +static struct attribute *as5712_54x_sfp_attributes[] = { + &sensor_dev_attr_sfp_is_present.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault.dev_attr.attr, + &sensor_dev_attr_sfp_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp_eeprom.dev_attr.attr, + &sensor_dev_attr_sfp_port_number.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los_all.dev_attr.attr, + &sensor_dev_attr_sfp_is_present_all.dev_attr.attr, + &sensor_dev_attr_sfp_lp_mode.dev_attr.attr, + &sensor_dev_attr_sfp_mod_rst.dev_attr.attr, + NULL +}; + +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as5712_54x_sfp_data *data = i2c_get_clientdata(client); + + return sprintf(buf, "%d\n", CPLD_PORT_TO_FRONT_PORT(data->port)); +} + +static ssize_t show_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct as5712_54x_sfp_data *data; + u8 val; + int values[7]; + + /* Error-check the CPLD read results. */ +#define VALIDATED_READ(_buf, _rv, _read_expr, _invert) \ + do { \ + _rv = (_read_expr); \ + if(_rv < 0) { \ + return sprintf(_buf, "READ ERROR\n"); \ + } \ + if(_invert) { \ + _rv = ~_rv; \ + } \ + _rv &= 0xFF; \ + } while(0) + + if(attr->index == SFP_RX_LOS_ALL) { + /* + * Report the RX_LOS status for all ports. + * This does not depend on the currently active SFP selector. + */ + + /* RX_LOS Ports 1-8 */ + VALIDATED_READ(buf, values[0], as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD2, 0x0F), 0); + /* RX_LOS Ports 9-16 */ + VALIDATED_READ(buf, values[1], as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD2, 0x10), 0); + /* RX_LOS Ports 17-24 */ + VALIDATED_READ(buf, values[2], as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD2, 0x11), 0); + /* RX_LOS Ports 25-32 */ + VALIDATED_READ(buf, values[3], as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD3, 0x0F), 0); + /* RX_LOS Ports 33-40 */ + VALIDATED_READ(buf, values[4], as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD3, 0x10), 0); + /* RX_LOS Ports 41-48 */ + VALIDATED_READ(buf, values[5], as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD3, 0x11), 0); + + /** Return values 1 -> 48 in order */ + return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], + values[3], values[4], values[5]); + } + + if(attr->index == SFP_IS_PRESENT_ALL) { + /* + * Report the SFP_PRESENCE status for all ports. + * This does not depend on the currently active SFP selector. + */ + + /* SFP_PRESENT Ports 1-8 */ + VALIDATED_READ(buf, values[0], as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD2, 0x6), 1); + /* SFP_PRESENT Ports 9-16 */ + VALIDATED_READ(buf, values[1], as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD2, 0x7), 1); + /* SFP_PRESENT Ports 17-24 */ + VALIDATED_READ(buf, values[2], as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD2, 0x8), 1); + /* SFP_PRESENT Ports 25-32 */ + VALIDATED_READ(buf, values[3], as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD3, 0x6), 1); + /* SFP_PRESENT Ports 33-40 */ + VALIDATED_READ(buf, values[4], as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD3, 0x7), 1); + /* SFP_PRESENT Ports 41-48 */ + VALIDATED_READ(buf, values[5], as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD3, 0x8), 1); + /* QSFP_PRESENT Ports 49-54 */ + VALIDATED_READ(buf, values[6], as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD3, 0x14), 1); + + /* Return values 1 -> 54 in order */ + return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], + values[3], values[4], values[5], + values[6] & 0x3F); + } + /* + * The remaining attributes are gathered on a per-selected-sfp basis. + */ + data = as5712_54x_sfp_update_device(dev, 0); + if (attr->index == SFP_IS_PRESENT) { + val = (data->status[attr->index] & BIT_INDEX(data->port)) ? 0 : 1; + } + else { + val = (data->status[attr->index] & BIT_INDEX(data->port)) ? 1 : 0; + } + + return sprintf(buf, "%d", val); +} + +static ssize_t get_lp_mode(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as5712_54x_sfp_data *data = i2c_get_clientdata(client); + u8 cpld_val = 0; + int port_bit; + int status = -EINVAL; + + /* Low power mode is not supported for SFP ports(1-48) */ + if (data->port < SFP_PORT_MAX) { + return -EINVAL; + } + mutex_lock(&data->update_lock); + + port_bit = data->port - SFP_PORT_MAX; + cpld_val = as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD3, CPLD3_OFFSET_QSFP_LPMODE); + cpld_val = cpld_val & 0x3F; + cpld_val = cpld_val & BIT_INDEX(port_bit); + status = snprintf(buf, PAGE_SIZE - 1, "%d\r\n", cpld_val>>port_bit); + + mutex_unlock(&data->update_lock); + + return status; +} + +static ssize_t set_lp_mode(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as5712_54x_sfp_data *data = i2c_get_clientdata(client); + u8 cpld_val = 0; + long mode; + int error, port_bit; + + /* Tx disable is not supported for QSFP ports(49-54) */ + if (data->port < SFP_PORT_MAX) { + return -EINVAL; + } + port_bit = data->port - SFP_PORT_MAX; + error = kstrtol(buf, 10, &mode); + if (error) { + return error; + } + mutex_lock(&data->update_lock); + + cpld_val = as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD3, CPLD3_OFFSET_QSFP_LPMODE); + /* Update lp_mode status */ + if (mode) + { + cpld_val |= BIT_INDEX(port_bit); + } + else + { + cpld_val &=~BIT_INDEX(port_bit); + } + as5712_54x_i2c_cpld_write(I2C_ADDR_CPLD3, CPLD3_OFFSET_QSFP_LPMODE, cpld_val); + + mutex_unlock(&data->update_lock); + + return count; +} + + +static ssize_t get_mode_reset(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as5712_54x_sfp_data *data = i2c_get_clientdata(client); + u8 cpld_val = 0; + int port_bit; + int status = -EINVAL; + + /* Low power mode is not supported for SFP ports(1-48) */ + if (data->port < SFP_PORT_MAX) { + return -EINVAL; + } + mutex_lock(&data->update_lock); + + port_bit = data->port - SFP_PORT_MAX; + cpld_val = as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD3, CPLD3_OFFSET_QSFP_MOD_RST); + cpld_val = cpld_val & 0x3F; + cpld_val = cpld_val & BIT_INDEX(port_bit); + status = snprintf(buf, PAGE_SIZE - 1, "%d\r\n", cpld_val>>port_bit); + + mutex_unlock(&data->update_lock); + + return status; +} + +static ssize_t set_mode_reset(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as5712_54x_sfp_data *data = i2c_get_clientdata(client); + u8 cpld_val = 0; + long reset; + int error, port_bit; + + /* Tx disable is not supported for QSFP ports(49-54) */ + if (data->port < SFP_PORT_MAX) { + return -EINVAL; + } + port_bit = data->port - SFP_PORT_MAX; + error = kstrtol(buf, 10, &reset); + if (error) { + return error; + } + mutex_lock(&data->update_lock); + + cpld_val = as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD3, CPLD3_OFFSET_QSFP_MOD_RST); + /* Update lp_mode status */ + if (reset) + { + cpld_val |= BIT_INDEX(port_bit); + } + else + { + cpld_val &=~BIT_INDEX(port_bit); + } + as5712_54x_i2c_cpld_write(I2C_ADDR_CPLD3, CPLD3_OFFSET_QSFP_MOD_RST, cpld_val); + + mutex_unlock(&data->update_lock); + + return count; +} + + +static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as5712_54x_sfp_data *data = i2c_get_clientdata(client); + unsigned short cpld_addr = 0; + u8 cpld_reg = 0, cpld_val = 0, cpld_bit = 0; + long disable; + int error; + + /* Tx disable is not supported for QSFP ports(49-54) */ + if (data->port >= SFP_PORT_MAX) { + return -EINVAL; + } + + error = kstrtol(buf, 10, &disable); + if (error) { + return error; + } + + mutex_lock(&data->update_lock); + + if(data->port < 24) { + cpld_addr = I2C_ADDR_CPLD2; + cpld_reg = 0xC + data->port / 8; + cpld_bit = 1 << (data->port % 8); + } + else { + cpld_addr = I2C_ADDR_CPLD3; + cpld_reg = 0xC + (data->port - 24) / 8; + cpld_bit = 1 << (data->port % 8); + } + + cpld_val = as5712_54x_i2c_cpld_read(cpld_addr, cpld_reg); + + /* Update tx_disable status */ + if (disable) { + data->status[SFP_TX_DISABLE] |= BIT_INDEX(data->port); + cpld_val |= cpld_bit; + } + else { + data->status[SFP_TX_DISABLE] &= ~BIT_INDEX(data->port); + cpld_val &= ~cpld_bit; + } + + as5712_54x_i2c_cpld_write(cpld_addr, cpld_reg, cpld_val); + + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t show_eeprom(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct as5712_54x_sfp_data *data = as5712_54x_sfp_update_device(dev, 1); + + if (!data->valid) { + return 0; + } + + if ((data->status[SFP_IS_PRESENT] & BIT_INDEX(data->port)) != 0) { + return 0; + } + + memcpy(buf, data->eeprom, sizeof(data->eeprom)); + + return sizeof(data->eeprom); +} + +static const struct attribute_group as5712_54x_sfp_group = { + .attrs = as5712_54x_sfp_attributes, +}; + +static int as5712_54x_sfp_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct as5712_54x_sfp_data *data; + int status; + + extern int platform_accton_as5712_54x(void); + if(!platform_accton_as5712_54x()) { + return -ENODEV; + } + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct as5712_54x_sfp_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + mutex_init(&data->update_lock); + data->port = dev_id->driver_data; + i2c_set_clientdata(client, data); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as5712_54x_sfp_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: sfp '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as5712_54x_sfp_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as5712_54x_sfp_remove(struct i2c_client *client) +{ + struct as5712_54x_sfp_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as5712_54x_sfp_group); + kfree(data); + + return 0; +} + +enum port_numbers { +as5712_54x_sfp1, as5712_54x_sfp2, as5712_54x_sfp3, as5712_54x_sfp4, +as5712_54x_sfp5, as5712_54x_sfp6, as5712_54x_sfp7, as5712_54x_sfp8, +as5712_54x_sfp9, as5712_54x_sfp10, as5712_54x_sfp11,as5712_54x_sfp12, +as5712_54x_sfp13, as5712_54x_sfp14, as5712_54x_sfp15,as5712_54x_sfp16, +as5712_54x_sfp17, as5712_54x_sfp18, as5712_54x_sfp19,as5712_54x_sfp20, +as5712_54x_sfp21, as5712_54x_sfp22, as5712_54x_sfp23,as5712_54x_sfp24, +as5712_54x_sfp25, as5712_54x_sfp26, as5712_54x_sfp27,as5712_54x_sfp28, +as5712_54x_sfp29, as5712_54x_sfp30, as5712_54x_sfp31,as5712_54x_sfp32, +as5712_54x_sfp33, as5712_54x_sfp34, as5712_54x_sfp35,as5712_54x_sfp36, +as5712_54x_sfp37, as5712_54x_sfp38, as5712_54x_sfp39,as5712_54x_sfp40, +as5712_54x_sfp41, as5712_54x_sfp42, as5712_54x_sfp43,as5712_54x_sfp44, +as5712_54x_sfp45, as5712_54x_sfp46, as5712_54x_sfp47,as5712_54x_sfp48, +as5712_54x_sfp49, as5712_54x_sfp52, as5712_54x_sfp50,as5712_54x_sfp53, +as5712_54x_sfp51, as5712_54x_sfp54 +}; + +static const struct i2c_device_id as5712_54x_sfp_id[] = { +{ "as5712_54x_sfp1", as5712_54x_sfp1 }, { "as5712_54x_sfp2", as5712_54x_sfp2 }, +{ "as5712_54x_sfp3", as5712_54x_sfp3 }, { "as5712_54x_sfp4", as5712_54x_sfp4 }, +{ "as5712_54x_sfp5", as5712_54x_sfp5 }, { "as5712_54x_sfp6", as5712_54x_sfp6 }, +{ "as5712_54x_sfp7", as5712_54x_sfp7 }, { "as5712_54x_sfp8", as5712_54x_sfp8 }, +{ "as5712_54x_sfp9", as5712_54x_sfp9 }, { "as5712_54x_sfp10", as5712_54x_sfp10 }, +{ "as5712_54x_sfp11", as5712_54x_sfp11 }, { "as5712_54x_sfp12", as5712_54x_sfp12 }, +{ "as5712_54x_sfp13", as5712_54x_sfp13 }, { "as5712_54x_sfp14", as5712_54x_sfp14 }, +{ "as5712_54x_sfp15", as5712_54x_sfp15 }, { "as5712_54x_sfp16", as5712_54x_sfp16 }, +{ "as5712_54x_sfp17", as5712_54x_sfp17 }, { "as5712_54x_sfp18", as5712_54x_sfp18 }, +{ "as5712_54x_sfp19", as5712_54x_sfp19 }, { "as5712_54x_sfp20", as5712_54x_sfp20 }, +{ "as5712_54x_sfp21", as5712_54x_sfp21 }, { "as5712_54x_sfp22", as5712_54x_sfp22 }, +{ "as5712_54x_sfp23", as5712_54x_sfp23 }, { "as5712_54x_sfp24", as5712_54x_sfp24 }, +{ "as5712_54x_sfp25", as5712_54x_sfp25 }, { "as5712_54x_sfp26", as5712_54x_sfp26 }, +{ "as5712_54x_sfp27", as5712_54x_sfp27 }, { "as5712_54x_sfp28", as5712_54x_sfp28 }, +{ "as5712_54x_sfp29", as5712_54x_sfp29 }, { "as5712_54x_sfp30", as5712_54x_sfp30 }, +{ "as5712_54x_sfp31", as5712_54x_sfp31 }, { "as5712_54x_sfp32", as5712_54x_sfp32 }, +{ "as5712_54x_sfp33", as5712_54x_sfp33 }, { "as5712_54x_sfp34", as5712_54x_sfp34 }, +{ "as5712_54x_sfp35", as5712_54x_sfp35 }, { "as5712_54x_sfp36", as5712_54x_sfp36 }, +{ "as5712_54x_sfp37", as5712_54x_sfp37 }, { "as5712_54x_sfp38", as5712_54x_sfp38 }, +{ "as5712_54x_sfp39", as5712_54x_sfp39 }, { "as5712_54x_sfp40", as5712_54x_sfp40 }, +{ "as5712_54x_sfp41", as5712_54x_sfp41 }, { "as5712_54x_sfp42", as5712_54x_sfp42 }, +{ "as5712_54x_sfp43", as5712_54x_sfp43 }, { "as5712_54x_sfp44", as5712_54x_sfp44 }, +{ "as5712_54x_sfp45", as5712_54x_sfp45 }, { "as5712_54x_sfp46", as5712_54x_sfp46 }, +{ "as5712_54x_sfp47", as5712_54x_sfp47 }, { "as5712_54x_sfp48", as5712_54x_sfp48 }, +{ "as5712_54x_sfp49", as5712_54x_sfp49 }, { "as5712_54x_sfp50", as5712_54x_sfp50 }, +{ "as5712_54x_sfp51", as5712_54x_sfp51 }, { "as5712_54x_sfp52", as5712_54x_sfp52 }, +{ "as5712_54x_sfp53", as5712_54x_sfp53 }, { "as5712_54x_sfp54", as5712_54x_sfp54 }, + +{} +}; +MODULE_DEVICE_TABLE(i2c, as5712_54x_sfp_id); + +static struct i2c_driver as5712_54x_sfp_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "as5712_54x_sfp", + }, + .probe = as5712_54x_sfp_probe, + .remove = as5712_54x_sfp_remove, + .id_table = as5712_54x_sfp_id, + .address_list = normal_i2c, +}; + +static int as5712_54x_sfp_read_byte(struct i2c_client *client, u8 command, u8 *data) +{ + int result = i2c_smbus_read_byte_data(client, command); + + if (unlikely(result < 0)) { + dev_dbg(&client->dev, "sfp read byte data failed, command(0x%2x), data(0x%2x)\r\n", command, result); + goto abort; + } + + *data = (u8)result; + result = 0; + +abort: + return result; +} + +#define ALWAYS_UPDATE_DEVICE 1 + +static struct as5712_54x_sfp_data *as5712_54x_sfp_update_device(struct device *dev, int update_eeprom) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as5712_54x_sfp_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (ALWAYS_UPDATE_DEVICE || time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int status = -1; + int i = 0, j = 0; + + data->valid = 0; + //dev_dbg(&client->dev, "Starting as5712_54x sfp status update\n"); + memset(data->status, 0, sizeof(data->status)); + + /* Read status of port 1~48(SFP port) */ + for (i = 0; i < 2; i++) { + for (j = 0; j < 12; j++) { + status = as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD2+i, 0x6+j); + + if (status < 0) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", I2C_ADDR_CPLD2+i, 0x6+j, status); + goto exit; + } + + data->status[j/3] |= (u64)status << ((i*24) + (j%3)*8); + } + } + + /* + * Bring QSFPs out of reset, + * This is a temporary fix until the QSFP+_MOD_RST register + * can be exposed through the driver. + */ + as5712_54x_i2c_cpld_write(I2C_ADDR_CPLD3, 0x15, 0x3F); + + /* Read present status of port 49-54(QSFP port) */ + status = as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD3, 0x14); + + if (status < 0) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", I2C_ADDR_CPLD2+i, 0x6+j, status); + } + else { + data->status[SFP_IS_PRESENT] |= (u64)status << 48; + } + + if (update_eeprom) { + /* Read eeprom data based on port number */ + memset(data->eeprom, 0, sizeof(data->eeprom)); + + /* Check if the port is present */ + if ((data->status[SFP_IS_PRESENT] & BIT_INDEX(data->port)) == 0) { + /* read eeprom */ + for (i = 0; i < sizeof(data->eeprom); i++) { + status = as5712_54x_sfp_read_byte(client, i, data->eeprom + i); + + if (status < 0) { + dev_dbg(&client->dev, "unable to read eeprom from port(%d)\n", + CPLD_PORT_TO_FRONT_PORT(data->port)); + goto exit; + } + } + } + } + + data->valid = 1; + data->last_updated = jiffies; + } + +exit: + mutex_unlock(&data->update_lock); + + return data; +} + +module_i2c_driver(as5712_54x_sfp_driver); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton as5712_54x_sfp driver"); +MODULE_LICENSE("GPL"); + +#if 0 + int i = 0, j = 0; + + data->valid = 0; + //dev_dbg(&client->dev, "Starting as5712_54x sfp update\n"); + memset(data->status, 0, sizeof(data->status)); + + /* Read status of port 1~48(SFP port) */ + for (i = 0; i < 2; i++) { + for (j = 0; j < 12; j++) { + status = as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD2+i, 0x6+j); + + if (status < 0) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", I2C_ADDR_CPLD2+i, 0x6+j, status); + continue; + } + + data->status[j/3] |= (u64)status << ((i*24) + (j%3)*8); + } + } + + /* Read present status of port 49-54(QSFP port) */ + status = as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD3, 0x14); + + if (status < 0) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", I2C_ADDR_CPLD2+i, 0x6+j, status); + } + else { + data->status[SFP_IS_PRESENT] |= (u64)status << 48; + } +#endif + +/* Reserver to prevent from CPLD port mapping is changed + */ +#if 0 +BIT_INDEX(port_present_index[data->port]) +/* The bit index of is_present field read from CPLD + * Array index 0 is for as5712_54x_sfp1, + * index 1 is for as5712_54x_sfp2, and so on. + */ +static const int port_present_index[] = { + 4, 5, 6, 7, 9, 8, 11, 10, + 0, 1, 2, 3, 12, 13, 14, 15, +16, 17, 18, 19, 28, 29, 30, 31, +20, 21, 22, 23, 24, 25, 26, 27 +}; +#endif + +#if 0 +static struct as5712_54x_sfp_data *as5712_54x_sfp_update_status(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as5712_54x_sfp_data *data = i2c_get_clientdata(client); + int status = -1; + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->status_last_updated + HZ + HZ / 2) + || !data->status_valid) { + int status = -1; + int i = 0, j = 0; + + data->status_valid = 0; + //dev_dbg(&client->dev, "Starting as5712_54x sfp status update\n"); + memset(data->status, 0, sizeof(data->status)); + + /* Read status of port 1~48(SFP port) */ + for (i = 0; i < 2; i++) { + for (j = 0; j < 12; j++) { + status = as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD2+i, 0x6+j); + + if (status < 0) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", I2C_ADDR_CPLD2+i, 0x6+j, status); + goto exit; + } + + data->status[j/3] |= (u64)status << ((i*24) + (j%3)*8); + } + } + + /* + * Bring QSFPs out of reset, + * This is a temporary fix until the QSFP+_MOD_RST register + * can be exposed through the driver. + */ + as5712_54x_i2c_cpld_write(I2C_ADDR_CPLD3, 0x15, 0x3F); + + /* Read present status of port 49-54(QSFP port) */ + status = as5712_54x_i2c_cpld_read(I2C_ADDR_CPLD3, 0x14); + + if (status < 0) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", I2C_ADDR_CPLD2+i, 0x6+j, status); + } + else { + data->status[SFP_IS_PRESENT] |= (u64)status << 48; + } + + data->status_valid = 1; + data->status_last_updated = jiffies; + } + +exit: + mutex_unlock(&data->update_lock); + + return data; +} + +static struct as5712_54x_sfp_data *as5712_54x_sfp_update_eeprom(struct device *dev) +{ + struct as5712_54x_sfp_data *data = NULL; + + data = as5712_54x_sfp_update_status(dev); + + if (data == NULL || data->status_valid == 0) { + data->eeprom_valid = 0; + return data; + } + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->eeprom_last_updated + HZ + HZ / 2) + || !data->eeprom_valid) { + int status = -1; + int i = 0; + + /* Read eeprom data based on port number */ + memset(data->eeprom, 0, sizeof(data->eeprom)); + + /* Check if the port is present */ + if ((data->status[SFP_IS_PRESENT] & BIT_INDEX(data->port)) == 0) { + /* read eeprom */ + for (i = 0; i < sizeof(data->eeprom)/I2C_SMBUS_BLOCK_MAX; i++) { + status = as5712_54x_sfp_read_block(client, i*I2C_SMBUS_BLOCK_MAX, + data->eeprom+(i*I2C_SMBUS_BLOCK_MAX), + I2C_SMBUS_BLOCK_MAX); + if (status < 0) { + dev_dbg(&client->dev, "unable to read eeprom from port(%d)\n", + CPLD_PORT_TO_FRONT_PORT(data->port)); + goto exit; + } + } + } + + data->eeprom_last_updated = jiffies; + data->eeprom_valid = 1; + } + +exit: + mutex_unlock(&data->update_lock); + + return data; +} +#endif diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/cpr_4011_4mxx.c b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/cpr_4011_4mxx.c new file mode 100755 index 000000000000..30bea914d589 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/cpr_4011_4mxx.c @@ -0,0 +1,400 @@ +/* + * An hwmon driver for the CPR-4011-4Mxx Redundant Power Module + * + * Copyright (C) Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#if 0 +#define DEBUG +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_FAN_DUTY_CYCLE 100 + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { 0x3c, 0x3d, 0x3e, 0x3f, I2C_CLIENT_END }; + +/* Each client has this additional data + */ +struct cpr_4011_4mxx_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 vout_mode; /* Register value */ + u16 v_in; /* Register value */ + u16 v_out; /* Register value */ + u16 i_in; /* Register value */ + u16 i_out; /* Register value */ + u16 p_in; /* Register value */ + u16 p_out; /* Register value */ + u16 temp_input[2]; /* Register value */ + u8 fan_fault; /* Register value */ + u16 fan_duty_cycle[2]; /* Register value */ + u16 fan_speed[2]; /* Register value */ +}; + +static ssize_t show_linear(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_vout(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static int cpr_4011_4mxx_write_word(struct i2c_client *client, u8 reg, u16 value); +static struct cpr_4011_4mxx_data *cpr_4011_4mxx_update_device(struct device *dev); + +enum cpr_4011_4mxx_sysfs_attributes { + PSU_V_IN, + PSU_V_OUT, + PSU_I_IN, + PSU_I_OUT, + PSU_P_IN, + PSU_P_OUT, + PSU_TEMP1_INPUT, + PSU_FAN1_FAULT, + PSU_FAN1_DUTY_CYCLE, + PSU_FAN1_SPEED, +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(psu_v_in, S_IRUGO, show_linear, NULL, PSU_V_IN); +static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, show_vout, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(psu_i_in, S_IRUGO, show_linear, NULL, PSU_I_IN); +static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, show_linear, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(psu_p_in, S_IRUGO, show_linear, NULL, PSU_P_IN); +static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, show_linear, NULL, PSU_P_OUT); +static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, show_fan_fault, NULL, PSU_FAN1_FAULT); +static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, show_linear, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); +static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); + +static struct attribute *cpr_4011_4mxx_attributes[] = { + &sensor_dev_attr_psu_v_in.dev_attr.attr, + &sensor_dev_attr_psu_v_out.dev_attr.attr, + &sensor_dev_attr_psu_i_in.dev_attr.attr, + &sensor_dev_attr_psu_i_out.dev_attr.attr, + &sensor_dev_attr_psu_p_in.dev_attr.attr, + &sensor_dev_attr_psu_p_out.dev_attr.attr, + &sensor_dev_attr_psu_temp1_input.dev_attr.attr, + &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, + &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, + &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, + NULL +}; + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + bool is_negative = valid_data >> (valid_bit - 1); + + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} + +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpr_4011_4mxx_data *data = i2c_get_clientdata(client); + int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; + long speed; + int error; + + error = kstrtol(buf, 10, &speed); + if (error) + return error; + + if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) + return -EINVAL; + + mutex_lock(&data->update_lock); + data->fan_duty_cycle[nr] = speed; + cpr_4011_4mxx_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t show_linear(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct cpr_4011_4mxx_data *data = cpr_4011_4mxx_update_device(dev); + + u16 value = 0; + int exponent, mantissa; + int multiplier = 1000; + + switch (attr->index) { + case PSU_V_IN: + value = data->v_in; + break; + case PSU_I_IN: + value = data->i_in; + break; + case PSU_I_OUT: + value = data->i_out; + break; + case PSU_P_IN: + value = data->p_in; + break; + case PSU_P_OUT: + value = data->p_out; + break; + case PSU_TEMP1_INPUT: + value = data->temp_input[0]; + break; + case PSU_FAN1_DUTY_CYCLE: + multiplier = 1; + value = data->fan_duty_cycle[0]; + break; + case PSU_FAN1_SPEED: + multiplier = 1; + value = data->fan_speed[0]; + break; + default: + break; + } + + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + + return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct cpr_4011_4mxx_data *data = cpr_4011_4mxx_update_device(dev); + + u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; + + return sprintf(buf, "%d\n", data->fan_fault >> shift); +} + +static ssize_t show_vout(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct cpr_4011_4mxx_data *data = cpr_4011_4mxx_update_device(dev); + int exponent, mantissa; + int multiplier = 1000; + + exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); + mantissa = data->v_out; + + return (exponent > 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static const struct attribute_group cpr_4011_4mxx_group = { + .attrs = cpr_4011_4mxx_attributes, +}; + +static int cpr_4011_4mxx_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct cpr_4011_4mxx_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct cpr_4011_4mxx_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &cpr_4011_4mxx_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &cpr_4011_4mxx_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int cpr_4011_4mxx_remove(struct i2c_client *client) +{ + struct cpr_4011_4mxx_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &cpr_4011_4mxx_group); + kfree(data); + + return 0; +} + +static const struct i2c_device_id cpr_4011_4mxx_id[] = { + { "cpr_4011_4mxx", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, cpr_4011_4mxx_id); + +static struct i2c_driver cpr_4011_4mxx_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "cpr_4011_4mxx", + }, + .probe = cpr_4011_4mxx_probe, + .remove = cpr_4011_4mxx_remove, + .id_table = cpr_4011_4mxx_id, + .address_list = normal_i2c, +}; + +static int cpr_4011_4mxx_read_byte(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int cpr_4011_4mxx_read_word(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_word_data(client, reg); +} + +static int cpr_4011_4mxx_write_word(struct i2c_client *client, u8 reg, u16 value) +{ + return i2c_smbus_write_word_data(client, reg, value); +} + +struct reg_data_byte { + u8 reg; + u8 *value; +}; + +struct reg_data_word { + u8 reg; + u16 *value; +}; + +static struct cpr_4011_4mxx_data *cpr_4011_4mxx_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpr_4011_4mxx_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int i, status; + struct reg_data_byte regs_byte[] = { {0x20, &data->vout_mode}, + {0x81, &data->fan_fault}}; + struct reg_data_word regs_word[] = { {0x88, &data->v_in}, + {0x8b, &data->v_out}, + {0x89, &data->i_in}, + {0x8c, &data->i_out}, + {0x96, &data->p_out}, + {0x97, &data->p_in}, + {0x8d, &(data->temp_input[0])}, + {0x8e, &(data->temp_input[1])}, + {0x3b, &(data->fan_duty_cycle[0])}, + {0x3c, &(data->fan_duty_cycle[1])}, + {0x90, &(data->fan_speed[0])}, + {0x91, &(data->fan_speed[1])}}; + + dev_dbg(&client->dev, "Starting cpr_4011_4mxx update\n"); + + /* Read byte data */ + for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { + status = cpr_4011_4mxx_read_byte(client, regs_byte[i].reg); + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_byte[i].reg, status); + } + else { + *(regs_byte[i].value) = status; + } + } + + /* Read word data */ + for (i = 0; i < ARRAY_SIZE(regs_word); i++) { + status = cpr_4011_4mxx_read_word(client, regs_word[i].reg); + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_word[i].reg, status); + } + else { + *(regs_word[i].value) = status; + } + } + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +static int __init cpr_4011_4mxx_init(void) +{ + return i2c_add_driver(&cpr_4011_4mxx_driver); +} + +static void __exit cpr_4011_4mxx_exit(void) +{ + i2c_del_driver(&cpr_4011_4mxx_driver); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("CPR_4011_4MXX driver"); +MODULE_LICENSE("GPL"); + +module_init(cpr_4011_4mxx_init); +module_exit(cpr_4011_4mxx_exit); diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/i2c-mux-accton_as5712_54x_cpld.c b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/i2c-mux-accton_as5712_54x_cpld.c new file mode 100755 index 000000000000..d63cb14b5a67 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/i2c-mux-accton_as5712_54x_cpld.c @@ -0,0 +1,1517 @@ +/* + * I2C multiplexer + * + * Copyright (C) Brandon Chuang + * + * This module supports the accton cpld that hold the channel select + * mechanism for other i2c slave devices, such as SFP. + * This includes the: + * Accton as5712_54x CPLD1/CPLD2/CPLD3 + * + * Based on: + * pca954x.c from Kumar Gala + * Copyright (C) 2006 + * + * Based on: + * pca954x.c from Ken Harrenstien + * Copyright (C) 2004 Google, Inc. (Ken Harrenstien) + * + * Based on: + * i2c-virtual_cb.c from Brian Kuschak + * and + * pca9540.c from Jean Delvare . + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ +#if 0 +#define DEBUG +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define I2C_RW_RETRY_COUNT 10 +#define I2C_RW_RETRY_INTERVAL 60 /* ms */ + +#define NUM_OF_CPLD1_CHANS 0x0 +#define NUM_OF_CPLD2_CHANS 0x18 +#define NUM_OF_CPLD3_CHANS 0x1E +#define CPLD_CHANNEL_SELECT_REG 0x2 +#define CPLD_DESELECT_CHANNEL 0xFF + +#if 0 +#define NUM_OF_ALL_CPLD_CHANS (NUM_OF_CPLD2_CHANS + NUM_OF_CPLD3_CHANS) +#endif + +#define ACCTON_I2C_CPLD_MUX_MAX_NCHANS NUM_OF_CPLD3_CHANS + +static LIST_HEAD(cpld_client_list); +static struct mutex list_lock; + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; + +enum cpld_mux_type { + as5712_54x_cpld2, + as5712_54x_cpld3, + as5712_54x_cpld1 +}; + +struct as5712_54x_cpld_data { + enum cpld_mux_type type; + struct i2c_adapter *virt_adaps[ACCTON_I2C_CPLD_MUX_MAX_NCHANS]; + u8 last_chan; /* last register value */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) + struct i2c_client *client; + struct i2c_mux_core *muxc; +#endif + struct device *hwmon_dev; + struct mutex update_lock; +}; + +#if 0 +/* The mapping table between mux index and adapter index + array index : the mux index + the content : adapter index + */ +static int mux_adap_map[NUM_OF_ALL_CPLD_CHANS]; +#endif + +struct chip_desc { + u8 nchans; + u8 deselectChan; +}; + +/* Provide specs for the PCA954x types we know about */ +static const struct chip_desc chips[] = { + [as5712_54x_cpld1] = { + .nchans = NUM_OF_CPLD1_CHANS, + .deselectChan = CPLD_DESELECT_CHANNEL, + }, + [as5712_54x_cpld2] = { + .nchans = NUM_OF_CPLD2_CHANS, + .deselectChan = CPLD_DESELECT_CHANNEL, + }, + [as5712_54x_cpld3] = { + .nchans = NUM_OF_CPLD3_CHANS, + .deselectChan = CPLD_DESELECT_CHANNEL, + } +}; + +static const struct i2c_device_id as5712_54x_cpld_mux_id[] = { + { "as5712_54x_cpld1", as5712_54x_cpld1 }, + { "as5712_54x_cpld2", as5712_54x_cpld2 }, + { "as5712_54x_cpld3", as5712_54x_cpld3 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, as5712_54x_cpld_mux_id); + +#define TRANSCEIVER_PRESENT_ATTR_ID(index) MODULE_PRESENT_##index +#define TRANSCEIVER_TXDISABLE_ATTR_ID(index) MODULE_TXDISABLE_##index +#define TRANSCEIVER_RXLOS_ATTR_ID(index) MODULE_RXLOS_##index +#define TRANSCEIVER_TXFAULT_ATTR_ID(index) MODULE_TXFAULT_##index +#define TRANSCEIVER_LPMODE_ATTR_ID(index) MODULE_LPMODE_##index +#define TRANSCEIVER_RESET_ATTR_ID(index) MODULE_RESET_##index + +enum as5712_54x_cpld1_sysfs_attributes { + CPLD_VERSION, + ACCESS, + MODULE_PRESENT_ALL, + MODULE_RXLOS_ALL, + /* transceiver attributes */ + TRANSCEIVER_PRESENT_ATTR_ID(1), + TRANSCEIVER_PRESENT_ATTR_ID(2), + TRANSCEIVER_PRESENT_ATTR_ID(3), + TRANSCEIVER_PRESENT_ATTR_ID(4), + TRANSCEIVER_PRESENT_ATTR_ID(5), + TRANSCEIVER_PRESENT_ATTR_ID(6), + TRANSCEIVER_PRESENT_ATTR_ID(7), + TRANSCEIVER_PRESENT_ATTR_ID(8), + TRANSCEIVER_PRESENT_ATTR_ID(9), + TRANSCEIVER_PRESENT_ATTR_ID(10), + TRANSCEIVER_PRESENT_ATTR_ID(11), + TRANSCEIVER_PRESENT_ATTR_ID(12), + TRANSCEIVER_PRESENT_ATTR_ID(13), + TRANSCEIVER_PRESENT_ATTR_ID(14), + TRANSCEIVER_PRESENT_ATTR_ID(15), + TRANSCEIVER_PRESENT_ATTR_ID(16), + TRANSCEIVER_PRESENT_ATTR_ID(17), + TRANSCEIVER_PRESENT_ATTR_ID(18), + TRANSCEIVER_PRESENT_ATTR_ID(19), + TRANSCEIVER_PRESENT_ATTR_ID(20), + TRANSCEIVER_PRESENT_ATTR_ID(21), + TRANSCEIVER_PRESENT_ATTR_ID(22), + TRANSCEIVER_PRESENT_ATTR_ID(23), + TRANSCEIVER_PRESENT_ATTR_ID(24), + TRANSCEIVER_PRESENT_ATTR_ID(25), + TRANSCEIVER_PRESENT_ATTR_ID(26), + TRANSCEIVER_PRESENT_ATTR_ID(27), + TRANSCEIVER_PRESENT_ATTR_ID(28), + TRANSCEIVER_PRESENT_ATTR_ID(29), + TRANSCEIVER_PRESENT_ATTR_ID(30), + TRANSCEIVER_PRESENT_ATTR_ID(31), + TRANSCEIVER_PRESENT_ATTR_ID(32), + TRANSCEIVER_PRESENT_ATTR_ID(33), + TRANSCEIVER_PRESENT_ATTR_ID(34), + TRANSCEIVER_PRESENT_ATTR_ID(35), + TRANSCEIVER_PRESENT_ATTR_ID(36), + TRANSCEIVER_PRESENT_ATTR_ID(37), + TRANSCEIVER_PRESENT_ATTR_ID(38), + TRANSCEIVER_PRESENT_ATTR_ID(39), + TRANSCEIVER_PRESENT_ATTR_ID(40), + TRANSCEIVER_PRESENT_ATTR_ID(41), + TRANSCEIVER_PRESENT_ATTR_ID(42), + TRANSCEIVER_PRESENT_ATTR_ID(43), + TRANSCEIVER_PRESENT_ATTR_ID(44), + TRANSCEIVER_PRESENT_ATTR_ID(45), + TRANSCEIVER_PRESENT_ATTR_ID(46), + TRANSCEIVER_PRESENT_ATTR_ID(47), + TRANSCEIVER_PRESENT_ATTR_ID(48), + TRANSCEIVER_PRESENT_ATTR_ID(49), + TRANSCEIVER_PRESENT_ATTR_ID(50), + TRANSCEIVER_PRESENT_ATTR_ID(51), + TRANSCEIVER_PRESENT_ATTR_ID(52), + TRANSCEIVER_PRESENT_ATTR_ID(53), + TRANSCEIVER_PRESENT_ATTR_ID(54), + TRANSCEIVER_TXDISABLE_ATTR_ID(1), + TRANSCEIVER_TXDISABLE_ATTR_ID(2), + TRANSCEIVER_TXDISABLE_ATTR_ID(3), + TRANSCEIVER_TXDISABLE_ATTR_ID(4), + TRANSCEIVER_TXDISABLE_ATTR_ID(5), + TRANSCEIVER_TXDISABLE_ATTR_ID(6), + TRANSCEIVER_TXDISABLE_ATTR_ID(7), + TRANSCEIVER_TXDISABLE_ATTR_ID(8), + TRANSCEIVER_TXDISABLE_ATTR_ID(9), + TRANSCEIVER_TXDISABLE_ATTR_ID(10), + TRANSCEIVER_TXDISABLE_ATTR_ID(11), + TRANSCEIVER_TXDISABLE_ATTR_ID(12), + TRANSCEIVER_TXDISABLE_ATTR_ID(13), + TRANSCEIVER_TXDISABLE_ATTR_ID(14), + TRANSCEIVER_TXDISABLE_ATTR_ID(15), + TRANSCEIVER_TXDISABLE_ATTR_ID(16), + TRANSCEIVER_TXDISABLE_ATTR_ID(17), + TRANSCEIVER_TXDISABLE_ATTR_ID(18), + TRANSCEIVER_TXDISABLE_ATTR_ID(19), + TRANSCEIVER_TXDISABLE_ATTR_ID(20), + TRANSCEIVER_TXDISABLE_ATTR_ID(21), + TRANSCEIVER_TXDISABLE_ATTR_ID(22), + TRANSCEIVER_TXDISABLE_ATTR_ID(23), + TRANSCEIVER_TXDISABLE_ATTR_ID(24), + TRANSCEIVER_TXDISABLE_ATTR_ID(25), + TRANSCEIVER_TXDISABLE_ATTR_ID(26), + TRANSCEIVER_TXDISABLE_ATTR_ID(27), + TRANSCEIVER_TXDISABLE_ATTR_ID(28), + TRANSCEIVER_TXDISABLE_ATTR_ID(29), + TRANSCEIVER_TXDISABLE_ATTR_ID(30), + TRANSCEIVER_TXDISABLE_ATTR_ID(31), + TRANSCEIVER_TXDISABLE_ATTR_ID(32), + TRANSCEIVER_TXDISABLE_ATTR_ID(33), + TRANSCEIVER_TXDISABLE_ATTR_ID(34), + TRANSCEIVER_TXDISABLE_ATTR_ID(35), + TRANSCEIVER_TXDISABLE_ATTR_ID(36), + TRANSCEIVER_TXDISABLE_ATTR_ID(37), + TRANSCEIVER_TXDISABLE_ATTR_ID(38), + TRANSCEIVER_TXDISABLE_ATTR_ID(39), + TRANSCEIVER_TXDISABLE_ATTR_ID(40), + TRANSCEIVER_TXDISABLE_ATTR_ID(41), + TRANSCEIVER_TXDISABLE_ATTR_ID(42), + TRANSCEIVER_TXDISABLE_ATTR_ID(43), + TRANSCEIVER_TXDISABLE_ATTR_ID(44), + TRANSCEIVER_TXDISABLE_ATTR_ID(45), + TRANSCEIVER_TXDISABLE_ATTR_ID(46), + TRANSCEIVER_TXDISABLE_ATTR_ID(47), + TRANSCEIVER_TXDISABLE_ATTR_ID(48), + TRANSCEIVER_RXLOS_ATTR_ID(1), + TRANSCEIVER_RXLOS_ATTR_ID(2), + TRANSCEIVER_RXLOS_ATTR_ID(3), + TRANSCEIVER_RXLOS_ATTR_ID(4), + TRANSCEIVER_RXLOS_ATTR_ID(5), + TRANSCEIVER_RXLOS_ATTR_ID(6), + TRANSCEIVER_RXLOS_ATTR_ID(7), + TRANSCEIVER_RXLOS_ATTR_ID(8), + TRANSCEIVER_RXLOS_ATTR_ID(9), + TRANSCEIVER_RXLOS_ATTR_ID(10), + TRANSCEIVER_RXLOS_ATTR_ID(11), + TRANSCEIVER_RXLOS_ATTR_ID(12), + TRANSCEIVER_RXLOS_ATTR_ID(13), + TRANSCEIVER_RXLOS_ATTR_ID(14), + TRANSCEIVER_RXLOS_ATTR_ID(15), + TRANSCEIVER_RXLOS_ATTR_ID(16), + TRANSCEIVER_RXLOS_ATTR_ID(17), + TRANSCEIVER_RXLOS_ATTR_ID(18), + TRANSCEIVER_RXLOS_ATTR_ID(19), + TRANSCEIVER_RXLOS_ATTR_ID(20), + TRANSCEIVER_RXLOS_ATTR_ID(21), + TRANSCEIVER_RXLOS_ATTR_ID(22), + TRANSCEIVER_RXLOS_ATTR_ID(23), + TRANSCEIVER_RXLOS_ATTR_ID(24), + TRANSCEIVER_RXLOS_ATTR_ID(25), + TRANSCEIVER_RXLOS_ATTR_ID(26), + TRANSCEIVER_RXLOS_ATTR_ID(27), + TRANSCEIVER_RXLOS_ATTR_ID(28), + TRANSCEIVER_RXLOS_ATTR_ID(29), + TRANSCEIVER_RXLOS_ATTR_ID(30), + TRANSCEIVER_RXLOS_ATTR_ID(31), + TRANSCEIVER_RXLOS_ATTR_ID(32), + TRANSCEIVER_RXLOS_ATTR_ID(33), + TRANSCEIVER_RXLOS_ATTR_ID(34), + TRANSCEIVER_RXLOS_ATTR_ID(35), + TRANSCEIVER_RXLOS_ATTR_ID(36), + TRANSCEIVER_RXLOS_ATTR_ID(37), + TRANSCEIVER_RXLOS_ATTR_ID(38), + TRANSCEIVER_RXLOS_ATTR_ID(39), + TRANSCEIVER_RXLOS_ATTR_ID(40), + TRANSCEIVER_RXLOS_ATTR_ID(41), + TRANSCEIVER_RXLOS_ATTR_ID(42), + TRANSCEIVER_RXLOS_ATTR_ID(43), + TRANSCEIVER_RXLOS_ATTR_ID(44), + TRANSCEIVER_RXLOS_ATTR_ID(45), + TRANSCEIVER_RXLOS_ATTR_ID(46), + TRANSCEIVER_RXLOS_ATTR_ID(47), + TRANSCEIVER_RXLOS_ATTR_ID(48), + TRANSCEIVER_TXFAULT_ATTR_ID(1), + TRANSCEIVER_TXFAULT_ATTR_ID(2), + TRANSCEIVER_TXFAULT_ATTR_ID(3), + TRANSCEIVER_TXFAULT_ATTR_ID(4), + TRANSCEIVER_TXFAULT_ATTR_ID(5), + TRANSCEIVER_TXFAULT_ATTR_ID(6), + TRANSCEIVER_TXFAULT_ATTR_ID(7), + TRANSCEIVER_TXFAULT_ATTR_ID(8), + TRANSCEIVER_TXFAULT_ATTR_ID(9), + TRANSCEIVER_TXFAULT_ATTR_ID(10), + TRANSCEIVER_TXFAULT_ATTR_ID(11), + TRANSCEIVER_TXFAULT_ATTR_ID(12), + TRANSCEIVER_TXFAULT_ATTR_ID(13), + TRANSCEIVER_TXFAULT_ATTR_ID(14), + TRANSCEIVER_TXFAULT_ATTR_ID(15), + TRANSCEIVER_TXFAULT_ATTR_ID(16), + TRANSCEIVER_TXFAULT_ATTR_ID(17), + TRANSCEIVER_TXFAULT_ATTR_ID(18), + TRANSCEIVER_TXFAULT_ATTR_ID(19), + TRANSCEIVER_TXFAULT_ATTR_ID(20), + TRANSCEIVER_TXFAULT_ATTR_ID(21), + TRANSCEIVER_TXFAULT_ATTR_ID(22), + TRANSCEIVER_TXFAULT_ATTR_ID(23), + TRANSCEIVER_TXFAULT_ATTR_ID(24), + TRANSCEIVER_TXFAULT_ATTR_ID(25), + TRANSCEIVER_TXFAULT_ATTR_ID(26), + TRANSCEIVER_TXFAULT_ATTR_ID(27), + TRANSCEIVER_TXFAULT_ATTR_ID(28), + TRANSCEIVER_TXFAULT_ATTR_ID(29), + TRANSCEIVER_TXFAULT_ATTR_ID(30), + TRANSCEIVER_TXFAULT_ATTR_ID(31), + TRANSCEIVER_TXFAULT_ATTR_ID(32), + TRANSCEIVER_TXFAULT_ATTR_ID(33), + TRANSCEIVER_TXFAULT_ATTR_ID(34), + TRANSCEIVER_TXFAULT_ATTR_ID(35), + TRANSCEIVER_TXFAULT_ATTR_ID(36), + TRANSCEIVER_TXFAULT_ATTR_ID(37), + TRANSCEIVER_TXFAULT_ATTR_ID(38), + TRANSCEIVER_TXFAULT_ATTR_ID(39), + TRANSCEIVER_TXFAULT_ATTR_ID(40), + TRANSCEIVER_TXFAULT_ATTR_ID(41), + TRANSCEIVER_TXFAULT_ATTR_ID(42), + TRANSCEIVER_TXFAULT_ATTR_ID(43), + TRANSCEIVER_TXFAULT_ATTR_ID(44), + TRANSCEIVER_TXFAULT_ATTR_ID(45), + TRANSCEIVER_TXFAULT_ATTR_ID(46), + TRANSCEIVER_TXFAULT_ATTR_ID(47), + TRANSCEIVER_TXFAULT_ATTR_ID(48), + TRANSCEIVER_LPMODE_ATTR_ID(49), + TRANSCEIVER_LPMODE_ATTR_ID(50), + TRANSCEIVER_LPMODE_ATTR_ID(51), + TRANSCEIVER_LPMODE_ATTR_ID(52), + TRANSCEIVER_LPMODE_ATTR_ID(53), + TRANSCEIVER_LPMODE_ATTR_ID(54), + TRANSCEIVER_RESET_ATTR_ID(49), + TRANSCEIVER_RESET_ATTR_ID(50), + TRANSCEIVER_RESET_ATTR_ID(51), + TRANSCEIVER_RESET_ATTR_ID(52), + TRANSCEIVER_RESET_ATTR_ID(53), + TRANSCEIVER_RESET_ATTR_ID(54), +}; + +/* sysfs attributes for hwmon + */ +static ssize_t show_status(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_present_all(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t set_lp_mode(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t set_mode_reset(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t access(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t show_version(struct device *dev, struct device_attribute *da, + char *buf); +static int as5712_54x_cpld_read_internal(struct i2c_client *client, u8 reg); +static int as5712_54x_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value); + +/* transceiver attributes */ +#define DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(index) \ + static SENSOR_DEVICE_ATTR(module_present_##index, S_IRUGO, show_status, NULL, MODULE_PRESENT_##index) +#define DECLARE_TRANSCEIVER_PRESENT_ATTR(index) &sensor_dev_attr_module_present_##index.dev_attr.attr + +#define DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(index) \ + static SENSOR_DEVICE_ATTR(module_tx_disable_##index, S_IRUGO | S_IWUSR, show_status, set_tx_disable, MODULE_TXDISABLE_##index); \ + static SENSOR_DEVICE_ATTR(module_rx_los_##index, S_IRUGO, show_status, NULL, MODULE_RXLOS_##index); \ + static SENSOR_DEVICE_ATTR(module_tx_fault_##index, S_IRUGO, show_status, NULL, MODULE_TXFAULT_##index) + +#define DECLARE_SFP_TRANSCEIVER_ATTR(index) \ + &sensor_dev_attr_module_tx_disable_##index.dev_attr.attr, \ + &sensor_dev_attr_module_rx_los_##index.dev_attr.attr, \ + &sensor_dev_attr_module_tx_fault_##index.dev_attr.attr + +#define DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(index) \ + static SENSOR_DEVICE_ATTR(module_lp_mode_##index, S_IRUGO | S_IWUSR, show_status, set_lp_mode, MODULE_LPMODE_##index); \ + static SENSOR_DEVICE_ATTR(module_reset_##index, S_IWUSR | S_IRUGO, show_status, set_mode_reset, MODULE_RESET_##index) + +#define DECLARE_QSFP_TRANSCEIVER_ATTR(index) \ + &sensor_dev_attr_module_lp_mode_##index.dev_attr.attr, \ + &sensor_dev_attr_module_reset_##index.dev_attr.attr + + +static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, CPLD_VERSION); +static SENSOR_DEVICE_ATTR(access, S_IWUSR, NULL, access, ACCESS); +/* transceiver attributes */ +static SENSOR_DEVICE_ATTR(module_present_all, S_IRUGO, show_present_all, NULL, MODULE_PRESENT_ALL); +static SENSOR_DEVICE_ATTR(module_rx_los_all, S_IRUGO, show_rxlos_all, NULL, MODULE_RXLOS_ALL); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(1); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(2); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(3); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(4); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(5); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(6); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(7); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(8); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(9); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(10); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(11); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(12); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(13); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(14); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(15); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(16); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(17); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(18); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(19); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(20); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(21); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(22); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(23); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(24); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(25); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(26); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(27); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(28); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(29); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(30); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(31); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(32); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(33); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(34); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(35); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(36); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(37); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(38); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(39); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(40); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(41); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(42); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(43); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(44); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(45); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(46); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(47); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(48); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(49); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(50); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(51); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(52); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(53); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(54); + +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(1); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(2); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(3); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(4); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(5); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(6); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(7); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(8); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(9); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(10); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(11); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(12); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(13); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(14); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(15); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(16); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(17); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(18); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(19); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(20); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(21); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(22); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(23); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(24); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(25); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(26); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(27); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(28); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(29); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(30); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(31); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(32); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(33); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(34); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(35); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(36); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(37); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(38); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(39); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(40); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(41); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(42); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(43); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(44); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(45); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(46); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(47); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(48); +DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(49); +DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(50); +DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(51); +DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(52); +DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(53); +DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(54); + +static struct attribute *as5712_54x_cpld1_attributes[] = { + &sensor_dev_attr_version.dev_attr.attr, + &sensor_dev_attr_access.dev_attr.attr, + NULL +}; + +static const struct attribute_group as5712_54x_cpld1_group = { + .attrs = as5712_54x_cpld1_attributes, +}; + +static struct attribute *as5712_54x_cpld2_attributes[] = { + &sensor_dev_attr_version.dev_attr.attr, + &sensor_dev_attr_access.dev_attr.attr, + /* transceiver attributes */ + &sensor_dev_attr_module_present_all.dev_attr.attr, + &sensor_dev_attr_module_rx_los_all.dev_attr.attr, + DECLARE_TRANSCEIVER_PRESENT_ATTR(1), + DECLARE_TRANSCEIVER_PRESENT_ATTR(2), + DECLARE_TRANSCEIVER_PRESENT_ATTR(3), + DECLARE_TRANSCEIVER_PRESENT_ATTR(4), + DECLARE_TRANSCEIVER_PRESENT_ATTR(5), + DECLARE_TRANSCEIVER_PRESENT_ATTR(6), + DECLARE_TRANSCEIVER_PRESENT_ATTR(7), + DECLARE_TRANSCEIVER_PRESENT_ATTR(8), + DECLARE_TRANSCEIVER_PRESENT_ATTR(9), + DECLARE_TRANSCEIVER_PRESENT_ATTR(10), + DECLARE_TRANSCEIVER_PRESENT_ATTR(11), + DECLARE_TRANSCEIVER_PRESENT_ATTR(12), + DECLARE_TRANSCEIVER_PRESENT_ATTR(13), + DECLARE_TRANSCEIVER_PRESENT_ATTR(14), + DECLARE_TRANSCEIVER_PRESENT_ATTR(15), + DECLARE_TRANSCEIVER_PRESENT_ATTR(16), + DECLARE_TRANSCEIVER_PRESENT_ATTR(17), + DECLARE_TRANSCEIVER_PRESENT_ATTR(18), + DECLARE_TRANSCEIVER_PRESENT_ATTR(19), + DECLARE_TRANSCEIVER_PRESENT_ATTR(20), + DECLARE_TRANSCEIVER_PRESENT_ATTR(21), + DECLARE_TRANSCEIVER_PRESENT_ATTR(22), + DECLARE_TRANSCEIVER_PRESENT_ATTR(23), + DECLARE_TRANSCEIVER_PRESENT_ATTR(24), + DECLARE_SFP_TRANSCEIVER_ATTR(1), + DECLARE_SFP_TRANSCEIVER_ATTR(2), + DECLARE_SFP_TRANSCEIVER_ATTR(3), + DECLARE_SFP_TRANSCEIVER_ATTR(4), + DECLARE_SFP_TRANSCEIVER_ATTR(5), + DECLARE_SFP_TRANSCEIVER_ATTR(6), + DECLARE_SFP_TRANSCEIVER_ATTR(7), + DECLARE_SFP_TRANSCEIVER_ATTR(8), + DECLARE_SFP_TRANSCEIVER_ATTR(9), + DECLARE_SFP_TRANSCEIVER_ATTR(10), + DECLARE_SFP_TRANSCEIVER_ATTR(11), + DECLARE_SFP_TRANSCEIVER_ATTR(12), + DECLARE_SFP_TRANSCEIVER_ATTR(13), + DECLARE_SFP_TRANSCEIVER_ATTR(14), + DECLARE_SFP_TRANSCEIVER_ATTR(15), + DECLARE_SFP_TRANSCEIVER_ATTR(16), + DECLARE_SFP_TRANSCEIVER_ATTR(17), + DECLARE_SFP_TRANSCEIVER_ATTR(18), + DECLARE_SFP_TRANSCEIVER_ATTR(19), + DECLARE_SFP_TRANSCEIVER_ATTR(20), + DECLARE_SFP_TRANSCEIVER_ATTR(21), + DECLARE_SFP_TRANSCEIVER_ATTR(22), + DECLARE_SFP_TRANSCEIVER_ATTR(23), + DECLARE_SFP_TRANSCEIVER_ATTR(24), + NULL +}; + +static const struct attribute_group as5712_54x_cpld2_group = { + .attrs = as5712_54x_cpld2_attributes, +}; + +static struct attribute *as5712_54x_cpld3_attributes[] = { + &sensor_dev_attr_version.dev_attr.attr, + &sensor_dev_attr_access.dev_attr.attr, + /* transceiver attributes */ + &sensor_dev_attr_module_present_all.dev_attr.attr, + &sensor_dev_attr_module_rx_los_all.dev_attr.attr, + DECLARE_TRANSCEIVER_PRESENT_ATTR(25), + DECLARE_TRANSCEIVER_PRESENT_ATTR(26), + DECLARE_TRANSCEIVER_PRESENT_ATTR(27), + DECLARE_TRANSCEIVER_PRESENT_ATTR(28), + DECLARE_TRANSCEIVER_PRESENT_ATTR(29), + DECLARE_TRANSCEIVER_PRESENT_ATTR(30), + DECLARE_TRANSCEIVER_PRESENT_ATTR(31), + DECLARE_TRANSCEIVER_PRESENT_ATTR(32), + DECLARE_TRANSCEIVER_PRESENT_ATTR(33), + DECLARE_TRANSCEIVER_PRESENT_ATTR(34), + DECLARE_TRANSCEIVER_PRESENT_ATTR(35), + DECLARE_TRANSCEIVER_PRESENT_ATTR(36), + DECLARE_TRANSCEIVER_PRESENT_ATTR(37), + DECLARE_TRANSCEIVER_PRESENT_ATTR(38), + DECLARE_TRANSCEIVER_PRESENT_ATTR(39), + DECLARE_TRANSCEIVER_PRESENT_ATTR(40), + DECLARE_TRANSCEIVER_PRESENT_ATTR(41), + DECLARE_TRANSCEIVER_PRESENT_ATTR(42), + DECLARE_TRANSCEIVER_PRESENT_ATTR(43), + DECLARE_TRANSCEIVER_PRESENT_ATTR(44), + DECLARE_TRANSCEIVER_PRESENT_ATTR(45), + DECLARE_TRANSCEIVER_PRESENT_ATTR(46), + DECLARE_TRANSCEIVER_PRESENT_ATTR(47), + DECLARE_TRANSCEIVER_PRESENT_ATTR(48), + DECLARE_TRANSCEIVER_PRESENT_ATTR(49), + DECLARE_TRANSCEIVER_PRESENT_ATTR(50), + DECLARE_TRANSCEIVER_PRESENT_ATTR(51), + DECLARE_TRANSCEIVER_PRESENT_ATTR(52), + DECLARE_TRANSCEIVER_PRESENT_ATTR(53), + DECLARE_TRANSCEIVER_PRESENT_ATTR(54), + DECLARE_SFP_TRANSCEIVER_ATTR(25), + DECLARE_SFP_TRANSCEIVER_ATTR(26), + DECLARE_SFP_TRANSCEIVER_ATTR(27), + DECLARE_SFP_TRANSCEIVER_ATTR(28), + DECLARE_SFP_TRANSCEIVER_ATTR(29), + DECLARE_SFP_TRANSCEIVER_ATTR(30), + DECLARE_SFP_TRANSCEIVER_ATTR(31), + DECLARE_SFP_TRANSCEIVER_ATTR(32), + DECLARE_SFP_TRANSCEIVER_ATTR(33), + DECLARE_SFP_TRANSCEIVER_ATTR(34), + DECLARE_SFP_TRANSCEIVER_ATTR(35), + DECLARE_SFP_TRANSCEIVER_ATTR(36), + DECLARE_SFP_TRANSCEIVER_ATTR(37), + DECLARE_SFP_TRANSCEIVER_ATTR(38), + DECLARE_SFP_TRANSCEIVER_ATTR(39), + DECLARE_SFP_TRANSCEIVER_ATTR(40), + DECLARE_SFP_TRANSCEIVER_ATTR(41), + DECLARE_SFP_TRANSCEIVER_ATTR(42), + DECLARE_SFP_TRANSCEIVER_ATTR(43), + DECLARE_SFP_TRANSCEIVER_ATTR(44), + DECLARE_SFP_TRANSCEIVER_ATTR(45), + DECLARE_SFP_TRANSCEIVER_ATTR(46), + DECLARE_SFP_TRANSCEIVER_ATTR(47), + DECLARE_SFP_TRANSCEIVER_ATTR(48), + DECLARE_QSFP_TRANSCEIVER_ATTR(49), + DECLARE_QSFP_TRANSCEIVER_ATTR(50), + DECLARE_QSFP_TRANSCEIVER_ATTR(51), + DECLARE_QSFP_TRANSCEIVER_ATTR(52), + DECLARE_QSFP_TRANSCEIVER_ATTR(53), + DECLARE_QSFP_TRANSCEIVER_ATTR(54), + NULL +}; + +static const struct attribute_group as5712_54x_cpld3_group = { + .attrs = as5712_54x_cpld3_attributes, +}; + +static ssize_t show_present_all(struct device *dev, struct device_attribute *da, + char *buf) +{ + int i, status, num_regs = 0; + u8 values[4] = {0}; + u8 regs[] = {0x6, 0x7, 0x8, 0x14}; + struct i2c_client *client = to_i2c_client(dev); + struct as5712_54x_cpld_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + num_regs = (data->type == as5712_54x_cpld2) ? 3 : 4; + + for (i = 0; i < num_regs; i++) { + status = as5712_54x_cpld_read_internal(client, regs[i]); + + if (status < 0) { + goto exit; + } + + values[i] = ~(u8)status; + } + + mutex_unlock(&data->update_lock); + + /* Return values 1 -> 54 in order */ + if (data->type == as5712_54x_cpld2) { + status = sprintf(buf, "%.2x %.2x %.2x\n", + values[0], values[1], values[2]); + } + else { /* as5712_54x_cpld3 */ + values[3] &= 0x3F; + status = sprintf(buf, "%.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], values[3]); + } + + return status; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da, + char *buf) +{ + int i, status; + u8 values[3] = {0}; + u8 regs[] = {0xF, 0x10, 0x11}; + struct i2c_client *client = to_i2c_client(dev); + struct as5712_54x_cpld_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + for (i = 0; i < ARRAY_SIZE(regs); i++) { + status = as5712_54x_cpld_read_internal(client, regs[i]); + + if (status < 0) { + goto exit; + } + + values[i] = (u8)status; + } + + mutex_unlock(&data->update_lock); + + /* Return values 1 -> 24 in order */ + return sprintf(buf, "%.2x %.2x %.2x\n", values[0], values[1], values[2]); + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t show_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as5712_54x_cpld_data *data = i2c_get_clientdata(client); + int status = 0; + u8 reg = 0, mask = 0, revert = 0; + + switch (attr->index) { + case MODULE_PRESENT_1 ... MODULE_PRESENT_8: + reg = 0x6; + mask = 0x1 << (attr->index - MODULE_PRESENT_1); + break; + case MODULE_PRESENT_9 ... MODULE_PRESENT_16: + reg = 0x7; + mask = 0x1 << (attr->index - MODULE_PRESENT_9); + break; + case MODULE_PRESENT_17 ... MODULE_PRESENT_24: + reg = 0x8; + mask = 0x1 << (attr->index - MODULE_PRESENT_17); + break; + case MODULE_PRESENT_25 ... MODULE_PRESENT_32: + reg = 0x6; + mask = 0x1 << (attr->index - MODULE_PRESENT_25); + break; + case MODULE_PRESENT_33 ... MODULE_PRESENT_40: + reg = 0x7; + mask = 0x1 << (attr->index - MODULE_PRESENT_33); + break; + case MODULE_PRESENT_41 ... MODULE_PRESENT_48: + reg = 0x8; + mask = 0x1 << (attr->index - MODULE_PRESENT_41); + break; + case MODULE_PRESENT_49: + reg = 0x14; + mask = 0x1; + break; + case MODULE_PRESENT_50: + reg = 0x14; + mask = 0x4; + break; + case MODULE_PRESENT_51: + reg = 0x14; + mask = 0x10; + break; + case MODULE_PRESENT_52: + reg = 0x14; + mask = 0x2; + break; + case MODULE_PRESENT_53: + reg = 0x14; + mask = 0x8; + break; + case MODULE_PRESENT_54: + reg = 0x14; + mask = 0x20; + break; + case MODULE_TXFAULT_1 ... MODULE_TXFAULT_8: + reg = 0x9; + mask = 0x1 << (attr->index - MODULE_TXFAULT_1); + break; + case MODULE_TXFAULT_9 ... MODULE_TXFAULT_16: + reg = 0xA; + mask = 0x1 << (attr->index - MODULE_TXFAULT_9); + break; + case MODULE_TXFAULT_17 ... MODULE_TXFAULT_24: + reg = 0xB; + mask = 0x1 << (attr->index - MODULE_TXFAULT_17); + break; + case MODULE_TXFAULT_25 ... MODULE_TXFAULT_32: + reg = 0x9; + mask = 0x1 << (attr->index - MODULE_TXFAULT_25); + break; + case MODULE_TXFAULT_33 ... MODULE_TXFAULT_40: + reg = 0xA; + mask = 0x1 << (attr->index - MODULE_TXFAULT_33); + break; + case MODULE_TXFAULT_41 ... MODULE_TXFAULT_48: + reg = 0xB; + mask = 0x1 << (attr->index - MODULE_TXFAULT_41); + break; + case MODULE_TXDISABLE_1 ... MODULE_TXDISABLE_8: + reg = 0xC; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_1); + break; + case MODULE_TXDISABLE_9 ... MODULE_TXDISABLE_16: + reg = 0xD; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_9); + break; + case MODULE_TXDISABLE_17 ... MODULE_TXDISABLE_24: + reg = 0xE; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_17); + break; + case MODULE_TXDISABLE_25 ... MODULE_TXDISABLE_32: + reg = 0xC; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_25); + break; + case MODULE_TXDISABLE_33 ... MODULE_TXDISABLE_40: + reg = 0xD; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_33); + break; + case MODULE_TXDISABLE_41 ... MODULE_TXDISABLE_48: + reg = 0xE; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_41); + break; + case MODULE_RXLOS_1 ... MODULE_RXLOS_8: + reg = 0xF; + mask = 0x1 << (attr->index - MODULE_RXLOS_1); + break; + case MODULE_RXLOS_9 ... MODULE_RXLOS_16: + reg = 0x10; + mask = 0x1 << (attr->index - MODULE_RXLOS_9); + break; + case MODULE_RXLOS_17 ... MODULE_RXLOS_24: + reg = 0x11; + mask = 0x1 << (attr->index - MODULE_RXLOS_17); + break; + case MODULE_RXLOS_25 ... MODULE_RXLOS_32: + reg = 0xF; + mask = 0x1 << (attr->index - MODULE_RXLOS_25); + break; + case MODULE_RXLOS_33 ... MODULE_RXLOS_40: + reg = 0x10; + mask = 0x1 << (attr->index - MODULE_RXLOS_33); + break; + case MODULE_RXLOS_41 ... MODULE_RXLOS_48: + reg = 0x11; + mask = 0x1 << (attr->index - MODULE_RXLOS_41); + break; + case MODULE_LPMODE_49 ... MODULE_LPMODE_54: + reg = 0x16; + mask = 0x1 << (attr->index - MODULE_LPMODE_49); + break; + case MODULE_RESET_49 ... MODULE_RESET_54: + reg = 0x15; + mask = 0x1 << (attr->index - MODULE_RESET_49); + break; + default: + return 0; + } + + if (attr->index >= MODULE_PRESENT_1 && attr->index <= MODULE_PRESENT_54) { + revert = 1; + } + + mutex_lock(&data->update_lock); + status = as5712_54x_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", revert ? !(status & mask) : !!(status & mask)); + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as5712_54x_cpld_data *data = i2c_get_clientdata(client); + long disable; + int status; + u8 reg = 0, mask = 0; + + status = kstrtol(buf, 10, &disable); + if (status) { + return status; + } + + switch (attr->index) { + case MODULE_TXDISABLE_1 ... MODULE_TXDISABLE_8: + reg = 0xC; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_1); + break; + case MODULE_TXDISABLE_9 ... MODULE_TXDISABLE_16: + reg = 0xD; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_9); + break; + case MODULE_TXDISABLE_17 ... MODULE_TXDISABLE_24: + reg = 0xE; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_17); + break; + case MODULE_TXDISABLE_25 ... MODULE_TXDISABLE_32: + reg = 0xC; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_25); + break; + case MODULE_TXDISABLE_33 ... MODULE_TXDISABLE_40: + reg = 0xD; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_33); + break; + case MODULE_TXDISABLE_41 ... MODULE_TXDISABLE_48: + reg = 0xE; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_41); + break; + default: + return 0; + } + + /* Read current status */ + mutex_lock(&data->update_lock); + status = as5712_54x_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + + /* Update tx_disable status */ + if (disable) { + status |= mask; + } + else { + status &= ~mask; + } + + status = as5712_54x_cpld_write_internal(client, reg, status); + if (unlikely(status < 0)) { + goto exit; + } + + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t set_lp_mode(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as5712_54x_cpld_data *data = i2c_get_clientdata(client); + long on; + int status= -ENOENT; + u8 reg = 0x16, mask = 0; + + if(attr->index < MODULE_LPMODE_49 || attr->index > MODULE_LPMODE_54) + return status; + + status = kstrtol(buf, 10, &on); + if (status) { + return status; + } + + /* Read current status */ + mutex_lock(&data->update_lock); + status = as5712_54x_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + + mask = 0x1 << (attr->index - MODULE_LPMODE_49); + + /* Update lp_mode status */ + if (on) { + status |= mask; + } + else { + status &= ~mask; + } + + status = as5712_54x_cpld_write_internal(client, reg, status); + if (unlikely(status < 0)) { + goto exit; + } + + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; + +} + +static ssize_t set_mode_reset(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as5712_54x_cpld_data *data = i2c_get_clientdata(client); + long on; + int status= -ENOENT; + u8 reg = 0x15, mask = 0; + + if(attr->index < MODULE_RESET_49 || attr->index > MODULE_RESET_54) + return status; + + status = kstrtol(buf, 10, &on); + if (status) { + return status; + } + + /* Read current status */ + mutex_lock(&data->update_lock); + status = as5712_54x_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + + mask = 0x1 << (attr->index - MODULE_RESET_49); + + /* Update tx_disable status */ + if (on) { + status |= mask; + } + else { + status &= ~mask; + } + + status = as5712_54x_cpld_write_internal(client, reg, status); + if (unlikely(status < 0)) { + goto exit; + } + + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; + +} + +static ssize_t access(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int status; + u32 addr, val; + struct i2c_client *client = to_i2c_client(dev); + struct as5712_54x_cpld_data *data = i2c_get_clientdata(client); + + if (sscanf(buf, "0x%x 0x%x", &addr, &val) != 2) { + return -EINVAL; + } + + if (addr > 0xFF || val > 0xFF) { + return -EINVAL; + } + + mutex_lock(&data->update_lock); + status = as5712_54x_cpld_write_internal(client, addr, val); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +/* Write to mux register. Don't use i2c_transfer()/i2c_smbus_xfer() + for this as they will try to lock adapter a second time */ +static int as5712_54x_cpld_mux_reg_write(struct i2c_adapter *adap, + struct i2c_client *client, u8 val) +{ + unsigned long orig_jiffies; + unsigned short flags; + union i2c_smbus_data data; + int try; + s32 res = -EIO; + + data.byte = val; + flags = client->flags; + flags &= I2C_M_TEN | I2C_CLIENT_PEC; + + if (adap->algo->smbus_xfer) { + /* Retry automatically on arbitration loss */ + orig_jiffies = jiffies; + for (res = 0, try = 0; try <= adap->retries; try++) { + res = adap->algo->smbus_xfer(adap, client->addr, flags, + I2C_SMBUS_WRITE, CPLD_CHANNEL_SELECT_REG, + I2C_SMBUS_BYTE_DATA, &data); + if (res != -EAGAIN) + break; + if (time_after(jiffies, + orig_jiffies + adap->timeout)) + break; + } + } + + return res; + +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) +static int as5712_54x_cpld_mux_select_chan(struct i2c_mux_core *muxc, + u32 chan) +{ + struct as5712_54x_cpld_data *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + u8 regval; + int ret = 0; + regval = chan; + + /* Only select the channel if its different from the last channel */ + if (data->last_chan != regval) { + ret = as5712_54x_cpld_mux_reg_write(muxc->parent, client, regval); + data->last_chan = regval; + } + + return ret; +} + +static int as5712_54x_cpld_mux_deselect_mux(struct i2c_mux_core *muxc, + u32 chan) +{ + struct as5712_54x_cpld_data *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + + /* Deselect active channel */ + data->last_chan = chips[data->type].deselectChan; + + return as5712_54x_cpld_mux_reg_write(muxc->parent, client, data->last_chan); +} +#else + +static int as5712_54x_cpld_mux_select_chan(struct i2c_adapter *adap, + void *client, u32 chan) +{ + struct as5712_54x_cpld_data *data = i2c_get_clientdata(client); + u8 regval; + int ret = 0; + regval = chan; + + /* Only select the channel if its different from the last channel */ + if (data->last_chan != regval) { + ret = as5712_54x_cpld_mux_reg_write(adap, client, regval); + data->last_chan = regval; + } + + return ret; +} + +static int as5712_54x_cpld_mux_deselect_mux(struct i2c_adapter *adap, + void *client, u32 chan) +{ + struct as5712_54x_cpld_data *data = i2c_get_clientdata(client); + + /* Deselect active channel */ + data->last_chan = chips[data->type].deselectChan; + + return as5712_54x_cpld_mux_reg_write(adap, client, data->last_chan); +} + +#endif /*#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)*/ + +static void as5712_54x_cpld_add_client(struct i2c_client *client) +{ + struct cpld_client_node *node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", client->addr); + return; + } + + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &cpld_client_list); + mutex_unlock(&list_lock); +} + +static void as5712_54x_cpld_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client == client) { + found = 1; + break; + } + } + + if (found) { + list_del(list_node); + kfree(cpld_node); + } + + mutex_unlock(&list_lock); +} + +static ssize_t show_version(struct device *dev, struct device_attribute *attr, char *buf) +{ + int val = 0; + struct i2c_client *client = to_i2c_client(dev); + + val = i2c_smbus_read_byte_data(client, 0x1); + + if (val < 0) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x1) err %d\n", client->addr, val); +} + + return sprintf(buf, "%d", val); +} + +/* + * I2C init/probing/exit functions + */ +static int as5712_54x_cpld_mux_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); + #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) + int force, class; + struct i2c_mux_core *muxc; +#endif + + int chan=0; + struct as5712_54x_cpld_data *data; + int ret = -ENODEV; + const struct attribute_group *group = NULL; + + if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE)) + goto exit; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) + muxc = i2c_mux_alloc(adap, &client->dev, + chips[id->driver_data].nchans, + sizeof(*data), 0, + accton_i2c_cpld_mux_select_chan, + accton_i2c_cpld_mux_deselect_mux); + if (!muxc) + return -ENOMEM; + + data = i2c_mux_priv(muxc); + i2c_set_clientdata(client, data); + data->muxc = muxc; + data->client = client; +#else + + data = kzalloc(sizeof(struct as5712_54x_cpld_data), GFP_KERNEL); + if (!data) { + ret = -ENOMEM; + goto exit; + } + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); +#endif + data->type = id->driver_data; + if (data->type == as5712_54x_cpld2 || data->type == as5712_54x_cpld3) { + data->last_chan = chips[data->type].deselectChan; /* force the first selection */ + + /* Now create an adapter for each channel */ + for (chan = 0; chan < chips[data->type].nchans; chan++) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) + force = 0; /* dynamic adap number */ + class = 0; /* no class by default */ + ret = i2c_mux_add_adapter(muxc, force, chan, class); + if (ret) +#else + data->virt_adaps[chan] = i2c_add_mux_adapter(adap, &client->dev, client, 0, chan, + 0, + as5712_54x_cpld_mux_select_chan, + as5712_54x_cpld_mux_deselect_mux); + if (data->virt_adaps[chan] == NULL) +#endif + { + ret = -ENODEV; + dev_err(&client->dev, "failed to register multiplexed adapter %d\n", chan); + goto exit_mux_register; + } + } + + dev_info(&client->dev, "registered %d multiplexed busses for I2C mux %s\n", + chan, client->name); + } + /* Register sysfs hooks */ + switch (data->type) + { + case as5712_54x_cpld1: + group = &as5712_54x_cpld1_group; + break; + case as5712_54x_cpld2: + group = &as5712_54x_cpld2_group; + break; + case as5712_54x_cpld3: + group = &as5712_54x_cpld3_group; + break; + default: + break; + } + + + if (group) { + ret = sysfs_create_group(&client->dev.kobj, group); + if (ret) { + goto exit_mux_register; + } + } + + as5712_54x_cpld_add_client(client); + return 0; + +exit_mux_register: +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) + i2c_mux_del_adapters(muxc); +#else + for (chan--; chan >= 0; chan--) { + i2c_del_mux_adapter(data->virt_adaps[chan]); + } +#endif + kfree(data); +exit: + return ret; +} + +static int as5712_54x_cpld_mux_remove(struct i2c_client *client) +{ + struct as5712_54x_cpld_data *data = i2c_get_clientdata(client); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) + struct i2c_mux_core *muxc = data->muxc; + + i2c_mux_del_adapters(muxc); +#else + const struct chip_desc *chip = &chips[data->type]; + int chan; + const struct attribute_group *group = NULL; + + as5712_54x_cpld_remove_client(client); + + /* Remove sysfs hooks */ + switch (data->type) { + case as5712_54x_cpld1: + group = &as5712_54x_cpld1_group; + break; + case as5712_54x_cpld2: + group = &as5712_54x_cpld2_group; + break; + case as5712_54x_cpld3: + group = &as5712_54x_cpld3_group; + break; + default: + break; + } + + if (group) { + sysfs_remove_group(&client->dev.kobj, group); + } + + for (chan = 0; chan < chip->nchans; ++chan) { + if (data->virt_adaps[chan]) { + i2c_del_mux_adapter(data->virt_adaps[chan]); + data->virt_adaps[chan] = NULL; + } + } +#endif + kfree(data); + + return 0; +} + +static int as5712_54x_cpld_read_internal(struct i2c_client *client, u8 reg) +{ + int status = 0, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_read_byte_data(client, reg); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + return status; +} + +static int as5712_54x_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value) +{ + int status = 0, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_write_byte_data(client, reg, value); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + return status; +} + +int as5712_54x_cpld_read(unsigned short cpld_addr, u8 reg) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EPERM; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = as5712_54x_cpld_read_internal(cpld_node->client, reg); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(as5712_54x_cpld_read); + +int as5712_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EIO; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = as5712_54x_cpld_write_internal(cpld_node->client, reg, value); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(as5712_54x_cpld_write); + +#if 0 +int accton_i2c_cpld_mux_get_index(int adap_index) +{ + int i; + + for (i = 0; i < NUM_OF_ALL_CPLD_CHANS; i++) { + if (mux_adap_map[i] == adap_index) { + return i; + } + } + + return -EINVAL; +} +EXPORT_SYMBOL(accton_i2c_cpld_mux_get_index); +#endif + +static struct i2c_driver as5712_54x_cpld_mux_driver = { + .driver = { + .name = "as5712_54x_cpld", + .owner = THIS_MODULE, + }, + .probe = as5712_54x_cpld_mux_probe, + .remove = as5712_54x_cpld_mux_remove, + .id_table = as5712_54x_cpld_mux_id, +}; + +static int __init as5712_54x_cpld_mux_init(void) +{ + mutex_init(&list_lock); + return i2c_add_driver(&as5712_54x_cpld_mux_driver); +} + +static void __exit as5712_54x_cpld_mux_exit(void) +{ + i2c_del_driver(&as5712_54x_cpld_mux_driver); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("Accton I2C CPLD mux driver"); +MODULE_LICENSE("GPL"); + +module_init(as5712_54x_cpld_mux_init); +module_exit(as5712_54x_cpld_mux_exit); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/leds-accton_as5712_54x.c b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/leds-accton_as5712_54x.c new file mode 100755 index 000000000000..cdea927368ae --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/leds-accton_as5712_54x.c @@ -0,0 +1,594 @@ +/* + * A LED driver for the accton_as5712_54x_led + * + * Copyright (C) 2013 Accton Technology Corporation. + * Brandon Chuang + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#if 0 +#define DEBUG +#endif + +#include +#include +#include +#include +#include +#include +#include + +extern int as5712_54x_cpld_read (unsigned short cpld_addr, u8 reg); +extern int as5712_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +extern void led_classdev_unregister(struct led_classdev *led_cdev); +extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); +extern void led_classdev_resume(struct led_classdev *led_cdev); +extern void led_classdev_suspend(struct led_classdev *led_cdev); + +#define DRVNAME "as5712_54x_led" + +struct accton_as5712_54x_led_data { + struct platform_device *pdev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[4]; /* Register value, 0 = LOC/DIAG/FAN LED + 1 = PSU1/PSU2 LED + 2 = FAN1-4 LED + 3 = FAN5-6 LED */ +}; + +static struct accton_as5712_54x_led_data *ledctl = NULL; + +/* LED related data + */ +#define LED_TYPE_PSU1_REG_MASK 0x03 +#define LED_MODE_PSU1_GREEN_MASK 0x02 +#define LED_MODE_PSU1_AMBER_MASK 0x01 +#define LED_MODE_PSU1_OFF_MASK 0x03 +#define LED_MODE_PSU1_AUTO_MASK 0x00 + +#define LED_TYPE_PSU2_REG_MASK 0x0C +#define LED_MODE_PSU2_GREEN_MASK 0x08 +#define LED_MODE_PSU2_AMBER_MASK 0x04 +#define LED_MODE_PSU2_OFF_MASK 0x0C +#define LED_MODE_PSU2_AUTO_MASK 0x00 + +#define LED_TYPE_DIAG_REG_MASK 0x0C +#define LED_MODE_DIAG_GREEN_MASK 0x08 +#define LED_MODE_DIAG_AMBER_MASK 0x04 +#define LED_MODE_DIAG_OFF_MASK 0x0C + +#define LED_TYPE_FAN_REG_MASK 0x03 +#define LED_MODE_FAN_GREEN_MASK 0x02 +#define LED_MODE_FAN_AMBER_MASK 0x01 +#define LED_MODE_FAN_OFF_MASK 0x03 +#define LED_MODE_FAN_AUTO_MASK 0x00 + +#define LED_TYPE_FAN1_REG_MASK 0x03 +#define LED_TYPE_FAN2_REG_MASK 0x0C +#define LED_TYPE_FAN3_REG_MASK 0x30 +#define LED_TYPE_FAN4_REG_MASK 0xC0 +#define LED_TYPE_FAN5_REG_MASK 0x03 +#define LED_TYPE_FAN6_REG_MASK 0x0C + +#define LED_MODE_FANX_GREEN_MASK 0x01 +#define LED_MODE_FANX_RED_MASK 0x02 +#define LED_MODE_FANX_OFF_MASK 0x00 + +#define LED_TYPE_LOC_REG_MASK 0x30 +#define LED_MODE_LOC_ON_MASK 0x00 +#define LED_MODE_LOC_OFF_MASK 0x10 +#define LED_MODE_LOC_BLINK_MASK 0x20 + +static const u8 led_reg[] = { + 0xA, /* LOC/DIAG/FAN LED*/ + 0xB, /* PSU1/PSU2 LED */ + 0x16, /* FAN1-4 LED */ + 0x17, /* FAN4-6 LED */ +}; + +enum led_type { + LED_TYPE_PSU1, + LED_TYPE_PSU2, + LED_TYPE_DIAG, + LED_TYPE_FAN, + LED_TYPE_FAN1, + LED_TYPE_FAN2, + LED_TYPE_FAN3, + LED_TYPE_FAN4, + LED_TYPE_FAN5, + LED_TYPE_LOC +}; + +enum led_light_mode { + LED_MODE_OFF = 0, + LED_MODE_GREEN, + LED_MODE_AMBER, + LED_MODE_RED, + LED_MODE_GREEN_BLINK, + LED_MODE_AMBER_BLINK, + LED_MODE_RED_BLINK, + LED_MODE_AUTO, +}; + +struct led_type_mode { + enum led_type type; + int type_mask; + enum led_light_mode mode; + int mode_mask; +}; + +static struct led_type_mode led_type_mode_data[] = { +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_GREEN, LED_MODE_PSU1_GREEN_MASK}, +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_AMBER, LED_MODE_PSU1_AMBER_MASK}, +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_AUTO, LED_MODE_PSU1_AUTO_MASK}, +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_OFF, LED_MODE_PSU1_OFF_MASK}, +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_GREEN, LED_MODE_PSU2_GREEN_MASK}, +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_AMBER, LED_MODE_PSU2_AMBER_MASK}, +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_AUTO, LED_MODE_PSU2_AUTO_MASK}, +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_OFF, LED_MODE_PSU2_OFF_MASK}, +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_GREEN, LED_MODE_FAN_GREEN_MASK}, +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_AMBER, LED_MODE_FAN_AMBER_MASK}, +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_AUTO, LED_MODE_FAN_AUTO_MASK}, +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_OFF, LED_MODE_FAN_OFF_MASK}, +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 0}, +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 0}, +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 0}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 2}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 2}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 2}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 4}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 4}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 4}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 6}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 6}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 6}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 0}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 0}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 0}, +{LED_TYPE_DIAG, LED_TYPE_DIAG_REG_MASK, LED_MODE_GREEN, LED_MODE_DIAG_GREEN_MASK}, +{LED_TYPE_DIAG, LED_TYPE_DIAG_REG_MASK, LED_MODE_AMBER, LED_MODE_DIAG_AMBER_MASK}, +{LED_TYPE_DIAG, LED_TYPE_DIAG_REG_MASK, LED_MODE_OFF, LED_MODE_DIAG_OFF_MASK}, +{LED_TYPE_LOC, LED_TYPE_LOC_REG_MASK, LED_MODE_AMBER, LED_MODE_LOC_ON_MASK}, +{LED_TYPE_LOC, LED_TYPE_LOC_REG_MASK, LED_MODE_OFF, LED_MODE_LOC_OFF_MASK}, +{LED_TYPE_LOC, LED_TYPE_LOC_REG_MASK, LED_MODE_AMBER_BLINK, LED_MODE_LOC_BLINK_MASK} +}; + + +struct fanx_info_s { + u8 cname; /* device name */ + enum led_type type; + u8 reg_id; /* map to led_reg & reg_val */ +}; + +static struct fanx_info_s fanx_info[] = { + {'1', LED_TYPE_FAN1, 2}, + {'2', LED_TYPE_FAN2, 2}, + {'3', LED_TYPE_FAN3, 2}, + {'4', LED_TYPE_FAN4, 2}, + {'5', LED_TYPE_FAN5, 3} +}; + +static int led_reg_val_to_light_mode(enum led_type type, u8 reg_val) { + int i; + + for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) { + + if (type != led_type_mode_data[i].type) + continue; + + if ((led_type_mode_data[i].type_mask & reg_val) == + led_type_mode_data[i].mode_mask) + { + return led_type_mode_data[i].mode; + } + } + + return 0; +} + +static u8 led_light_mode_to_reg_val(enum led_type type, + enum led_light_mode mode, u8 reg_val) { + int i; + + for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) { + if (type != led_type_mode_data[i].type) + continue; + + if (mode != led_type_mode_data[i].mode) + continue; + + reg_val = led_type_mode_data[i].mode_mask | + (reg_val & (~led_type_mode_data[i].type_mask)); + } + + return reg_val; +} + +static int accton_as5712_54x_led_read_value(u8 reg) +{ + return as5712_54x_cpld_read(0x60, reg); +} + +static int accton_as5712_54x_led_write_value(u8 reg, u8 value) +{ + return as5712_54x_cpld_write(0x60, reg, value); +} + +static void accton_as5712_54x_led_update(void) +{ + mutex_lock(&ledctl->update_lock); + + if (time_after(jiffies, ledctl->last_updated + HZ + HZ / 2) + || !ledctl->valid) { + int i; + + dev_dbg(&ledctl->pdev->dev, "Starting accton_as5712_54x_led update\n"); + + /* Update LED data + */ + for (i = 0; i < ARRAY_SIZE(ledctl->reg_val); i++) { + int status = accton_as5712_54x_led_read_value(led_reg[i]); + + if (status < 0) { + ledctl->valid = 0; + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", led_reg[i], status); + goto exit; + } + else + { + ledctl->reg_val[i] = status; + } + } + + ledctl->last_updated = jiffies; + ledctl->valid = 1; + } + +exit: + mutex_unlock(&ledctl->update_lock); +} + +static void accton_as5712_54x_led_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode, + u8 reg, enum led_type type) +{ + int reg_val; + + mutex_lock(&ledctl->update_lock); + + reg_val = accton_as5712_54x_led_read_value(reg); + + if (reg_val < 0) { + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", reg, reg_val); + goto exit; + } + + reg_val = led_light_mode_to_reg_val(type, led_light_mode, reg_val); + accton_as5712_54x_led_write_value(reg, reg_val); + + /* to prevent the slow-update issue */ + ledctl->valid = 0; + +exit: + mutex_unlock(&ledctl->update_lock); +} + +static void accton_as5712_54x_led_psu_1_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + accton_as5712_54x_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_PSU1); +} + +static enum led_brightness accton_as5712_54x_led_psu_1_get(struct led_classdev *cdev) +{ + accton_as5712_54x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_PSU1, ledctl->reg_val[1]); +} + +static void accton_as5712_54x_led_psu_2_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + accton_as5712_54x_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_PSU2); +} + +static enum led_brightness accton_as5712_54x_led_psu_2_get(struct led_classdev *cdev) +{ + accton_as5712_54x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_PSU2, ledctl->reg_val[1]); +} + +static void accton_as5712_54x_led_fan_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + accton_as5712_54x_led_set(led_cdev, led_light_mode, led_reg[0], LED_TYPE_FAN); +} + +static enum led_brightness accton_as5712_54x_led_fan_get(struct led_classdev *cdev) +{ + accton_as5712_54x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_FAN, ledctl->reg_val[0]); +} + + +static void accton_as5712_54x_led_fanx_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + enum led_type led_type1; + int reg_id; + int i, nsize; + int ncount = sizeof(fanx_info)/sizeof(struct fanx_info_s); + + for(i=0;iname); + + if (led_cdev->name[nsize-1] == fanx_info[i].cname) + { + led_type1 = fanx_info[i].type; + reg_id = fanx_info[i].reg_id; + accton_as5712_54x_led_set(led_cdev, led_light_mode, led_reg[reg_id], led_type1); + return; + } + } +} + + +static enum led_brightness accton_as5712_54x_led_fanx_get(struct led_classdev *cdev) +{ + enum led_type led_type1; + int reg_id; + int i, nsize; + int ncount = sizeof(fanx_info)/sizeof(struct fanx_info_s); + + for(i=0;iname); + + if (cdev->name[nsize-1] == fanx_info[i].cname) + { + led_type1 = fanx_info[i].type; + reg_id = fanx_info[i].reg_id; + accton_as5712_54x_led_update(); + return led_reg_val_to_light_mode(led_type1, ledctl->reg_val[reg_id]); + } + } + + + return led_reg_val_to_light_mode(LED_TYPE_FAN1, ledctl->reg_val[2]); +} + + +static void accton_as5712_54x_led_diag_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + accton_as5712_54x_led_set(led_cdev, led_light_mode, led_reg[0], LED_TYPE_DIAG); +} + +static enum led_brightness accton_as5712_54x_led_diag_get(struct led_classdev *cdev) +{ + accton_as5712_54x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_DIAG, ledctl->reg_val[0]); +} + +static void accton_as5712_54x_led_loc_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + accton_as5712_54x_led_set(led_cdev, led_light_mode, led_reg[0], LED_TYPE_LOC); +} + +static enum led_brightness accton_as5712_54x_led_loc_get(struct led_classdev *cdev) +{ + accton_as5712_54x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_LOC, ledctl->reg_val[0]); +} + +static struct led_classdev accton_as5712_54x_leds[] = { + [LED_TYPE_PSU1] = { + .name = "accton_as5712_54x_led::psu1", + .default_trigger = "unused", + .brightness_set = accton_as5712_54x_led_psu_1_set, + .brightness_get = accton_as5712_54x_led_psu_1_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_PSU2] = { + .name = "accton_as5712_54x_led::psu2", + .default_trigger = "unused", + .brightness_set = accton_as5712_54x_led_psu_2_set, + .brightness_get = accton_as5712_54x_led_psu_2_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN] = { + .name = "accton_as5712_54x_led::fan", + .default_trigger = "unused", + .brightness_set = accton_as5712_54x_led_fan_set, + .brightness_get = accton_as5712_54x_led_fan_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN1] = { + .name = "accton_as5712_54x_led::fan1", + .default_trigger = "unused", + .brightness_set = accton_as5712_54x_led_fanx_set, + .brightness_get = accton_as5712_54x_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN2] = { + .name = "accton_as5712_54x_led::fan2", + .default_trigger = "unused", + .brightness_set = accton_as5712_54x_led_fanx_set, + .brightness_get = accton_as5712_54x_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN3] = { + .name = "accton_as5712_54x_led::fan3", + .default_trigger = "unused", + .brightness_set = accton_as5712_54x_led_fanx_set, + .brightness_get = accton_as5712_54x_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN4] = { + .name = "accton_as5712_54x_led::fan4", + .default_trigger = "unused", + .brightness_set = accton_as5712_54x_led_fanx_set, + .brightness_get = accton_as5712_54x_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN5] = { + .name = "accton_as5712_54x_led::fan5", + .default_trigger = "unused", + .brightness_set = accton_as5712_54x_led_fanx_set, + .brightness_get = accton_as5712_54x_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_DIAG] = { + .name = "accton_as5712_54x_led::diag", + .default_trigger = "unused", + .brightness_set = accton_as5712_54x_led_diag_set, + .brightness_get = accton_as5712_54x_led_diag_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_LOC] = { + .name = "accton_as5712_54x_led::loc", + .default_trigger = "unused", + .brightness_set = accton_as5712_54x_led_loc_set, + .brightness_get = accton_as5712_54x_led_loc_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, +}; + +static int accton_as5712_54x_led_suspend(struct platform_device *dev, + pm_message_t state) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(accton_as5712_54x_leds); i++) { + led_classdev_suspend(&accton_as5712_54x_leds[i]); + } + + return 0; +} + +static int accton_as5712_54x_led_resume(struct platform_device *dev) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(accton_as5712_54x_leds); i++) { + led_classdev_resume(&accton_as5712_54x_leds[i]); + } + + return 0; +} + +static int accton_as5712_54x_led_probe(struct platform_device *pdev) +{ + int ret, i; + + for (i = 0; i < ARRAY_SIZE(accton_as5712_54x_leds); i++) { + ret = led_classdev_register(&pdev->dev, &accton_as5712_54x_leds[i]); + + if (ret < 0) + break; + } + + /* Check if all LEDs were successfully registered */ + if (i != ARRAY_SIZE(accton_as5712_54x_leds)){ + int j; + + /* only unregister the LEDs that were successfully registered */ + for (j = 0; j < i; j++) { + led_classdev_unregister(&accton_as5712_54x_leds[i]); + } + } + + return ret; +} + +static int accton_as5712_54x_led_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(accton_as5712_54x_leds); i++) { + led_classdev_unregister(&accton_as5712_54x_leds[i]); + } + + return 0; +} + +static struct platform_driver accton_as5712_54x_led_driver = { + .probe = accton_as5712_54x_led_probe, + .remove = accton_as5712_54x_led_remove, + .suspend = accton_as5712_54x_led_suspend, + .resume = accton_as5712_54x_led_resume, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +static int __init accton_as5712_54x_led_init(void) +{ + int ret; + + ret = platform_driver_register(&accton_as5712_54x_led_driver); + if (ret < 0) { + goto exit; + } + + ledctl = kzalloc(sizeof(struct accton_as5712_54x_led_data), GFP_KERNEL); + if (!ledctl) { + ret = -ENOMEM; + platform_driver_unregister(&accton_as5712_54x_led_driver); + goto exit; + } + + mutex_init(&ledctl->update_lock); + + ledctl->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(ledctl->pdev)) { + ret = PTR_ERR(ledctl->pdev); + platform_driver_unregister(&accton_as5712_54x_led_driver); + kfree(ledctl); + goto exit; + } + +exit: + return ret; +} + +static void __exit accton_as5712_54x_led_exit(void) +{ + platform_device_unregister(ledctl->pdev); + platform_driver_unregister(&accton_as5712_54x_led_driver); + kfree(ledctl); +} + +module_init(accton_as5712_54x_led_init); +module_exit(accton_as5712_54x_led_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton_as5712_54x_led driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/ym2651y.c b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/ym2651y.c new file mode 100755 index 000000000000..519530387e29 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/ym2651y.c @@ -0,0 +1,683 @@ +/* + * An hwmon driver for the 3Y Power YM-2651Y Power Module + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#if 0 +#define DEBUG +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_FAN_DUTY_CYCLE 100 + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +enum chips { + YM2651, + YM2401, +}; + +/* Each client has this additional data + */ +struct ym2651y_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 chip; /* chip id */ + u8 capability; /* Register value */ + u16 status_word; /* Register value */ + u8 fan_fault; /* Register value */ + u8 over_temp; /* Register value */ + u16 v_out; /* Register value */ + u16 i_out; /* Register value */ + u16 p_out; /* Register value */ + u8 vout_mode; /* Register value */ + u16 temp; /* Register value */ + u16 fan_speed; /* Register value */ + u16 fan_duty_cycle[2]; /* Register value */ + u8 fan_dir[5]; /* Register value */ + u8 pmbus_revision; /* Register value */ + u8 mfr_id[10]; /* Register value */ + u8 mfr_model[16]; /* Register value */ + u8 mfr_revsion[3]; /* Register value */ + u16 mfr_vin_min; /* Register value */ + u16 mfr_vin_max; /* Register value */ + u16 mfr_iin_max; /* Register value */ + u16 mfr_iout_max; /* Register value */ + u16 mfr_pin_max; /* Register value */ + u16 mfr_pout_max; /* Register value */ + u16 mfr_vout_min; /* Register value */ + u16 mfr_vout_max; /* Register value */ +}; + +static ssize_t show_byte(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_word(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_linear(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_vout(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_over_temp(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_ascii(struct device *dev, struct device_attribute *da, + char *buf); +static struct ym2651y_data *ym2651y_update_device(struct device *dev); +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value); + +enum ym2651y_sysfs_attributes { + PSU_POWER_ON = 0, + PSU_TEMP_FAULT, + PSU_POWER_GOOD, + PSU_FAN1_FAULT, + PSU_FAN_DIRECTION, + PSU_OVER_TEMP, + PSU_V_OUT, + PSU_I_OUT, + PSU_P_OUT, + PSU_TEMP1_INPUT, + PSU_FAN1_SPEED, + PSU_FAN1_DUTY_CYCLE, + PSU_PMBUS_REVISION, + PSU_MFR_ID, + PSU_MFR_MODEL, + PSU_MFR_REVISION, + PSU_MFR_VIN_MIN, + PSU_MFR_VIN_MAX, + PSU_MFR_VOUT_MIN, + PSU_MFR_VOUT_MAX, + PSU_MFR_IIN_MAX, + PSU_MFR_IOUT_MAX, + PSU_MFR_PIN_MAX, + PSU_MFR_POUT_MAX +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(psu_power_on, S_IRUGO, show_word, NULL, PSU_POWER_ON); +static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, show_word, NULL, PSU_TEMP_FAULT); +static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_word, NULL, PSU_POWER_GOOD); +static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, show_fan_fault, NULL, PSU_FAN1_FAULT); +static SENSOR_DEVICE_ATTR(psu_over_temp, S_IRUGO, show_over_temp, NULL, PSU_OVER_TEMP); +static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, show_vout, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, show_linear, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, show_linear, NULL, PSU_P_OUT); +static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); +static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, show_linear, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); +static SENSOR_DEVICE_ATTR(psu_fan_dir, S_IRUGO, show_ascii, NULL, PSU_FAN_DIRECTION); +static SENSOR_DEVICE_ATTR(psu_pmbus_revision,S_IRUGO, show_byte, NULL, PSU_PMBUS_REVISION); +static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, show_ascii, NULL, PSU_MFR_ID); +static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, show_ascii, NULL, PSU_MFR_MODEL); +static SENSOR_DEVICE_ATTR(psu_mfr_revision, S_IRUGO, show_ascii, NULL, PSU_MFR_REVISION); +static SENSOR_DEVICE_ATTR(psu_mfr_vin_min, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MIN); +static SENSOR_DEVICE_ATTR(psu_mfr_vin_max, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_vout_min, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MIN); +static SENSOR_DEVICE_ATTR(psu_mfr_vout_max, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_iin_max, S_IRUGO, show_linear, NULL, PSU_MFR_IIN_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_iout_max, S_IRUGO, show_linear, NULL, PSU_MFR_IOUT_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_pin_max, S_IRUGO, show_linear, NULL, PSU_MFR_PIN_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_pout_max, S_IRUGO, show_linear, NULL, PSU_MFR_POUT_MAX); + +static struct attribute *ym2651y_attributes[] = { + &sensor_dev_attr_psu_power_on.dev_attr.attr, + &sensor_dev_attr_psu_temp_fault.dev_attr.attr, + &sensor_dev_attr_psu_power_good.dev_attr.attr, + &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, + &sensor_dev_attr_psu_over_temp.dev_attr.attr, + &sensor_dev_attr_psu_v_out.dev_attr.attr, + &sensor_dev_attr_psu_i_out.dev_attr.attr, + &sensor_dev_attr_psu_p_out.dev_attr.attr, + &sensor_dev_attr_psu_temp1_input.dev_attr.attr, + &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, + &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, + &sensor_dev_attr_psu_fan_dir.dev_attr.attr, + &sensor_dev_attr_psu_pmbus_revision.dev_attr.attr, + &sensor_dev_attr_psu_mfr_id.dev_attr.attr, + &sensor_dev_attr_psu_mfr_model.dev_attr.attr, + &sensor_dev_attr_psu_mfr_revision.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vin_min.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vin_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_pout_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_iin_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_pin_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vout_min.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vout_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_iout_max.dev_attr.attr, + NULL +}; + +static ssize_t show_byte(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + + if (!data->valid) { + return 0; + } + + return (attr->index == PSU_PMBUS_REVISION) ? sprintf(buf, "%d\n", data->pmbus_revision) : + sprintf(buf, "0\n"); +} + +static ssize_t show_word(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + u16 status = 0; + + if (!data->valid) { + return 0; + } + + switch (attr->index) { + case PSU_POWER_ON: /* psu_power_on, low byte bit 6 of status_word, 0=>ON, 1=>OFF */ + status = (data->status_word & 0x40) ? 0 : 1; + break; + case PSU_TEMP_FAULT: /* psu_temp_fault, low byte bit 2 of status_word, 0=>Normal, 1=>temp fault */ + status = (data->status_word & 0x4) >> 2; + break; + case PSU_POWER_GOOD: /* psu_power_good, high byte bit 3 of status_word, 0=>OK, 1=>FAIL */ + status = (data->status_word & 0x800) ? 0 : 1; + break; + } + + return sprintf(buf, "%d\n", status); +} + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + bool is_negative = valid_data >> (valid_bit - 1); + + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} + +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct ym2651y_data *data = i2c_get_clientdata(client); + int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; + long speed; + int error; + + error = kstrtol(buf, 10, &speed); + if (error) + return error; + + if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) + return -EINVAL; + + mutex_lock(&data->update_lock); + data->fan_duty_cycle[nr] = speed; + ym2651y_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t show_linear(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + + u16 value = 0; + int exponent, mantissa; + int multiplier = 1000; + + if (!data->valid) { + return 0; + } + + switch (attr->index) { + case PSU_V_OUT: + value = data->v_out; + break; + case PSU_I_OUT: + value = data->i_out; + break; + case PSU_P_OUT: + value = data->p_out; + break; + case PSU_TEMP1_INPUT: + value = data->temp; + break; + case PSU_FAN1_SPEED: + value = data->fan_speed; + multiplier = 1; + break; + case PSU_FAN1_DUTY_CYCLE: + value = data->fan_duty_cycle[0]; + multiplier = 1; + break; + case PSU_MFR_VIN_MIN: + value = data->mfr_vin_min; + break; + case PSU_MFR_VIN_MAX: + value = data->mfr_vin_max; + break; + case PSU_MFR_VOUT_MIN: + value = data->mfr_vout_min; + break; + case PSU_MFR_VOUT_MAX: + value = data->mfr_vout_max; + break; + case PSU_MFR_PIN_MAX: + value = data->mfr_pin_max; + break; + case PSU_MFR_POUT_MAX: + value = data->mfr_pout_max; + break; + case PSU_MFR_IOUT_MAX: + value = data->mfr_iout_max; + break; + case PSU_MFR_IIN_MAX: + value = data->mfr_iin_max; + break; + } + + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + + return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + u8 shift; + + if (!data->valid) { + return 0; + } + + shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; + + return sprintf(buf, "%d\n", data->fan_fault >> shift); +} + +static ssize_t show_over_temp(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct ym2651y_data *data = ym2651y_update_device(dev); + + if (!data->valid) { + return 0; + } + + return sprintf(buf, "%d\n", data->over_temp >> 7); +} + +static ssize_t show_ascii(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + u8 *ptr = NULL; + + if (!data->valid) { + return 0; + } + + switch (attr->index) { + case PSU_FAN_DIRECTION: /* psu_fan_dir */ + ptr = data->fan_dir + 1; /* Skip the first byte since it is the length of string. */ + break; + case PSU_MFR_ID: /* psu_mfr_id */ + ptr = data->mfr_id + 1; /* The first byte is the count byte of string. */; + break; + case PSU_MFR_MODEL: /* psu_mfr_model */ + ptr = data->mfr_model + 1; /* The first byte is the count byte of string. */ + break; + case PSU_MFR_REVISION: /* psu_mfr_revision */ + ptr = data->mfr_revsion + 1; /* The first byte is the count byte of string. */ + break; + default: + return 0; + } + + return sprintf(buf, "%s\n", ptr); +} + +static ssize_t show_vout_by_mode(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct ym2651y_data *data = ym2651y_update_device(dev); + int exponent, mantissa; + int multiplier = 1000; + + if (!data->valid) { + return 0; + } + + exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); + mantissa = data->v_out; + + return (exponent > 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static ssize_t show_vout(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct ym2651y_data *data = i2c_get_clientdata(client); + + if (data->chip == YM2401) { + return show_vout_by_mode(dev, da, buf); + } + + return show_linear(dev, da, buf); +} + +static const struct attribute_group ym2651y_group = { + .attrs = ym2651y_attributes, +}; + +static int ym2651y_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct ym2651y_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct ym2651y_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->chip = dev_id->driver_data; + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &ym2651y_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &ym2651y_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int ym2651y_remove(struct i2c_client *client) +{ + struct ym2651y_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &ym2651y_group); + kfree(data); + + return 0; +} + +static const struct i2c_device_id ym2651y_id[] = { + { "ym2651", YM2651 }, + { "ym2401", YM2401 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, ym2651y_id); + +static struct i2c_driver ym2651y_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "ym2651", + }, + .probe = ym2651y_probe, + .remove = ym2651y_remove, + .id_table = ym2651y_id, + .address_list = normal_i2c, +}; + +static int ym2651y_read_byte(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int ym2651y_read_word(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_word_data(client, reg); +} + +static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value) +{ + return i2c_smbus_write_word_data(client, reg, value); +} + +static int ym2651y_read_block(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ + int result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + + if (unlikely(result < 0)) + goto abort; + if (unlikely(result != data_len)) { + result = -EIO; + goto abort; + } + + result = 0; + +abort: + return result; +} + +struct reg_data_byte { + u8 reg; + u8 *value; +}; + +struct reg_data_word { + u8 reg; + u16 *value; +}; + +static struct ym2651y_data *ym2651y_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct ym2651y_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int i, status, length; + u8 command, buf; + struct reg_data_byte regs_byte[] = { {0x19, &data->capability}, + {0x20, &data->vout_mode}, + {0x7d, &data->over_temp}, + {0x81, &data->fan_fault}, + {0x98, &data->pmbus_revision}}; + struct reg_data_word regs_word[] = { {0x79, &data->status_word}, + {0x8b, &data->v_out}, + {0x8c, &data->i_out}, + {0x96, &data->p_out}, + {0x8d, &data->temp}, + {0x3b, &(data->fan_duty_cycle[0])}, + {0x3c, &(data->fan_duty_cycle[1])}, + {0x90, &data->fan_speed}, + {0xa0, &data->mfr_vin_min}, + {0xa1, &data->mfr_vin_max}, + {0xa2, &data->mfr_iin_max}, + {0xa3, &data->mfr_pin_max}, + {0xa4, &data->mfr_vout_min}, + {0xa5, &data->mfr_vout_max}, + {0xa6, &data->mfr_iout_max}, + {0xa7, &data->mfr_pout_max}}; + + dev_dbg(&client->dev, "Starting ym2651 update\n"); + data->valid = 0; + + /* Read byte data */ + for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { + status = ym2651y_read_byte(client, regs_byte[i].reg); + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_byte[i].reg, status); + goto exit; + } + else { + *(regs_byte[i].value) = status; + } + } + + /* Read word data */ + for (i = 0; i < ARRAY_SIZE(regs_word); i++) { + status = ym2651y_read_word(client, regs_word[i].reg); + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_word[i].reg, status); + goto exit; + } + else { + *(regs_word[i].value) = status; + } + } + + /* Read fan_direction */ + command = 0xC3; + status = ym2651y_read_block(client, command, data->fan_dir, + ARRAY_SIZE(data->fan_dir)-1); + data->fan_dir[ARRAY_SIZE(data->fan_dir)-1] = '\0'; + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + goto exit; + } + + /* Read mfr_id */ + command = 0x99; + status = ym2651y_read_block(client, command, data->mfr_id, + ARRAY_SIZE(data->mfr_id)-1); + data->mfr_id[ARRAY_SIZE(data->mfr_id)-1] = '\0'; + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + goto exit; + } + + /* Read mfr_model */ + command = 0x9a; + length = 1; + + /* Read first byte to determine the length of data */ + status = ym2651y_read_block(client, command, &buf, length); + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + goto exit; + } + + status = ym2651y_read_block(client, command, data->mfr_model, buf+1); + data->mfr_model[buf+1] = '\0'; + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + goto exit; + } + + /* Read mfr_revsion */ + command = 0x9b; + status = ym2651y_read_block(client, command, data->mfr_revsion, + ARRAY_SIZE(data->mfr_revsion)-1); + data->mfr_revsion[ARRAY_SIZE(data->mfr_revsion)-1] = '\0'; + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + goto exit; + } + + data->last_updated = jiffies; + data->valid = 1; + } + +exit: + mutex_unlock(&data->update_lock); + + return data; +} + +static int __init ym2651y_init(void) +{ + return i2c_add_driver(&ym2651y_driver); +} + +static void __exit ym2651y_exit(void) +{ + i2c_del_driver(&ym2651y_driver); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("3Y Power YM-2651Y driver"); +MODULE_LICENSE("GPL"); + +module_init(ym2651y_init); +module_exit(ym2651y_exit); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/service/as5712-platform-monitor.service b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/service/as5712-platform-monitor.service new file mode 100755 index 000000000000..da5d283a6d61 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/service/as5712-platform-monitor.service @@ -0,0 +1,17 @@ +[Unit] +Description=Accton AS5712-54X Platform Monitoring service +Before=pmon.service +After=sysinit.target +DefaultDependencies=no + +[Service] +ExecStartPre=/usr/local/bin/accton_as5712_util.py install +ExecStart=/usr/local/bin/accton_as5712_monitor.py +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/setup.py b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/setup.py new file mode 100755 index 000000000000..f4cb5f960a4d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/setup.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python + +import os +import sys +from setuptools import setup +os.listdir + +setup( + name='as5712_54x', + version='1.0', + description='Module to initialize Accton AS5712-54X platforms', + + packages=['as5712_54x'], + package_dir={'as5712_54x': 'as5712-54x/classes'}, +) + diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/README b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/README new file mode 100755 index 000000000000..44e03cab5f52 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/README @@ -0,0 +1,117 @@ +Copyright (C) 2016 Accton Networks, 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 3 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, see . + +Contents of this package: + patch - files under patch/ is for kernel and ONIE installer + for the kernel: + config-accton-as5712_54x.patch + for kernel configuration. + driver-i2c-muxes-pca954x-always-deselect.patch + for i2c_mux deselects after transaction. + driver-patches-for-accton-as5712-fan-psu-cpld.patch + for as5712's fan/psu/cpld/led/sfp drivers. + for ONIE: + onie_installer-accton-AS5712-54X.patch + for console port setting and copy util script o rootfs. + module - Contains source code of as5712 kernel driver modules. + +The late Sonic building scripts, pushed @Dec 5 2016, will automatically +create a docker container and run building process under it. +User is not necessary to handle docker environment creation. + +1. Download sonic-buildimage environment. + - Run "git clone https://github.com/Azure/sonic-buildimage". + - cd to sonic-buildimage and run "git submodule update --init --recursive". +2. Build kernel + - cd ./src/sonic-linux-kernel + - Copy patches and series from patch/kernel of this release to + sonic-linux-kernel/patch. + - Build kernel by "make". + - The built kernel package, linux-image-3.16.0-5-amd64_3.16.51-3+deb8u1_amd64.deb + , is generated. +3. Build installer + - Change directory back to sonic-buildimage/. + - Get onie_installer-accton-AS5712-54X.patch" from patch/installer. + - Change setting for AS5712-54X by patching build_image.sh. + "patch -p1 < onie_installer-accton-AS5712-54X.patch" + !!NOTICE, patching onie_installer-accton-AS5712-54X.patch comments out the + "git status" checking at build_image.sh. + - The account and password of installed OS can be given at rules/config. + The default user and password are "admin" & "YourPaSsWoRd" respectively. + - Run "make configure PLATFORM=broadcom" + - Copy the built kernel debian package to target/debs/. + The file is linux-image-3.16.0-5-amd64_*_amd64.deb under directory + src/sonic-linux-kernel/. + - Run "make target/sonic-generic.bin" + - Get the installer, target/sonic-generic.bin, to target machine and install. + +All Linux kernel code is licensed under the GPLv1. All other code is +licensed under the GPLv3. Please see the LICENSE file for copies of +both licenses. + +The code for integacting with Accton AS5712-54X has 2 parts, +kernel drivers and operational script. +The kernel drivers of peripherals are under module/ directory. +1. These drivers are patched into kernel by + driver-patches-for-accton-as5712-fan-psu-cpld.patch + Or you can build the driver under module/ by setting environment variable, + KERNEL_SRC, to proper linux built directory and run make. + It may be sonic-linux-kernel/linux-3.*/debian/build/build_amd64_none_amd64/. +2. A operational script, accton_as5712_util.py, for device initializatian and + peripheral accessing should be installed at /usr/bin. + This script is generated by onie_installer-accton-AS5712-54X.patch. + It's done by patching onie_installer-accton-AS5712-54X.patch at build-image. + Run "accton_as5712_util.py install" to install drivers. + +To initialize the system, run "accton_as5712_util.py install". +To clean up the drivers & devices, run "accton_as5712_util.py clean". +To dump information of sensors, run "accton_as5712_util.py show". +To dump SFP EEPROM, run "accton_as5712_util.py sff". +To set fan speed, run "accton_as5712_util.py set fan". +To enable/disable SFP emission, run "accton_as5712_util.py set sfp". +To set system LEDs' color, run "accton_as5712_util.py set led" +For more information, run "accton_as5712_util.py --help". + +==================================================================== +Besides applying accton_as5712_util.py to access peripherals, you can +access peripherals by sysfs nodes directly after the installation is run. + +System LED: + There are 5 system LEDs at the lower-left corner of front panel. + They are loc, diag, fan, ps1, and ps2. + The sysfs interface color mappings are as follows: + Brightness: + 0 => off + 1 => green + 2 => amber + 3 => red + 4 => blue + But not all colors are available for each LED. + +Fan Control: + There are 10 fans inside 5 fan modules. + All fans share 1 duty setting, ranged from 0~100. + +Thermal sensers: + 3 temperature sensors are controlled by the lm75 kernel modules. + +PSUs: + There 2 power supplies slot at the left/right side of the back. + Once if a PSU is not plugged, the status of it is shown failed. + +There are 48 SFP+ and 6 QSFP modules are equipped. +Before operating on PSU and QSFP+, please make sure it is well plugged. +Otherwise, operation is going to fail. + diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_monitor.py new file mode 100755 index 000000000000..84ab2d83bab4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_monitor.py @@ -0,0 +1,195 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 Accton Technology Corporation +# +# 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 3 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, see . + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 11/13/2017: Polly Hsu, Create +# +# ------------------------------------------------------------------ + +try: + import os + import sys, getopt + import subprocess + import click + import imp + import logging + import logging.config + import types + import time # this is only being used as part of the example + import traceback + from tabulate import tabulate + from as5712_54x.fanutil import FanUtil + from as5712_54x.thermalutil import ThermalUtil +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + +# Deafults +VERSION = '1.0' +FUNCTION_NAME = 'accton_as5712_monitor' + +global log_file +global log_level + +# Make a class we can use to capture stdout and sterr in the log +class accton_as5712_monitor(object): + # static temp var + _ori_temp = 0 + _new_perc = 0 + _ori_perc = 0 + + def __init__(self, log_file, log_level): + """Needs a logger and a logger level.""" + # set up logging to file + logging.basicConfig( + filename=log_file, + filemode='w', + level=log_level, + format= '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s', + datefmt='%H:%M:%S' + ) + + # set up logging to console + if log_level == logging.DEBUG: + console = logging.StreamHandler() + console.setLevel(log_level) + formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') + console.setFormatter(formatter) + logging.getLogger('').addHandler(console) + + logging.debug('SET. logfile:%s / loglevel:%d', log_file, log_level) + + def manage_fans(self): + FAN_LEV1_UP_TEMP = 57500 # temperature + FAN_LEV1_DOWN_TEMP = 0 # unused + FAN_LEV1_SPEED_PERC = 100 # percentage*/ + + FAN_LEV2_UP_TEMP = 53000 + FAN_LEV2_DOWN_TEMP = 52700 + FAN_LEV2_SPEED_PERC = 80 + + FAN_LEV3_UP_TEMP = 49500 + FAN_LEV3_DOWN_TEMP = 47700 + FAN_LEV3_SPEED_PERC = 65 + + FAN_LEV4_UP_TEMP = 0 # unused + FAN_LEV4_DOWN_TEMP = 42700 + FAN_LEV4_SPEED_PERC = 40 + + + thermal = ThermalUtil() + fan = FanUtil() + + temp1 = thermal.get_thermal_1_val() + if temp1 is None: + return False + + temp2 = thermal.get_thermal_2_val() + if temp2 is None: + return False + + new_temp = (temp1 + temp2) / 2 + + for x in range(fan.get_idx_fan_start(), fan.get_num_fans()+1): + fan_stat = fan.get_fan_status(x) + if fan_stat is None: + return False + if fan_stat is False: + self._new_perc = FAN_LEV1_SPEED_PERC + logging.debug('INFO. SET new_perc to %d (FAN fault. fan_num:%d)', self._new_perc, x) + break + logging.debug('INFO. fan_stat is True (fan_num:%d)', x) + + if fan_stat is not None and fan_stat is not False: + diff = new_temp - self._ori_temp + if diff == 0: + logging.debug('INFO. RETURN. THERMAL temp not changed. %d / %d (new_temp / ori_temp)', new_temp, self._ori_temp) + return True + else: + if diff >= 0: + is_up = True + logging.debug('INFO. THERMAL temp UP %d / %d (new_temp / ori_temp)', new_temp, self._ori_temp) + else: + is_up = False + logging.debug('INFO. THERMAL temp DOWN %d / %d (new_temp / ori_temp)', new_temp, self._ori_temp) + + if is_up is True: + if new_temp >= FAN_LEV1_UP_TEMP: + self._new_perc = FAN_LEV1_SPEED_PERC + elif new_temp >= FAN_LEV2_UP_TEMP: + self._new_perc = FAN_LEV2_SPEED_PERC + elif new_temp >= FAN_LEV3_UP_TEMP: + self._new_perc = FAN_LEV3_SPEED_PERC + else: + self._new_perc = FAN_LEV4_SPEED_PERC + logging.debug('INFO. SET. FAN_SPEED as %d (new THERMAL temp:%d)', self._new_perc, new_temp) + else: + if new_temp <= FAN_LEV4_DOWN_TEMP: + self._new_perc = FAN_LEV4_SPEED_PERC + elif new_temp <= FAN_LEV3_DOWN_TEMP: + self._new_perc = FAN_LEV3_SPEED_PERC + elif new_temp <= FAN_LEV2_DOWN_TEMP: + self._new_perc = FAN_LEV2_SPEED_PERC + else: + self._new_perc = FAN_LEV1_SPEED_PERC + logging.debug('INFO. SET. FAN_SPEED as %d (new THERMAL temp:%d)', self._new_perc, new_temp) + + if self._ori_perc == self._new_perc: + logging.debug('INFO. RETURN. FAN speed not changed. %d / %d (new_perc / ori_perc)', self._new_perc, self._ori_perc) + return True + + set_stat = fan.set_fan_duty_cycle(fan.get_idx_fan_start(), self._new_perc) + if set_stat is True: + logging.debug('INFO: PASS. set_fan_duty_cycle (%d)', self._new_perc) + else: + logging.debug('INFO: FAIL. set_fan_duty_cycle (%d)', self._new_perc) + + logging.debug('INFO: GET. ori_perc is %d. ori_temp is %d', self._ori_perc, self._ori_temp) + self._ori_perc = self._new_perc + self._ori_temp = new_temp + logging.debug('INFO: UPDATE. ori_perc to %d. ori_temp to %d', self._ori_perc, self._ori_temp) + + return True + +def main(argv): + log_file = '%s.log' % FUNCTION_NAME + log_level = logging.INFO + if len(sys.argv) != 1: + try: + opts, args = getopt.getopt(argv,'hdl:',['lfile=']) + except getopt.GetoptError: + print 'Usage: %s [-d] [-l ]' % sys.argv[0] + return 0 + for opt, arg in opts: + if opt == '-h': + print 'Usage: %s [-d] [-l ]' % sys.argv[0] + return 0 + elif opt in ('-d', '--debug'): + log_level = logging.DEBUG + elif opt in ('-l', '--lfile'): + log_file = arg + + monitor = accton_as5712_monitor(log_file, log_level) + + # Loop forever, doing something useful hopefully: + while True: + monitor.manage_fans() + time.sleep(1) + +if __name__ == '__main__': + main(sys.argv[1:]) diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_util.py b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_util.py new file mode 100755 index 000000000000..e958cb596862 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_util.py @@ -0,0 +1,602 @@ +#!/usr/bin/env python +# +# Copyright (C) 2016 Accton Networks, 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 3 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, see . + +""" +Usage: %(scriptName)s [options] command object + +options: + -h | --help : this help message + -d | --debug : run with debug mode + -f | --force : ignore error during installation or clean +command: + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes + show : show all systen status + sff : dump SFP eeprom + set : change board setting with fan|led|sfp +""" + +import os +import commands +import sys, getopt +import logging +import re +import time +from collections import namedtuple + +PROJECT_NAME = 'as5712_54x' +version = '0.2.0' +verbose = False +DEBUG = False +args = [] +ALL_DEVICE = {} +DEVICE_NO = {'led':5, 'fan1':1, 'fan2':1,'fan3':1,'fan4':1,'fan5':1,'thermal':3, 'psu':2, 'sfp':54} + + +led_prefix ='/sys/devices/platform/as5712_54x_led/leds/accton_'+PROJECT_NAME+'_led::' +fan_prefix ='/sys/devices/platform/as5712_54x_' +hwmon_types = {'led': ['diag','fan','loc','psu1','psu2'], + 'fan1': ['fan'], + 'fan2': ['fan'], + 'fan3': ['fan'], + 'fan4': ['fan'], + 'fan5': ['fan'], + } +hwmon_nodes = {'led': ['brightness'] , + 'fan1': ['fan1_duty_cycle_percentage', 'fan1_fault', 'fan1_speed_rpm', 'fan1_direction', 'fanr1_fault', 'fanr1_speed_rpm'], + 'fan2': ['fan2_duty_cycle_percentage','fan2_fault', 'fan2_speed_rpm', 'fan2_direction', 'fanr2_fault', 'fanr2_speed_rpm'], + 'fan3': ['fan3_duty_cycle_percentage','fan3_fault', 'fan3_speed_rpm', 'fan3_direction', 'fanr3_fault', 'fanr3_speed_rpm'], + 'fan4': ['fan4_duty_cycle_percentage','fan4_fault', 'fan4_speed_rpm', 'fan4_direction', 'fanr4_fault', 'fanr4_speed_rpm'], + 'fan5': ['fan5_duty_cycle_percentage','fan5_fault', 'fan5_speed_rpm', 'fan5_direction', 'fanr5_fault', 'fanr5_speed_rpm'], + } +hwmon_prefix ={'led': led_prefix, + 'fan1': fan_prefix, + 'fan2': fan_prefix, + 'fan3': fan_prefix, + 'fan4': fan_prefix, + 'fan5': fan_prefix, + } + +i2c_prefix = '/sys/bus/i2c/devices/' +i2c_bus = {'thermal': ['61-0048','62-0049', '63-004a'] , + 'psu': ['57-0050','58-0053'], + 'sfp': ['-0050']} +i2c_nodes = { + 'thermal': ['hwmon/hwmon*/temp1_input'] , + 'psu': ['psu_present ', 'psu_power_good'] , + 'sfp': ['sfp_is_present ', 'sfp_tx_disable']} + +sfp_map = [2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 52, 54, 51, 53, 55] +mknod =[ +'echo as5712_54x_cpld1 0x60 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo as5712_54x_cpld2 0x61 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo as5712_54x_cpld3 0x62 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-1/new_device', + +# PSU-1 +'echo as5712_54x_psu1 0x38 > /sys/bus/i2c/devices/i2c-57/new_device', +'echo cpr_4011_4mxx 0x3c > /sys/bus/i2c/devices/i2c-57/new_device', +'echo as5712_54x_psu1 0x50 > /sys/bus/i2c/devices/i2c-57/new_device', + +# PSU-2 +'echo as5712_54x_psu2 0x3b > /sys/bus/i2c/devices/i2c-58/new_device', +'echo cpr_4011_4mxx 0x3f > /sys/bus/i2c/devices/i2c-58/new_device', +'echo as5712_54x_psu2 0x53 > /sys/bus/i2c/devices/i2c-58/new_device', + +'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-61/new_device', +'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-62/new_device', +'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-63/new_device', + +#EERPOM +'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-1/new_device', +] + +mknod2 =[ +'echo as5712_54x_cpld1 0x60 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo as5712_54x_cpld2 0x61 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo as5712_54x_cpld3 0x62 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-0/new_device', + +# PSU-1 +'echo as5712_54x_psu1 0x38 > /sys/bus/i2c/devices/i2c-57/new_device', +'echo cpr_4011_4mxx 0x3c > /sys/bus/i2c/devices/i2c-57/new_device', +'echo as5712_54x_psu1 0x50 > /sys/bus/i2c/devices/i2c-57/new_device', + +# PSU-2 +'echo as5712_54x_psu2 0x3b > /sys/bus/i2c/devices/i2c-58/new_device', +'echo cpr_4011_4mxx 0x3f > /sys/bus/i2c/devices/i2c-58/new_device', +'echo as5712_54x_psu2 0x53 > /sys/bus/i2c/devices/i2c-58/new_device', + +'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-61/new_device', +'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-62/new_device', +'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-63/new_device', + +#EERPOM +'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-1/new_device', +] + +FORCE = 0 +logging.basicConfig(filename= PROJECT_NAME+'.log', filemode='w',level=logging.DEBUG) +logging.basicConfig(level=logging.INFO) + + +if DEBUG == True: + print sys.argv[0] + print 'ARGV :', sys.argv[1:] + + +def main(): + global DEBUG + global args + global FORCE + + if len(sys.argv)<2: + show_help() + + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', + 'debug', + 'force', + ]) + if DEBUG == True: + print options + print args + print len(sys.argv) + + for opt, arg in options: + if opt in ('-h', '--help'): + show_help() + elif opt in ('-d', '--debug'): + DEBUG = True + logging.basicConfig(level=logging.INFO) + elif opt in ('-f', '--force'): + FORCE = 1 + else: + logging.info('no option') + for arg in args: + if arg == 'install': + do_install() + elif arg == 'clean': + do_uninstall() + elif arg == 'show': + device_traversal() + elif arg == 'sff': + if len(args)!=2: + show_eeprom_help() + elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']: + show_eeprom_help() + else: + show_eeprom(args[1]) + return + elif arg == 'set': + if len(args)<3: + show_set_help() + else: + set_device(args[1:]) + return + else: + show_help() + + + return 0 + +def show_help(): + print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + sys.exit(0) + +def show_set_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print cmd +" [led|sfp|fan]" + print " use \""+ cmd + " led 0-4 \" to set led color" + print " use \""+ cmd + " fan 0-100\" to set fan duty percetage" + print " use \""+ cmd + " sfp 1-54 {0|1}\" to set sfp# tx_disable" + sys.exit(0) + +def show_eeprom_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print " use \""+ cmd + " 1-54 \" to dump sfp# eeprom" + sys.exit(0) + +def my_log(txt): + if DEBUG == True: + print "[ACCTON DBG]: "+txt + return + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status = 1 + output = "" + status, output = commands.getstatusoutput(cmd) + my_log (cmd +"with result:" + str(status)) + my_log ("cmd:" + cmd) + my_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + +def driver_inserted(): + ret, lsmod = log_os_system("lsmod| grep accton", 0) + logging.info('mods:'+lsmod) + if len(lsmod) ==0: + return False + + + +kos = [ +'depmod -ae', +'modprobe i2c_dev', +'modprobe i2c_mux_pca954x', +'modprobe optoe', +'modprobe i2c-mux-accton_as5712_54x_cpld', +'modprobe cpr_4011_4mxx', +'modprobe ym2651y', +'modprobe accton_as5712_54x_fan', +'modprobe leds-accton_as5712_54x', +'modprobe accton_as5712_54x_psu'] + +def driver_install(): + global FORCE + for i in range(0,len(kos)): + status, output = log_os_system(kos[i], 1) + if status: + if FORCE == 0: + return status + return 0 + +def driver_uninstall(): + global FORCE + for i in range(0,len(kos)): + rm = kos[-(i+1)].replace("modprobe", "modprobe -rq") + rm = rm.replace("insmod", "rmmod") + status, output = log_os_system(rm, 1) + if status: + if FORCE == 0: + return status + return 0 + + + +def i2c_order_check(): + # i2c bus 0 and 1 might be installed in different order. + # Here check if 0x70 is exist @ i2c-0 + tmp = "echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-1/new_device" + status, output = log_os_system(tmp, 0) + if not device_exist(): + order = 1 + else: + order = 0 + tmp = "echo 0x70 > /sys/bus/i2c/devices/i2c-1/delete_device" + status, output = log_os_system(tmp, 0) + return order + +def device_install(): + global FORCE + + order = i2c_order_check() + # if 0x76 is not exist @i2c-0, use reversed bus order + if order: + for i in range(0,len(mknod2)): + #for pca954x need times to built new i2c buses + if mknod2[i].find('pca954') != -1: + time.sleep(2) + + status, output = log_os_system(mknod2[i], 1) + if status: + print output + if FORCE == 0: + return status + else: + for i in range(0,len(mknod)): + #for pca954x need times to built new i2c buses + if mknod[i].find('pca954') != -1: + time.sleep(2) + + status, output = log_os_system(mknod[i], 1) + if status: + print output + if FORCE == 0: + return status + + for i in range(0,len(sfp_map)): + status, output =log_os_system("echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + status, output =log_os_system("echo port"+str(i)+" > /sys/bus/i2c/devices/"+str(sfp_map[i])+"-0050/port_name", 1) + if status: + print output + if FORCE == 0: + return status + + return + +def device_uninstall(): + global FORCE + + status, output =log_os_system("ls /sys/bus/i2c/devices/0-0070", 0) + if status==0: + I2C_ORDER=1 + else: + I2C_ORDER=0 + + for i in range(0,len(sfp_map)): + target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device" + status, output =log_os_system("echo 0x50 > "+ target, 1) + if status: + print output + if FORCE == 0: + return status + + if I2C_ORDER==0: + nodelist = mknod + else: + nodelist = mknod2 + + for i in range(len(nodelist)): + target = nodelist[-(i+1)] + temp = target.split() + del temp[1] + temp[-1] = temp[-1].replace('new_device', 'delete_device') + status, output = log_os_system(" ".join(temp), 1) + if status: + print output + if FORCE == 0: + return status + + return + +def system_ready(): + if driver_inserted() == False: + return False + if not device_exist(): + return False + return True + +def do_install(): + print "Checking system...." + if driver_inserted() == False: + print "No driver, installing...." + status = driver_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" drivers detected...." + if not device_exist(): + print "No device, installing...." + status = device_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" devices detected...." + return + +def do_uninstall(): + print "Checking system...." + if not device_exist(): + print PROJECT_NAME.upper() +" has no device installed...." + else: + print "Removing device...." + status = device_uninstall() + if status: + if FORCE == 0: + return status + + if driver_inserted()== False : + print PROJECT_NAME.upper() +" has no driver installed...." + else: + print "Removing installed driver...." + status = driver_uninstall() + if status: + if FORCE == 0: + return status + + return + +def devices_info(): + global DEVICE_NO + global ALL_DEVICE + global i2c_bus, hwmon_types + for key in DEVICE_NO: + ALL_DEVICE[key]= {} + for i in range(0,DEVICE_NO[key]): + ALL_DEVICE[key][key+str(i+1)] = [] + + for key in i2c_bus: + buses = i2c_bus[key] + nodes = i2c_nodes[key] + for i in range(0,len(buses)): + for j in range(0,len(nodes)): + if 'fan' == key: + for k in range(0,DEVICE_NO[key]): + node = key+str(k+1) + path = i2c_prefix+ buses[i]+"/fan"+str(k+1)+"_"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + elif 'sfp' == key: + for k in range(0,DEVICE_NO[key]): + node = key+str(k+1) + path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + else: + node = key+str(i+1) + path = i2c_prefix+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + + for key in hwmon_types: + itypes = hwmon_types[key] + nodes = hwmon_nodes[key] + for i in range(0,len(itypes)): + for j in range(0,len(nodes)): + node = key+"_"+itypes[i] + path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][ key+str(i+1)].append(path) + + #show dict all in the order + if DEBUG == True: + for i in sorted(ALL_DEVICE.keys()): + print(i+": ") + for j in sorted(ALL_DEVICE[i].keys()): + print(" "+j) + for k in (ALL_DEVICE[i][j]): + print(" "+" "+k) + return + +def show_eeprom(index): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0] + node = node.replace(node.split("/")[-1], 'sfp_eeprom') + # check if got hexdump command in current environment + ret, log = log_os_system("which hexdump", 0) + ret, log2 = log_os_system("which busybox hexdump", 0) + if len(log): + hex_cmd = 'hexdump' + elif len(log2): + hex_cmd = ' busybox hexdump' + else: + log = 'Failed : no hexdump cmd!!' + logging.info(log) + print log + return 1 + + print node + ":" + ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1) + if ret==0: + print log + else: + print "**********device no found**********" + return + +def set_device(args): + global DEVICE_NO + global ALL_DEVICE + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + + if args[0]=='led': + if int(args[1])>4: + show_set_help() + return + #print ALL_DEVICE['led'] + for i in range(0,len(ALL_DEVICE['led'])): + for k in (ALL_DEVICE['led']['led'+str(i+1)]): + ret, log = log_os_system("echo "+args[1]+" >"+k, 1) + if ret: + return ret + elif args[0]=='fan': + if int(args[1])>100: + show_set_help() + return + #print ALL_DEVICE['fan'] + #fan1~6 is all fine, all fan share same setting + node = ALL_DEVICE['fan1'] ['fan11'][0] + node = node.replace(node.split("/")[-1], 'fan1_duty_cycle_percentage') + ret, log = log_os_system("cat "+ node, 1) + if ret==0: + print ("Previous fan duty: " + log.strip() +"%") + ret, log = log_os_system("echo "+args[1]+" >"+node, 1) + if ret==0: + print ("Current fan duty: " + args[1] +"%") + return ret + elif args[0]=='sfp': + if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0: + show_set_help() + return + if len(args)<2: + show_set_help() + return + + if int(args[2])>1: + show_set_help() + return + + #print ALL_DEVICE[args[0]] + for i in range(0,len(ALL_DEVICE[args[0]])): + for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]: + if j.find('tx_disable')!= -1: + ret, log = log_os_system("echo "+args[2]+" >"+ j, 1) + if ret: + return ret + + return + +#get digits inside a string. +#Ex: 31 for "sfp31" +def get_value(input): + digit = re.findall('\d+', input) + return int(digit[0]) + +def device_traversal(): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + for i in sorted(ALL_DEVICE.keys()): + print("============================================") + print(i.upper()+": ") + print("============================================") + + for j in sorted(ALL_DEVICE[i].keys(), key=get_value): + print " "+j+":", + for k in (ALL_DEVICE[i][j]): + ret, log = log_os_system("cat "+k, 0) + func = k.split("/")[-1].strip() + func = re.sub(j+'_','',func,1) + func = re.sub(i.lower()+'_','',func,1) + if ret==0: + print func+"="+log+" ", + else: + print func+"="+"X"+" ", + print + print("----------------------------------------------------------------") + + + print + return + +def device_exist(): + ret1, log = log_os_system("ls "+i2c_prefix+"*0070", 0) + ret2, log = log_os_system("ls "+i2c_prefix+"i2c-2", 0) + return not(ret1 or ret2) + +if __name__ == "__main__": + main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/Makefile b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/Makefile new file mode 100644 index 000000000000..697dcff656c3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/Makefile @@ -0,0 +1,4 @@ +obj-m:=accton_i2c_cpld.o x86-64-accton-as5812-54t-fan.o \ + x86-64-accton-as5812-54t-leds.o x86-64-accton-as5812-54t-psu.o \ + x86-64-accton-as5812-54t-sfp.o ym2651y.o + diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/accton_i2c_cpld.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/accton_i2c_cpld.c new file mode 100644 index 000000000000..c01d6bcca228 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/accton_i2c_cpld.c @@ -0,0 +1,330 @@ +/* + * A hwmon driver for the accton_i2c_cpld + * + * Copyright (C) 2013 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include + +static LIST_HEAD(cpld_client_list); +static struct mutex list_lock; + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; + +/* Addresses scanned for accton_i2c_cpld + */ +static const unsigned short normal_i2c[] = { 0x31, 0x35, 0x60, 0x61, 0x62, 0x64, I2C_CLIENT_END }; + +static ssize_t show_cpld_version(struct device *dev, struct device_attribute *attr, char *buf) +{ + int val = 0; + struct i2c_client *client = to_i2c_client(dev); + + val = i2c_smbus_read_byte_data(client, 0x1); + + if (val < 0) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x1) err %d\n", client->addr, val); + } + + return sprintf(buf, "%d", val); +} + +static struct device_attribute ver = __ATTR(version, 0600, show_cpld_version, NULL); + +static void accton_i2c_cpld_add_client(struct i2c_client *client) +{ + struct cpld_client_node *node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", client->addr); + return; + } + + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &cpld_client_list); + mutex_unlock(&list_lock); +} + +static void accton_i2c_cpld_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client == client) { + found = 1; + break; + } + } + + if (found) { + list_del(list_node); + kfree(cpld_node); + } + + mutex_unlock(&list_lock); +} + +static int accton_i2c_cpld_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_dbg(&client->dev, "i2c_check_functionality failed (0x%x)\n", client->addr); + status = -EIO; + goto exit; + } + + status = sysfs_create_file(&client->dev.kobj, &ver.attr); + if (status) { + goto exit; + } + + dev_info(&client->dev, "chip found\n"); + accton_i2c_cpld_add_client(client); + + return 0; + +exit: + return status; +} + +static int accton_i2c_cpld_remove(struct i2c_client *client) +{ + sysfs_remove_file(&client->dev.kobj, &ver.attr); + accton_i2c_cpld_remove_client(client); + + return 0; +} + +static const struct i2c_device_id accton_i2c_cpld_id[] = { + { "accton_i2c_cpld", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, accton_i2c_cpld_id); + +static struct i2c_driver accton_i2c_cpld_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "accton_i2c_cpld", + }, + .probe = accton_i2c_cpld_probe, + .remove = accton_i2c_cpld_remove, + .id_table = accton_i2c_cpld_id, + .address_list = normal_i2c, +}; + +int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EPERM; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = i2c_smbus_read_byte_data(cpld_node->client, reg); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(accton_i2c_cpld_read); + +int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EIO; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = i2c_smbus_write_byte_data(cpld_node->client, reg, value); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(accton_i2c_cpld_write); + +static int __init accton_i2c_cpld_init(void) +{ + mutex_init(&list_lock); + return i2c_add_driver(&accton_i2c_cpld_driver); +} + +static void __exit accton_i2c_cpld_exit(void) +{ + i2c_del_driver(&accton_i2c_cpld_driver); +} + +static struct dmi_system_id as7512_dmi_table[] = { + { + .ident = "Accton AS7512", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Accton"), + DMI_MATCH(DMI_PRODUCT_NAME, "AS7512"), + }, + }, + { + .ident = "Accton AS7512", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Accton"), + DMI_MATCH(DMI_PRODUCT_NAME, "AS7512"), + }, + }, +}; + +int platform_accton_as7512_32x(void) +{ + return dmi_check_system(as7512_dmi_table); +} +EXPORT_SYMBOL(platform_accton_as7512_32x); + +static struct dmi_system_id as7712_dmi_table[] = { + { + .ident = "Accton AS7712", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Accton"), + DMI_MATCH(DMI_PRODUCT_NAME, "AS7712"), + }, + }, + { + .ident = "Accton AS7712", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Accton"), + DMI_MATCH(DMI_PRODUCT_NAME, "AS7712"), + }, + }, +}; + +int platform_accton_as7712_32x(void) +{ + return dmi_check_system(as7712_dmi_table); +} +EXPORT_SYMBOL(platform_accton_as7712_32x); + +static struct dmi_system_id as5812_54t_dmi_table[] = { + { + .ident = "Accton AS5812 54t", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Accton"), + DMI_MATCH(DMI_PRODUCT_NAME, "AS5812-54T"), + }, + }, + { + .ident = "Accton AS5812 54t", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Accton"), + DMI_MATCH(DMI_PRODUCT_NAME, "AS5812-54T"), + }, + }, +}; + +int platform_accton_as5812_54t(void) +{ + return dmi_check_system(as5812_54t_dmi_table); +} +EXPORT_SYMBOL(platform_accton_as5812_54t); + +static struct dmi_system_id as5512_54x_dmi_table[] = { + { + .ident = "Accton AS5512", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Accton"), + DMI_MATCH(DMI_PRODUCT_NAME, "AS5512"), + }, + }, + { + .ident = "Accton AS5512", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Accton"), + DMI_MATCH(DMI_PRODUCT_NAME, "AS5512"), + }, + }, +}; + +int platform_accton_as5512_54x(void) +{ + return dmi_check_system(as5512_54x_dmi_table); +} +EXPORT_SYMBOL(platform_accton_as5512_54x); + +static struct dmi_system_id as7716_dmi_table[] = { + { + .ident = "Accton AS7716", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Accton"), + DMI_MATCH(DMI_PRODUCT_NAME, "AS7716"), + }, + }, + { + .ident = "Accton AS7716", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Accton"), + DMI_MATCH(DMI_PRODUCT_NAME, "AS7716"), + }, + }, +}; + +int platform_accton_as7716_32x(void) +{ + return dmi_check_system(as7716_dmi_table); +} +EXPORT_SYMBOL(platform_accton_as7716_32x); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton_i2c_cpld driver"); +MODULE_LICENSE("GPL"); + +module_init(accton_i2c_cpld_init); +module_exit(accton_i2c_cpld_exit); diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-fan.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-fan.c new file mode 100644 index 000000000000..bad9245e93ac --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-fan.c @@ -0,0 +1,442 @@ +/* + * A hwmon driver for the Accton as5812 54t fan + * + * Copyright (C) 2015 Accton Technology Corporation. + * Brandon Chuang + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define FAN_MAX_NUMBER 5 +#define FAN_SPEED_CPLD_TO_RPM_STEP 150 +#define FAN_SPEED_PRECENT_TO_CPLD_STEP 5 +#define FAN_DUTY_CYCLE_MIN 0 +#define FAN_DUTY_CYCLE_MAX 100 /* 100% */ + +#define CPLD_REG_FAN_STATUS_OFFSET 0xC +#define CPLD_REG_FANR_STATUS_OFFSET 0x1F +#define CPLD_REG_FAN_DIRECTION_OFFSET 0x1E + +#define CPLD_FAN1_REG_SPEED_OFFSET 0x10 +#define CPLD_FAN2_REG_SPEED_OFFSET 0x11 +#define CPLD_FAN3_REG_SPEED_OFFSET 0x12 +#define CPLD_FAN4_REG_SPEED_OFFSET 0x13 +#define CPLD_FAN5_REG_SPEED_OFFSET 0x14 + +#define CPLD_FANR1_REG_SPEED_OFFSET 0x18 +#define CPLD_FANR2_REG_SPEED_OFFSET 0x19 +#define CPLD_FANR3_REG_SPEED_OFFSET 0x1A +#define CPLD_FANR4_REG_SPEED_OFFSET 0x1B +#define CPLD_FANR5_REG_SPEED_OFFSET 0x1C + +#define CPLD_REG_FAN_PWM_CYCLE_OFFSET 0xD + +#define CPLD_FAN1_INFO_BIT_MASK 0x1 +#define CPLD_FAN2_INFO_BIT_MASK 0x2 +#define CPLD_FAN3_INFO_BIT_MASK 0x4 +#define CPLD_FAN4_INFO_BIT_MASK 0x8 +#define CPLD_FAN5_INFO_BIT_MASK 0x10 + +#define PROJECT_NAME + +#define LOCAL_DEBUG 0 + +static struct accton_as5812_54t_fan *fan_data = NULL; + +struct accton_as5812_54t_fan { + struct platform_device *pdev; + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 status[FAN_MAX_NUMBER]; /* inner first fan status */ + u32 speed[FAN_MAX_NUMBER]; /* inner first fan speed */ + u8 direction[FAN_MAX_NUMBER]; /* reconrd the direction of inner first and second fans */ + u32 duty_cycle[FAN_MAX_NUMBER]; /* control the speed of inner first and second fans */ + u8 r_status[FAN_MAX_NUMBER]; /* inner second fan status */ + u32 r_speed[FAN_MAX_NUMBER]; /* inner second fan speed */ +}; + +/*******************/ +#define MAKE_FAN_MASK_OR_REG(name,type) \ + CPLD_FAN##type##1_##name, \ + CPLD_FAN##type##2_##name, \ + CPLD_FAN##type##3_##name, \ + CPLD_FAN##type##4_##name, \ + CPLD_FAN##type##5_##name, + +/* fan related data + */ +static const u8 fan_info_mask[] = { + MAKE_FAN_MASK_OR_REG(INFO_BIT_MASK,) +}; + +static const u8 fan_speed_reg[] = { + MAKE_FAN_MASK_OR_REG(REG_SPEED_OFFSET,) +}; + +static const u8 fanr_speed_reg[] = { + MAKE_FAN_MASK_OR_REG(REG_SPEED_OFFSET,R) +}; + +/*******************/ +#define DEF_FAN_SET(id) \ + FAN##id##_FAULT, \ + FAN##id##_SPEED, \ + FAN##id##_DUTY_CYCLE, \ + FAN##id##_DIRECTION, \ + FANR##id##_FAULT, \ + FANR##id##_SPEED, + +enum sysfs_fan_attributes { + DEF_FAN_SET(1) + DEF_FAN_SET(2) + DEF_FAN_SET(3) + DEF_FAN_SET(4) + DEF_FAN_SET(5) +}; +/*******************/ +static void accton_as5812_54t_fan_update_device(struct device *dev); +static int accton_as5812_54t_fan_read_value(u8 reg); +static int accton_as5812_54t_fan_write_value(u8 reg, u8 value); + +static ssize_t fan_set_duty_cycle(struct device *dev, + struct device_attribute *da,const char *buf, size_t count); +static ssize_t fan_show_value(struct device *dev, + struct device_attribute *da, char *buf); + +extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + + +/*******************/ +#define _MAKE_SENSOR_DEVICE_ATTR(prj, id) \ + static SENSOR_DEVICE_ATTR(prj##fan##id##_fault, S_IRUGO, fan_show_value, NULL, FAN##id##_FAULT); \ + static SENSOR_DEVICE_ATTR(prj##fan##id##_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##id##_SPEED); \ + static SENSOR_DEVICE_ATTR(prj##fan##id##_duty_cycle_percentage, S_IWUSR | S_IRUGO, fan_show_value, \ + fan_set_duty_cycle, FAN##id##_DUTY_CYCLE); \ + static SENSOR_DEVICE_ATTR(prj##fan##id##_direction, S_IRUGO, fan_show_value, NULL, FAN##id##_DIRECTION); \ + static SENSOR_DEVICE_ATTR(prj##fanr##id##_fault, S_IRUGO, fan_show_value, NULL, FANR##id##_FAULT); \ + static SENSOR_DEVICE_ATTR(prj##fanr##id##_speed_rpm, S_IRUGO, fan_show_value, NULL, FANR##id##_SPEED); + +#define MAKE_SENSOR_DEVICE_ATTR(prj,id) _MAKE_SENSOR_DEVICE_ATTR(prj,id) + +MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 1) +MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 2) +MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 3) +MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 4) +MAKE_SENSOR_DEVICE_ATTR(PROJECT_NAME, 5) +/*******************/ + +#define _MAKE_FAN_ATTR(prj, id) \ + &sensor_dev_attr_##prj##fan##id##_fault.dev_attr.attr, \ + &sensor_dev_attr_##prj##fan##id##_speed_rpm.dev_attr.attr, \ + &sensor_dev_attr_##prj##fan##id##_duty_cycle_percentage.dev_attr.attr,\ + &sensor_dev_attr_##prj##fan##id##_direction.dev_attr.attr, \ + &sensor_dev_attr_##prj##fanr##id##_fault.dev_attr.attr, \ + &sensor_dev_attr_##prj##fanr##id##_speed_rpm.dev_attr.attr, + +#define MAKE_FAN_ATTR(prj, id) _MAKE_FAN_ATTR(prj, id) + +static struct attribute *accton_as5812_54t_fan_attributes[] = { + /* fan related attributes */ + MAKE_FAN_ATTR(PROJECT_NAME,1) + MAKE_FAN_ATTR(PROJECT_NAME,2) + MAKE_FAN_ATTR(PROJECT_NAME,3) + MAKE_FAN_ATTR(PROJECT_NAME,4) + MAKE_FAN_ATTR(PROJECT_NAME,5) + NULL +}; +/*******************/ + +/* fan related functions + */ +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + ssize_t ret = 0; + int data_index, type_index; + + accton_as5812_54t_fan_update_device(dev); + + if (fan_data->valid == 0) { + return ret; + } + + type_index = attr->index%FAN2_FAULT; + data_index = attr->index/FAN2_FAULT; + + switch (type_index) { + case FAN1_FAULT: + ret = sprintf(buf, "%d\n", fan_data->status[data_index]); + if (LOCAL_DEBUG) + printk ("[Check !!][%s][%d][type->index=%d][data->index=%d]\n", __FUNCTION__, __LINE__, type_index, data_index); + break; + case FAN1_SPEED: + ret = sprintf(buf, "%d\n", fan_data->speed[data_index]); + if (LOCAL_DEBUG) + printk ("[Check !!][%s][%d][type->index=%d][data->index=%d]\n", __FUNCTION__, __LINE__, type_index, data_index); + break; + case FAN1_DUTY_CYCLE: + ret = sprintf(buf, "%d\n", fan_data->duty_cycle[data_index]); + if (LOCAL_DEBUG) + printk ("[Check !!][%s][%d][type->index=%d][data->index=%d]\n", __FUNCTION__, __LINE__, type_index, data_index); + break; + case FAN1_DIRECTION: + ret = sprintf(buf, "%d\n", fan_data->direction[data_index]); /* presnet, need to modify*/ + if (LOCAL_DEBUG) + printk ("[Check !!][%s][%d][type->index=%d][data->index=%d]\n", __FUNCTION__, __LINE__, type_index, data_index); + break; + case FANR1_FAULT: + ret = sprintf(buf, "%d\n", fan_data->r_status[data_index]); + if (LOCAL_DEBUG) + printk ("[Check !!][%s][%d][type->index=%d][data->index=%d]\n", __FUNCTION__, __LINE__, type_index, data_index); + break; + case FANR1_SPEED: + ret = sprintf(buf, "%d\n", fan_data->r_speed[data_index]); + if (LOCAL_DEBUG) + printk ("[Check !!][%s][%d][type->index=%d][data->index=%d]\n", __FUNCTION__, __LINE__, type_index, data_index); + break; + default: + if (LOCAL_DEBUG) + printk ("[Check !!][%s][%d] \n", __FUNCTION__, __LINE__); + break; + } + + return ret; +} +/*******************/ +static ssize_t fan_set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) { + + int error, value; + + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (value < FAN_DUTY_CYCLE_MIN || value > FAN_DUTY_CYCLE_MAX) + return -EINVAL; + + accton_as5812_54t_fan_write_value(CPLD_REG_FAN_PWM_CYCLE_OFFSET, value/FAN_SPEED_PRECENT_TO_CPLD_STEP); + + fan_data->valid = 0; + + return count; +} + +static const struct attribute_group accton_as5812_54t_fan_group = { + .attrs = accton_as5812_54t_fan_attributes, +}; + +static int accton_as5812_54t_fan_read_value(u8 reg) +{ + return accton_i2c_cpld_read(0x60, reg); +} + +static int accton_as5812_54t_fan_write_value(u8 reg, u8 value) +{ + return accton_i2c_cpld_write(0x60, reg, value); +} + +static void accton_as5812_54t_fan_update_device(struct device *dev) +{ + int speed, r_speed, fault, r_fault, ctrl_speed, direction; + int i; + + mutex_lock(&fan_data->update_lock); + + if (LOCAL_DEBUG) + printk ("Starting accton_as5812_54t_fan update \n"); + + if (!(time_after(jiffies, fan_data->last_updated + HZ + HZ / 2) || !fan_data->valid)) { + /* do nothing */ + goto _exit; + } + + fan_data->valid = 0; + + if (LOCAL_DEBUG) + printk ("Starting accton_as5812_54t_fan update 2 \n"); + + fault = accton_as5812_54t_fan_read_value(CPLD_REG_FAN_STATUS_OFFSET); + r_fault = accton_as5812_54t_fan_read_value(CPLD_REG_FANR_STATUS_OFFSET); + direction = accton_as5812_54t_fan_read_value(CPLD_REG_FAN_DIRECTION_OFFSET); + ctrl_speed = accton_as5812_54t_fan_read_value(CPLD_REG_FAN_PWM_CYCLE_OFFSET); + + if ( (fault < 0) || (r_fault < 0) || (direction < 0) || (ctrl_speed < 0) ) + { + if (LOCAL_DEBUG) + printk ("[Error!!][%s][%d] \n", __FUNCTION__, __LINE__); + goto _exit; /* error */ + } + + if (LOCAL_DEBUG) + printk ("[fan:] fault:%d, r_fault=%d, direction=%d, ctrl_speed=%d \n",fault, r_fault, direction, ctrl_speed); + + for (i=0; istatus[i] = (fault & fan_info_mask[i]) >> i; + if (LOCAL_DEBUG) + printk ("[fan%d:] fail=%d \n",i, fan_data->status[i]); + + fan_data->r_status[i] = (r_fault & fan_info_mask[i]) >> i; + fan_data->direction[i] = (direction & fan_info_mask[i]) >> i; + fan_data->duty_cycle[i] = ctrl_speed * FAN_SPEED_PRECENT_TO_CPLD_STEP; + + /* fan speed + */ + speed = accton_as5812_54t_fan_read_value(fan_speed_reg[i]); + r_speed = accton_as5812_54t_fan_read_value(fanr_speed_reg[i]); + if ( (speed < 0) || (r_speed < 0) ) + { + if (LOCAL_DEBUG) + printk ("[Error!!][%s][%d] \n", __FUNCTION__, __LINE__); + goto _exit; /* error */ + } + + if (LOCAL_DEBUG) + printk ("[fan%d:] speed:%d, r_speed=%d \n", i, speed, r_speed); + + fan_data->speed[i] = speed * FAN_SPEED_CPLD_TO_RPM_STEP; + fan_data->r_speed[i] = r_speed * FAN_SPEED_CPLD_TO_RPM_STEP; + } + + /* finish to update */ + fan_data->last_updated = jiffies; + fan_data->valid = 1; + +_exit: + mutex_unlock(&fan_data->update_lock); +} + +static int accton_as5812_54t_fan_probe(struct platform_device *pdev) +{ + int status = -1; + + /* Register sysfs hooks */ + status = sysfs_create_group(&pdev->dev.kobj, &accton_as5812_54t_fan_group); + if (status) { + goto exit; + + } + + fan_data->hwmon_dev = hwmon_device_register(&pdev->dev); + if (IS_ERR(fan_data->hwmon_dev)) { + status = PTR_ERR(fan_data->hwmon_dev); + goto exit_remove; + } + + dev_info(&pdev->dev, "accton_as5812_54t_fan\n"); + + return 0; + +exit_remove: + sysfs_remove_group(&pdev->dev.kobj, &accton_as5812_54t_fan_group); +exit: + return status; +} + +static int accton_as5812_54t_fan_remove(struct platform_device *pdev) +{ + hwmon_device_unregister(fan_data->hwmon_dev); + sysfs_remove_group(&fan_data->pdev->dev.kobj, &accton_as5812_54t_fan_group); + + return 0; +} + +#define DRVNAME "as5812_54t_fan" + +static struct platform_driver accton_as5812_54t_fan_driver = { + .probe = accton_as5812_54t_fan_probe, + .remove = accton_as5812_54t_fan_remove, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +static int __init accton_as5812_54t_fan_init(void) +{ + int ret; + + extern int platform_accton_as5812_54t(void); + if (!platform_accton_as5812_54t()) { + return -ENODEV; + } + + ret = platform_driver_register(&accton_as5812_54t_fan_driver); + if (ret < 0) { + goto exit; + } + + fan_data = kzalloc(sizeof(struct accton_as5812_54t_fan), GFP_KERNEL); + if (!fan_data) { + ret = -ENOMEM; + platform_driver_unregister(&accton_as5812_54t_fan_driver); + goto exit; + } + + mutex_init(&fan_data->update_lock); + fan_data->valid = 0; + + fan_data->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(fan_data->pdev)) { + ret = PTR_ERR(fan_data->pdev); + platform_driver_unregister(&accton_as5812_54t_fan_driver); + kfree(fan_data); + goto exit; + } + +exit: + return ret; +} + +static void __exit accton_as5812_54t_fan_exit(void) +{ + platform_device_unregister(fan_data->pdev); + platform_driver_unregister(&accton_as5812_54t_fan_driver); + kfree(fan_data); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton_as5812_54t_fan driver"); +MODULE_LICENSE("GPL"); + +module_init(accton_as5812_54t_fan_init); +module_exit(accton_as5812_54t_fan_exit); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-leds.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-leds.c new file mode 100644 index 000000000000..011f62e76c06 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-leds.c @@ -0,0 +1,601 @@ +/* + * A LED driver for the accton_as5812_54t_led + * + * Copyright (C) 2015 Accton Technology Corporation. + * Brandon Chuang + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*#define DEBUG*/ + +#include +#include +#include +#include +#include +#include +#include + +extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +extern void led_classdev_unregister(struct led_classdev *led_cdev); +extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); +extern void led_classdev_resume(struct led_classdev *led_cdev); +extern void led_classdev_suspend(struct led_classdev *led_cdev); + +#define DRVNAME "as5812_54t_led" + +struct accton_as5812_54t_led_data { + struct platform_device *pdev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[4]; /* Register value, 0 = LOC/DIAG/FAN LED + 1 = PSU1/PSU2 LED + 2 = FAN1-4 LED + 3 = FAN5-6 LED */ +}; + +static struct accton_as5812_54t_led_data *ledctl = NULL; + +/* LED related data + */ +#define LED_TYPE_PSU1_REG_MASK 0x03 +#define LED_MODE_PSU1_GREEN_MASK 0x02 +#define LED_MODE_PSU1_AMBER_MASK 0x01 +#define LED_MODE_PSU1_OFF_MASK 0x03 +#define LED_MODE_PSU1_AUTO_MASK 0x00 + +#define LED_TYPE_PSU2_REG_MASK 0x0C +#define LED_MODE_PSU2_GREEN_MASK 0x08 +#define LED_MODE_PSU2_AMBER_MASK 0x04 +#define LED_MODE_PSU2_OFF_MASK 0x0C +#define LED_MODE_PSU2_AUTO_MASK 0x00 + +#define LED_TYPE_DIAG_REG_MASK 0x0C +#define LED_MODE_DIAG_GREEN_MASK 0x08 +#define LED_MODE_DIAG_AMBER_MASK 0x04 +#define LED_MODE_DIAG_OFF_MASK 0x0C + +#define LED_TYPE_FAN_REG_MASK 0x03 +#define LED_MODE_FAN_GREEN_MASK 0x02 +#define LED_MODE_FAN_AMBER_MASK 0x01 +#define LED_MODE_FAN_OFF_MASK 0x03 +#define LED_MODE_FAN_AUTO_MASK 0x00 + +#define LED_TYPE_FAN1_REG_MASK 0x03 +#define LED_TYPE_FAN2_REG_MASK 0x0C +#define LED_TYPE_FAN3_REG_MASK 0x30 +#define LED_TYPE_FAN4_REG_MASK 0xC0 +#define LED_TYPE_FAN5_REG_MASK 0x03 +#define LED_TYPE_FAN6_REG_MASK 0x0C + +#define LED_MODE_FANX_GREEN_MASK 0x01 +#define LED_MODE_FANX_RED_MASK 0x02 +#define LED_MODE_FANX_OFF_MASK 0x00 + +#define LED_TYPE_LOC_REG_MASK 0x30 +#define LED_MODE_LOC_ON_MASK 0x00 +#define LED_MODE_LOC_OFF_MASK 0x10 +#define LED_MODE_LOC_BLINK_MASK 0x20 + +static const u8 led_reg[] = { + 0xA, /* LOC/DIAG/FAN LED*/ + 0xB, /* PSU1/PSU2 LED */ + 0x16, /* FAN1-4 LED */ + 0x17, /* FAN4-6 LED */ +}; + +enum led_type { + LED_TYPE_PSU1, + LED_TYPE_PSU2, + LED_TYPE_DIAG, + LED_TYPE_FAN, + LED_TYPE_FAN1, + LED_TYPE_FAN2, + LED_TYPE_FAN3, + LED_TYPE_FAN4, + LED_TYPE_FAN5, + LED_TYPE_LOC +}; + +enum led_light_mode { + LED_MODE_OFF = 0, + LED_MODE_GREEN, + LED_MODE_GREEN_BLINK, + LED_MODE_AMBER, + LED_MODE_AMBER_BLINK, + LED_MODE_RED, + LED_MODE_RED_BLINK, + LED_MODE_BLUE, + LED_MODE_BLUE_BLINK, + LED_MODE_AUTO, + LED_MODE_UNKNOWN +}; + +struct led_type_mode { + enum led_type type; + int type_mask; + enum led_light_mode mode; + int mode_mask; +}; + +static struct led_type_mode led_type_mode_data[] = { +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_GREEN, LED_MODE_PSU1_GREEN_MASK}, +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_AMBER, LED_MODE_PSU1_AMBER_MASK}, +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_AUTO, LED_MODE_PSU1_AUTO_MASK}, +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_OFF, LED_MODE_PSU1_OFF_MASK}, +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_GREEN, LED_MODE_PSU2_GREEN_MASK}, +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_AMBER, LED_MODE_PSU2_AMBER_MASK}, +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_AUTO, LED_MODE_PSU2_AUTO_MASK}, +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_OFF, LED_MODE_PSU2_OFF_MASK}, +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_GREEN, LED_MODE_FAN_GREEN_MASK}, +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_AMBER, LED_MODE_FAN_AMBER_MASK}, +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_AUTO, LED_MODE_FAN_AUTO_MASK}, +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_OFF, LED_MODE_FAN_OFF_MASK}, +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 0}, +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 0}, +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 0}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 2}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 2}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 2}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 4}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 4}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 4}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 6}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 6}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 6}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 0}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 0}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 0}, +{LED_TYPE_DIAG, LED_TYPE_DIAG_REG_MASK, LED_MODE_GREEN, LED_MODE_DIAG_GREEN_MASK}, +{LED_TYPE_DIAG, LED_TYPE_DIAG_REG_MASK, LED_MODE_AMBER, LED_MODE_DIAG_AMBER_MASK}, +{LED_TYPE_DIAG, LED_TYPE_DIAG_REG_MASK, LED_MODE_OFF, LED_MODE_DIAG_OFF_MASK}, +{LED_TYPE_LOC, LED_TYPE_LOC_REG_MASK, LED_MODE_AMBER, LED_MODE_LOC_ON_MASK}, +{LED_TYPE_LOC, LED_TYPE_LOC_REG_MASK, LED_MODE_OFF, LED_MODE_LOC_OFF_MASK}, +{LED_TYPE_LOC, LED_TYPE_LOC_REG_MASK, LED_MODE_AMBER_BLINK, LED_MODE_LOC_BLINK_MASK} +}; + + +struct fanx_info_s { + u8 cname; /* device name */ + enum led_type type; + u8 reg_id; /* map to led_reg & reg_val */ +}; + +static struct fanx_info_s fanx_info[] = { + {'1', LED_TYPE_FAN1, 2}, + {'2', LED_TYPE_FAN2, 2}, + {'3', LED_TYPE_FAN3, 2}, + {'4', LED_TYPE_FAN4, 2}, + {'5', LED_TYPE_FAN5, 3} +}; + +static int led_reg_val_to_light_mode(enum led_type type, u8 reg_val) { + int i; + + for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) { + + if (type != led_type_mode_data[i].type) + continue; + + if ((led_type_mode_data[i].type_mask & reg_val) == + led_type_mode_data[i].mode_mask) + { + return led_type_mode_data[i].mode; + } + } + + return LED_MODE_UNKNOWN; +} + +static u8 led_light_mode_to_reg_val(enum led_type type, + enum led_light_mode mode, u8 reg_val) { + int i; + + for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) { + if (type != led_type_mode_data[i].type) + continue; + + if (mode != led_type_mode_data[i].mode) + continue; + + reg_val = led_type_mode_data[i].mode_mask | + (reg_val & (~led_type_mode_data[i].type_mask)); + } + + return reg_val; +} + +static int accton_as5812_54t_led_read_value(u8 reg) +{ + return accton_i2c_cpld_read(0x60, reg); +} + +static int accton_as5812_54t_led_write_value(u8 reg, u8 value) +{ + return accton_i2c_cpld_write(0x60, reg, value); +} + +static void accton_as5812_54t_led_update(void) +{ + mutex_lock(&ledctl->update_lock); + + if (time_after(jiffies, ledctl->last_updated + HZ + HZ / 2) + || !ledctl->valid) { + int i; + + dev_dbg(&ledctl->pdev->dev, "Starting accton_as5812_54t_led update\n"); + + /* Update LED data + */ + for (i = 0; i < ARRAY_SIZE(ledctl->reg_val); i++) { + int status = accton_as5812_54t_led_read_value(led_reg[i]); + + if (status < 0) { + ledctl->valid = 0; + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", led_reg[i], status); + goto exit; + } + else + { + ledctl->reg_val[i] = status; + } + } + + ledctl->last_updated = jiffies; + ledctl->valid = 1; + } + +exit: + mutex_unlock(&ledctl->update_lock); +} + +static void accton_as5812_54t_led_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode, + u8 reg, enum led_type type) +{ + int reg_val; + + mutex_lock(&ledctl->update_lock); + + reg_val = accton_as5812_54t_led_read_value(reg); + + if (reg_val < 0) { + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", reg, reg_val); + goto exit; + } + + reg_val = led_light_mode_to_reg_val(type, led_light_mode, reg_val); + accton_as5812_54t_led_write_value(reg, reg_val); + + /* to prevent the slow-update issue */ + ledctl->valid = 0; + +exit: + mutex_unlock(&ledctl->update_lock); +} + +static void accton_as5812_54t_led_psu_1_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + accton_as5812_54t_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_PSU1); +} + +static enum led_brightness accton_as5812_54t_led_psu_1_get(struct led_classdev *cdev) +{ + accton_as5812_54t_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_PSU1, ledctl->reg_val[1]); +} + +static void accton_as5812_54t_led_psu_2_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + accton_as5812_54t_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_PSU2); +} + +static enum led_brightness accton_as5812_54t_led_psu_2_get(struct led_classdev *cdev) +{ + accton_as5812_54t_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_PSU2, ledctl->reg_val[1]); +} + +static void accton_as5812_54t_led_fan_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + accton_as5812_54t_led_set(led_cdev, led_light_mode, led_reg[0], LED_TYPE_FAN); +} + +static enum led_brightness accton_as5812_54t_led_fan_get(struct led_classdev *cdev) +{ + accton_as5812_54t_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_FAN, ledctl->reg_val[0]); +} + + +static void accton_as5812_54t_led_fanx_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + enum led_type led_type1; + int reg_id; + int i, nsize; + int ncount = sizeof(fanx_info)/sizeof(struct fanx_info_s); + + for(i=0;iname); + + if (led_cdev->name[nsize-1] == fanx_info[i].cname) + { + led_type1 = fanx_info[i].type; + reg_id = fanx_info[i].reg_id; + accton_as5812_54t_led_set(led_cdev, led_light_mode, led_reg[reg_id], led_type1); + return; + } + } +} + + +static enum led_brightness accton_as5812_54t_led_fanx_get(struct led_classdev *cdev) +{ + enum led_type led_type1; + int reg_id; + int i, nsize; + int ncount = sizeof(fanx_info)/sizeof(struct fanx_info_s); + + for(i=0;iname); + + if (cdev->name[nsize-1] == fanx_info[i].cname) + { + led_type1 = fanx_info[i].type; + reg_id = fanx_info[i].reg_id; + accton_as5812_54t_led_update(); + return led_reg_val_to_light_mode(led_type1, ledctl->reg_val[reg_id]); + } + } + + + return led_reg_val_to_light_mode(LED_TYPE_FAN1, ledctl->reg_val[2]); +} + + +static void accton_as5812_54t_led_diag_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + accton_as5812_54t_led_set(led_cdev, led_light_mode, led_reg[0], LED_TYPE_DIAG); +} + +static enum led_brightness accton_as5812_54t_led_diag_get(struct led_classdev *cdev) +{ + accton_as5812_54t_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_DIAG, ledctl->reg_val[0]); +} + +static void accton_as5812_54t_led_loc_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + accton_as5812_54t_led_set(led_cdev, led_light_mode, led_reg[0], LED_TYPE_LOC); +} + +static enum led_brightness accton_as5812_54t_led_loc_get(struct led_classdev *cdev) +{ + accton_as5812_54t_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_LOC, ledctl->reg_val[0]); +} + +static struct led_classdev accton_as5812_54t_leds[] = { + [LED_TYPE_PSU1] = { + .name = "accton_as5812_54t_led::psu1", + .default_trigger = "unused", + .brightness_set = accton_as5812_54t_led_psu_1_set, + .brightness_get = accton_as5812_54t_led_psu_1_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_PSU2] = { + .name = "accton_as5812_54t_led::psu2", + .default_trigger = "unused", + .brightness_set = accton_as5812_54t_led_psu_2_set, + .brightness_get = accton_as5812_54t_led_psu_2_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN] = { + .name = "accton_as5812_54t_led::fan", + .default_trigger = "unused", + .brightness_set = accton_as5812_54t_led_fan_set, + .brightness_get = accton_as5812_54t_led_fan_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN1] = { + .name = "accton_as5812_54t_led::fan1", + .default_trigger = "unused", + .brightness_set = accton_as5812_54t_led_fanx_set, + .brightness_get = accton_as5812_54t_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN2] = { + .name = "accton_as5812_54t_led::fan2", + .default_trigger = "unused", + .brightness_set = accton_as5812_54t_led_fanx_set, + .brightness_get = accton_as5812_54t_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN3] = { + .name = "accton_as5812_54t_led::fan3", + .default_trigger = "unused", + .brightness_set = accton_as5812_54t_led_fanx_set, + .brightness_get = accton_as5812_54t_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN4] = { + .name = "accton_as5812_54t_led::fan4", + .default_trigger = "unused", + .brightness_set = accton_as5812_54t_led_fanx_set, + .brightness_get = accton_as5812_54t_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN5] = { + .name = "accton_as5812_54t_led::fan5", + .default_trigger = "unused", + .brightness_set = accton_as5812_54t_led_fanx_set, + .brightness_get = accton_as5812_54t_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_DIAG] = { + .name = "accton_as5812_54t_led::diag", + .default_trigger = "unused", + .brightness_set = accton_as5812_54t_led_diag_set, + .brightness_get = accton_as5812_54t_led_diag_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_LOC] = { + .name = "accton_as5812_54t_led::loc", + .default_trigger = "unused", + .brightness_set = accton_as5812_54t_led_loc_set, + .brightness_get = accton_as5812_54t_led_loc_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, +}; + +static int accton_as5812_54t_led_suspend(struct platform_device *dev, + pm_message_t state) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(accton_as5812_54t_leds); i++) { + led_classdev_suspend(&accton_as5812_54t_leds[i]); + } + + return 0; +} + +static int accton_as5812_54t_led_resume(struct platform_device *dev) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(accton_as5812_54t_leds); i++) { + led_classdev_resume(&accton_as5812_54t_leds[i]); + } + + return 0; +} + +static int accton_as5812_54t_led_probe(struct platform_device *pdev) +{ + int ret, i; + + for (i = 0; i < ARRAY_SIZE(accton_as5812_54t_leds); i++) { + ret = led_classdev_register(&pdev->dev, &accton_as5812_54t_leds[i]); + + if (ret < 0) + break; + } + + /* Check if all LEDs were successfully registered */ + if (i != ARRAY_SIZE(accton_as5812_54t_leds)){ + int j; + + /* only unregister the LEDs that were successfully registered */ + for (j = 0; j < i; j++) { + led_classdev_unregister(&accton_as5812_54t_leds[i]); + } + } + + return ret; +} + +static int accton_as5812_54t_led_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(accton_as5812_54t_leds); i++) { + led_classdev_unregister(&accton_as5812_54t_leds[i]); + } + + return 0; +} + +static struct platform_driver accton_as5812_54t_led_driver = { + .probe = accton_as5812_54t_led_probe, + .remove = accton_as5812_54t_led_remove, + .suspend = accton_as5812_54t_led_suspend, + .resume = accton_as5812_54t_led_resume, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +static int __init accton_as5812_54t_led_init(void) +{ + int ret; + + extern int platform_accton_as5812_54t(void); + if (!platform_accton_as5812_54t()) { + return -ENODEV; + } + + ret = platform_driver_register(&accton_as5812_54t_led_driver); + if (ret < 0) { + goto exit; + } + + ledctl = kzalloc(sizeof(struct accton_as5812_54t_led_data), GFP_KERNEL); + if (!ledctl) { + ret = -ENOMEM; + platform_driver_unregister(&accton_as5812_54t_led_driver); + goto exit; + } + + mutex_init(&ledctl->update_lock); + + ledctl->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(ledctl->pdev)) { + ret = PTR_ERR(ledctl->pdev); + platform_driver_unregister(&accton_as5812_54t_led_driver); + kfree(ledctl); + goto exit; + } + +exit: + return ret; +} + +static void __exit accton_as5812_54t_led_exit(void) +{ + platform_device_unregister(ledctl->pdev); + platform_driver_unregister(&accton_as5812_54t_led_driver); + kfree(ledctl); +} + +module_init(accton_as5812_54t_led_init); +module_exit(accton_as5812_54t_led_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton_as5812_54t_led driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-psu.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-psu.c new file mode 100644 index 000000000000..a77014e877ca --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-psu.c @@ -0,0 +1,372 @@ +/* + * An hwmon driver for accton as5812_54t Power Module + * + * Copyright (C) 2015 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define PSU_STATUS_I2C_ADDR 0x60 +#define PSU_STATUS_I2C_REG_OFFSET 0x2 + +#define IS_POWER_GOOD(id, value) (!!(value & BIT(id*4 + 1))) +#define IS_PRESENT(id, value) (!(value & BIT(id*4))) + +static ssize_t show_index(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_model_name(struct device *dev, struct device_attribute *da, char *buf); +static int as5812_54t_psu_read_block(struct i2c_client *client, u8 command, u8 *data,int data_len); +extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +static int as5812_54t_psu_model_name_get(struct device *dev); + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +/* Each client has this additional data + */ +struct as5812_54t_psu_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 index; /* PSU index */ + u8 status; /* Status(present/power_good) register read from CPLD */ + char model_name[14]; /* Model name, read from eeprom */ +}; + +static struct as5812_54t_psu_data *as5812_54t_psu_update_device(struct device *dev); + +enum as5812_54t_psu_sysfs_attributes { + PSU_INDEX, + PSU_PRESENT, + PSU_MODEL_NAME, + PSU_POWER_GOOD +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(psu_index, S_IRUGO, show_index, NULL, PSU_INDEX); +static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, show_status, NULL, PSU_PRESENT); +static SENSOR_DEVICE_ATTR(psu_model_name, S_IRUGO, show_model_name,NULL, PSU_MODEL_NAME); +static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_status, NULL, PSU_POWER_GOOD); + +static struct attribute *as5812_54t_psu_attributes[] = { + &sensor_dev_attr_psu_index.dev_attr.attr, + &sensor_dev_attr_psu_present.dev_attr.attr, + &sensor_dev_attr_psu_model_name.dev_attr.attr, + &sensor_dev_attr_psu_power_good.dev_attr.attr, + NULL +}; + +static ssize_t show_index(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as5812_54t_psu_data *data = i2c_get_clientdata(client); + + return sprintf(buf, "%d\n", data->index); +} + +static ssize_t show_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct as5812_54t_psu_data *data = as5812_54t_psu_update_device(dev); + u8 status = 0; + + if (!data->valid) { + return sprintf(buf, "0\n"); + } + + if (attr->index == PSU_PRESENT) { + status = IS_PRESENT(data->index, data->status); + } + else { /* PSU_POWER_GOOD */ + status = IS_POWER_GOOD(data->index, data->status); + } + + return sprintf(buf, "%d\n", status); +} + +static ssize_t show_model_name(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct as5812_54t_psu_data *data = as5812_54t_psu_update_device(dev); + + if (!data->valid) { + return 0; + } + + if (!IS_PRESENT(data->index, data->status)) { + return 0; + } + + if (as5812_54t_psu_model_name_get(dev) < 0) { + return -ENXIO; + } + + return sprintf(buf, "%s\n", data->model_name); +} + +static const struct attribute_group as5812_54t_psu_group = { + .attrs = as5812_54t_psu_attributes, +}; + +static int as5812_54t_psu_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct as5812_54t_psu_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct as5812_54t_psu_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + data->index = dev_id->driver_data; + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as5812_54t_psu_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as5812_54t_psu_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as5812_54t_psu_remove(struct i2c_client *client) +{ + struct as5812_54t_psu_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as5812_54t_psu_group); + kfree(data); + + return 0; +} + +enum psu_index +{ + as5812_54t_psu1, + as5812_54t_psu2 +}; + +static const struct i2c_device_id as5812_54t_psu_id[] = { + { "as5812_54t_psu1", as5812_54t_psu1 }, + { "as5812_54t_psu2", as5812_54t_psu2 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, as5812_54t_psu_id); + +static struct i2c_driver as5812_54t_psu_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "as5812_54t_psu", + }, + .probe = as5812_54t_psu_probe, + .remove = as5812_54t_psu_remove, + .id_table = as5812_54t_psu_id, + .address_list = normal_i2c, +}; + +static int as5812_54t_psu_read_block(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ + int result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + + if (unlikely(result < 0)) + goto abort; + if (unlikely(result != data_len)) { + result = -EIO; + goto abort; + } + + result = 0; + +abort: + return result; +} + +enum psu_type { + PSU_YM_2401_JCR, /* AC110V - F2B */ + PSU_YM_2401_JDR, /* AC110V - B2F */ + PSU_CPR_4011_4M11, /* AC110V - F2B */ + PSU_CPR_4011_4M21, /* AC110V - B2F */ + PSU_CPR_6011_2M11, /* AC110V - F2B */ + PSU_CPR_6011_2M21, /* AC110V - B2F */ + PSU_UM400D_01G, /* DC48V - F2B */ + PSU_UM400D01_01G /* DC48V - B2F */ +}; + +struct model_name_info { + enum psu_type type; + u8 offset; + u8 length; + char* model_name; +}; + +struct model_name_info models[] = { +{PSU_YM_2401_JCR, 0x20, 11, "YM-2401JCR"}, +{PSU_YM_2401_JDR, 0x20, 11, "YM-2401JDR"}, +{PSU_CPR_4011_4M11, 0x26, 13, "CPR-4011-4M11"}, +{PSU_CPR_4011_4M21, 0x26, 13, "CPR-4011-4M21"}, +{PSU_CPR_6011_2M11, 0x26, 13, "CPR-6011-2M11"}, +{PSU_CPR_6011_2M21, 0x26, 13, "CPR-6011-2M21"}, +{PSU_UM400D_01G, 0x50, 9, "um400d01G"}, +{PSU_UM400D01_01G, 0x50, 12, "um400d01-01G"}, +}; + +static int as5812_54t_psu_model_name_get(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as5812_54t_psu_data *data = i2c_get_clientdata(client); + int i, status; + + for (i = 0; i < ARRAY_SIZE(models); i++) { + memset(data->model_name, 0, sizeof(data->model_name)); + + status = as5812_54t_psu_read_block(client, models[i].offset, + data->model_name, models[i].length); + if (status < 0) { + data->model_name[0] = '\0'; + dev_dbg(&client->dev, "unable to read model name from (0x%x) offset(0x%x)\n", + client->addr, models[i].offset); + return status; + } + else { + data->model_name[models[i].length] = '\0'; + } + + if (i == PSU_YM_2401_JCR || i == PSU_YM_2401_JDR) { + /* Skip the meaningless data byte 8*/ + data->model_name[8] = data->model_name[9]; + data->model_name[9] = data->model_name[10]; + data->model_name[10] = '\0'; + } + + /* Determine if the model name is known, if not, read next index + */ + if (strncmp(data->model_name, models[i].model_name, models[i].length) == 0) { + return 0; + } + else { + data->model_name[0] = '\0'; + } + } + + return -ENODATA; +} + +static struct as5812_54t_psu_data *as5812_54t_psu_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as5812_54t_psu_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int status = -1; + + dev_dbg(&client->dev, "Starting as5812_54t update\n"); + data->valid = 0; + + /* Read psu status */ + status = accton_i2c_cpld_read(PSU_STATUS_I2C_ADDR, PSU_STATUS_I2C_REG_OFFSET); + + if (status < 0) { + dev_dbg(&client->dev, "cpld reg (0x%x) err %d\n", PSU_STATUS_I2C_ADDR, status); + goto exit; + } + else { + data->status = status; + } + + data->last_updated = jiffies; + data->valid = 1; + } + +exit: + mutex_unlock(&data->update_lock); + + return data; +} + +static int __init as5812_54t_psu_init(void) +{ + extern int platform_accton_as5812_54t(void); + if (!platform_accton_as5812_54t()) { + return -ENODEV; + } + + return i2c_add_driver(&as5812_54t_psu_driver); +} + +static void __exit as5812_54t_psu_exit(void) +{ + i2c_del_driver(&as5812_54t_psu_driver); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton as5812_54t_psu driver"); +MODULE_LICENSE("GPL"); + +module_init(as5812_54t_psu_init); +module_exit(as5812_54t_psu_exit); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-sfp.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-sfp.c new file mode 100644 index 000000000000..88bf552de0f0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/x86-64-accton-as5812-54t-sfp.c @@ -0,0 +1,318 @@ +/* + * An hwmon driver for accton as5812_54t sfp + * + * Copyright (C) 2015 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define QSFP_PORT_START_INDEX 49 +#define BIT_INDEX(i) (1ULL << (i)) + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { 0x50, I2C_CLIENT_END }; + +/* Each client has this additional data + */ +struct as5812_54t_sfp_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + int port; /* Front port index */ + char eeprom[256]; /* eeprom data */ + u8 status; /* bit0:port49, bit1:port50 and so on */ +}; + +static struct as5812_54t_sfp_data *as5812_54t_sfp_update_device(struct device *dev, int update_eeprom); +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_eeprom(struct device *dev, struct device_attribute *da, char *buf); +extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +enum as5812_54t_sfp_sysfs_attributes { + SFP_IS_PRESENT, + SFP_PORT_NUMBER, + SFP_EEPROM, + SFP_IS_PRESENT_ALL, +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(sfp_is_present, S_IRUGO, show_status, NULL, SFP_IS_PRESENT); +static SENSOR_DEVICE_ATTR(sfp_port_number, S_IRUGO, show_port_number, NULL, SFP_PORT_NUMBER); +static SENSOR_DEVICE_ATTR(sfp_eeprom, S_IRUGO, show_eeprom, NULL, SFP_EEPROM); +static SENSOR_DEVICE_ATTR(sfp_is_present_all, S_IRUGO, show_status,NULL, SFP_IS_PRESENT_ALL); + +static struct attribute *as5812_54t_sfp_attributes[] = { + &sensor_dev_attr_sfp_is_present.dev_attr.attr, + &sensor_dev_attr_sfp_eeprom.dev_attr.attr, + &sensor_dev_attr_sfp_port_number.dev_attr.attr, + &sensor_dev_attr_sfp_is_present_all.dev_attr.attr, + NULL +}; + +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as5812_54t_sfp_data *data = i2c_get_clientdata(client); + + return sprintf(buf, "%d\n",data->port); +} + +static ssize_t show_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct as5812_54t_sfp_data *data = as5812_54t_sfp_update_device(dev, 0); + + if (attr->index == SFP_IS_PRESENT) { + u8 val; + + val = (data->status & BIT_INDEX(data->port - QSFP_PORT_START_INDEX)) ? 0 : 1; + return sprintf(buf, "%d", val); + } + else { /* SFP_IS_PRESENT_ALL */ + return sprintf(buf, "%.2x\n", ~data->status); + } +} + +static ssize_t show_eeprom(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct as5812_54t_sfp_data *data = as5812_54t_sfp_update_device(dev, 1); + + if (!data->valid) { + return 0; + } + + if ((data->status & BIT_INDEX(data->port - QSFP_PORT_START_INDEX)) != 0) { + return 0; + } + + memcpy(buf, data->eeprom, sizeof(data->eeprom)); + + return sizeof(data->eeprom); +} + +static const struct attribute_group as5812_54t_sfp_group = { + .attrs = as5812_54t_sfp_attributes, +}; + +static int as5812_54t_sfp_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct as5812_54t_sfp_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct as5812_54t_sfp_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + mutex_init(&data->update_lock); + data->port = dev_id->driver_data; + i2c_set_clientdata(client, data); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as5812_54t_sfp_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: sfp '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as5812_54t_sfp_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as5812_54t_sfp_remove(struct i2c_client *client) +{ + struct as5812_54t_sfp_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as5812_54t_sfp_group); + kfree(data); + + return 0; +} + +enum port_numbers { +as5812_54t_qsfp49 = 49, +as5812_54t_qsfp50, +as5812_54t_qsfp51, +as5812_54t_qsfp52, +as5812_54t_qsfp53, +as5812_54t_qsfp54 +}; + +static const struct i2c_device_id as5812_54t_sfp_id[] = { +{ "as5812_54t_qsfp49", as5812_54t_qsfp49 }, { "as5812_54t_qsfp50", as5812_54t_qsfp50 }, +{ "as5812_54t_qsfp51", as5812_54t_qsfp51 }, { "as5812_54t_qsfp52", as5812_54t_qsfp52 }, +{ "as5812_54t_qsfp53", as5812_54t_qsfp53 }, { "as5812_54t_qsfp54", as5812_54t_qsfp54 }, +{} +}; +MODULE_DEVICE_TABLE(i2c, as5812_54t_sfp_id); + +static struct i2c_driver as5812_54t_sfp_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "as5812_54t_sfp", + }, + .probe = as5812_54t_sfp_probe, + .remove = as5812_54t_sfp_remove, + .id_table = as5812_54t_sfp_id, + .address_list = normal_i2c, +}; + +static int as5812_54t_sfp_read_byte(struct i2c_client *client, u8 command, u8 *data) +{ + int result = i2c_smbus_read_byte_data(client, command); + + if (unlikely(result < 0)) { + dev_dbg(&client->dev, "sfp read byte data failed, command(0x%2x), data(0x%2x)\r\n", command, result); + goto abort; + } + + *data = (u8)result; + result = 0; + +abort: + return result; +} + +static struct as5812_54t_sfp_data *as5812_54t_sfp_update_device(struct device *dev, int update_eeprom) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as5812_54t_sfp_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid || update_eeprom) { + int status = -1; + int i = 0; + + data->valid = 0; + //dev_dbg(&client->dev, "Starting as5812_54t sfp status update\n"); + data->status = 0xFF; + + /* + * Bring QSFPs out of reset, + * This is a temporary fix until the QSFP+_MOD_RST register + * can be exposed through the driver. + */ + accton_i2c_cpld_write(0x60, 0x23, 0x3F); + + /* Read present status of port 49-54(QSFP port) */ + status = accton_i2c_cpld_read(0x60, 0x22); + + if (status < 0) { + dev_dbg(&client->dev, "cpld(0x60) reg(0x22) err %d\n", status); + } + else { + data->status = status & 0x3F; /* (u32)status */ + } + + if (update_eeprom) { + /* Read eeprom data based on port number */ + memset(data->eeprom, 0, sizeof(data->eeprom)); + + /* Check if the port is present */ + if ((data->status & BIT_INDEX(data->port - QSFP_PORT_START_INDEX)) == 0) { + /* read eeprom */ + for (i = 0; i < sizeof(data->eeprom); i++) { + status = as5812_54t_sfp_read_byte(client, i, data->eeprom + i); + + if (status < 0) { + dev_dbg(&client->dev, "unable to read eeprom from port(%d)\n", + data->port); + goto exit; + } + } + } + } + + data->valid = 1; + data->last_updated = jiffies; + } + +exit: + mutex_unlock(&data->update_lock); + + return data; +} + +static int __init as5812_54t_sfp_init(void) +{ + extern int platform_accton_as5812_54t(void); + if (!platform_accton_as5812_54t()) { + return -ENODEV; + } + + return i2c_add_driver(&as5812_54t_sfp_driver); +} + +static void __exit as5812_54t_sfp_exit(void) +{ + i2c_del_driver(&as5812_54t_sfp_driver); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton as5812_54t_sfp driver"); +MODULE_LICENSE("GPL"); + +module_init(as5812_54t_sfp_init); +module_exit(as5812_54t_sfp_exit); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/ym2651y.c b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/ym2651y.c new file mode 100644 index 000000000000..7101aa411f72 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/modules/ym2651y.c @@ -0,0 +1,680 @@ +/* + * An hwmon driver for the 3Y Power YM-2651Y Power Module + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_FAN_DUTY_CYCLE 100 + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +enum chips { + YM2651, + YM2401, +}; + +/* Each client has this additional data + */ +struct ym2651y_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 chip; /* chip id */ + u8 capability; /* Register value */ + u16 status_word; /* Register value */ + u8 fan_fault; /* Register value */ + u8 over_temp; /* Register value */ + u16 v_out; /* Register value */ + u16 i_out; /* Register value */ + u16 p_out; /* Register value */ + u8 vout_mode; /* Register value */ + u16 temp; /* Register value */ + u16 fan_speed; /* Register value */ + u16 fan_duty_cycle[2]; /* Register value */ + u8 fan_dir[5]; /* Register value */ + u8 pmbus_revision; /* Register value */ + u8 mfr_id[10]; /* Register value */ + u8 mfr_model[16]; /* Register value */ + u8 mfr_revsion[3]; /* Register value */ + u16 mfr_vin_min; /* Register value */ + u16 mfr_vin_max; /* Register value */ + u16 mfr_iin_max; /* Register value */ + u16 mfr_iout_max; /* Register value */ + u16 mfr_pin_max; /* Register value */ + u16 mfr_pout_max; /* Register value */ + u16 mfr_vout_min; /* Register value */ + u16 mfr_vout_max; /* Register value */ +}; + +static ssize_t show_byte(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_word(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_linear(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_vout(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_over_temp(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_ascii(struct device *dev, struct device_attribute *da, + char *buf); +static struct ym2651y_data *ym2651y_update_device(struct device *dev); +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value); + +enum ym2651y_sysfs_attributes { + PSU_POWER_ON = 0, + PSU_TEMP_FAULT, + PSU_POWER_GOOD, + PSU_FAN1_FAULT, + PSU_FAN_DIRECTION, + PSU_OVER_TEMP, + PSU_V_OUT, + PSU_I_OUT, + PSU_P_OUT, + PSU_TEMP1_INPUT, + PSU_FAN1_SPEED, + PSU_FAN1_DUTY_CYCLE, + PSU_PMBUS_REVISION, + PSU_MFR_ID, + PSU_MFR_MODEL, + PSU_MFR_REVISION, + PSU_MFR_VIN_MIN, + PSU_MFR_VIN_MAX, + PSU_MFR_VOUT_MIN, + PSU_MFR_VOUT_MAX, + PSU_MFR_IIN_MAX, + PSU_MFR_IOUT_MAX, + PSU_MFR_PIN_MAX, + PSU_MFR_POUT_MAX +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(psu_power_on, S_IRUGO, show_word, NULL, PSU_POWER_ON); +static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, show_word, NULL, PSU_TEMP_FAULT); +static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_word, NULL, PSU_POWER_GOOD); +static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, show_fan_fault, NULL, PSU_FAN1_FAULT); +static SENSOR_DEVICE_ATTR(psu_over_temp, S_IRUGO, show_over_temp, NULL, PSU_OVER_TEMP); +static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, show_vout, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, show_linear, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, show_linear, NULL, PSU_P_OUT); +static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); +static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, show_linear, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); +static SENSOR_DEVICE_ATTR(psu_fan_dir, S_IRUGO, show_ascii, NULL, PSU_FAN_DIRECTION); +static SENSOR_DEVICE_ATTR(psu_pmbus_revision,S_IRUGO, show_byte, NULL, PSU_PMBUS_REVISION); +static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, show_ascii, NULL, PSU_MFR_ID); +static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, show_ascii, NULL, PSU_MFR_MODEL); +static SENSOR_DEVICE_ATTR(psu_mfr_revision, S_IRUGO, show_ascii, NULL, PSU_MFR_REVISION); +static SENSOR_DEVICE_ATTR(psu_mfr_vin_min, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MIN); +static SENSOR_DEVICE_ATTR(psu_mfr_vin_max, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_vout_min, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MIN); +static SENSOR_DEVICE_ATTR(psu_mfr_vout_max, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_iin_max, S_IRUGO, show_linear, NULL, PSU_MFR_IIN_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_iout_max, S_IRUGO, show_linear, NULL, PSU_MFR_IOUT_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_pin_max, S_IRUGO, show_linear, NULL, PSU_MFR_PIN_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_pout_max, S_IRUGO, show_linear, NULL, PSU_MFR_POUT_MAX); + +static struct attribute *ym2651y_attributes[] = { + &sensor_dev_attr_psu_power_on.dev_attr.attr, + &sensor_dev_attr_psu_temp_fault.dev_attr.attr, + &sensor_dev_attr_psu_power_good.dev_attr.attr, + &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, + &sensor_dev_attr_psu_over_temp.dev_attr.attr, + &sensor_dev_attr_psu_v_out.dev_attr.attr, + &sensor_dev_attr_psu_i_out.dev_attr.attr, + &sensor_dev_attr_psu_p_out.dev_attr.attr, + &sensor_dev_attr_psu_temp1_input.dev_attr.attr, + &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, + &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, + &sensor_dev_attr_psu_fan_dir.dev_attr.attr, + &sensor_dev_attr_psu_pmbus_revision.dev_attr.attr, + &sensor_dev_attr_psu_mfr_id.dev_attr.attr, + &sensor_dev_attr_psu_mfr_model.dev_attr.attr, + &sensor_dev_attr_psu_mfr_revision.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vin_min.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vin_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_pout_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_iin_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_pin_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vout_min.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vout_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_iout_max.dev_attr.attr, + NULL +}; + +static ssize_t show_byte(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + + if (!data->valid) { + return 0; + } + + return (attr->index == PSU_PMBUS_REVISION) ? sprintf(buf, "%d\n", data->pmbus_revision) : + sprintf(buf, "0\n"); +} + +static ssize_t show_word(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + u16 status = 0; + + if (!data->valid) { + return 0; + } + + switch (attr->index) { + case PSU_POWER_ON: /* psu_power_on, low byte bit 6 of status_word, 0=>ON, 1=>OFF */ + status = (data->status_word & 0x40) ? 0 : 1; + break; + case PSU_TEMP_FAULT: /* psu_temp_fault, low byte bit 2 of status_word, 0=>Normal, 1=>temp fault */ + status = (data->status_word & 0x4) >> 2; + break; + case PSU_POWER_GOOD: /* psu_power_good, high byte bit 3 of status_word, 0=>OK, 1=>FAIL */ + status = (data->status_word & 0x800) ? 0 : 1; + break; + } + + return sprintf(buf, "%d\n", status); +} + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + bool is_negative = valid_data >> (valid_bit - 1); + + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} + +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct ym2651y_data *data = i2c_get_clientdata(client); + int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; + long speed; + int error; + + error = kstrtol(buf, 10, &speed); + if (error) + return error; + + if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) + return -EINVAL; + + mutex_lock(&data->update_lock); + data->fan_duty_cycle[nr] = speed; + ym2651y_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t show_linear(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + + u16 value = 0; + int exponent, mantissa; + int multiplier = 1000; + + if (!data->valid) { + return 0; + } + + switch (attr->index) { + case PSU_V_OUT: + value = data->v_out; + break; + case PSU_I_OUT: + value = data->i_out; + break; + case PSU_P_OUT: + value = data->p_out; + break; + case PSU_TEMP1_INPUT: + value = data->temp; + break; + case PSU_FAN1_SPEED: + value = data->fan_speed; + multiplier = 1; + break; + case PSU_FAN1_DUTY_CYCLE: + value = data->fan_duty_cycle[0]; + multiplier = 1; + break; + case PSU_MFR_VIN_MIN: + value = data->mfr_vin_min; + break; + case PSU_MFR_VIN_MAX: + value = data->mfr_vin_max; + break; + case PSU_MFR_VOUT_MIN: + value = data->mfr_vout_min; + break; + case PSU_MFR_VOUT_MAX: + value = data->mfr_vout_max; + break; + case PSU_MFR_PIN_MAX: + value = data->mfr_pin_max; + break; + case PSU_MFR_POUT_MAX: + value = data->mfr_pout_max; + break; + case PSU_MFR_IOUT_MAX: + value = data->mfr_iout_max; + break; + case PSU_MFR_IIN_MAX: + value = data->mfr_iin_max; + break; + } + + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + + return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + u8 shift; + + if (!data->valid) { + return 0; + } + + shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; + + return sprintf(buf, "%d\n", data->fan_fault >> shift); +} + +static ssize_t show_over_temp(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct ym2651y_data *data = ym2651y_update_device(dev); + + if (!data->valid) { + return 0; + } + + return sprintf(buf, "%d\n", data->over_temp >> 7); +} + +static ssize_t show_ascii(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + u8 *ptr = NULL; + + if (!data->valid) { + return 0; + } + + switch (attr->index) { + case PSU_FAN_DIRECTION: /* psu_fan_dir */ + ptr = data->fan_dir + 1; /* Skip the first byte since it is the length of string. */ + break; + case PSU_MFR_ID: /* psu_mfr_id */ + ptr = data->mfr_id + 1; /* The first byte is the count byte of string. */; + break; + case PSU_MFR_MODEL: /* psu_mfr_model */ + ptr = data->mfr_model + 1; /* The first byte is the count byte of string. */ + break; + case PSU_MFR_REVISION: /* psu_mfr_revision */ + ptr = data->mfr_revsion + 1; /* The first byte is the count byte of string. */ + break; + default: + return 0; + } + + return sprintf(buf, "%s\n", ptr); +} + +static ssize_t show_vout_by_mode(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct ym2651y_data *data = ym2651y_update_device(dev); + int exponent, mantissa; + int multiplier = 1000; + + if (!data->valid) { + return 0; + } + + exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); + mantissa = data->v_out; + + return (exponent > 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static ssize_t show_vout(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct ym2651y_data *data = i2c_get_clientdata(client); + + if (data->chip == YM2401) { + return show_vout_by_mode(dev, da, buf); + } + + return show_linear(dev, da, buf); +} + +static const struct attribute_group ym2651y_group = { + .attrs = ym2651y_attributes, +}; + +static int ym2651y_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct ym2651y_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct ym2651y_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->chip = dev_id->driver_data; + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &ym2651y_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &ym2651y_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int ym2651y_remove(struct i2c_client *client) +{ + struct ym2651y_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &ym2651y_group); + kfree(data); + + return 0; +} + +static const struct i2c_device_id ym2651y_id[] = { + { "ym2651", YM2651 }, + { "ym2401", YM2401 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, ym2651y_id); + +static struct i2c_driver ym2651y_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "ym2651", + }, + .probe = ym2651y_probe, + .remove = ym2651y_remove, + .id_table = ym2651y_id, + .address_list = normal_i2c, +}; + +static int ym2651y_read_byte(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int ym2651y_read_word(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_word_data(client, reg); +} + +static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value) +{ + return i2c_smbus_write_word_data(client, reg, value); +} + +static int ym2651y_read_block(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ + int result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + + if (unlikely(result < 0)) + goto abort; + if (unlikely(result != data_len)) { + result = -EIO; + goto abort; + } + + result = 0; + +abort: + return result; +} + +struct reg_data_byte { + u8 reg; + u8 *value; +}; + +struct reg_data_word { + u8 reg; + u16 *value; +}; + +static struct ym2651y_data *ym2651y_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct ym2651y_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int i, status, length; + u8 command, buf; + struct reg_data_byte regs_byte[] = { {0x19, &data->capability}, + {0x20, &data->vout_mode}, + {0x7d, &data->over_temp}, + {0x81, &data->fan_fault}, + {0x98, &data->pmbus_revision}}; + struct reg_data_word regs_word[] = { {0x79, &data->status_word}, + {0x8b, &data->v_out}, + {0x8c, &data->i_out}, + {0x96, &data->p_out}, + {0x8d, &data->temp}, + {0x3b, &(data->fan_duty_cycle[0])}, + {0x3c, &(data->fan_duty_cycle[1])}, + {0x90, &data->fan_speed}, + {0xa0, &data->mfr_vin_min}, + {0xa1, &data->mfr_vin_max}, + {0xa2, &data->mfr_iin_max}, + {0xa3, &data->mfr_pin_max}, + {0xa4, &data->mfr_vout_min}, + {0xa5, &data->mfr_vout_max}, + {0xa6, &data->mfr_iout_max}, + {0xa7, &data->mfr_pout_max}}; + + dev_dbg(&client->dev, "Starting ym2651 update\n"); + data->valid = 0; + + /* Read byte data */ + for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { + status = ym2651y_read_byte(client, regs_byte[i].reg); + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_byte[i].reg, status); + goto exit; + } + else { + *(regs_byte[i].value) = status; + } + } + + /* Read word data */ + for (i = 0; i < ARRAY_SIZE(regs_word); i++) { + status = ym2651y_read_word(client, regs_word[i].reg); + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_word[i].reg, status); + goto exit; + } + else { + *(regs_word[i].value) = status; + } + } + + /* Read fan_direction */ + command = 0xC3; + status = ym2651y_read_block(client, command, data->fan_dir, + ARRAY_SIZE(data->fan_dir)-1); + data->fan_dir[ARRAY_SIZE(data->fan_dir)-1] = '\0'; + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + goto exit; + } + + /* Read mfr_id */ + command = 0x99; + status = ym2651y_read_block(client, command, data->mfr_id, + ARRAY_SIZE(data->mfr_id)-1); + data->mfr_id[ARRAY_SIZE(data->mfr_id)-1] = '\0'; + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + goto exit; + } + + /* Read mfr_model */ + command = 0x9a; + length = 1; + + /* Read first byte to determine the length of data */ + status = ym2651y_read_block(client, command, &buf, length); + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + goto exit; + } + + status = ym2651y_read_block(client, command, data->mfr_model, buf+1); + data->mfr_model[buf+1] = '\0'; + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + goto exit; + } + + /* Read mfr_revsion */ + command = 0x9b; + status = ym2651y_read_block(client, command, data->mfr_revsion, + ARRAY_SIZE(data->mfr_revsion)-1); + data->mfr_revsion[ARRAY_SIZE(data->mfr_revsion)-1] = '\0'; + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + goto exit; + } + + data->last_updated = jiffies; + data->valid = 1; + } + +exit: + mutex_unlock(&data->update_lock); + + return data; +} + +static int __init ym2651y_init(void) +{ + return i2c_add_driver(&ym2651y_driver); +} + +static void __exit ym2651y_exit(void) +{ + i2c_del_driver(&ym2651y_driver); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("3Y Power YM-2651Y driver"); +MODULE_LICENSE("GPL"); + +module_init(ym2651y_init); +module_exit(ym2651y_exit); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/service/as5812-platform-init.service b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/service/as5812-platform-init.service new file mode 100755 index 000000000000..30c1703dc40f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/service/as5812-platform-init.service @@ -0,0 +1,13 @@ +[Unit] +Description=Accton AS5712-54T Platform initialization service +Before=pmon.service +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/accton_as5812_54t_util.py install +ExecStop=/usr/local/bin/accton_as5812_54t_util.py clean +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/README b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/README new file mode 100755 index 000000000000..2284eb091fcb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/README @@ -0,0 +1,60 @@ +Copyright (C) 2016 Accton Networks, 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 3 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, see . + +To initialize the system, run "accton_as5812_54t_util.py install". +To clean up the drivers & devices, run "accton_as5812_54t_util.py clean". +To dump information of sensors, run "accton_as5812_54t_util.py show". +To dump SFP EEPROM, run "accton_as5812_54t_util.py sff". +To set fan speed, run "accton_as5812_54t_util.py set fan". +To enable/disable SFP emission, run "accton_as5812_54t_util.py set sfp". +To set system LEDs' color, run "accton_as5812_54t_util.py set led" +For more information, run "accton_as5812_54t_util.py --help". + +==================================================================== +Besides applying accton_as5812_54t_util.py to access peripherals, you can +access peripherals by sysfs nodes directly after the installation is run. + +LED controls can be found under /sys/class/leds. The sysfs interface +color mappings are as follows: +Brightness: + 0 => off + 1 => green + 2 => amber + 3 => red + 4 => blue + +There are 5 system LEDs, loc, diag, fan, ps1, and ps2. +They are lit automatically by CPLD, but the loc and diag. +The loc led has only 1 color, blue. +The diag one has 3 colors: red, amber, and green. + +Fan controls can be found in /sys/bus/i2c/devices/2-0066. +There are 12 fans inside 6 fan modules. +All fans share 1 duty setting, ranged from 0~100. + +Three temperature sensors are controlled by the lm75 kernel modules. +They should already be visible under /sys/bus/i2c/drivers/lm75/. + +Two power supplies are controlled by the CPLD. +Here provide their status under +/sys/bus/i2c/devices/10-0050 and /sys/bus/i2c/devices/11-0053. + +There are 32 QSFP+ modules are equipped. +Apply "accton_as5812_54t_util.py show" to get their status. +Apply "accton_as5812_54t_util.py set sfp" to turn on/off light transmission. +Apply "accton_as5812_54t_util.py sff" to dump EEPROM information. +Before operating on that QSFP+, please make sure it is well plugged. +Otherwise, operation is going to fail. + diff --git a/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_54t_util.py b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_54t_util.py new file mode 100755 index 000000000000..4e9b0795081d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as5812-54t/utils/accton_as5812_54t_util.py @@ -0,0 +1,565 @@ +#!/usr/bin/env python +# +# Copyright (C) 2016 Accton Networks, 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 3 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, see . + +""" +Usage: %(scriptName)s [options] command object + +options: + -h | --help : this help message + -d | --debug : run with debug mode + -f | --force : ignore error during installation or clean +command: + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes + show : show all systen status + sff : dump SFP eeprom + set : change board setting with fan|led|sfp +""" + +import os +import commands +import sys, getopt +import logging +import re +import time +from collections import namedtuple + + + + +PROJECT_NAME = 'as5812_54t' +version = '0.1.0' +verbose = False +DEBUG = False +args = [] +ALL_DEVICE = {} +DEVICE_NO = {'led':5, 'fan':5,'thermal':3, 'psu':2, 'sfp':6} +FORCE = 0 +logging.basicConfig(filename= PROJECT_NAME+'.log', filemode='w',level=logging.DEBUG) +logging.basicConfig(level=logging.INFO) + + +if DEBUG == True: + print sys.argv[0] + print 'ARGV :', sys.argv[1:] + + +def main(): + global DEBUG + global args + global FORCE + + if len(sys.argv)<2: + show_help() + + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', + 'debug', + 'force', + ]) + if DEBUG == True: + print options + print args + print len(sys.argv) + + for opt, arg in options: + if opt in ('-h', '--help'): + show_help() + elif opt in ('-d', '--debug'): + DEBUG = True + logging.basicConfig(level=logging.INFO) + elif opt in ('-f', '--force'): + FORCE = 1 + else: + logging.info('no option') + for arg in args: + if arg == 'install': + do_install() + elif arg == 'clean': + do_uninstall() + elif arg == 'show': + device_traversal() + elif arg == 'sff': + if len(args)!=2: + show_eeprom_help() + elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']: + show_eeprom_help() + else: + show_eeprom(args[1]) + return + elif arg == 'set': + if len(args)<3: + show_set_help() + else: + set_device(args[1:]) + return + else: + show_help() + + + return 0 + +def show_help(): + print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + sys.exit(0) + +def show_set_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print cmd +" [led|sfp|fan]" + print " use \""+ cmd + " led 0-4 \" to set led color" + print " use \""+ cmd + " fan 0-100\" to set fan duty percetage" + print " use \""+ cmd + " sfp 1-6 {0|1}\" to set sfp# tx_disable" + sys.exit(0) + +def show_eeprom_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print " use \""+ cmd + " 1-32 \" to dump sfp# eeprom" + sys.exit(0) + +def my_log(txt): + if DEBUG == True: + print "[ROY]"+txt + return + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) + my_log (cmd +"with result:" + str(status)) + my_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + +def driver_check(): + ret, lsmod = log_os_system("lsmod| grep accton", 0) + logging.info('mods:'+lsmod) + if len(lsmod) ==0: + return False + return True + + + self.insmod("accton_i2c_cpld") + self.insmod("cpr_4011_4mxx") + self.insmod("ym2651y") + for m in [ "sfp", "psu", "fan", "leds" ]: + self.insmod("x86-64-accton-as5812-54t-%s" % m) + +kos = [ +'modprobe i2c_dev', +'modprobe i2c_mux_pca954x force_deselect_on_exit=1', +'modprobe accton_i2c_cpld' , +'modprobe cpr_4011_4mxx' , +'modprobe ym2651y' , +'modprobe x86-64-accton-as5812-54t-sfp' , +'modprobe x86-64-accton-as5812-54t-psu' , +'modprobe x86-64-accton-as5812-54t-fan' , +'modprobe x86-64-accton-as5812-54t-leds' ] + +def driver_install(): + global FORCE + for i in range(0,len(kos)): + status, output = log_os_system(kos[i], 1) + if status: + if FORCE == 0: + return status + return 0 + +def driver_uninstall(): + global FORCE + for i in range(0,len(kos)): + rm = kos[-(i+1)].replace("modprobe", "modprobe -rq") + rm = rm.replace("insmod", "rmmod") + status, output = log_os_system(rm, 1) + if status: + if FORCE == 0: + return status + return 0 + +led_prefix ='/sys/class/leds/accton_'+PROJECT_NAME+'_led::' +hwmon_types = {'led': ['diag','fan','loc','psu1','psu2']} +hwmon_nodes = {'led': ['brightness'] } +hwmon_prefix ={'led': led_prefix} + +i2c_prefix = '/sys/bus/i2c/devices/' +i2c_bus = {'fan': ['2-0066'] , + 'thermal': ['15-0048','16-0049', '17-004a'] , + 'psu': ['11-0050','12-0053'], + 'sfp': ['-0050']} +i2c_nodes = {'fan': ['present', 'front_speed_rpm', 'rear_speed_rpm'] , + 'thermal': ['hwmon/hwmon*/temp1_input'] , + 'psu': ['psu_present ', 'psu_power_good'] , + 'sfp': ['sfp_is_present ', 'sfp_tx_disable_all']} + +sfp_map = [4,6,3,5,7,2] + +sfp_1st_index = 48 + +mknod =[ +'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-1/new_device' , +'echo accton_i2c_cpld 0x60 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-15/new_device', +'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-16/new_device', +'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-17/new_device', +'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo as5812_54t_psu1 0x38 > /sys/bus/i2c/devices/i2c-11/new_device', +'echo cpr_4011_4mxx 0x3c > /sys/bus/i2c/devices/i2c-11/new_device', +'echo as5812_54t_psu1 0x50 > /sys/bus/i2c/devices/i2c-11/new_device', +'echo ym2401 0x58 > /sys/bus/i2c/devices/i2c-11/new_device', +'echo as5812_54t_psu2 0x3b > /sys/bus/i2c/devices/i2c-12/new_device', +'echo cpr_4011_4mxx 0x3f > /sys/bus/i2c/devices/i2c-12/new_device', +'echo as5812_54t_psu2 0x53 > /sys/bus/i2c/devices/i2c-12/new_device', +'echo ym2401 0x5b > /sys/bus/i2c/devices/i2c-12/new_device'] + +mknod2 =[ +'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-0/new_device' , +'echo accton_i2c_cpld 0x60 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-15/new_device', +'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-16/new_device', +'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-17/new_device', +'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo as5812_54t_psu1 0x38 > /sys/bus/i2c/devices/i2c-11/new_device', +'echo cpr_4011_4mxx 0x3c > /sys/bus/i2c/devices/i2c-11/new_device', +'echo as5812_54t_psu1 0x50 > /sys/bus/i2c/devices/i2c-11/new_device', +'echo ym2401 0x58 > /sys/bus/i2c/devices/i2c-11/new_device', +'echo as5812_54t_psu2 0x3b > /sys/bus/i2c/devices/i2c-12/new_device', +'echo cpr_4011_4mxx 0x3f > /sys/bus/i2c/devices/i2c-12/new_device', +'echo as5812_54t_psu2 0x53 > /sys/bus/i2c/devices/i2c-12/new_device', +'echo ym2401 0x5b > /sys/bus/i2c/devices/i2c-12/new_device'] + + + +def i2c_order_check(): + # i2c bus 0 and 1 might be installed in different order. + # Here check if 0x71 is exist @ i2c-0 + tmp = "echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-0/new_device" + status, output = log_os_system(tmp, 0) + if not device_exist(): + order = 1 + else: + order = 0 + tmp = "echo 0x71 > /sys/bus/i2c/devices/i2c-0/delete_device" + status, output = log_os_system(tmp, 0) + return order + +def device_install(): + global FORCE + + order = i2c_order_check() + + # if 0x71 is not exist @i2c-0, use reversed bus order + if order: + for i in range(0,len(mknod2)): + #for pca954x need times to built new i2c buses + if mknod2[i].find('pca954') != -1: + time.sleep(1) + + status, output = log_os_system(mknod2[i], 1) + if status: + print output + if FORCE == 0: + return status + else: + for i in range(0,len(mknod)): + #for pca954x need times to built new i2c buses + if mknod[i].find('pca954') != -1: + time.sleep(1) + + status, output = log_os_system(mknod[i], 1) + if status: + print output + if FORCE == 0: + return status + for i in range(sfp_1st_index,len(sfp_map)): + status, output =log_os_system("echo sfp"+str(i+1)+" 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + return + +def device_uninstall(): + global FORCE + + status, output =log_os_system("ls /sys/bus/i2c/devices/1-0071", 0) + if status==0: + I2C_ORDER=1 + else: + I2C_ORDER=0 + + for i in range(sfp_1st_index,len(sfp_map)): + target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device" + status, output =log_os_system("echo 0x50 > "+ target, 1) + if status: + print output + if FORCE == 0: + return status + + if I2C_ORDER==0: + nodelist = mknod + else: + nodelist = mknod2 + + for i in range(len(nodelist)): + target = nodelist[-(i+1)] + temp = target.split() + del temp[1] + temp[-1] = temp[-1].replace('new_device', 'delete_device') + status, output = log_os_system(" ".join(temp), 1) + if status: + print output + if FORCE == 0: + return status + + return + +def system_ready(): + if driver_check() == False: + return False + if not device_exist(): + return False + return True + +def do_install(): + print "Checking system...." + if driver_check() == False: + print "No driver, installing...." + status = driver_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" drivers detected...." + if not device_exist(): + print "No device, installing...." + status = device_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" devices detected...." + return + +def do_uninstall(): + print "Checking system...." + if not device_exist(): + print PROJECT_NAME.upper() +" has no device installed...." + else: + print "Removing device...." + status = device_uninstall() + if status: + if FORCE == 0: + return status + + if driver_check()== False : + print PROJECT_NAME.upper() +" has no driver installed...." + else: + print "Removing installed driver...." + status = driver_uninstall() + if status: + if FORCE == 0: + return status + + return + +def devices_info(): + global DEVICE_NO + global ALL_DEVICE + global i2c_bus, hwmon_types + for key in DEVICE_NO: + ALL_DEVICE[key]= {} + for i in range(0,DEVICE_NO[key]): + ALL_DEVICE[key][key+str(i+1)] = [] + + for key in i2c_bus: + buses = i2c_bus[key] + nodes = i2c_nodes[key] + for i in range(0,len(buses)): + for j in range(0,len(nodes)): + if 'fan' == key: + for k in range(0,DEVICE_NO[key]): + node = key+str(k+1) + path = i2c_prefix+ buses[i]+"/fan"+str(k+1)+"_"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + elif 'sfp' == key: + for k in range(sfp_1st_index,DEVICE_NO[key]): + node = key+str(k+1) + path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + else: + node = key+str(i+1) + path = i2c_prefix+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + + for key in hwmon_types: + itypes = hwmon_types[key] + nodes = hwmon_nodes[key] + for i in range(0,len(itypes)): + for j in range(0,len(nodes)): + node = key+"_"+itypes[i] + path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][ key+str(i+1)].append(path) + + #show dict all in the order + if DEBUG == True: + for i in sorted(ALL_DEVICE.keys()): + print(i+": ") + for j in sorted(ALL_DEVICE[i].keys()): + print(" "+j) + for k in (ALL_DEVICE[i][j]): + print(" "+" "+k) + return + +def show_eeprom(index): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0] + node = node.replace(node.split("/")[-1], 'sfp_eeprom') + # check if got hexdump command in current environment + ret, log = log_os_system("which hexdump", 0) + ret, log2 = log_os_system("which busybox hexdump", 0) + if len(log): + hex_cmd = 'hexdump' + elif len(log2): + hex_cmd = ' busybox hexdump' + else: + log = 'Failed : no hexdump cmd!!' + logging.info(log) + print log + return 1 + + print node + ":" + ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1) + if ret==0: + print log + else: + print "**********device no found**********" + return + +def set_device(args): + global DEVICE_NO + global ALL_DEVICE + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + + if args[0]=='led': + if int(args[1])>4: + show_set_help() + return + #print ALL_DEVICE['led'] + for i in range(0,len(ALL_DEVICE['led'])): + for k in (ALL_DEVICE['led']['led'+str(i+1)]): + ret, log = log_os_system("echo "+args[1]+" >"+k, 1) + if ret: + return ret + elif args[0]=='fan': + if int(args[1])>100: + show_set_help() + return + #print ALL_DEVICE['fan'] + #fan1~6 is all fine, all fan share same setting + node = ALL_DEVICE['fan'] ['fan1'][0] + node = node.replace(node.split("/")[-1], 'fan_duty_cycle_percentage') + ret, log = log_os_system("cat "+ node, 1) + if ret==0: + print ("Previous fan duty: " + log.strip() +"%") + ret, log = log_os_system("echo "+args[1]+" >"+node, 1) + if ret==0: + print ("Current fan duty: " + args[1] +"%") + return ret + elif args[0]=='sfp': + if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0: + show_set_help() + return + if len(args)<2: + show_set_help() + return + + if int(args[2])>1: + show_set_help() + return + + #print ALL_DEVICE[args[0]] + for i in range(0,len(ALL_DEVICE[args[0]])): + for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]: + if j.find('tx_disable')!= -1: + ret, log = log_os_system("echo "+args[2]+" >"+ j, 1) + if ret: + return ret + + return + +#get digits inside a string. +#Ex: 31 for "sfp31" +def get_value(input): + digit = re.findall('\d+', input) + return int(digit[0]) + +def device_traversal(): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + for i in sorted(ALL_DEVICE.keys()): + print("============================================") + print(i.upper()+": ") + print("============================================") + + for j in sorted(ALL_DEVICE[i].keys(), key=get_value): + print " "+j+":", + for k in (ALL_DEVICE[i][j]): + ret, log = log_os_system("cat "+k, 0) + func = k.split("/")[-1].strip() + func = re.sub(j+'_','',func,1) + func = re.sub(i.lower()+'_','',func,1) + if ret==0: + print func+"="+log+" ", + else: + print func+"="+"X"+" ", + print + print("----------------------------------------------------------------") + + + print + return + +def device_exist(): + ret1, log = log_os_system("ls "+i2c_prefix+"*0071", 0) + ret2, log = log_os_system("ls "+i2c_prefix+"i2c-2", 0) + return not(ret1 or ret2) + +if __name__ == "__main__": + main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/classes/__init__.py b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/classes/__init__.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/classes/fanutil.py b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/classes/fanutil.py new file mode 100755 index 000000000000..207436c1fc96 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/classes/fanutil.py @@ -0,0 +1,255 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 Accton Technology Corporation +# +# 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 3 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, see . + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 11/13/2017: Polly Hsu, Create +# 1/10/2018: Jostar modify for as7716_32 +# 2/27/2018: Roy Lee modify for as7312_54x +# ------------------------------------------------------------------ + +try: + import time + import logging + from collections import namedtuple +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + + +class FanUtil(object): + """Platform-specific FanUtil class""" + + FAN_NUM_ON_MAIN_BROAD = 6 + FAN_NUM_1_IDX = 1 + FAN_NUM_2_IDX = 2 + FAN_NUM_3_IDX = 3 + FAN_NUM_4_IDX = 4 + FAN_NUM_5_IDX = 5 + FAN_NUM_6_IDX = 6 + + FAN_NODE_NUM_OF_MAP = 2 + FAN_NODE_FAULT_IDX_OF_MAP = 1 + #FAN_NODE_SPEED_IDX_OF_MAP = 2 + FAN_NODE_DIR_IDX_OF_MAP = 2 + #FAN_NODE_DUTY_IDX_OF_MAP = 4 + #FANR_NODE_FAULT_IDX_OF_MAP = 5 + + #BASE_VAL_PATH = '/sys/devices/platform/as5712_54x_fan/{0}' + BASE_VAL_PATH = '/sys/bus/i2c/devices/2-0066/{0}' + FAN_DUTY_PATH = '/sys/bus/i2c/devices/2-0066/fan_duty_cycle_percentage' + + #logfile = '' + #loglevel = logging.INFO + + """ Dictionary where + key1 = fan id index (integer) starting from 1 + key2 = fan node index (interger) starting from 1 + value = path to fan device file (string) """ + _fan_to_device_path_mapping = {} + +#fan1_direction +#fan1_fault +#fan1_present + + #(FAN_NUM_2_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan2_duty_cycle_percentage', + _fan_to_device_node_mapping = { + (FAN_NUM_1_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan1_fault', + (FAN_NUM_1_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan1_direction', + + (FAN_NUM_2_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan2_fault', + (FAN_NUM_2_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan2_direction', + + (FAN_NUM_3_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan3_fault', + (FAN_NUM_3_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan3_direction', + + (FAN_NUM_4_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan4_fault', + (FAN_NUM_4_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan4_direction', + + (FAN_NUM_5_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan5_fault', + (FAN_NUM_5_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan5_direction', + + (FAN_NUM_6_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan6_fault', + (FAN_NUM_6_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan6_direction', + } + + def _get_fan_to_device_node(self, fan_num, node_num): + return self._fan_to_device_node_mapping[(fan_num, node_num)] + + def _get_fan_node_val(self, fan_num, node_num): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. fan_num:%d', fan_num) + return None + + if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP: + logging.debug('GET. Parameter error. node_num:%d', node_num) + return None + + device_path = self.get_fan_to_device_path(fan_num, node_num) + + try: + val_file = open(device_path, 'r') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None + + content = val_file.readline().rstrip() + + if content == '': + logging.debug('GET. content is NULL. device_path:%s', device_path) + return None + + try: + val_file.close() + except: + logging.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return int(content) + + def _set_fan_node_val(self, fan_num, node_num, val): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. fan_num:%d', fan_num) + return None + + if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP: + logging.debug('GET. Parameter error. node_num:%d', node_num) + return None + + content = str(val) + if content == '': + logging.debug('GET. content is NULL. device_path:%s', device_path) + return None + + device_path = self.get_fan_to_device_path(fan_num, node_num) + try: + val_file = open(device_path, 'w') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None + + val_file.write(content) + + try: + val_file.close() + except: + logging.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return True + + def __init__(self): + fan_path = self.BASE_VAL_PATH + + for fan_num in range(self.FAN_NUM_1_IDX, self.FAN_NUM_ON_MAIN_BROAD+1): + for node_num in range(self.FAN_NODE_FAULT_IDX_OF_MAP, self.FAN_NODE_NUM_OF_MAP+1): + self._fan_to_device_path_mapping[(fan_num, node_num)] = fan_path.format( + self._fan_to_device_node_mapping[(fan_num, node_num)]) + + def get_num_fans(self): + return self.FAN_NUM_ON_MAIN_BROAD + + def get_idx_fan_start(self): + return self.FAN_NUM_1_IDX + + def get_num_nodes(self): + return self.FAN_NODE_NUM_OF_MAP + + def get_idx_node_start(self): + return self.FAN_NODE_FAULT_IDX_OF_MAP + + def get_size_node_map(self): + return len(self._fan_to_device_node_mapping) + + def get_size_path_map(self): + return len(self._fan_to_device_path_mapping) + + def get_fan_to_device_path(self, fan_num, node_num): + return self._fan_to_device_path_mapping[(fan_num, node_num)] + + def get_fan_fault(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_FAULT_IDX_OF_MAP) + + #def get_fan_speed(self, fan_num): + # return self._get_fan_node_val(fan_num, self.FAN_NODE_SPEED_IDX_OF_MAP) + + def get_fan_dir(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_DIR_IDX_OF_MAP) + + def get_fan_duty_cycle(self): + #duty_path = self.FAN_DUTY_PATH + try: + val_file = open(self.FAN_DUTY_PATH) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = val_file.readline().rstrip() + val_file.close() + + return int(content) + #self._get_fan_node_val(fan_num, self.FAN_NODE_DUTY_IDX_OF_MAP) +#static u32 reg_val_to_duty_cycle(u8 reg_val) +#{ +# reg_val &= FAN_DUTY_CYCLE_REG_MASK; +# return ((u32)(reg_val+1) * 625 + 75)/ 100; +#} +# + def set_fan_duty_cycle(self, val): + + try: + fan_file = open(self.FAN_DUTY_PATH, 'r+') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + #val = ((val + 1 ) * 625 +75 ) / 100 + fan_file.write(str(val)) + fan_file.close() + return True + + #def get_fanr_fault(self, fan_num): + # return self._get_fan_node_val(fan_num, self.FANR_NODE_FAULT_IDX_OF_MAP) + + def get_fanr_speed(self, fan_num): + return self._get_fan_node_val(fan_num, self.FANR_NODE_SPEED_IDX_OF_MAP) + + def get_fan_status(self, fan_num): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. fan_num, %d', fan_num) + return None + + if self.get_fan_fault(fan_num) is not None and self.get_fan_fault(fan_num) > 0: + logging.debug('GET. FAN fault. fan_num, %d', fan_num) + return False + + #if self.get_fanr_fault(fan_num) is not None and self.get_fanr_fault(fan_num) > 0: + # logging.debug('GET. FANR fault. fan_num, %d', fan_num) + # return False + + return True + +#def main(): +# fan = FanUtil() +# +# print 'get_size_node_map : %d' % fan.get_size_node_map() +# print 'get_size_path_map : %d' % fan.get_size_path_map() +# for x in range(fan.get_idx_fan_start(), fan.get_num_fans()+1): +# for y in range(fan.get_idx_node_start(), fan.get_num_nodes()+1): +# print fan.get_fan_to_device_path(x, y) +# +#if __name__ == '__main__': +# main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/classes/thermalutil.py b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/classes/thermalutil.py new file mode 100755 index 000000000000..68f0ef900df6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/classes/thermalutil.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 Accton Technology Corporation +# +# 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 3 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, see . + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 11/13/2017: Polly Hsu, Create +# 1/10/2018:Jostar modify for as7716_32x +# 2/27/2018: Roy Lee modify for as7312_54x +# ------------------------------------------------------------------ + +try: + import time + import logging + import glob + from collections import namedtuple +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + + +class ThermalUtil(object): + """Platform-specific ThermalUtil class""" + + THERMAL_NUM_ON_MAIN_BROAD = 3 + THERMAL_NUM_1_IDX = 1 # 1_ON_MAIN_BROAD + THERMAL_NUM_2_IDX = 2 # 2_ON_MAIN_BROAD + THERMAL_NUM_3_IDX = 3 # 3_ON_MAIN_BROAD + + BASE_VAL_PATH = '/sys/bus/i2c/devices/{0}-00{1}/hwmon/hwmon*/temp1_input' + + """ Dictionary where + key1 = thermal id index (integer) starting from 1 + value = path to fan device file (string) """ + _thermal_to_device_path_mapping = {} + + _thermal_to_device_node_mapping = { + THERMAL_NUM_1_IDX: ['3', '48'], + THERMAL_NUM_2_IDX: ['3', '49'], + THERMAL_NUM_3_IDX: ['3', '4a'], + } + + def __init__(self): + thermal_path = self.BASE_VAL_PATH + + for x in range(self.THERMAL_NUM_1_IDX, self.THERMAL_NUM_ON_MAIN_BROAD+1): + self._thermal_to_device_path_mapping[x] = thermal_path.format( + self._thermal_to_device_node_mapping[x][0], + self._thermal_to_device_node_mapping[x][1]) + + def _get_thermal_node_val(self, thermal_num): + if thermal_num < self.THERMAL_NUM_1_IDX or thermal_num > self.THERMAL_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. thermal_num, %d', thermal_num) + return None + + device_path = self.get_thermal_to_device_path(thermal_num) + for filename in glob.glob(device_path): + try: + val_file = open(filename, 'r') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None + + content = val_file.readline().rstrip() + + if content == '': + logging.debug('GET. content is NULL. device_path:%s', device_path) + return None + + try: + val_file.close() + except: + logging.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return int(content) + + + def get_num_thermals(self): + return self.THERMAL_NUM_ON_MAIN_BROAD + + def get_idx_thermal_start(self): + return self.THERMAL_NUM_1_IDX + + def get_size_node_map(self): + return len(self._thermal_to_device_node_mapping) + + def get_size_path_map(self): + return len(self._thermal_to_device_path_mapping) + + def get_thermal_to_device_path(self, thermal_num): + return self._thermal_to_device_path_mapping[thermal_num] + + def get_thermal_1_val(self): + return self._get_thermal_node_val(self.THERMAL_NUM_1_IDX) + + def get_thermal_2_val(self): + return self._get_thermal_node_val(self.THERMAL_NUM_2_IDX) + def get_thermal_temp(self): + return (self._get_thermal_node_val(self.THERMAL_NUM_1_IDX) + self._get_thermal_node_val(self.THERMAL_NUM_2_IDX) +self._get_thermal_node_val(self.THERMAL_NUM_3_IDX)) + +#def main(): +# thermal = ThermalUtil() +# +# print 'get_size_node_map : %d' % thermal.get_size_node_map() +# print 'get_size_path_map : %d' % thermal.get_size_path_map() +# for x in range(thermal.get_idx_thermal_start(), thermal.get_num_thermals()+1): +# print thermal.get_thermal_to_device_path(x) +# +#if __name__ == '__main__': +# main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/Makefile b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/Makefile new file mode 100755 index 000000000000..488fdb321cac --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/Makefile @@ -0,0 +1,17 @@ +ifneq ($(KERNELRELEASE),) +obj-m:= accton_i2c_cpld.o \ + accton_as7312_54x_fan.o accton_as7312_54x_leds.o \ + accton_as7312_54x_psu.o ym2651y.o + +else +ifeq (,$(KERNEL_SRC)) +$(error KERNEL_SRC is not defined) +else +KERNELDIR:=$(KERNEL_SRC) +endif +PWD:=$(shell pwd) +default: + $(MAKE) -C $(KERNELDIR) M=$(PWD) modules +clean: + rm -rf *.o *.mod.o *.mod.o *.ko .*cmd .tmp_versions Module.markers Module.symvers modules.order +endif diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_fan.c b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_fan.c new file mode 100755 index 000000000000..8764ec8a3176 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_fan.c @@ -0,0 +1,815 @@ +/* + * A hwmon driver for the Accton as7312 54x fan + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "as7312_54x_fan" + +#define NUM_THERMAL_SENSORS (3) /* Get sum of this number of sensors.*/ +#define THERMAL_SENSORS_DRIVER "lm75" +#define THERMAL_SENSORS_ADDRS {0x48, 0x49, 0x4a} + +#define IN +#define OUT + +static struct as7312_54x_fan_data *as7312_54x_fan_update_device(struct device *dev); +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t get_enable(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_enable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t get_sys_temp(struct device *dev, struct device_attribute *da, char *buf); +extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +/* fan related data, the index should match sysfs_fan_attributes + */ +static const u8 fan_reg[] = { + 0x0F, /* fan 1-6 present status */ + 0x10, /* fan 1-6 direction(0:F2B 1:B2F) */ + 0x11, /* fan PWM(for all fan) */ + 0x12, /* front fan 1 speed(rpm) */ + 0x13, /* front fan 2 speed(rpm) */ + 0x14, /* front fan 3 speed(rpm) */ + 0x15, /* front fan 4 speed(rpm) */ + 0x16, /* front fan 5 speed(rpm) */ + 0x17, /* front fan 6 speed(rpm) */ + 0x22, /* rear fan 1 speed(rpm) */ + 0x23, /* rear fan 2 speed(rpm) */ + 0x24, /* rear fan 3 speed(rpm) */ + 0x25, /* rear fan 4 speed(rpm) */ + 0x26, /* rear fan 5 speed(rpm) */ + 0x27, /* rear fan 6 speed(rpm) */ +}; + +/* Each client has this additional data */ +struct as7312_54x_fan_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[ARRAY_SIZE(fan_reg)]; /* Register value */ + u8 enable; + int system_temp; /*In unit of mini-Celsius*/ + int sensors_found; +}; + +enum fan_id { + FAN1_ID, + FAN2_ID, + FAN3_ID, + FAN4_ID, + FAN5_ID, + FAN6_ID +}; + +enum sysfs_fan_attributes { + FAN_PRESENT_REG, + FAN_DIRECTION_REG, + FAN_DUTY_CYCLE_PERCENTAGE, /* Only one CPLD register to control duty cycle for all fans */ + FAN1_FRONT_SPEED_RPM, + FAN2_FRONT_SPEED_RPM, + FAN3_FRONT_SPEED_RPM, + FAN4_FRONT_SPEED_RPM, + FAN5_FRONT_SPEED_RPM, + FAN6_FRONT_SPEED_RPM, + FAN1_REAR_SPEED_RPM, + FAN2_REAR_SPEED_RPM, + FAN3_REAR_SPEED_RPM, + FAN4_REAR_SPEED_RPM, + FAN5_REAR_SPEED_RPM, + FAN6_REAR_SPEED_RPM, + FAN1_DIRECTION, + FAN2_DIRECTION, + FAN3_DIRECTION, + FAN4_DIRECTION, + FAN5_DIRECTION, + FAN6_DIRECTION, + FAN1_PRESENT, + FAN2_PRESENT, + FAN3_PRESENT, + FAN4_PRESENT, + FAN5_PRESENT, + FAN6_PRESENT, + FAN1_FAULT, + FAN2_FAULT, + FAN3_FAULT, + FAN4_FAULT, + FAN5_FAULT, + FAN6_FAULT +}; + +/* Define attributes + */ +#define DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(index, index2) \ + static SENSOR_DEVICE_ATTR(fan##index##_fault, S_IRUGO, fan_show_value, NULL, FAN##index##_FAULT);\ + static SENSOR_DEVICE_ATTR(fan##index2##_fault, S_IRUGO, fan_show_value, NULL, FAN##index##_FAULT) +#define DECLARE_FAN_FAULT_ATTR(index, index2) &sensor_dev_attr_fan##index##_fault.dev_attr.attr, \ + &sensor_dev_attr_fan##index2##_fault.dev_attr.attr + +#define DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_direction, S_IRUGO, fan_show_value, NULL, FAN##index##_DIRECTION) +#define DECLARE_FAN_DIRECTION_ATTR(index) &sensor_dev_attr_fan##index##_direction.dev_attr.attr + +#define DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan_duty_cycle_percentage, S_IWUSR | S_IRUGO, fan_show_value, set_duty_cycle, FAN_DUTY_CYCLE_PERCENTAGE);\ + static SENSOR_DEVICE_ATTR(pwm##index, S_IWUSR | S_IRUGO, fan_show_value, set_duty_cycle, FAN_DUTY_CYCLE_PERCENTAGE);\ + static SENSOR_DEVICE_ATTR(pwm##index##_enable, S_IWUSR | S_IRUGO, get_enable, set_enable, FAN_DUTY_CYCLE_PERCENTAGE) + +#define DECLARE_FAN_DUTY_CYCLE_ATTR(index) &sensor_dev_attr_fan_duty_cycle_percentage.dev_attr.attr, \ + &sensor_dev_attr_pwm##index.dev_attr.attr, \ + &sensor_dev_attr_pwm##index##_enable.dev_attr.attr + +#define DECLARE_FAN_SYSTEM_TEMP_SENSOR_DEV_ATTR() \ + static SENSOR_DEVICE_ATTR(sys_temp, S_IRUGO, get_sys_temp, NULL, FAN_DUTY_CYCLE_PERCENTAGE) + +#define DECLARE_FAN_SYSTEM_TEMP_ATTR() &sensor_dev_attr_sys_temp.dev_attr.attr + + +#define DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_present, S_IRUGO, fan_show_value, NULL, FAN##index##_PRESENT) +#define DECLARE_FAN_PRESENT_ATTR(index) &sensor_dev_attr_fan##index##_present.dev_attr.attr + +#define DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(index, index2) \ + static SENSOR_DEVICE_ATTR(fan##index##_front_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_FRONT_SPEED_RPM);\ + static SENSOR_DEVICE_ATTR(fan##index##_rear_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_REAR_SPEED_RPM);\ + static SENSOR_DEVICE_ATTR(fan##index##_input, S_IRUGO, fan_show_value, NULL, FAN##index##_FRONT_SPEED_RPM);\ + static SENSOR_DEVICE_ATTR(fan##index2##_input, S_IRUGO, fan_show_value, NULL, FAN##index##_REAR_SPEED_RPM) +#define DECLARE_FAN_SPEED_RPM_ATTR(index, index2) &sensor_dev_attr_fan##index##_front_speed_rpm.dev_attr.attr, \ + &sensor_dev_attr_fan##index##_rear_speed_rpm.dev_attr.attr, \ + &sensor_dev_attr_fan##index##_input.dev_attr.attr, \ + &sensor_dev_attr_fan##index2##_input.dev_attr.attr + +/* 6 fan fault attributes in this platform */ +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(1,11); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(2,12); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(3,13); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(4,14); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(5,15); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(6,16); +/* 6 fan speed(rpm) attributes in this platform */ +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(1,11); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(2,12); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(3,13); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(4,14); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(5,15); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(6,16); +/* 6 fan present attributes in this platform */ +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(1); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(2); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(3); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(4); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(5); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(6); +/* 6 fan direction attribute in this platform */ +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(1); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(2); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(3); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(4); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(5); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(6); +/* 1 fan duty cycle attribute in this platform */ +DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(1); +/* System temperature for fancontrol */ +DECLARE_FAN_SYSTEM_TEMP_SENSOR_DEV_ATTR(); + +static struct attribute *as7312_54x_fan_attributes[] = { + /* fan related attributes */ + DECLARE_FAN_FAULT_ATTR(1,11), + DECLARE_FAN_FAULT_ATTR(2,12), + DECLARE_FAN_FAULT_ATTR(3,13), + DECLARE_FAN_FAULT_ATTR(4,14), + DECLARE_FAN_FAULT_ATTR(5,15), + DECLARE_FAN_FAULT_ATTR(6,16), + DECLARE_FAN_SPEED_RPM_ATTR(1,11), + DECLARE_FAN_SPEED_RPM_ATTR(2,12), + DECLARE_FAN_SPEED_RPM_ATTR(3,13), + DECLARE_FAN_SPEED_RPM_ATTR(4,14), + DECLARE_FAN_SPEED_RPM_ATTR(5,15), + DECLARE_FAN_SPEED_RPM_ATTR(6,16), + DECLARE_FAN_PRESENT_ATTR(1), + DECLARE_FAN_PRESENT_ATTR(2), + DECLARE_FAN_PRESENT_ATTR(3), + DECLARE_FAN_PRESENT_ATTR(4), + DECLARE_FAN_PRESENT_ATTR(5), + DECLARE_FAN_PRESENT_ATTR(6), + DECLARE_FAN_DIRECTION_ATTR(1), + DECLARE_FAN_DIRECTION_ATTR(2), + DECLARE_FAN_DIRECTION_ATTR(3), + DECLARE_FAN_DIRECTION_ATTR(4), + DECLARE_FAN_DIRECTION_ATTR(5), + DECLARE_FAN_DIRECTION_ATTR(6), + DECLARE_FAN_DUTY_CYCLE_ATTR(1), + DECLARE_FAN_SYSTEM_TEMP_ATTR(), + NULL +}; + +#define FAN_DUTY_CYCLE_REG_MASK 0xF +#define FAN_MAX_DUTY_CYCLE 100 +#define FAN_REG_VAL_TO_SPEED_RPM_STEP 100 + +static int as7312_54x_fan_read_value(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int as7312_54x_fan_write_value(struct i2c_client *client, u8 reg, u8 value) +{ + return i2c_smbus_write_byte_data(client, reg, value); +} + +/* fan utility functions + */ +static u32 reg_val_to_duty_cycle(u8 reg_val) +{ + reg_val &= FAN_DUTY_CYCLE_REG_MASK; + return ((u32)(reg_val+1) * 625 + 75)/ 100; +} + +static u8 duty_cycle_to_reg_val(u8 duty_cycle) +{ + return ((u32)duty_cycle * 100 / 625) - 1; +} + +static u32 reg_val_to_speed_rpm(u8 reg_val) +{ + return (u32)reg_val * FAN_REG_VAL_TO_SPEED_RPM_STEP; +} + +static u8 reg_val_to_direction(u8 reg_val, enum fan_id id) +{ + u8 mask = (1 << id); + + reg_val &= mask; + + return reg_val ? 1 : 0; +} +static u8 reg_val_to_is_present(u8 reg_val, enum fan_id id) +{ + u8 mask = (1 << id); + + reg_val &= mask; + + return reg_val ? 0 : 1; +} + +static u8 is_fan_fault(struct as7312_54x_fan_data *data, enum fan_id id) +{ + u8 ret = 1; + int front_fan_index = FAN1_FRONT_SPEED_RPM + id; + int rear_fan_index = FAN1_REAR_SPEED_RPM + id; + + /* Check if the speed of front or rear fan is ZERO, + */ + if (reg_val_to_speed_rpm(data->reg_val[front_fan_index]) && + reg_val_to_speed_rpm(data->reg_val[rear_fan_index])) { + ret = 0; + } + + return ret; +} + +static ssize_t set_enable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct as7312_54x_fan_data *data = as7312_54x_fan_update_device(dev); + int error, value; + + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (value < 0 || value > 1) + return -EINVAL; + + data->enable = value; + if (value == 0) + { + return set_duty_cycle(dev, da, buf, FAN_MAX_DUTY_CYCLE); + } + return count; +} + + +static ssize_t get_enable(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct as7312_54x_fan_data *data = as7312_54x_fan_update_device(dev); + + return sprintf(buf, "%u\n", data->enable); +} +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int error, value; + struct i2c_client *client = to_i2c_client(dev); + + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (value < 0) + return -EINVAL; + + value = (value > FAN_MAX_DUTY_CYCLE)? FAN_MAX_DUTY_CYCLE : value; + + as7312_54x_fan_write_value(client, 0x33, 0); /* Disable fan speed watch dog */ + as7312_54x_fan_write_value(client, fan_reg[FAN_DUTY_CYCLE_PERCENTAGE], duty_cycle_to_reg_val(value)); + return count; +} + +/* Due to this struct is declared at lm75.c, it cannot be include + * under Sonic environment. I duplicate it from lm75.c. + */ +struct lm75_data { + struct i2c_client *client; + struct device *hwmon_dev; + struct thermal_zone_device *tz; + struct mutex update_lock; + u8 orig_conf; + u8 resolution; /* In bits, between 9 and 12 */ + u8 resolution_limits; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + unsigned long sample_time; /* In jiffies */ + s16 temp[3]; /* Register values, + 0 = input + 1 = max + 2 = hyst */ +}; + +/*Copied from lm75.c*/ +static inline long lm75_reg_to_mc(s16 temp, u8 resolution) +{ + return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8); +} + +/*Get hwmon_dev from i2c_client, set hwmon_dev = NULL is failed.*/ +static struct device * get_hwmon_dev( + struct i2c_client *client) +{ + struct lm75_data *data = NULL; + + data = i2c_get_clientdata(client); + if(data) + { + if( data->valid == 1 && data->hwmon_dev) + { + return data->hwmon_dev; + } + + } + return NULL; +} + +/* To find hwmon index by opening hwmon under that i2c address. + */ +static int find_hwmon_index_by_FileOpen( + int bus_nr, + unsigned short addr, + OUT int *index) +{ +#define MAX_HWMON_DEVICE (10) /* Find hwmon device in 0~10*/ + struct file *sfd; + char client_name[96]; + int i=0; + + do { + snprintf(client_name, sizeof(client_name), + "/sys/bus/i2c/devices/%d-%04x/hwmon/hwmon%d/temp1_input", + bus_nr, addr, i); + + sfd = filp_open(client_name, O_RDONLY, 0); + i++; + } while( IS_ERR(sfd) && i < MAX_HWMON_DEVICE); + + if (IS_ERR(sfd)) { + pr_err("Failed to open file(%s)#%d\r\n", client_name, __LINE__); + return -ENOENT; + } + filp_close(sfd, 0); + *index = i - 1; + return 0; + +#undef MAX_HWMON_DEVICE +} + +static int get_temp_file_path( + int bus_nr, unsigned short addr, + struct device *hwmon_dev + ,char *path, int max_len) +{ + + if(hwmon_dev && strlen(dev_name(hwmon_dev))) + { + snprintf(path, max_len, + "/sys/bus/i2c/devices/%d-%04x/hwmon/%s/temp1_input", + bus_nr, addr, dev_name(hwmon_dev)); + } + else + { + int i=0; + if(find_hwmon_index_by_FileOpen( bus_nr, addr, &i)) + { + return -EIO; + } + snprintf(path, max_len, + "/sys/bus/i2c/devices/%d-%04x/hwmon/hwmon%d/temp1_input", + bus_nr, addr, i); + } + return 0; +} + +/*File read the dev file at user space.*/ +static int read_devfile_temp1_input( + struct device *dev, + int bus_nr, + unsigned short addr, + struct device *hwmon_dev, + int *miniCelsius) +{ + struct file *sfd; + char buffer[96]; + char devfile[96]; + int rc, status; + int rdlen, value; + mm_segment_t old_fs; + + rc = 0; + get_temp_file_path(bus_nr, addr, hwmon_dev, devfile, sizeof(devfile)); + sfd = filp_open(devfile, O_RDONLY, 0); + if (IS_ERR(sfd)) { + pr_err("Failed to open file(%s)#%d\r\n", devfile, __LINE__); + return -ENOENT; + } + dev_dbg(dev, "Found device:%s\n",devfile); + + if(!(sfd->f_op) || !(sfd->f_op->read) ) { + pr_err("file %s cann't readable ?\n",devfile); + return -ENOENT; + } + + old_fs = get_fs(); + set_fs(KERNEL_DS); + rdlen = sfd->f_op->read(sfd, buffer, sizeof(buffer), &sfd->f_pos); + if (rdlen == 0) { + pr_err( "File(%s) empty!\n", devfile); + rc = -EIO; + goto exit; + } + status = sscanf(buffer, "%d", &value); + if (status != 1) { + rc = -EIO; + goto exit; + } + *miniCelsius = value; + dev_dbg(dev,"found sensors: %d @i2c %d-%04x\n", value, bus_nr, addr); + +exit: + set_fs(old_fs); + filp_close(sfd, 0); + return rc; +} + +static u8 is_lm75_data_due(struct i2c_client *client) +{ + struct lm75_data *data = NULL; + + data = i2c_get_clientdata(client); + if (time_after(jiffies, data->last_updated + data->sample_time)) + { + return 1; + } + return 0; +} +static int get_lm75_temp(struct i2c_client *client, int *miniCelsius) +{ + struct lm75_data *data = NULL; + + data = i2c_get_clientdata(client); + *miniCelsius = lm75_reg_to_mc(data->temp[0], data->resolution); + + return 0; +} + +static bool lm75_addr_mached(unsigned short addr) +{ + int i; + unsigned short addrs[] = THERMAL_SENSORS_ADDRS; + + for (i = 0; i < ARRAY_SIZE(addrs); i++) + { + if( addr == addrs[i]) + return 1; + } + return 0; +} + +static int _find_lm75_device(struct device *dev, void *data) +{ + struct device_driver *driver; + struct as7312_54x_fan_data *prv = data; + char *driver_name = THERMAL_SENSORS_DRIVER; + + driver = dev->driver; + if (driver && driver->name && + strcmp(driver->name, driver_name) == 0) + { + struct i2c_client *client; + client = to_i2c_client(dev); + if (client) + { + /*cannot use "struct i2c_adapter *adap = to_i2c_adapter(dev);"*/ + struct i2c_adapter *adap = client->adapter; + int miniCelsius = 0; + + if (! lm75_addr_mached(client->addr)) + { + return 0; + } + + if (!adap) { + return -ENXIO; + } + + /* If the data is not updated, read them from devfile + to drive them updateing data from chip.*/ + if (is_lm75_data_due(client)) + { + struct device *hwmon_dev; + + hwmon_dev = get_hwmon_dev(client); + if(0 == read_devfile_temp1_input(dev, adap->nr, + client->addr, hwmon_dev, &miniCelsius)) + { + prv->system_temp += miniCelsius; + prv->sensors_found++; + } + + } + else + { + get_lm75_temp(client, &miniCelsius); + prv->system_temp += miniCelsius; + prv->sensors_found++; + + } + } + } + return 0; +} + +/*Find all lm75 devices and return sum of temperatures.*/ +static ssize_t get_sys_temp(struct device *dev, struct device_attribute *da, + char *buf) +{ + ssize_t ret = 0; + struct as7312_54x_fan_data *data = as7312_54x_fan_update_device(dev); + + data->system_temp=0; + data->sensors_found=0; + i2c_for_each_dev(data, _find_lm75_device); + if (NUM_THERMAL_SENSORS != data->sensors_found) + { + dev_dbg(dev,"only %d of %d temps are found\n", + data->sensors_found, NUM_THERMAL_SENSORS); + data->system_temp = INT_MAX; + } + ret = sprintf(buf, "%d\n",data->system_temp); + return ret; +} + +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct as7312_54x_fan_data *data = as7312_54x_fan_update_device(dev); + ssize_t ret = 0; + + if (data->valid) { + switch (attr->index) { + case FAN_DUTY_CYCLE_PERCENTAGE: + { + u32 duty_cycle = reg_val_to_duty_cycle(data->reg_val[FAN_DUTY_CYCLE_PERCENTAGE]); + ret = sprintf(buf, "%u\n", duty_cycle); + break; + } + case FAN1_FRONT_SPEED_RPM: + case FAN2_FRONT_SPEED_RPM: + case FAN3_FRONT_SPEED_RPM: + case FAN4_FRONT_SPEED_RPM: + case FAN5_FRONT_SPEED_RPM: + case FAN6_FRONT_SPEED_RPM: + case FAN1_REAR_SPEED_RPM: + case FAN2_REAR_SPEED_RPM: + case FAN3_REAR_SPEED_RPM: + case FAN4_REAR_SPEED_RPM: + case FAN5_REAR_SPEED_RPM: + case FAN6_REAR_SPEED_RPM: + ret = sprintf(buf, "%u\n", reg_val_to_speed_rpm(data->reg_val[attr->index])); + break; + case FAN1_PRESENT: + case FAN2_PRESENT: + case FAN3_PRESENT: + case FAN4_PRESENT: + case FAN5_PRESENT: + case FAN6_PRESENT: + ret = sprintf(buf, "%d\n", + reg_val_to_is_present(data->reg_val[FAN_PRESENT_REG], + attr->index - FAN1_PRESENT)); + break; + case FAN1_FAULT: + case FAN2_FAULT: + case FAN3_FAULT: + case FAN4_FAULT: + case FAN5_FAULT: + case FAN6_FAULT: + ret = sprintf(buf, "%d\n", is_fan_fault(data, attr->index - FAN1_FAULT)); + break; + case FAN1_DIRECTION: + case FAN2_DIRECTION: + case FAN3_DIRECTION: + case FAN4_DIRECTION: + case FAN5_DIRECTION: + case FAN6_DIRECTION: + ret = sprintf(buf, "%d\n", + reg_val_to_direction(data->reg_val[FAN_DIRECTION_REG], + attr->index - FAN1_DIRECTION)); + break; + default: + break; + } + } + + return ret; +} + +static const struct attribute_group as7312_54x_fan_group = { + .attrs = as7312_54x_fan_attributes, +}; + +static struct as7312_54x_fan_data *as7312_54x_fan_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as7312_54x_fan_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || + !data->valid) { + int i; + + dev_dbg(&client->dev, "Starting as7312_54x_fan update\n"); + data->valid = 0; + + /* Update fan data + */ + for (i = 0; i < ARRAY_SIZE(data->reg_val); i++) { + int status = as7312_54x_fan_read_value(client, fan_reg[i]); + + if (status < 0) { + data->valid = 0; + mutex_unlock(&data->update_lock); + dev_dbg(&client->dev, "reg %d, err %d\n", fan_reg[i], status); + return data; + } + else { + data->reg_val[i] = status; + } + } + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +static int as7312_54x_fan_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct as7312_54x_fan_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct as7312_54x_fan_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + data->enable = 0; + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as7312_54x_fan_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: fan '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as7312_54x_fan_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as7312_54x_fan_remove(struct i2c_client *client) +{ + struct as7312_54x_fan_data *data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as7312_54x_fan_group); + + return 0; +} + +/* Addresses to scan */ +static const unsigned short normal_i2c[] = { 0x66, I2C_CLIENT_END }; + +static const struct i2c_device_id as7312_54x_fan_id[] = { + { "as7312_54x_fan", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, as7312_54x_fan_id); + +static struct i2c_driver as7312_54x_fan_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = DRVNAME, + }, + .probe = as7312_54x_fan_probe, + .remove = as7312_54x_fan_remove, + .id_table = as7312_54x_fan_id, + .address_list = normal_i2c, +}; + +static int __init as7312_54x_fan_init(void) +{ + return i2c_add_driver(&as7312_54x_fan_driver); +} + +static void __exit as7312_54x_fan_exit(void) +{ + i2c_del_driver(&as7312_54x_fan_driver); +} + +module_init(as7312_54x_fan_init); +module_exit(as7312_54x_fan_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("as7312_54x_fan driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_leds.c b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_leds.c new file mode 100644 index 000000000000..1d54517c6243 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_leds.c @@ -0,0 +1,438 @@ +/* + * A LED driver for the accton_as7312_54x_led + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*#define DEBUG*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +extern int as7312_54x_cpld_read (unsigned short cpld_addr, u8 reg); +extern int as7312_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +extern void led_classdev_unregister(struct led_classdev *led_cdev); +extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); +extern void led_classdev_resume(struct led_classdev *led_cdev); +extern void led_classdev_suspend(struct led_classdev *led_cdev); + +#define DRVNAME "accton_as7312_54x_led" + +struct accton_as7312_54x_led_data { + struct platform_device *pdev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[1]; /* only 1 register*/ +}; + +static struct accton_as7312_54x_led_data *ledctl = NULL; + +/* LED related data + */ + +#define LED_CNTRLER_I2C_ADDRESS (0x60) + +#define LED_TYPE_DIAG_REG_MASK (0x3) +#define LED_MODE_DIAG_GREEN_VALUE (0x02) +#define LED_MODE_DIAG_RED_VALUE (0x01) +#define LED_MODE_DIAG_AMBER_VALUE (0x00) /*It's yellow actually. Green+Red=Yellow*/ +#define LED_MODE_DIAG_OFF_VALUE (0x03) + + +#define LED_TYPE_LOC_REG_MASK (0x80) +#define LED_MODE_LOC_ON_VALUE (0) +#define LED_MODE_LOC_OFF_VALUE (0x80) + +enum led_type { + LED_TYPE_DIAG, + LED_TYPE_LOC, + LED_TYPE_FAN, + LED_TYPE_PSU1, + LED_TYPE_PSU2 +}; + +struct led_reg { + u32 types; + u8 reg_addr; +}; + +static const struct led_reg led_reg_map[] = { + {(1<update_lock); + + if (time_after(jiffies, ledctl->last_updated + HZ + HZ / 2) + || !ledctl->valid) { + int i; + + dev_dbg(&ledctl->pdev->dev, "Starting accton_as7312_54x_led update\n"); + + /* Update LED data + */ + for (i = 0; i < ARRAY_SIZE(ledctl->reg_val); i++) { + int status = accton_as7312_54x_led_read_value(led_reg_map[i].reg_addr); + + if (status < 0) { + ledctl->valid = 0; + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", led_reg_map[i].reg_addr, status); + goto exit; + } + else + { + ledctl->reg_val[i] = status; + } + } + + ledctl->last_updated = jiffies; + ledctl->valid = 1; + } + +exit: + mutex_unlock(&ledctl->update_lock); +} + +static void accton_as7312_54x_led_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode, + enum led_type type) +{ + int reg_val; + u8 reg ; + mutex_lock(&ledctl->update_lock); + + if( !accton_getLedReg(type, ®)) + { + dev_dbg(&ledctl->pdev->dev, "Not match item for %d.\n", type); + } + + reg_val = accton_as7312_54x_led_read_value(reg); + + if (reg_val < 0) { + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", reg, reg_val); + goto exit; + } + reg_val = led_light_mode_to_reg_val(type, led_light_mode, reg_val); + accton_as7312_54x_led_write_value(reg, reg_val); + + /* to prevent the slow-update issue */ + ledctl->valid = 0; + +exit: + mutex_unlock(&ledctl->update_lock); +} + + +static void accton_as7312_54x_led_diag_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + accton_as7312_54x_led_set(led_cdev, led_light_mode, LED_TYPE_DIAG); +} + +static enum led_brightness accton_as7312_54x_led_diag_get(struct led_classdev *cdev) +{ + accton_as7312_54x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_DIAG, ledctl->reg_val[0]); +} + +static void accton_as7312_54x_led_loc_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + accton_as7312_54x_led_set(led_cdev, led_light_mode, LED_TYPE_LOC); +} + +static enum led_brightness accton_as7312_54x_led_loc_get(struct led_classdev *cdev) +{ + accton_as7312_54x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_LOC, ledctl->reg_val[0]); +} + +static void accton_as7312_54x_led_auto_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ +} + +static enum led_brightness accton_as7312_54x_led_auto_get(struct led_classdev *cdev) +{ + return LED_MODE_AUTO; +} + +static struct led_classdev accton_as7312_54x_leds[] = { + [LED_TYPE_DIAG] = { + .name = "accton_as7312_54x_led::diag", + .default_trigger = "unused", + .brightness_set = accton_as7312_54x_led_diag_set, + .brightness_get = accton_as7312_54x_led_diag_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_RED, + }, + [LED_TYPE_LOC] = { + .name = "accton_as7312_54x_led::loc", + .default_trigger = "unused", + .brightness_set = accton_as7312_54x_led_loc_set, + .brightness_get = accton_as7312_54x_led_loc_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_BLUE, + }, + [LED_TYPE_FAN] = { + .name = "accton_as7312_54x_led::fan", + .default_trigger = "unused", + .brightness_set = accton_as7312_54x_led_auto_set, + .brightness_get = accton_as7312_54x_led_auto_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_PSU1] = { + .name = "accton_as7312_54x_led::psu1", + .default_trigger = "unused", + .brightness_set = accton_as7312_54x_led_auto_set, + .brightness_get = accton_as7312_54x_led_auto_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_PSU2] = { + .name = "accton_as7312_54x_led::psu2", + .default_trigger = "unused", + .brightness_set = accton_as7312_54x_led_auto_set, + .brightness_get = accton_as7312_54x_led_auto_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, +}; + +static int accton_as7312_54x_led_suspend(struct platform_device *dev, + pm_message_t state) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(accton_as7312_54x_leds); i++) { + led_classdev_suspend(&accton_as7312_54x_leds[i]); + } + + return 0; +} + +static int accton_as7312_54x_led_resume(struct platform_device *dev) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(accton_as7312_54x_leds); i++) { + led_classdev_resume(&accton_as7312_54x_leds[i]); + } + + return 0; +} + +static int accton_as7312_54x_led_probe(struct platform_device *pdev) +{ + int ret, i; + + for (i = 0; i < ARRAY_SIZE(accton_as7312_54x_leds); i++) { + ret = led_classdev_register(&pdev->dev, &accton_as7312_54x_leds[i]); + + if (ret < 0) + break; + } + + /* Check if all LEDs were successfully registered */ + if (i != ARRAY_SIZE(accton_as7312_54x_leds)) { + int j; + + /* only unregister the LEDs that were successfully registered */ + for (j = 0; j < i; j++) { + led_classdev_unregister(&accton_as7312_54x_leds[i]); + } + } + + return ret; +} + +static int accton_as7312_54x_led_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(accton_as7312_54x_leds); i++) { + led_classdev_unregister(&accton_as7312_54x_leds[i]); + } + + return 0; +} + +static struct platform_driver accton_as7312_54x_led_driver = { + .probe = accton_as7312_54x_led_probe, + .remove = accton_as7312_54x_led_remove, + .suspend = accton_as7312_54x_led_suspend, + .resume = accton_as7312_54x_led_resume, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +static int __init accton_as7312_54x_led_init(void) +{ + int ret; + + ret = platform_driver_register(&accton_as7312_54x_led_driver); + if (ret < 0) { + goto exit; + } + + ledctl = kzalloc(sizeof(struct accton_as7312_54x_led_data), GFP_KERNEL); + if (!ledctl) { + ret = -ENOMEM; + platform_driver_unregister(&accton_as7312_54x_led_driver); + goto exit; + } + + mutex_init(&ledctl->update_lock); + + ledctl->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(ledctl->pdev)) { + ret = PTR_ERR(ledctl->pdev); + platform_driver_unregister(&accton_as7312_54x_led_driver); + kfree(ledctl); + goto exit; + } + +exit: + return ret; +} + +static void __exit accton_as7312_54x_led_exit(void) +{ + platform_device_unregister(ledctl->pdev); + platform_driver_unregister(&accton_as7312_54x_led_driver); + kfree(ledctl); +} + +module_init(accton_as7312_54x_led_init); +module_exit(accton_as7312_54x_led_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton_as7312_54x_led driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_psu.c b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_psu.c new file mode 100644 index 000000000000..4646224ef903 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_psu.c @@ -0,0 +1,277 @@ +/* + * An hwmon driver for accton as7312_54x Power Module + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_model_name(struct device *dev, struct device_attribute *da, char *buf); +static int as7312_54x_psu_read_block(struct i2c_client *client, u8 command, u8 *data,int data_len); +extern int as7312_54x_cpld_read(unsigned short cpld_addr, u8 reg); + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { 0x50, 0x53, I2C_CLIENT_END }; + +/* Each client has this additional data + */ +struct as7312_54x_psu_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 index; /* PSU index */ + u8 status; /* Status(present/power_good) register read from CPLD */ + char model_name[9]; /* Model name, read from eeprom */ +}; + +static struct as7312_54x_psu_data *as7312_54x_psu_update_device(struct device *dev); + +enum as7312_54x_psu_sysfs_attributes { + PSU_PRESENT, + PSU_MODEL_NAME, + PSU_POWER_GOOD +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, show_status, NULL, PSU_PRESENT); +static SENSOR_DEVICE_ATTR(psu_model_name, S_IRUGO, show_model_name,NULL, PSU_MODEL_NAME); +static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_status, NULL, PSU_POWER_GOOD); + +static struct attribute *as7312_54x_psu_attributes[] = { + &sensor_dev_attr_psu_present.dev_attr.attr, + &sensor_dev_attr_psu_model_name.dev_attr.attr, + &sensor_dev_attr_psu_power_good.dev_attr.attr, + NULL +}; + +static ssize_t show_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct as7312_54x_psu_data *data = as7312_54x_psu_update_device(dev); + u8 status = 0; + + if (attr->index == PSU_PRESENT) { + status = !(data->status >> (1-data->index) & 0x1); + } + else { /* PSU_POWER_GOOD */ + status = (data->status >> (3-data->index) & 0x1); + } + + return sprintf(buf, "%d\n", status); +} + +static ssize_t show_model_name(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct as7312_54x_psu_data *data = as7312_54x_psu_update_device(dev); + + return sprintf(buf, "%s\n", data->model_name); +} + +static const struct attribute_group as7312_54x_psu_group = { + .attrs = as7312_54x_psu_attributes, +}; + +static int as7312_54x_psu_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct as7312_54x_psu_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct as7312_54x_psu_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + data->index = dev_id->driver_data; + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as7312_54x_psu_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as7312_54x_psu_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as7312_54x_psu_remove(struct i2c_client *client) +{ + struct as7312_54x_psu_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as7312_54x_psu_group); + kfree(data); + + return 0; +} + +enum psu_index +{ + as7312_54x_psu1, + as7312_54x_psu2 +}; + +static const struct i2c_device_id as7312_54x_psu_id[] = { + { "as7312_54x_psu1", as7312_54x_psu1 }, + { "as7312_54x_psu2", as7312_54x_psu2 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, as7312_54x_psu_id); + +static struct i2c_driver as7312_54x_psu_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "as7312_54x_psu", + }, + .probe = as7312_54x_psu_probe, + .remove = as7312_54x_psu_remove, + .id_table = as7312_54x_psu_id, + .address_list = normal_i2c, +}; + +static int as7312_54x_psu_read_block(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ + int result = 0; + int retry_count = 5; + + while (retry_count) { + retry_count--; + + result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + + if (unlikely(result < 0)) { + msleep(10); + continue; + } + + if (unlikely(result != data_len)) { + result = -EIO; + msleep(10); + continue; + } + + result = 0; + break; + } + + return result; +} + +static struct as7312_54x_psu_data *as7312_54x_psu_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as7312_54x_psu_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int status; + int power_good = 0; + + dev_dbg(&client->dev, "Starting as7312_54x update\n"); + + /* Read psu status */ + status = as7312_54x_cpld_read(0x60, 0x2); + + if (status < 0) { + dev_dbg(&client->dev, "cpld reg 0x60 err %d\n", status); + } + else { + data->status = status; + } + + /* Read model name */ + memset(data->model_name, 0, sizeof(data->model_name)); + power_good = (data->status >> (3-data->index) & 0x1); + + if (power_good) { + status = as7312_54x_psu_read_block(client, 0x20, data->model_name, + ARRAY_SIZE(data->model_name)-1); + + if (status < 0) { + data->model_name[0] = '\0'; + dev_dbg(&client->dev, "unable to read model name from (0x%x)\n", client->addr); + } + else { + data->model_name[ARRAY_SIZE(data->model_name)-1] = '\0'; + } + } + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +module_i2c_driver(as7312_54x_psu_driver); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("as7312_54x_psu driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_sfp.c b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_sfp.c new file mode 100644 index 000000000000..921d9f892cac --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_as7312_54x_sfp.c @@ -0,0 +1,1972 @@ +/* + * SFP driver for accton as7312_54x sfp + * + * Copyright (C) Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "as7312_54x_sfp" /* Platform dependent */ + +#define DEBUG_MODE 0 + +#if (DEBUG_MODE == 1) +#define DEBUG_PRINT(fmt, args...) \ + printk (KERN_INFO "%s:%s[%d]: " fmt "\r\n", __FILE__, __FUNCTION__, __LINE__, ##args) +#else +#define DEBUG_PRINT(fmt, args...) +#endif + +#define NUM_OF_PORT 54 +#define SFP_PORT_MAX 48 +#define EEPROM_NAME "sfp_eeprom" +#define EEPROM_SIZE 256 /* 256 byte eeprom */ +#define BIT_INDEX(i) (1ULL << (i)) +#define USE_I2C_BLOCK_READ 1 /* Platform dependent */ +#define I2C_RW_RETRY_COUNT 10 +#define I2C_RW_RETRY_INTERVAL 60 /* ms */ + +#define SFP_EEPROM_A0_I2C_ADDR (0xA0 >> 1) + +#define SFF8024_PHYSICAL_DEVICE_ID_ADDR 0x0 +#define SFF8024_DEVICE_ID_SFP 0x3 +#define SFF8024_DEVICE_ID_QSFP 0xC +#define SFF8024_DEVICE_ID_QSFP_PLUS 0xD +#define SFF8024_DEVICE_ID_QSFP28 0x11 + +#define SFF8472_DIAG_MON_TYPE_ADDR 92 +#define SFF8472_DIAG_MON_TYPE_DDM_MASK 0x40 +#define SFF8436_RX_LOS_ADDR 3 +#define SFF8436_TX_FAULT_ADDR 4 +#define SFF8436_TX_DISABLE_ADDR 86 + +#define MULTIPAGE_SUPPORT 1 + +#if (MULTIPAGE_SUPPORT == 1) +/* fundamental unit of addressing for SFF_8472/SFF_8436 */ +#define SFF_8436_PAGE_SIZE 128 +/* + * The current 8436 (QSFP) spec provides for only 4 supported + * pages (pages 0-3). + * This driver is prepared to support more, but needs a register in the + * EEPROM to indicate how many pages are supported before it is safe + * to implement more pages in the driver. + */ +#define SFF_8436_SPECED_PAGES 4 +#define SFF_8436_EEPROM_SIZE ((1 + SFF_8436_SPECED_PAGES) * SFF_8436_PAGE_SIZE) +#define SFF_8436_EEPROM_UNPAGED_SIZE (2 * SFF_8436_PAGE_SIZE) +/* + * The current 8472 (SFP) spec provides for only 3 supported + * pages (pages 0-2). + * This driver is prepared to support more, but needs a register in the + * EEPROM to indicate how many pages are supported before it is safe + * to implement more pages in the driver. + */ +#define SFF_8472_SPECED_PAGES 3 +#define SFF_8472_EEPROM_SIZE ((3 + SFF_8472_SPECED_PAGES) * SFF_8436_PAGE_SIZE) +#define SFF_8472_EEPROM_UNPAGED_SIZE (4 * SFF_8436_PAGE_SIZE) + +/* a few constants to find our way around the EEPROM */ +#define SFF_8436_PAGE_SELECT_REG 0x7F +#define SFF_8436_PAGEABLE_REG 0x02 +#define SFF_8436_NOT_PAGEABLE (1<<2) +#define SFF_8472_PAGEABLE_REG 0x40 +#define SFF_8472_PAGEABLE (1<<4) + +/* + * This parameter is to help this driver avoid blocking other drivers out + * of I2C for potentially troublesome amounts of time. With a 100 kHz I2C + * clock, one 256 byte read takes about 1/43 second which is excessive; + * but the 1/170 second it takes at 400 kHz may be quite reasonable; and + * at 1 MHz (Fm+) a 1/430 second delay could easily be invisible. + * + * This value is forced to be a power of two so that writes align on pages. + */ +static unsigned io_limit = SFF_8436_PAGE_SIZE; + +/* + * specs often allow 5 msec for a page write, sometimes 20 msec; + * it's important to recover from write timeouts. + */ +static unsigned write_timeout = 25; + +typedef enum qsfp_opcode { + QSFP_READ_OP = 0, + QSFP_WRITE_OP = 1 +} qsfp_opcode_e; +#endif + +/* Platform dependent +++ */ +#define I2C_ADDR_CPLD1 0x60 +#define I2C_ADDR_CPLD2 0x62 +#define I2C_ADDR_CPLD3 0x64 + +#define CPLD3_OFFSET_QSFP_MOD_RST 0x17 +/* Platform dependent --- */ +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_present(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute *da, const char *buf, size_t count);; +static ssize_t sfp_eeprom_read(struct i2c_client *, u8, u8 *,int); +static ssize_t sfp_eeprom_write(struct i2c_client *, u8 , const char *,int); +static ssize_t get_mode_reset(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t set_mode_reset(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); +enum sfp_sysfs_attributes { + PRESENT, + PRESENT_ALL, + PORT_NUMBER, + PORT_TYPE, + DDM_IMPLEMENTED, + TX_FAULT, + TX_FAULT1, + TX_FAULT2, + TX_FAULT3, + TX_FAULT4, + TX_DISABLE, + TX_DISABLE1, + TX_DISABLE2, + TX_DISABLE3, + TX_DISABLE4, + RX_LOS, + RX_LOS1, + RX_LOS2, + RX_LOS3, + RX_LOS4, + RX_LOS_ALL, + SFP_MOD_RST +}; + +/* SFP/QSFP common attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_port_number, S_IRUGO, show_port_number, NULL, PORT_NUMBER); +static SENSOR_DEVICE_ATTR(sfp_is_present, S_IRUGO, show_present, NULL, PRESENT); +static SENSOR_DEVICE_ATTR(sfp_is_present_all, S_IRUGO, show_present, NULL, PRESENT_ALL); +static SENSOR_DEVICE_ATTR(sfp_rx_los, S_IRUGO, sfp_show_tx_rx_status, NULL, RX_LOS); +static SENSOR_DEVICE_ATTR(sfp_tx_disable, S_IWUSR | S_IRUGO, sfp_show_tx_rx_status, sfp_set_tx_disable, TX_DISABLE); +static SENSOR_DEVICE_ATTR(sfp_tx_fault, S_IRUGO, sfp_show_tx_rx_status, NULL, TX_FAULT); + +/* QSFP attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_rx_los1, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS1); +static SENSOR_DEVICE_ATTR(sfp_rx_los2, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS2); +static SENSOR_DEVICE_ATTR(sfp_rx_los3, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS3); +static SENSOR_DEVICE_ATTR(sfp_rx_los4, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS4); +static SENSOR_DEVICE_ATTR(sfp_tx_disable1, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE1); +static SENSOR_DEVICE_ATTR(sfp_tx_disable2, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE2); +static SENSOR_DEVICE_ATTR(sfp_tx_disable3, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE3); +static SENSOR_DEVICE_ATTR(sfp_tx_disable4, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE4); +static SENSOR_DEVICE_ATTR(sfp_tx_fault1, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT1); +static SENSOR_DEVICE_ATTR(sfp_tx_fault2, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT2); +static SENSOR_DEVICE_ATTR(sfp_tx_fault3, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT3); +static SENSOR_DEVICE_ATTR(sfp_tx_fault4, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT4); +static SENSOR_DEVICE_ATTR(sfp_mod_rst, S_IWUSR | S_IRUGO, get_mode_reset, set_mode_reset, SFP_MOD_RST); + +static struct attribute *qsfp_attributes[] = { + &sensor_dev_attr_sfp_port_number.dev_attr.attr, + &sensor_dev_attr_sfp_is_present.dev_attr.attr, + &sensor_dev_attr_sfp_is_present_all.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los1.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los2.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los3.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los4.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable1.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable2.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable3.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable4.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault1.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault2.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault3.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault4.dev_attr.attr, + &sensor_dev_attr_sfp_mod_rst.dev_attr.attr, + NULL +}; + +/* SFP msa attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_rx_los_all, S_IRUGO, sfp_show_tx_rx_status, NULL, RX_LOS_ALL); +static struct attribute *sfp_msa_attributes[] = { + &sensor_dev_attr_sfp_port_number.dev_attr.attr, + &sensor_dev_attr_sfp_is_present.dev_attr.attr, + &sensor_dev_attr_sfp_is_present_all.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los_all.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable.dev_attr.attr, + NULL +}; + +/* Platform dependent +++ */ +#define CPLD_PORT_TO_FRONT_PORT(port) (port+1) + +enum port_numbers { + as7312_54x_port1, as7312_54x_port2, as7312_54x_port3, as7312_54x_port4, + as7312_54x_port5, as7312_54x_port6, as7312_54x_port7, as7312_54x_port8, + as7312_54x_port9, as7312_54x_port10, as7312_54x_port11, as7312_54x_port12, + as7312_54x_port13, as7312_54x_port14, as7312_54x_port15, as7312_54x_port16, + as7312_54x_port17, as7312_54x_port18, as7312_54x_port19, as7312_54x_port20, + as7312_54x_port21, as7312_54x_port22, as7312_54x_port23, as7312_54x_port24, + as7312_54x_port25, as7312_54x_port26, as7312_54x_port27, as7312_54x_port28, + as7312_54x_port29, as7312_54x_port30, as7312_54x_port31, as7312_54x_port32, + as7312_54x_port33, as7312_54x_port34, as7312_54x_port35, as7312_54x_port36, + as7312_54x_port37, as7312_54x_port38, as7312_54x_port39, as7312_54x_port40, + as7312_54x_port41, as7312_54x_port42, as7312_54x_port43, as7312_54x_port44, + as7312_54x_port45, as7312_54x_port46, as7312_54x_port47, as7312_54x_port48, + as7312_54x_port49, as7312_54x_port52, as7312_54x_port50, as7312_54x_port53, + as7312_54x_port51, as7312_54x_port54 +}; + +#define I2C_DEV_ID(x) { #x, x} + +static const struct i2c_device_id sfp_device_id[] = { + I2C_DEV_ID(as7312_54x_port1), + I2C_DEV_ID(as7312_54x_port2), + I2C_DEV_ID(as7312_54x_port3), + I2C_DEV_ID(as7312_54x_port4), + I2C_DEV_ID(as7312_54x_port5), + I2C_DEV_ID(as7312_54x_port6), + I2C_DEV_ID(as7312_54x_port7), + I2C_DEV_ID(as7312_54x_port8), + I2C_DEV_ID(as7312_54x_port9), + I2C_DEV_ID(as7312_54x_port10), + I2C_DEV_ID(as7312_54x_port11), + I2C_DEV_ID(as7312_54x_port12), + I2C_DEV_ID(as7312_54x_port13), + I2C_DEV_ID(as7312_54x_port14), + I2C_DEV_ID(as7312_54x_port15), + I2C_DEV_ID(as7312_54x_port16), + I2C_DEV_ID(as7312_54x_port17), + I2C_DEV_ID(as7312_54x_port18), + I2C_DEV_ID(as7312_54x_port19), + I2C_DEV_ID(as7312_54x_port20), + I2C_DEV_ID(as7312_54x_port21), + I2C_DEV_ID(as7312_54x_port22), + I2C_DEV_ID(as7312_54x_port23), + I2C_DEV_ID(as7312_54x_port24), + I2C_DEV_ID(as7312_54x_port25), + I2C_DEV_ID(as7312_54x_port26), + I2C_DEV_ID(as7312_54x_port27), + I2C_DEV_ID(as7312_54x_port28), + I2C_DEV_ID(as7312_54x_port29), + I2C_DEV_ID(as7312_54x_port30), + I2C_DEV_ID(as7312_54x_port31), + I2C_DEV_ID(as7312_54x_port32), + I2C_DEV_ID(as7312_54x_port33), + I2C_DEV_ID(as7312_54x_port34), + I2C_DEV_ID(as7312_54x_port35), + I2C_DEV_ID(as7312_54x_port36), + I2C_DEV_ID(as7312_54x_port37), + I2C_DEV_ID(as7312_54x_port38), + I2C_DEV_ID(as7312_54x_port39), + I2C_DEV_ID(as7312_54x_port40), + I2C_DEV_ID(as7312_54x_port41), + I2C_DEV_ID(as7312_54x_port42), + I2C_DEV_ID(as7312_54x_port43), + I2C_DEV_ID(as7312_54x_port44), + I2C_DEV_ID(as7312_54x_port45), + I2C_DEV_ID(as7312_54x_port46), + I2C_DEV_ID(as7312_54x_port47), + I2C_DEV_ID(as7312_54x_port48), + I2C_DEV_ID(as7312_54x_port49), + I2C_DEV_ID(as7312_54x_port50), + I2C_DEV_ID(as7312_54x_port51), + I2C_DEV_ID(as7312_54x_port52), + I2C_DEV_ID(as7312_54x_port53), + I2C_DEV_ID(as7312_54x_port54), + { /* LIST END */ } +}; +MODULE_DEVICE_TABLE(i2c, sfp_device_id); +/* Platform dependent --- */ + +enum driver_type_e { + DRIVER_TYPE_SFP_MSA, + DRIVER_TYPE_QSFP +}; + +/* Each client has this additional data + */ +struct eeprom_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + struct bin_attribute bin; /* eeprom data */ +}; + +struct sfp_msa_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u64 status[6]; /* bit0:port0, bit1:port1 and so on */ + /* index 0 => tx_fail + 1 => tx_disable + 2 => rx_loss + 3 => device id + 4 => 10G Ethernet Compliance Codes + to distinguish SFP or SFP+ + 5 => DIAGNOSTIC MONITORING TYPE */ + struct eeprom_data eeprom; +#if (MULTIPAGE_SUPPORT == 1) + struct i2c_client *ddm_client; /* dummy client instance for 0xA2 */ +#endif +}; + +struct qsfp_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 status[3]; /* bit0:port0, bit1:port1 and so on */ + /* index 0 => tx_fail + 1 => tx_disable + 2 => rx_loss */ + + u8 device_id; + struct eeprom_data eeprom; +}; + +struct sfp_port_data { + struct mutex update_lock; + enum driver_type_e driver_type; + int port; /* CPLD port index */ + u64 present; /* present status, bit0:port0, bit1:port1 and so on */ + + struct sfp_msa_data *msa; + struct qsfp_data *qsfp; + + struct i2c_client *client; +#if (MULTIPAGE_SUPPORT == 1) + int use_smbus; + u8 *writebuf; + unsigned write_max; +#endif +}; + +#if (MULTIPAGE_SUPPORT == 1) +static ssize_t sfp_port_read_write(struct sfp_port_data *port_data, + char *buf, loff_t off, size_t len, qsfp_opcode_e opcode); +#endif +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + return sprintf(buf, "%d\n", CPLD_PORT_TO_FRONT_PORT(data->port)); +} + +/* Platform dependent +++ */ +static struct sfp_port_data *sfp_update_present(struct i2c_client *client) +{ + int i = 0, j = 0, status = -1; + u8 reg; + unsigned short cpld_addr; + struct sfp_port_data *data = i2c_get_clientdata(client); + + DEBUG_PRINT("Starting sfp present status update"); + mutex_lock(&data->update_lock); + data->present = 0; + + /* Read present status of port 1~48(SFP port) */ + for (i = 0; i < 2; i++) { + for (j = 0; j < 3; j++) { + cpld_addr = I2C_ADDR_CPLD2 + i*2; + reg = 0x9+j; + status = accton_i2c_cpld_read(cpld_addr, reg); + + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_addr, reg, status); + goto exit; + } + + DEBUG_PRINT("Present status = 0x%lx\r\n", data->present); + data->present |= (u64)status << ((i*24) + (j%3)*8); + } + } + + /* Read present status of port 49-52(QSFP port) */ + cpld_addr = I2C_ADDR_CPLD2; + reg = 0x18; + status = accton_i2c_cpld_read(cpld_addr, reg); + + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_addr, reg, status); + goto exit; + } + else { + data->present |= (u64)(status & 0xF) << SFP_PORT_MAX; + } + + /* Read present status of port 53-54(QSFP port) */ + cpld_addr = I2C_ADDR_CPLD3; + reg = 0x18; + status = accton_i2c_cpld_read(cpld_addr, reg); + + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_addr, reg, status); + goto exit; + } + else { + data->present |= (u64)(status & 0x3) << 52; + } + + DEBUG_PRINT("Present status = 0x%lx", data->present); +exit: + mutex_unlock(&data->update_lock); + return (status < 0) ? ERR_PTR(status) : data; +} + +static struct sfp_port_data* sfp_update_tx_rx_status(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int i = 0, j = 0; + int status = -1; + + if (time_before(jiffies, data->msa->last_updated + HZ + HZ / 2) && data->msa->valid) { + return data; + } + + DEBUG_PRINT("Starting as7312_54x sfp tx rx status update"); + mutex_lock(&data->update_lock); + data->msa->valid = 0; + memset(data->msa->status, 0, sizeof(data->msa->status)); + + /* Read status of port 1~48(SFP port) */ + for (i = 0; i < 2; i++) { + for (j = 0; j < 9; j++) { + u8 reg; + unsigned short cpld_addr; + reg = 0xc+j; + cpld_addr = I2C_ADDR_CPLD2 + i*2; + + status = accton_i2c_cpld_read(cpld_addr, reg); + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_addr, reg, status); + goto exit; + } + + data->msa->status[j/3] |= (u64)status << ((i*24) + (j%3)*8); + } + } + + data->msa->valid = 1; + data->msa->last_updated = jiffies; + +exit: + mutex_unlock(&data->update_lock); + return (status < 0) ? ERR_PTR(status) : data; +} + +static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + unsigned short cpld_addr = 0; + u8 cpld_reg = 0, cpld_val = 0, cpld_bit = 0; + long disable; + int error; + + if (data->driver_type == DRIVER_TYPE_QSFP) { + return qsfp_set_tx_disable(dev, da, buf, count); + } + + error = kstrtol(buf, 10, &disable); + if (error) { + return error; + } + + mutex_lock(&data->update_lock); + + if(data->port < 24) { + cpld_addr = I2C_ADDR_CPLD2; + cpld_reg = 0xF + data->port / 8; + cpld_bit = 1 << (data->port % 8); + } + else { /* port 24 ~ 48 */ + cpld_addr = I2C_ADDR_CPLD3; + cpld_reg = 0xF + (data->port - 24) / 8; + cpld_bit = 1 << (data->port % 8); + } + + /* Read current status */ + cpld_val = accton_i2c_cpld_read(cpld_addr, cpld_reg); + + /* Update tx_disable status */ + if (disable) { + data->msa->status[1] |= BIT_INDEX(data->port); + cpld_val |= cpld_bit; + } + else { + data->msa->status[1] &= ~BIT_INDEX(data->port); + cpld_val &= ~cpld_bit; + } + + accton_i2c_cpld_write(cpld_addr, cpld_reg, cpld_val); + mutex_unlock(&data->update_lock); + return count; +} + +static int sfp_is_port_present(struct i2c_client *client, int port) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + + data = sfp_update_present(client); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + return (data->present & BIT_INDEX(data->port)) ? 0 : 1; /* Platform dependent */ +} + +/* Platform dependent +++ */ +static ssize_t show_present(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + + if (PRESENT_ALL == attr->index) { + int i; + u8 values[7] = {0}; + struct sfp_port_data *data = sfp_update_present(client); + + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + for (i = 0; i < ARRAY_SIZE(values); i++) { + values[i] = ~(u8)(data->present >> (i * 8)); + } + + /* Return values 1 -> 54 in order */ + return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], + values[3], values[4], values[5], + values[6] & 0x3F); + } + else { + struct sfp_port_data *data = i2c_get_clientdata(client); + int present = sfp_is_port_present(client, data->port); + + if (IS_ERR_VALUE(present)) { + return present; + } + + /* PRESENT */ + return sprintf(buf, "%d\n", present); + } +} +/* Platform dependent --- */ + +static struct sfp_port_data *qsfp_update_tx_rx_status(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int i, status = -1; + u8 buf = 0; + u8 reg[] = {SFF8436_TX_FAULT_ADDR, SFF8436_TX_DISABLE_ADDR, SFF8436_RX_LOS_ADDR}; + + if (time_before(jiffies, data->qsfp->last_updated + HZ + HZ / 2) && data->qsfp->valid) { + return data; + } + + DEBUG_PRINT("Starting sfp tx rx status update"); + mutex_lock(&data->update_lock); + data->qsfp->valid = 0; + memset(data->qsfp->status, 0, sizeof(data->qsfp->status)); + + /* Notify device to update tx fault/ tx disable/ rx los status */ + for (i = 0; i < ARRAY_SIZE(reg); i++) { + status = sfp_eeprom_read(client, reg[i], &buf, sizeof(buf)); + if (unlikely(status < 0)) { + goto exit; + } + } + msleep(200); + + /* Read actual tx fault/ tx disable/ rx los status */ + for (i = 0; i < ARRAY_SIZE(reg); i++) { + status = sfp_eeprom_read(client, reg[i], &buf, sizeof(buf)); + if (unlikely(status < 0)) { + goto exit; + } + + DEBUG_PRINT("qsfp reg(0x%x) status = (0x%x)", reg[i], data->qsfp->status[i]); + data->qsfp->status[i] = (buf & 0xF); + } + + data->qsfp->valid = 1; + data->qsfp->last_updated = jiffies; + +exit: + mutex_unlock(&data->update_lock); + return (status < 0) ? ERR_PTR(status) : data; +} + +static ssize_t get_mode_reset(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + u8 cpld_val = 0; + int port_bit; + int status = -EINVAL; + u8 cpld_addr[] = {I2C_ADDR_CPLD2, I2C_ADDR_CPLD3}; + + /* Low power mode is not supported for SFP ports(1-48) */ + if (data->port < SFP_PORT_MAX) { + return -EINVAL; + } + mutex_lock(&data->update_lock); + + port_bit = data->port - SFP_PORT_MAX; + cpld_val = accton_i2c_cpld_read(cpld_addr[port_bit/4], CPLD3_OFFSET_QSFP_MOD_RST); + + pr_err("[ROY]%s#%d, %x from %x\n", __func__, __LINE__, cpld_val, cpld_addr[port_bit/4]); + + cpld_val = cpld_val & 0x0F; + cpld_val = cpld_val & BIT_INDEX(port_bit%4); + + pr_err("[ROY]%s#%d, %x of bit %d\n", __func__, __LINE__, cpld_val, port_bit); + + status = snprintf(buf, PAGE_SIZE - 1, "%d\r\n", cpld_val>>(port_bit%4)); + + mutex_unlock(&data->update_lock); + + return status; +} + +static ssize_t set_mode_reset(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + u8 cpld_val = 0; + long reset; + int error, port_bit; + u8 cpld_addr[] = {I2C_ADDR_CPLD2, I2C_ADDR_CPLD3}; + + pr_err("[ROY]%s#%d, port:%d\n", __func__, __LINE__, data->port); + + /* Tx disable is not supported for QSFP ports(49-54) */ + if (data->port < SFP_PORT_MAX) { + return -EINVAL; + } + port_bit = data->port - SFP_PORT_MAX; + error = kstrtol(buf, 10, &reset); + + pr_err("[ROY]%s#%d, %s == %d\n", __func__, __LINE__, buf, error); + if (error) { + return error; + } + mutex_lock(&data->update_lock); + + cpld_val = accton_i2c_cpld_read(cpld_addr[port_bit/4], CPLD3_OFFSET_QSFP_MOD_RST); + pr_err("[ROY]%s#%d, %x\n", __func__, __LINE__, cpld_val); + /* Update lp_mode status */ + if (reset) + { + cpld_val |= BIT_INDEX(port_bit%4); + } + else + { + cpld_val &= ~BIT_INDEX(port_bit%4); + } + pr_err("[ROY]%s#%d, %x to %x\n", __func__, __LINE__, cpld_val, cpld_addr[port_bit/4]); + + accton_i2c_cpld_write(cpld_addr[port_bit/4], CPLD3_OFFSET_QSFP_MOD_RST, cpld_val); + + mutex_unlock(&data->update_lock); + + return count; +} +static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + int present; + u8 val = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENXIO; + } + + data = qsfp_update_tx_rx_status(dev); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + switch (attr->index) { + case TX_FAULT: + val = !!(data->qsfp->status[2] & 0xF); + break; + case TX_FAULT1: + case TX_FAULT2: + case TX_FAULT3: + case TX_FAULT4: + val = !!(data->qsfp->status[2] & BIT_INDEX(attr->index - TX_FAULT1)); + break; + case TX_DISABLE: + val = data->qsfp->status[1] & 0xF; + break; + case TX_DISABLE1: + case TX_DISABLE2: + case TX_DISABLE3: + case TX_DISABLE4: + val = !!(data->qsfp->status[1] & BIT_INDEX(attr->index - TX_DISABLE1)); + break; + case RX_LOS: + val = !!(data->qsfp->status[0] & 0xF); + break; + case RX_LOS1: + case RX_LOS2: + case RX_LOS3: + case RX_LOS4: + val = !!(data->qsfp->status[0] & BIT_INDEX(attr->index - RX_LOS1)); + break; + default: + break; + } + + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + long disable; + int status; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + status = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(status)) { + return status; + } + + if (!status) { + /* port is not present */ + return -ENXIO; + } + + status = kstrtol(buf, 10, &disable); + if (status) { + return status; + } + + data = qsfp_update_tx_rx_status(dev); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + mutex_lock(&data->update_lock); + + if (attr->index == TX_DISABLE) { + if (disable) { + data->qsfp->status[1] |= 0xF; + } + else { + data->qsfp->status[1] &= ~0xF; + } + } + else {/* TX_DISABLE1 ~ TX_DISABLE4*/ + if (disable) { + data->qsfp->status[1] |= (1 << (attr->index - TX_DISABLE1)); + } + else { + data->qsfp->status[1] &= ~(1 << (attr->index - TX_DISABLE1)); + } + } + + DEBUG_PRINT("index = (%d), status = (0x%x)", attr->index, data->qsfp->status[1]); + status = sfp_eeprom_write(data->client, SFF8436_TX_DISABLE_ADDR, &data->qsfp->status[1], sizeof(data->qsfp->status[1])); + if (unlikely(status < 0)) { + count = status; + } + + mutex_unlock(&data->update_lock); + return count; +} + +/* Platform dependent +++ */ +static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + u8 val = 0, index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + if (data->driver_type == DRIVER_TYPE_QSFP) { + return qsfp_show_tx_rx_status(dev, da, buf); + } + + data = sfp_update_tx_rx_status(dev); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + if(attr->index == RX_LOS_ALL) { + int i = 0; + u8 values[6] = {0}; + + for (i = 0; i < ARRAY_SIZE(values); i++) { + values[i] = (u8)(data->msa->status[2] >> (i * 8)); + } + + /** Return values 1 -> 48 in order */ + return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], + values[3], values[4], values[5]); + } + + switch (attr->index) { + case TX_FAULT: + index = 0; + break; + case TX_DISABLE: + index = 1; + break; + case RX_LOS: + index = 2; + break; + default: + return 0; + } + + val = (data->msa->status[index] & BIT_INDEX(data->port)) ? 1 : 0; + return sprintf(buf, "%d\n", val); +} +/* Platform dependent --- */ +static ssize_t sfp_eeprom_write(struct i2c_client *client, u8 command, const char *data, + int data_len) +{ +#if USE_I2C_BLOCK_READ + int status, retry = I2C_RW_RETRY_COUNT; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_write_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + return status; + } + + return data_len; +#else + int status, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_write_byte_data(client, command, *data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + return status; + } + + return 1; +#endif + + +} + +#if (MULTIPAGE_SUPPORT == 0) +static ssize_t sfp_port_write(struct sfp_port_data *data, + const char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + return count; + } + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&data->update_lock); + + while (count) { + ssize_t status; + + status = sfp_eeprom_write(data->client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&data->update_lock); + return retval; +} +#endif + +static ssize_t sfp_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct sfp_port_data *data; + DEBUG_PRINT("%s(%d) offset = (%d), count = (%d)", off, count); + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + + present = sfp_is_port_present(data->client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + +#if (MULTIPAGE_SUPPORT == 1) + return sfp_port_read_write(data, buf, off, count, QSFP_WRITE_OP); +#else + return sfp_port_write(data, buf, off, count); +#endif +} + +static ssize_t sfp_eeprom_read(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ +#if USE_I2C_BLOCK_READ + int status, retry = I2C_RW_RETRY_COUNT; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + goto abort; + } + if (unlikely(status != data_len)) { + status = -EIO; + goto abort; + } + + //result = data_len; + +abort: + return status; +#else + int status, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_read_byte_data(client, command); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "sfp read byte data failed, command(0x%2x), data(0x%2x)\r\n", command, status); + goto abort; + } + + *data = (u8)status; + status = 1; + +abort: + return status; +#endif +} + +#if (MULTIPAGE_SUPPORT == 1) +/*-------------------------------------------------------------------------*/ +/* + * This routine computes the addressing information to be used for + * a given r/w request. + * + * Task is to calculate the client (0 = i2c addr 50, 1 = i2c addr 51), + * the page, and the offset. + * + * Handles both SFP and QSFP. + * For SFP, offset 0-255 are on client[0], >255 is on client[1] + * Offset 256-383 are on the lower half of client[1] + * Pages are accessible on the upper half of client[1]. + * Offset >383 are in 128 byte pages mapped into the upper half + * + * For QSFP, all offsets are on client[0] + * offset 0-127 are on the lower half of client[0] (no paging) + * Pages are accessible on the upper half of client[1]. + * Offset >127 are in 128 byte pages mapped into the upper half + * + * Callers must not read/write beyond the end of a client or a page + * without recomputing the client/page. Hence offset (within page) + * plus length must be less than or equal to 128. (Note that this + * routine does not have access to the length of the call, hence + * cannot do the validity check.) + * + * Offset within Lower Page 00h and Upper Page 00h are not recomputed + */ +static uint8_t sff_8436_translate_offset(struct sfp_port_data *port_data, + loff_t *offset, struct i2c_client **client) +{ + unsigned page = 0; + + *client = port_data->client; + + /* if SFP style, offset > 255, shift to i2c addr 0x51 */ + if (port_data->driver_type == DRIVER_TYPE_SFP_MSA) { + if (*offset > 255) { + /* like QSFP, but shifted to client[1] */ + *client = port_data->msa->ddm_client; + *offset -= 256; + } + } + + /* + * if offset is in the range 0-128... + * page doesn't matter (using lower half), return 0. + * offset is already correct (don't add 128 to get to paged area) + */ + if (*offset < SFF_8436_PAGE_SIZE) + return page; + + /* note, page will always be positive since *offset >= 128 */ + page = (*offset >> 7)-1; + /* 0x80 places the offset in the top half, offset is last 7 bits */ + *offset = SFF_8436_PAGE_SIZE + (*offset & 0x7f); + + return page; /* note also returning client and offset */ +} + +static ssize_t sff_8436_eeprom_read(struct sfp_port_data *port_data, + struct i2c_client *client, + char *buf, unsigned offset, size_t count) +{ + struct i2c_msg msg[2]; + u8 msgbuf[2]; + unsigned long timeout, read_time; + int status, i; + + memset(msg, 0, sizeof(msg)); + + switch (port_data->use_smbus) { + case I2C_SMBUS_I2C_BLOCK_DATA: + /*smaller eeproms can work given some SMBus extension calls */ + if (count > I2C_SMBUS_BLOCK_MAX) + count = I2C_SMBUS_BLOCK_MAX; + break; + case I2C_SMBUS_WORD_DATA: + /* Check for odd length transaction */ + count = (count == 1) ? 1 : 2; + break; + case I2C_SMBUS_BYTE_DATA: + count = 1; + break; + default: + /* + * When we have a better choice than SMBus calls, use a + * combined I2C message. Write address; then read up to + * io_limit data bytes. msgbuf is u8 and will cast to our + * needs. + */ + i = 0; + msgbuf[i++] = offset; + + msg[0].addr = client->addr; + msg[0].buf = msgbuf; + msg[0].len = i; + + msg[1].addr = client->addr; + msg[1].flags = I2C_M_RD; + msg[1].buf = buf; + msg[1].len = count; + } + + /* + * Reads fail if the previous write didn't complete yet. We may + * loop a few times until this one succeeds, waiting at least + * long enough for one entire page write to work. + */ + timeout = jiffies + msecs_to_jiffies(write_timeout); + do { + read_time = jiffies; + + switch (port_data->use_smbus) { + case I2C_SMBUS_I2C_BLOCK_DATA: + status = i2c_smbus_read_i2c_block_data(client, offset, + count, buf); + break; + case I2C_SMBUS_WORD_DATA: + status = i2c_smbus_read_word_data(client, offset); + if (status >= 0) { + buf[0] = status & 0xff; + if (count == 2) + buf[1] = status >> 8; + status = count; + } + break; + case I2C_SMBUS_BYTE_DATA: + status = i2c_smbus_read_byte_data(client, offset); + if (status >= 0) { + buf[0] = status; + status = count; + } + break; + default: + status = i2c_transfer(client->adapter, msg, 2); + if (status == 2) + status = count; + } + + dev_dbg(&client->dev, "eeprom read %zu@%d --> %d (%ld)\n", + count, offset, status, jiffies); + + if (status == count) /* happy path */ + return count; + + if (status == -ENXIO) /* no module present */ + return status; + + /* REVISIT: at HZ=100, this is sloooow */ + msleep(1); + } while (time_before(read_time, timeout)); + + return -ETIMEDOUT; +} + +static ssize_t sff_8436_eeprom_write(struct sfp_port_data *port_data, + struct i2c_client *client, + const char *buf, + unsigned offset, size_t count) +{ + struct i2c_msg msg; + ssize_t status; + unsigned long timeout, write_time; + unsigned next_page_start; + int i = 0; + + /* write max is at most a page + * (In this driver, write_max is actually one byte!) + */ + if (count > port_data->write_max) + count = port_data->write_max; + + /* shorten count if necessary to avoid crossing page boundary */ + next_page_start = roundup(offset + 1, SFF_8436_PAGE_SIZE); + if (offset + count > next_page_start) + count = next_page_start - offset; + + switch (port_data->use_smbus) { + case I2C_SMBUS_I2C_BLOCK_DATA: + /*smaller eeproms can work given some SMBus extension calls */ + if (count > I2C_SMBUS_BLOCK_MAX) + count = I2C_SMBUS_BLOCK_MAX; + break; + case I2C_SMBUS_WORD_DATA: + /* Check for odd length transaction */ + count = (count == 1) ? 1 : 2; + break; + case I2C_SMBUS_BYTE_DATA: + count = 1; + break; + default: + /* If we'll use I2C calls for I/O, set up the message */ + msg.addr = client->addr; + msg.flags = 0; + + /* msg.buf is u8 and casts will mask the values */ + msg.buf = port_data->writebuf; + + msg.buf[i++] = offset; + memcpy(&msg.buf[i], buf, count); + msg.len = i + count; + break; + } + + /* + * Reads fail if the previous write didn't complete yet. We may + * loop a few times until this one succeeds, waiting at least + * long enough for one entire page write to work. + */ + timeout = jiffies + msecs_to_jiffies(write_timeout); + do { + write_time = jiffies; + + switch (port_data->use_smbus) { + case I2C_SMBUS_I2C_BLOCK_DATA: + status = i2c_smbus_write_i2c_block_data(client, + offset, count, buf); + if (status == 0) + status = count; + break; + case I2C_SMBUS_WORD_DATA: + if (count == 2) { + status = i2c_smbus_write_word_data(client, + offset, (u16)((buf[0])|(buf[1] << 8))); + } else { + /* count = 1 */ + status = i2c_smbus_write_byte_data(client, + offset, buf[0]); + } + if (status == 0) + status = count; + break; + case I2C_SMBUS_BYTE_DATA: + status = i2c_smbus_write_byte_data(client, offset, + buf[0]); + if (status == 0) + status = count; + break; + default: + status = i2c_transfer(client->adapter, &msg, 1); + if (status == 1) + status = count; + break; + } + + dev_dbg(&client->dev, "eeprom write %zu@%d --> %ld (%lu)\n", + count, offset, (long int) status, jiffies); + + if (status == count) + return count; + + /* REVISIT: at HZ=100, this is sloooow */ + msleep(1); + } while (time_before(write_time, timeout)); + + return -ETIMEDOUT; +} + + +static ssize_t sff_8436_eeprom_update_client(struct sfp_port_data *port_data, + char *buf, loff_t off, + size_t count, qsfp_opcode_e opcode) +{ + struct i2c_client *client; + ssize_t retval = 0; + u8 page = 0; + loff_t phy_offset = off; + int ret = 0; + + page = sff_8436_translate_offset(port_data, &phy_offset, &client); + + dev_dbg(&client->dev, + "sff_8436_eeprom_update_client off %lld page:%d phy_offset:%lld, count:%ld, opcode:%d\n", + off, page, phy_offset, (long int) count, opcode); + if (page > 0) { + ret = sff_8436_eeprom_write(port_data, client, &page, + SFF_8436_PAGE_SELECT_REG, 1); + if (ret < 0) { + dev_dbg(&client->dev, + "Write page register for page %d failed ret:%d!\n", + page, ret); + return ret; + } + } + + while (count) { + ssize_t status; + + if (opcode == QSFP_READ_OP) { + status = sff_8436_eeprom_read(port_data, client, + buf, phy_offset, count); + } else { + status = sff_8436_eeprom_write(port_data, client, + buf, phy_offset, count); + } + if (status <= 0) { + if (retval == 0) + retval = status; + break; + } + buf += status; + phy_offset += status; + count -= status; + retval += status; + } + + + if (page > 0) { + /* return the page register to page 0 (why?) */ + page = 0; + ret = sff_8436_eeprom_write(port_data, client, &page, + SFF_8436_PAGE_SELECT_REG, 1); + if (ret < 0) { + dev_err(&client->dev, + "Restore page register to page %d failed ret:%d!\n", + page, ret); + return ret; + } + } + return retval; +} + + +/* + * Figure out if this access is within the range of supported pages. + * Note this is called on every access because we don't know if the + * module has been replaced since the last call. + * If/when modules support more pages, this is the routine to update + * to validate and allow access to additional pages. + * + * Returns updated len for this access: + * - entire access is legal, original len is returned. + * - access begins legal but is too long, len is truncated to fit. + * - initial offset exceeds supported pages, return -EINVAL + */ +static ssize_t sff_8436_page_legal(struct sfp_port_data *port_data, + loff_t off, size_t len) +{ + struct i2c_client *client = port_data->client; + u8 regval; + int status; + size_t maxlen; + + if (off < 0) return -EINVAL; + if (port_data->driver_type == DRIVER_TYPE_SFP_MSA) { + /* SFP case */ + if ((off + len) <= 256) return len; + /* if no pages needed, we're good */ + //if ((off + len) <= SFF_8472_EEPROM_UNPAGED_SIZE) return len; + /* if offset exceeds possible pages, we're not good */ + if (off >= SFF_8472_EEPROM_SIZE) return -EINVAL; + + /* Check if ddm is supported */ + status = sff_8436_eeprom_read(port_data, client, ®val, + SFF8472_DIAG_MON_TYPE_ADDR, 1); + if (status < 0) return status; /* error out (no module?) */ + if (!(regval & SFF8472_DIAG_MON_TYPE_DDM_MASK)) { + if (off >= 256) return -EINVAL; + maxlen = 256 - off; + } + else { + /* in between, are pages supported? */ + status = sff_8436_eeprom_read(port_data, client, ®val, + SFF_8472_PAGEABLE_REG, 1); + if (status < 0) return status; /* error out (no module?) */ + if (regval & SFF_8472_PAGEABLE) { + /* Pages supported, trim len to the end of pages */ + maxlen = SFF_8472_EEPROM_SIZE - off; + } else { + /* pages not supported, trim len to unpaged size */ + if (off >= SFF_8472_EEPROM_UNPAGED_SIZE) return -EINVAL; + maxlen = SFF_8472_EEPROM_UNPAGED_SIZE - off; + } + } + len = (len > maxlen) ? maxlen : len; + dev_dbg(&client->dev, + "page_legal, SFP, off %lld len %ld\n", + off, (long int) len); + } + else if (port_data->driver_type == DRIVER_TYPE_QSFP) { + /* QSFP case */ + /* if no pages needed, we're good */ + if ((off + len) <= SFF_8436_EEPROM_UNPAGED_SIZE) return len; + /* if offset exceeds possible pages, we're not good */ + if (off >= SFF_8436_EEPROM_SIZE) return -EINVAL; + /* in between, are pages supported? */ + status = sff_8436_eeprom_read(port_data, client, ®val, + SFF_8436_PAGEABLE_REG, 1); + if (status < 0) return status; /* error out (no module?) */ + if (regval & SFF_8436_NOT_PAGEABLE) { + /* pages not supported, trim len to unpaged size */ + if (off >= SFF_8436_EEPROM_UNPAGED_SIZE) return -EINVAL; + maxlen = SFF_8436_EEPROM_UNPAGED_SIZE - off; + } else { + /* Pages supported, trim len to the end of pages */ + maxlen = SFF_8436_EEPROM_SIZE - off; + } + len = (len > maxlen) ? maxlen : len; + dev_dbg(&client->dev, + "page_legal, QSFP, off %lld len %ld\n", + off, (long int) len); + } + else { + return -EINVAL; + } + return len; +} + + +static ssize_t sfp_port_read_write(struct sfp_port_data *port_data, + char *buf, loff_t off, size_t len, qsfp_opcode_e opcode) +{ + struct i2c_client *client = port_data->client; + int chunk; + int status = 0; + ssize_t retval; + size_t pending_len = 0, chunk_len = 0; + loff_t chunk_offset = 0, chunk_start_offset = 0; + + if (unlikely(!len)) + return len; + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&port_data->update_lock); + + /* + * Confirm this access fits within the device suppored addr range + */ + len = sff_8436_page_legal(port_data, off, len); + if (len < 0) { + status = len; + goto err; + } + + /* + * For each (128 byte) chunk involved in this request, issue a + * separate call to sff_eeprom_update_client(), to + * ensure that each access recalculates the client/page + * and writes the page register as needed. + * Note that chunk to page mapping is confusing, is different for + * QSFP and SFP, and never needs to be done. Don't try! + */ + pending_len = len; /* amount remaining to transfer */ + retval = 0; /* amount transferred */ + for (chunk = off >> 7; chunk <= (off + len - 1) >> 7; chunk++) { + + /* + * Compute the offset and number of bytes to be read/write + * + * 1. start at offset 0 (within the chunk), and read/write + * the entire chunk + * 2. start at offset 0 (within the chunk) and read/write less + * than entire chunk + * 3. start at an offset not equal to 0 and read/write the rest + * of the chunk + * 4. start at an offset not equal to 0 and read/write less than + * (end of chunk - offset) + */ + chunk_start_offset = chunk * SFF_8436_PAGE_SIZE; + + if (chunk_start_offset < off) { + chunk_offset = off; + if ((off + pending_len) < (chunk_start_offset + + SFF_8436_PAGE_SIZE)) + chunk_len = pending_len; + else + chunk_len = (chunk+1)*SFF_8436_PAGE_SIZE - off;/*SFF_8436_PAGE_SIZE - off;*/ + } else { + chunk_offset = chunk_start_offset; + if (pending_len > SFF_8436_PAGE_SIZE) + chunk_len = SFF_8436_PAGE_SIZE; + else + chunk_len = pending_len; + } + + dev_dbg(&client->dev, + "sff_r/w: off %lld, len %ld, chunk_start_offset %lld, chunk_offset %lld, chunk_len %ld, pending_len %ld\n", + off, (long int) len, chunk_start_offset, chunk_offset, + (long int) chunk_len, (long int) pending_len); + + /* + * note: chunk_offset is from the start of the EEPROM, + * not the start of the chunk + */ + status = sff_8436_eeprom_update_client(port_data, buf, + chunk_offset, chunk_len, opcode); + if (status != chunk_len) { + /* This is another 'no device present' path */ + dev_dbg(&client->dev, + "sff_8436_update_client for chunk %d chunk_offset %lld chunk_len %ld failed %d!\n", + chunk, chunk_offset, (long int) chunk_len, status); + goto err; + } + buf += status; + pending_len -= status; + retval += status; + } + mutex_unlock(&port_data->update_lock); + + return retval; + +err: + mutex_unlock(&port_data->update_lock); + + return status; +} + +#else +static ssize_t sfp_port_read(struct sfp_port_data *data, + char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + DEBUG_PRINT("Count = 0, return"); + return count; + } + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&data->update_lock); + + while (count) { + ssize_t status; + + status = sfp_eeprom_read(data->client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&data->update_lock); + return retval; + +} +#endif + +static ssize_t sfp_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct sfp_port_data *data; + DEBUG_PRINT("offset = (%d), count = (%d)", off, count); + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + + present = sfp_is_port_present(data->client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + +#if (MULTIPAGE_SUPPORT == 1) + return sfp_port_read_write(data, buf, off, count, QSFP_READ_OP); +#else + return sfp_port_read(data, buf, off, count); +#endif +} + +#if (MULTIPAGE_SUPPORT == 1) +static int sfp_sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom, size_t size) +#else +static int sfp_sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom) +#endif +{ + int err; + + sysfs_bin_attr_init(eeprom); + eeprom->attr.name = EEPROM_NAME; + eeprom->attr.mode = S_IWUSR | S_IRUGO; + eeprom->read = sfp_bin_read; + eeprom->write = sfp_bin_write; +#if (MULTIPAGE_SUPPORT == 1) + eeprom->size = size; +#else + eeprom->size = EEPROM_SIZE; +#endif + + /* Create eeprom file */ + err = sysfs_create_bin_file(kobj, eeprom); + if (err) { + return err; + } + + return 0; +} + +static int sfp_sysfs_eeprom_cleanup(struct kobject *kobj, struct bin_attribute *eeprom) +{ + sysfs_remove_bin_file(kobj, eeprom); + return 0; +} + + +#if (MULTIPAGE_SUPPORT == 0) +static int sfp_i2c_check_functionality(struct i2c_client *client) +{ +#if USE_I2C_BLOCK_READ + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK); +#else + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA); +#endif +} +#endif + +static const struct attribute_group sfp_msa_group = { + .attrs = sfp_msa_attributes, +}; + +static int sfp_msa_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct sfp_msa_data **data) +{ + int status; + struct sfp_msa_data *msa; + +#if (MULTIPAGE_SUPPORT == 0) + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } +#endif + + msa = kzalloc(sizeof(struct sfp_msa_data), GFP_KERNEL); + if (!msa) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &sfp_msa_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ +#if (MULTIPAGE_SUPPORT == 1) + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &msa->eeprom.bin, SFF_8436_EEPROM_SIZE); +#else + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &msa->eeprom.bin); +#endif + if (status) { + goto exit_remove; + } + +#if (MULTIPAGE_SUPPORT == 1) + msa->ddm_client = i2c_new_dummy(client->adapter, client->addr + 1); + if (!msa->ddm_client) { + dev_err(&client->dev, "address 0x%02x unavailable\n", client->addr + 1); + status = -EADDRINUSE; + goto exit_eeprom; + } +#endif + + *data = msa; + dev_info(&client->dev, "sfp msa '%s'\n", client->name); + + return 0; + +exit_eeprom: + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &msa->eeprom.bin); +exit_remove: + sysfs_remove_group(&client->dev.kobj, &sfp_msa_group); +exit_free: + kfree(msa); +exit: + + return status; +} + +static const struct attribute_group qsfp_group = { + .attrs = qsfp_attributes, +}; + +static int qsfp_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct qsfp_data **data) +{ + int status; + struct qsfp_data *qsfp; + +#if (MULTIPAGE_SUPPORT == 0) + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } +#endif + + qsfp = kzalloc(sizeof(struct qsfp_data), GFP_KERNEL); + if (!qsfp) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &qsfp_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ +#if (MULTIPAGE_SUPPORT == 1) + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &qsfp->eeprom.bin, SFF_8436_EEPROM_SIZE); +#else + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &qsfp->eeprom.bin); +#endif + if (status) { + goto exit_remove; + } + + *data = qsfp; + dev_info(&client->dev, "qsfp '%s'\n", client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &qsfp_group); +exit_free: + kfree(qsfp); +exit: + + return status; +} + +/* Platform dependent +++ */ +static int sfp_device_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int ret = 0; + struct sfp_port_data *data = NULL; + + if (client->addr != SFP_EEPROM_A0_I2C_ADDR) { + return -ENODEV; + } + + if (dev_id->driver_data < as7312_54x_port1 || dev_id->driver_data > as7312_54x_port54) { + return -ENXIO; + } + + data = kzalloc(sizeof(struct sfp_port_data), GFP_KERNEL); + if (!data) { + return -ENOMEM; + } + +#if (MULTIPAGE_SUPPORT == 1) + data->use_smbus = 0; + + /* Use I2C operations unless we're stuck with SMBus extensions. */ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { + data->use_smbus = I2C_SMBUS_I2C_BLOCK_DATA; + } else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_WORD_DATA)) { + data->use_smbus = I2C_SMBUS_WORD_DATA; + } else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_BYTE_DATA)) { + data->use_smbus = I2C_SMBUS_BYTE_DATA; + } else { + ret = -EPFNOSUPPORT; + goto exit_kfree; + } + } + + if (!data->use_smbus || + (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) || + i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_WORD_DATA) || + i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { + /* + * NOTE: AN-2079 + * Finisar recommends that the host implement 1 byte writes + * only since this module only supports 32 byte page boundaries. + * 2 byte writes are acceptable for PE and Vout changes per + * Application Note AN-2071. + */ + unsigned write_max = 1; + + if (write_max > io_limit) + write_max = io_limit; + if (data->use_smbus && write_max > I2C_SMBUS_BLOCK_MAX) + write_max = I2C_SMBUS_BLOCK_MAX; + data->write_max = write_max; + + /* buffer (data + address at the beginning) */ + data->writebuf = kmalloc(write_max + 2, GFP_KERNEL); + if (!data->writebuf) { + ret = -ENOMEM; + goto exit_kfree; + } + } else { + dev_warn(&client->dev, + "cannot write due to controller restrictions."); + } + + if (data->use_smbus == I2C_SMBUS_WORD_DATA || + data->use_smbus == I2C_SMBUS_BYTE_DATA) { + dev_notice(&client->dev, "Falling back to %s reads, " + "performance will suffer\n", data->use_smbus == + I2C_SMBUS_WORD_DATA ? "word" : "byte"); + } +#endif + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->port = dev_id->driver_data; + data->client = client; + + if (dev_id->driver_data >= as7312_54x_port1 && dev_id->driver_data <= as7312_54x_port48) { + data->driver_type = DRIVER_TYPE_SFP_MSA; + ret = sfp_msa_probe(client, dev_id, &data->msa); + } + else { /* as7312_54x_portsfp49 ~ as7312_54x_portsfp54 */ + data->driver_type = DRIVER_TYPE_QSFP; + ret = qsfp_probe(client, dev_id, &data->qsfp); + } + + if (ret < 0) { + goto exit_kfree_buf; + } + + + return ret; + +exit_kfree_buf: +#if (MULTIPAGE_SUPPORT == 1) + if (data->writebuf) kfree(data->writebuf); +#endif + +exit_kfree: + kfree(data); + return ret; +} +/* Platform dependent --- */ + +static int sfp_msa_remove(struct i2c_client *client, struct sfp_msa_data *data) +{ + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); +#if (MULTIPAGE_SUPPORT == 1) + i2c_unregister_device(data->ddm_client); +#endif + sysfs_remove_group(&client->dev.kobj, &sfp_msa_group); + kfree(data); + return 0; +} + +static int qfp_remove(struct i2c_client *client, struct qsfp_data *data) +{ + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + sysfs_remove_group(&client->dev.kobj, &qsfp_group); + kfree(data); + return 0; +} + +static int sfp_device_remove(struct i2c_client *client) +{ + int ret = 0; + struct sfp_port_data *data = i2c_get_clientdata(client); + + switch (data->driver_type) { + case DRIVER_TYPE_SFP_MSA: + return sfp_msa_remove(client, data->msa); + case DRIVER_TYPE_QSFP: + return qfp_remove(client, data->qsfp); + } + +#if (MULTIPAGE_SUPPORT == 1) + if (data->writebuf) + kfree(data->writebuf); +#endif + kfree(data); + return ret; +} + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +static struct i2c_driver sfp_driver = { + .driver = { + .name = DRIVER_NAME, + }, + .probe = sfp_device_probe, + .remove = sfp_device_remove, + .id_table = sfp_device_id, + .address_list = normal_i2c, +}; + +static int __init sfp_init(void) +{ + return i2c_add_driver(&sfp_driver); +} + +static void __exit sfp_exit(void) +{ + i2c_del_driver(&sfp_driver); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton as7312_54x_sfp driver"); +MODULE_LICENSE("GPL"); + +module_init(sfp_init); +module_exit(sfp_exit); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_i2c_cpld.c b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_i2c_cpld.c new file mode 100644 index 000000000000..67ecd8e036a9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/accton_i2c_cpld.c @@ -0,0 +1,1219 @@ +/* + * Copyright (C) Brandon Chuang + * + * This module supports the accton cpld that hold the channel select + * mechanism for other i2c slave devices, such as SFP. + * This includes the: + * Accton as7312_54x CPLD1/CPLD2/CPLD3 + * + * Based on: + * pca954x.c from Kumar Gala + * Copyright (C) 2006 + * + * Based on: + * pca954x.c from Ken Harrenstien + * Copyright (C) 2004 Google, Inc. (Ken Harrenstien) + * + * Based on: + * i2c-virtual_cb.c from Brian Kuschak + * and + * pca9540.c from Jean Delvare . + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define I2C_RW_RETRY_COUNT 10 +#define I2C_RW_RETRY_INTERVAL 60 /* ms */ + +static LIST_HEAD(cpld_client_list); +static struct mutex list_lock; + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; + +enum cpld_type { + as7312_54x_cpld1, + as7312_54x_cpld2, + as7312_54x_cpld3 +}; + +struct as7312_54x_cpld_data { + enum cpld_type type; + struct device *hwmon_dev; + struct mutex update_lock; +}; + +static const struct i2c_device_id as7312_54x_cpld_id[] = { + { "as7312_54x_cpld1", as7312_54x_cpld1 }, + { "as7312_54x_cpld2", as7312_54x_cpld2 }, + { "as7312_54x_cpld3", as7312_54x_cpld3 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, as7312_54x_cpld_id); + +#define TRANSCEIVER_PRESENT_ATTR_ID(index) MODULE_PRESENT_##index +#define TRANSCEIVER_TXDISABLE_ATTR_ID(index) MODULE_TXDISABLE_##index +#define TRANSCEIVER_RXLOS_ATTR_ID(index) MODULE_RXLOS_##index +#define TRANSCEIVER_TXFAULT_ATTR_ID(index) MODULE_TXFAULT_##index +#define TRANSCEIVER_RESET_ATTR_ID(index) MODULE_RESET_##index + +enum as7312_54x_cpld1_sysfs_attributes { + CPLD_VERSION, + ACCESS, + MODULE_PRESENT_ALL, + MODULE_RXLOS_ALL, + /* transceiver attributes */ + TRANSCEIVER_PRESENT_ATTR_ID(1), + TRANSCEIVER_PRESENT_ATTR_ID(2), + TRANSCEIVER_PRESENT_ATTR_ID(3), + TRANSCEIVER_PRESENT_ATTR_ID(4), + TRANSCEIVER_PRESENT_ATTR_ID(5), + TRANSCEIVER_PRESENT_ATTR_ID(6), + TRANSCEIVER_PRESENT_ATTR_ID(7), + TRANSCEIVER_PRESENT_ATTR_ID(8), + TRANSCEIVER_PRESENT_ATTR_ID(9), + TRANSCEIVER_PRESENT_ATTR_ID(10), + TRANSCEIVER_PRESENT_ATTR_ID(11), + TRANSCEIVER_PRESENT_ATTR_ID(12), + TRANSCEIVER_PRESENT_ATTR_ID(13), + TRANSCEIVER_PRESENT_ATTR_ID(14), + TRANSCEIVER_PRESENT_ATTR_ID(15), + TRANSCEIVER_PRESENT_ATTR_ID(16), + TRANSCEIVER_PRESENT_ATTR_ID(17), + TRANSCEIVER_PRESENT_ATTR_ID(18), + TRANSCEIVER_PRESENT_ATTR_ID(19), + TRANSCEIVER_PRESENT_ATTR_ID(20), + TRANSCEIVER_PRESENT_ATTR_ID(21), + TRANSCEIVER_PRESENT_ATTR_ID(22), + TRANSCEIVER_PRESENT_ATTR_ID(23), + TRANSCEIVER_PRESENT_ATTR_ID(24), + TRANSCEIVER_PRESENT_ATTR_ID(25), + TRANSCEIVER_PRESENT_ATTR_ID(26), + TRANSCEIVER_PRESENT_ATTR_ID(27), + TRANSCEIVER_PRESENT_ATTR_ID(28), + TRANSCEIVER_PRESENT_ATTR_ID(29), + TRANSCEIVER_PRESENT_ATTR_ID(30), + TRANSCEIVER_PRESENT_ATTR_ID(31), + TRANSCEIVER_PRESENT_ATTR_ID(32), + TRANSCEIVER_PRESENT_ATTR_ID(33), + TRANSCEIVER_PRESENT_ATTR_ID(34), + TRANSCEIVER_PRESENT_ATTR_ID(35), + TRANSCEIVER_PRESENT_ATTR_ID(36), + TRANSCEIVER_PRESENT_ATTR_ID(37), + TRANSCEIVER_PRESENT_ATTR_ID(38), + TRANSCEIVER_PRESENT_ATTR_ID(39), + TRANSCEIVER_PRESENT_ATTR_ID(40), + TRANSCEIVER_PRESENT_ATTR_ID(41), + TRANSCEIVER_PRESENT_ATTR_ID(42), + TRANSCEIVER_PRESENT_ATTR_ID(43), + TRANSCEIVER_PRESENT_ATTR_ID(44), + TRANSCEIVER_PRESENT_ATTR_ID(45), + TRANSCEIVER_PRESENT_ATTR_ID(46), + TRANSCEIVER_PRESENT_ATTR_ID(47), + TRANSCEIVER_PRESENT_ATTR_ID(48), + TRANSCEIVER_PRESENT_ATTR_ID(49), + TRANSCEIVER_PRESENT_ATTR_ID(50), + TRANSCEIVER_PRESENT_ATTR_ID(51), + TRANSCEIVER_PRESENT_ATTR_ID(52), + TRANSCEIVER_PRESENT_ATTR_ID(53), + TRANSCEIVER_PRESENT_ATTR_ID(54), + TRANSCEIVER_RESET_ATTR_ID(49), + TRANSCEIVER_RESET_ATTR_ID(50), + TRANSCEIVER_RESET_ATTR_ID(51), + TRANSCEIVER_RESET_ATTR_ID(52), + TRANSCEIVER_RESET_ATTR_ID(53), + TRANSCEIVER_RESET_ATTR_ID(54), + TRANSCEIVER_TXDISABLE_ATTR_ID(1), + TRANSCEIVER_TXDISABLE_ATTR_ID(2), + TRANSCEIVER_TXDISABLE_ATTR_ID(3), + TRANSCEIVER_TXDISABLE_ATTR_ID(4), + TRANSCEIVER_TXDISABLE_ATTR_ID(5), + TRANSCEIVER_TXDISABLE_ATTR_ID(6), + TRANSCEIVER_TXDISABLE_ATTR_ID(7), + TRANSCEIVER_TXDISABLE_ATTR_ID(8), + TRANSCEIVER_TXDISABLE_ATTR_ID(9), + TRANSCEIVER_TXDISABLE_ATTR_ID(10), + TRANSCEIVER_TXDISABLE_ATTR_ID(11), + TRANSCEIVER_TXDISABLE_ATTR_ID(12), + TRANSCEIVER_TXDISABLE_ATTR_ID(13), + TRANSCEIVER_TXDISABLE_ATTR_ID(14), + TRANSCEIVER_TXDISABLE_ATTR_ID(15), + TRANSCEIVER_TXDISABLE_ATTR_ID(16), + TRANSCEIVER_TXDISABLE_ATTR_ID(17), + TRANSCEIVER_TXDISABLE_ATTR_ID(18), + TRANSCEIVER_TXDISABLE_ATTR_ID(19), + TRANSCEIVER_TXDISABLE_ATTR_ID(20), + TRANSCEIVER_TXDISABLE_ATTR_ID(21), + TRANSCEIVER_TXDISABLE_ATTR_ID(22), + TRANSCEIVER_TXDISABLE_ATTR_ID(23), + TRANSCEIVER_TXDISABLE_ATTR_ID(24), + TRANSCEIVER_TXDISABLE_ATTR_ID(25), + TRANSCEIVER_TXDISABLE_ATTR_ID(26), + TRANSCEIVER_TXDISABLE_ATTR_ID(27), + TRANSCEIVER_TXDISABLE_ATTR_ID(28), + TRANSCEIVER_TXDISABLE_ATTR_ID(29), + TRANSCEIVER_TXDISABLE_ATTR_ID(30), + TRANSCEIVER_TXDISABLE_ATTR_ID(31), + TRANSCEIVER_TXDISABLE_ATTR_ID(32), + TRANSCEIVER_TXDISABLE_ATTR_ID(33), + TRANSCEIVER_TXDISABLE_ATTR_ID(34), + TRANSCEIVER_TXDISABLE_ATTR_ID(35), + TRANSCEIVER_TXDISABLE_ATTR_ID(36), + TRANSCEIVER_TXDISABLE_ATTR_ID(37), + TRANSCEIVER_TXDISABLE_ATTR_ID(38), + TRANSCEIVER_TXDISABLE_ATTR_ID(39), + TRANSCEIVER_TXDISABLE_ATTR_ID(40), + TRANSCEIVER_TXDISABLE_ATTR_ID(41), + TRANSCEIVER_TXDISABLE_ATTR_ID(42), + TRANSCEIVER_TXDISABLE_ATTR_ID(43), + TRANSCEIVER_TXDISABLE_ATTR_ID(44), + TRANSCEIVER_TXDISABLE_ATTR_ID(45), + TRANSCEIVER_TXDISABLE_ATTR_ID(46), + TRANSCEIVER_TXDISABLE_ATTR_ID(47), + TRANSCEIVER_TXDISABLE_ATTR_ID(48), + TRANSCEIVER_RXLOS_ATTR_ID(1), + TRANSCEIVER_RXLOS_ATTR_ID(2), + TRANSCEIVER_RXLOS_ATTR_ID(3), + TRANSCEIVER_RXLOS_ATTR_ID(4), + TRANSCEIVER_RXLOS_ATTR_ID(5), + TRANSCEIVER_RXLOS_ATTR_ID(6), + TRANSCEIVER_RXLOS_ATTR_ID(7), + TRANSCEIVER_RXLOS_ATTR_ID(8), + TRANSCEIVER_RXLOS_ATTR_ID(9), + TRANSCEIVER_RXLOS_ATTR_ID(10), + TRANSCEIVER_RXLOS_ATTR_ID(11), + TRANSCEIVER_RXLOS_ATTR_ID(12), + TRANSCEIVER_RXLOS_ATTR_ID(13), + TRANSCEIVER_RXLOS_ATTR_ID(14), + TRANSCEIVER_RXLOS_ATTR_ID(15), + TRANSCEIVER_RXLOS_ATTR_ID(16), + TRANSCEIVER_RXLOS_ATTR_ID(17), + TRANSCEIVER_RXLOS_ATTR_ID(18), + TRANSCEIVER_RXLOS_ATTR_ID(19), + TRANSCEIVER_RXLOS_ATTR_ID(20), + TRANSCEIVER_RXLOS_ATTR_ID(21), + TRANSCEIVER_RXLOS_ATTR_ID(22), + TRANSCEIVER_RXLOS_ATTR_ID(23), + TRANSCEIVER_RXLOS_ATTR_ID(24), + TRANSCEIVER_RXLOS_ATTR_ID(25), + TRANSCEIVER_RXLOS_ATTR_ID(26), + TRANSCEIVER_RXLOS_ATTR_ID(27), + TRANSCEIVER_RXLOS_ATTR_ID(28), + TRANSCEIVER_RXLOS_ATTR_ID(29), + TRANSCEIVER_RXLOS_ATTR_ID(30), + TRANSCEIVER_RXLOS_ATTR_ID(31), + TRANSCEIVER_RXLOS_ATTR_ID(32), + TRANSCEIVER_RXLOS_ATTR_ID(33), + TRANSCEIVER_RXLOS_ATTR_ID(34), + TRANSCEIVER_RXLOS_ATTR_ID(35), + TRANSCEIVER_RXLOS_ATTR_ID(36), + TRANSCEIVER_RXLOS_ATTR_ID(37), + TRANSCEIVER_RXLOS_ATTR_ID(38), + TRANSCEIVER_RXLOS_ATTR_ID(39), + TRANSCEIVER_RXLOS_ATTR_ID(40), + TRANSCEIVER_RXLOS_ATTR_ID(41), + TRANSCEIVER_RXLOS_ATTR_ID(42), + TRANSCEIVER_RXLOS_ATTR_ID(43), + TRANSCEIVER_RXLOS_ATTR_ID(44), + TRANSCEIVER_RXLOS_ATTR_ID(45), + TRANSCEIVER_RXLOS_ATTR_ID(46), + TRANSCEIVER_RXLOS_ATTR_ID(47), + TRANSCEIVER_RXLOS_ATTR_ID(48), + TRANSCEIVER_TXFAULT_ATTR_ID(1), + TRANSCEIVER_TXFAULT_ATTR_ID(2), + TRANSCEIVER_TXFAULT_ATTR_ID(3), + TRANSCEIVER_TXFAULT_ATTR_ID(4), + TRANSCEIVER_TXFAULT_ATTR_ID(5), + TRANSCEIVER_TXFAULT_ATTR_ID(6), + TRANSCEIVER_TXFAULT_ATTR_ID(7), + TRANSCEIVER_TXFAULT_ATTR_ID(8), + TRANSCEIVER_TXFAULT_ATTR_ID(9), + TRANSCEIVER_TXFAULT_ATTR_ID(10), + TRANSCEIVER_TXFAULT_ATTR_ID(11), + TRANSCEIVER_TXFAULT_ATTR_ID(12), + TRANSCEIVER_TXFAULT_ATTR_ID(13), + TRANSCEIVER_TXFAULT_ATTR_ID(14), + TRANSCEIVER_TXFAULT_ATTR_ID(15), + TRANSCEIVER_TXFAULT_ATTR_ID(16), + TRANSCEIVER_TXFAULT_ATTR_ID(17), + TRANSCEIVER_TXFAULT_ATTR_ID(18), + TRANSCEIVER_TXFAULT_ATTR_ID(19), + TRANSCEIVER_TXFAULT_ATTR_ID(20), + TRANSCEIVER_TXFAULT_ATTR_ID(21), + TRANSCEIVER_TXFAULT_ATTR_ID(22), + TRANSCEIVER_TXFAULT_ATTR_ID(23), + TRANSCEIVER_TXFAULT_ATTR_ID(24), + TRANSCEIVER_TXFAULT_ATTR_ID(25), + TRANSCEIVER_TXFAULT_ATTR_ID(26), + TRANSCEIVER_TXFAULT_ATTR_ID(27), + TRANSCEIVER_TXFAULT_ATTR_ID(28), + TRANSCEIVER_TXFAULT_ATTR_ID(29), + TRANSCEIVER_TXFAULT_ATTR_ID(30), + TRANSCEIVER_TXFAULT_ATTR_ID(31), + TRANSCEIVER_TXFAULT_ATTR_ID(32), + TRANSCEIVER_TXFAULT_ATTR_ID(33), + TRANSCEIVER_TXFAULT_ATTR_ID(34), + TRANSCEIVER_TXFAULT_ATTR_ID(35), + TRANSCEIVER_TXFAULT_ATTR_ID(36), + TRANSCEIVER_TXFAULT_ATTR_ID(37), + TRANSCEIVER_TXFAULT_ATTR_ID(38), + TRANSCEIVER_TXFAULT_ATTR_ID(39), + TRANSCEIVER_TXFAULT_ATTR_ID(40), + TRANSCEIVER_TXFAULT_ATTR_ID(41), + TRANSCEIVER_TXFAULT_ATTR_ID(42), + TRANSCEIVER_TXFAULT_ATTR_ID(43), + TRANSCEIVER_TXFAULT_ATTR_ID(44), + TRANSCEIVER_TXFAULT_ATTR_ID(45), + TRANSCEIVER_TXFAULT_ATTR_ID(46), + TRANSCEIVER_TXFAULT_ATTR_ID(47), + TRANSCEIVER_TXFAULT_ATTR_ID(48), +}; + +/* sysfs attributes for hwmon + */ +static ssize_t show_status(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_present_all(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t set_reset(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t access(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t show_version(struct device *dev, struct device_attribute *da, + char *buf); +static int as7312_54x_cpld_read_internal(struct i2c_client *client, u8 reg); +static int as7312_54x_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value); + +/* transceiver attributes */ +#define DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(index) \ + static SENSOR_DEVICE_ATTR(module_present_##index, S_IRUGO, show_status, NULL, MODULE_PRESENT_##index) +#define DECLARE_TRANSCEIVER_PRESENT_ATTR(index) &sensor_dev_attr_module_present_##index.dev_attr.attr + +#define DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(index) \ + static SENSOR_DEVICE_ATTR(module_reset_##index, S_IRUGO | S_IWUSR, show_status, set_reset, MODULE_RESET_##index) +#define DECLARE_TRANSCEIVER_RESET_ATTR(index) &sensor_dev_attr_module_reset_##index.dev_attr.attr + +#define DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(index) \ + static SENSOR_DEVICE_ATTR(module_tx_disable_##index, S_IRUGO | S_IWUSR, show_status, set_tx_disable, MODULE_TXDISABLE_##index); \ + static SENSOR_DEVICE_ATTR(module_rx_los_##index, S_IRUGO, show_status, NULL, MODULE_RXLOS_##index); \ + static SENSOR_DEVICE_ATTR(module_tx_fault_##index, S_IRUGO, show_status, NULL, MODULE_TXFAULT_##index) +#define DECLARE_SFP_TRANSCEIVER_ATTR(index) \ + &sensor_dev_attr_module_tx_disable_##index.dev_attr.attr, \ + &sensor_dev_attr_module_rx_los_##index.dev_attr.attr, \ + &sensor_dev_attr_module_tx_fault_##index.dev_attr.attr + +static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, CPLD_VERSION); +static SENSOR_DEVICE_ATTR(access, S_IWUSR, NULL, access, ACCESS); +/* transceiver attributes */ +static SENSOR_DEVICE_ATTR(module_present_all, S_IRUGO, show_present_all, NULL, MODULE_PRESENT_ALL); +static SENSOR_DEVICE_ATTR(module_rx_los_all, S_IRUGO, show_rxlos_all, NULL, MODULE_RXLOS_ALL); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(1); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(2); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(3); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(4); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(5); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(6); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(7); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(8); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(9); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(10); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(11); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(12); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(13); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(14); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(15); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(16); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(17); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(18); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(19); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(20); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(21); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(22); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(23); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(24); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(25); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(26); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(27); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(28); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(29); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(30); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(31); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(32); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(33); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(34); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(35); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(36); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(37); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(38); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(39); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(40); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(41); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(42); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(43); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(44); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(45); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(46); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(47); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(48); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(49); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(50); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(51); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(52); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(53); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(54); + +DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(49); +DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(50); +DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(51); +DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(52); +DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(53); +DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(54); + +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(1); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(2); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(3); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(4); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(5); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(6); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(7); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(8); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(9); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(10); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(11); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(12); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(13); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(14); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(15); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(16); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(17); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(18); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(19); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(20); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(21); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(22); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(23); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(24); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(25); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(26); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(27); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(28); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(29); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(30); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(31); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(32); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(33); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(34); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(35); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(36); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(37); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(38); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(39); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(40); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(41); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(42); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(43); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(44); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(45); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(46); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(47); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(48); + +static struct attribute *as7312_54x_cpld1_attributes[] = { + &sensor_dev_attr_version.dev_attr.attr, + &sensor_dev_attr_access.dev_attr.attr, + NULL +}; + +static const struct attribute_group as7312_54x_cpld1_group = { + .attrs = as7312_54x_cpld1_attributes, +}; + +static struct attribute *as7312_54x_cpld2_attributes[] = { + &sensor_dev_attr_version.dev_attr.attr, + &sensor_dev_attr_access.dev_attr.attr, + /* transceiver attributes */ + &sensor_dev_attr_module_present_all.dev_attr.attr, + &sensor_dev_attr_module_rx_los_all.dev_attr.attr, + DECLARE_TRANSCEIVER_PRESENT_ATTR(1), + DECLARE_TRANSCEIVER_PRESENT_ATTR(2), + DECLARE_TRANSCEIVER_PRESENT_ATTR(3), + DECLARE_TRANSCEIVER_PRESENT_ATTR(4), + DECLARE_TRANSCEIVER_PRESENT_ATTR(5), + DECLARE_TRANSCEIVER_PRESENT_ATTR(6), + DECLARE_TRANSCEIVER_PRESENT_ATTR(7), + DECLARE_TRANSCEIVER_PRESENT_ATTR(8), + DECLARE_TRANSCEIVER_PRESENT_ATTR(9), + DECLARE_TRANSCEIVER_PRESENT_ATTR(10), + DECLARE_TRANSCEIVER_PRESENT_ATTR(11), + DECLARE_TRANSCEIVER_PRESENT_ATTR(12), + DECLARE_TRANSCEIVER_PRESENT_ATTR(13), + DECLARE_TRANSCEIVER_PRESENT_ATTR(14), + DECLARE_TRANSCEIVER_PRESENT_ATTR(15), + DECLARE_TRANSCEIVER_PRESENT_ATTR(16), + DECLARE_TRANSCEIVER_PRESENT_ATTR(17), + DECLARE_TRANSCEIVER_PRESENT_ATTR(18), + DECLARE_TRANSCEIVER_PRESENT_ATTR(19), + DECLARE_TRANSCEIVER_PRESENT_ATTR(20), + DECLARE_TRANSCEIVER_PRESENT_ATTR(21), + DECLARE_TRANSCEIVER_PRESENT_ATTR(22), + DECLARE_TRANSCEIVER_PRESENT_ATTR(23), + DECLARE_TRANSCEIVER_PRESENT_ATTR(24), + DECLARE_TRANSCEIVER_PRESENT_ATTR(49), + DECLARE_TRANSCEIVER_PRESENT_ATTR(50), + DECLARE_TRANSCEIVER_PRESENT_ATTR(51), + DECLARE_TRANSCEIVER_PRESENT_ATTR(52), + DECLARE_TRANSCEIVER_RESET_ATTR(49), + DECLARE_TRANSCEIVER_RESET_ATTR(50), + DECLARE_TRANSCEIVER_RESET_ATTR(51), + DECLARE_TRANSCEIVER_RESET_ATTR(52), + DECLARE_SFP_TRANSCEIVER_ATTR(1), + DECLARE_SFP_TRANSCEIVER_ATTR(2), + DECLARE_SFP_TRANSCEIVER_ATTR(3), + DECLARE_SFP_TRANSCEIVER_ATTR(4), + DECLARE_SFP_TRANSCEIVER_ATTR(5), + DECLARE_SFP_TRANSCEIVER_ATTR(6), + DECLARE_SFP_TRANSCEIVER_ATTR(7), + DECLARE_SFP_TRANSCEIVER_ATTR(8), + DECLARE_SFP_TRANSCEIVER_ATTR(9), + DECLARE_SFP_TRANSCEIVER_ATTR(10), + DECLARE_SFP_TRANSCEIVER_ATTR(11), + DECLARE_SFP_TRANSCEIVER_ATTR(12), + DECLARE_SFP_TRANSCEIVER_ATTR(13), + DECLARE_SFP_TRANSCEIVER_ATTR(14), + DECLARE_SFP_TRANSCEIVER_ATTR(15), + DECLARE_SFP_TRANSCEIVER_ATTR(16), + DECLARE_SFP_TRANSCEIVER_ATTR(17), + DECLARE_SFP_TRANSCEIVER_ATTR(18), + DECLARE_SFP_TRANSCEIVER_ATTR(19), + DECLARE_SFP_TRANSCEIVER_ATTR(20), + DECLARE_SFP_TRANSCEIVER_ATTR(21), + DECLARE_SFP_TRANSCEIVER_ATTR(22), + DECLARE_SFP_TRANSCEIVER_ATTR(23), + DECLARE_SFP_TRANSCEIVER_ATTR(24), + NULL +}; + +static const struct attribute_group as7312_54x_cpld2_group = { + .attrs = as7312_54x_cpld2_attributes, +}; + +static struct attribute *as7312_54x_cpld3_attributes[] = { + &sensor_dev_attr_version.dev_attr.attr, + &sensor_dev_attr_access.dev_attr.attr, + /* transceiver attributes */ + &sensor_dev_attr_module_present_all.dev_attr.attr, + &sensor_dev_attr_module_rx_los_all.dev_attr.attr, + DECLARE_TRANSCEIVER_PRESENT_ATTR(25), + DECLARE_TRANSCEIVER_PRESENT_ATTR(26), + DECLARE_TRANSCEIVER_PRESENT_ATTR(27), + DECLARE_TRANSCEIVER_PRESENT_ATTR(28), + DECLARE_TRANSCEIVER_PRESENT_ATTR(29), + DECLARE_TRANSCEIVER_PRESENT_ATTR(30), + DECLARE_TRANSCEIVER_PRESENT_ATTR(31), + DECLARE_TRANSCEIVER_PRESENT_ATTR(32), + DECLARE_TRANSCEIVER_PRESENT_ATTR(33), + DECLARE_TRANSCEIVER_PRESENT_ATTR(34), + DECLARE_TRANSCEIVER_PRESENT_ATTR(35), + DECLARE_TRANSCEIVER_PRESENT_ATTR(36), + DECLARE_TRANSCEIVER_PRESENT_ATTR(37), + DECLARE_TRANSCEIVER_PRESENT_ATTR(38), + DECLARE_TRANSCEIVER_PRESENT_ATTR(39), + DECLARE_TRANSCEIVER_PRESENT_ATTR(40), + DECLARE_TRANSCEIVER_PRESENT_ATTR(41), + DECLARE_TRANSCEIVER_PRESENT_ATTR(42), + DECLARE_TRANSCEIVER_PRESENT_ATTR(43), + DECLARE_TRANSCEIVER_PRESENT_ATTR(44), + DECLARE_TRANSCEIVER_PRESENT_ATTR(45), + DECLARE_TRANSCEIVER_PRESENT_ATTR(46), + DECLARE_TRANSCEIVER_PRESENT_ATTR(47), + DECLARE_TRANSCEIVER_PRESENT_ATTR(48), + DECLARE_TRANSCEIVER_PRESENT_ATTR(53), + DECLARE_TRANSCEIVER_PRESENT_ATTR(54), + DECLARE_TRANSCEIVER_RESET_ATTR(53), + DECLARE_TRANSCEIVER_RESET_ATTR(54), + DECLARE_SFP_TRANSCEIVER_ATTR(25), + DECLARE_SFP_TRANSCEIVER_ATTR(26), + DECLARE_SFP_TRANSCEIVER_ATTR(27), + DECLARE_SFP_TRANSCEIVER_ATTR(28), + DECLARE_SFP_TRANSCEIVER_ATTR(29), + DECLARE_SFP_TRANSCEIVER_ATTR(30), + DECLARE_SFP_TRANSCEIVER_ATTR(31), + DECLARE_SFP_TRANSCEIVER_ATTR(32), + DECLARE_SFP_TRANSCEIVER_ATTR(33), + DECLARE_SFP_TRANSCEIVER_ATTR(34), + DECLARE_SFP_TRANSCEIVER_ATTR(35), + DECLARE_SFP_TRANSCEIVER_ATTR(36), + DECLARE_SFP_TRANSCEIVER_ATTR(37), + DECLARE_SFP_TRANSCEIVER_ATTR(38), + DECLARE_SFP_TRANSCEIVER_ATTR(39), + DECLARE_SFP_TRANSCEIVER_ATTR(40), + DECLARE_SFP_TRANSCEIVER_ATTR(41), + DECLARE_SFP_TRANSCEIVER_ATTR(42), + DECLARE_SFP_TRANSCEIVER_ATTR(43), + DECLARE_SFP_TRANSCEIVER_ATTR(44), + DECLARE_SFP_TRANSCEIVER_ATTR(45), + DECLARE_SFP_TRANSCEIVER_ATTR(46), + DECLARE_SFP_TRANSCEIVER_ATTR(47), + DECLARE_SFP_TRANSCEIVER_ATTR(48), + NULL +}; + +static const struct attribute_group as7312_54x_cpld3_group = { + .attrs = as7312_54x_cpld3_attributes, +}; + +static ssize_t show_present_all(struct device *dev, struct device_attribute *da, + char *buf) +{ + int i, status; + u8 values[4] = {0}; + u8 regs[] = {0x9, 0xA, 0xB, 0x18}; + struct i2c_client *client = to_i2c_client(dev); + struct as7312_54x_cpld_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + for (i = 0; i < ARRAY_SIZE(regs); i++) { + status = as7312_54x_cpld_read_internal(client, regs[i]); + + if (status < 0) { + goto exit; + } + + values[i] = ~(u8)status; + } + + mutex_unlock(&data->update_lock); + + /* Return values 1 -> 54 in order */ + if (data->type == as7312_54x_cpld2) { + values[3] &= 0xF; + } + else { /* as7312_54x_cpld3 */ + values[3] &= 0x3; + } + + return sprintf(buf, "%.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], values[3]); + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da, + char *buf) +{ + int i, status; + u8 values[3] = {0}; + u8 regs[] = {0x12, 0x13, 0x14}; + struct i2c_client *client = to_i2c_client(dev); + struct as7312_54x_cpld_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + for (i = 0; i < ARRAY_SIZE(regs); i++) { + status = as7312_54x_cpld_read_internal(client, regs[i]); + + if (status < 0) { + goto exit; + } + + values[i] = (u8)status; + } + + mutex_unlock(&data->update_lock); + + /* Return values 1 -> 24 in order */ + return sprintf(buf, "%.2x %.2x %.2x\n", values[0], values[1], values[2]); + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t show_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as7312_54x_cpld_data *data = i2c_get_clientdata(client); + int status = 0; + u8 reg = 0, mask = 0, revert = 0; + + switch (attr->index) { + case MODULE_PRESENT_1 ... MODULE_PRESENT_8: + reg = 0x9; + mask = 0x1 << (attr->index - MODULE_PRESENT_1); + break; + case MODULE_PRESENT_9 ... MODULE_PRESENT_16: + reg = 0xA; + mask = 0x1 << (attr->index - MODULE_PRESENT_9); + break; + case MODULE_PRESENT_17 ... MODULE_PRESENT_24: + reg = 0xB; + mask = 0x1 << (attr->index - MODULE_PRESENT_17); + break; + case MODULE_PRESENT_25 ... MODULE_PRESENT_32: + reg = 0x9; + mask = 0x1 << (attr->index - MODULE_PRESENT_25); + break; + case MODULE_PRESENT_33 ... MODULE_PRESENT_40: + reg = 0xA; + mask = 0x1 << (attr->index - MODULE_PRESENT_33); + break; + case MODULE_PRESENT_41 ... MODULE_PRESENT_48: + reg = 0xB; + mask = 0x1 << (attr->index - MODULE_PRESENT_41); + break; + case MODULE_PRESENT_49: + reg = 0x18; + mask = 0x1; + break; + case MODULE_PRESENT_50: + reg = 0x18; + mask = 0x2; + break; + case MODULE_PRESENT_51: + reg = 0x18; + mask = 0x4; + break; + case MODULE_PRESENT_52: + reg = 0x18; + mask = 0x8; + break; + case MODULE_PRESENT_53: + reg = 0x18; + mask = 0x1; + break; + case MODULE_PRESENT_54: + reg = 0x18; + mask = 0x2; + break; + + case MODULE_RESET_49 ... MODULE_RESET_54: + reg = 0x17; + mask = 1 << ((attr->index - MODULE_PRESENT_49)%4); + break; + + case MODULE_TXFAULT_1 ... MODULE_TXFAULT_8: + reg = 0xC; + mask = 0x1 << (attr->index - MODULE_TXFAULT_1); + break; + case MODULE_TXFAULT_9 ... MODULE_TXFAULT_16: + reg = 0xD; + mask = 0x1 << (attr->index - MODULE_TXFAULT_9); + break; + case MODULE_TXFAULT_17 ... MODULE_TXFAULT_24: + reg = 0xE; + mask = 0x1 << (attr->index - MODULE_TXFAULT_17); + break; + case MODULE_TXFAULT_25 ... MODULE_TXFAULT_32: + reg = 0xC; + mask = 0x1 << (attr->index - MODULE_TXFAULT_25); + break; + case MODULE_TXFAULT_33 ... MODULE_TXFAULT_40: + reg = 0xD; + mask = 0x1 << (attr->index - MODULE_TXFAULT_33); + break; + case MODULE_TXFAULT_41 ... MODULE_TXFAULT_48: + reg = 0xE; + mask = 0x1 << (attr->index - MODULE_TXFAULT_41); + break; + case MODULE_TXDISABLE_1 ... MODULE_TXDISABLE_8: + reg = 0xF; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_1); + break; + case MODULE_TXDISABLE_9 ... MODULE_TXDISABLE_16: + reg = 0x10; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_9); + break; + case MODULE_TXDISABLE_17 ... MODULE_TXDISABLE_24: + reg = 0x11; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_17); + break; + case MODULE_TXDISABLE_25 ... MODULE_TXDISABLE_32: + reg = 0xF; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_25); + break; + case MODULE_TXDISABLE_33 ... MODULE_TXDISABLE_40: + reg = 0x10; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_33); + break; + case MODULE_TXDISABLE_41 ... MODULE_TXDISABLE_48: + reg = 0x11; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_41); + break; + case MODULE_RXLOS_1 ... MODULE_RXLOS_8: + reg = 0x12; + mask = 0x1 << (attr->index - MODULE_RXLOS_1); + break; + case MODULE_RXLOS_9 ... MODULE_RXLOS_16: + reg = 0x13; + mask = 0x1 << (attr->index - MODULE_RXLOS_9); + break; + case MODULE_RXLOS_17 ... MODULE_RXLOS_24: + reg = 0x14; + mask = 0x1 << (attr->index - MODULE_RXLOS_17); + break; + case MODULE_RXLOS_25 ... MODULE_RXLOS_32: + reg = 0x12; + mask = 0x1 << (attr->index - MODULE_RXLOS_25); + break; + case MODULE_RXLOS_33 ... MODULE_RXLOS_40: + reg = 0x13; + mask = 0x1 << (attr->index - MODULE_RXLOS_33); + break; + case MODULE_RXLOS_41 ... MODULE_RXLOS_48: + reg = 0x14; + mask = 0x1 << (attr->index - MODULE_RXLOS_41); + break; + default: + return 0; + } + + if (attr->index >= MODULE_PRESENT_1 && attr->index <= MODULE_PRESENT_54) { + revert = 1; + } + + mutex_lock(&data->update_lock); + status = as7312_54x_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", revert ? !(status & mask) : !!(status & mask)); + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t set_reset(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as7312_54x_cpld_data *data = i2c_get_clientdata(client); + long reset; + int status; + u8 reg = 0, mask = 0; + + status = kstrtol(buf, 10, &reset); + if (status) { + return status; + } + + switch (attr->index) { + case MODULE_RESET_49 ... MODULE_RESET_54: + reg = 0x17; + mask = 1 << ((attr->index - MODULE_RESET_49)%4); + break; + default: + return 0; + } + + /* Read current status */ + mutex_lock(&data->update_lock); + status = as7312_54x_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + + /* Update reset status */ + if (reset) { + status |= mask; + } + else { + status &= ~mask; + } + status = as7312_54x_cpld_write_internal(client, reg, status); + if (unlikely(status < 0)) { + goto exit; + } + + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + + + + +static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as7312_54x_cpld_data *data = i2c_get_clientdata(client); + long disable; + int status; + u8 reg = 0, mask = 0; + + status = kstrtol(buf, 10, &disable); + if (status) { + return status; + } + + switch (attr->index) { + case MODULE_TXDISABLE_1 ... MODULE_TXDISABLE_8: + reg = 0xF; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_1); + break; + case MODULE_TXDISABLE_9 ... MODULE_TXDISABLE_16: + reg = 0x10; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_9); + break; + case MODULE_TXDISABLE_17 ... MODULE_TXDISABLE_24: + reg = 0x11; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_17); + break; + case MODULE_TXDISABLE_25 ... MODULE_TXDISABLE_32: + reg = 0xF; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_25); + break; + case MODULE_TXDISABLE_33 ... MODULE_TXDISABLE_40: + reg = 0x10; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_33); + break; + case MODULE_TXDISABLE_41 ... MODULE_TXDISABLE_48: + reg = 0x11; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_41); + break; + default: + return 0; + } + + /* Read current status */ + mutex_lock(&data->update_lock); + status = as7312_54x_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + + /* Update tx_disable status */ + if (disable) { + status |= mask; + } + else { + status &= ~mask; + } + + status = as7312_54x_cpld_write_internal(client, reg, status); + if (unlikely(status < 0)) { + goto exit; + } + + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t access(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int status; + u32 addr, val; + struct i2c_client *client = to_i2c_client(dev); + struct as7312_54x_cpld_data *data = i2c_get_clientdata(client); + + if (sscanf(buf, "0x%x 0x%x", &addr, &val) != 2) { + return -EINVAL; + } + + if (addr > 0xFF || val > 0xFF) { + return -EINVAL; + } + + mutex_lock(&data->update_lock); + status = as7312_54x_cpld_write_internal(client, addr, val); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static void as7312_54x_cpld_add_client(struct i2c_client *client) +{ + struct cpld_client_node *node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", client->addr); + return; + } + + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &cpld_client_list); + mutex_unlock(&list_lock); +} + +static void as7312_54x_cpld_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client == client) { + found = 1; + break; + } + } + + if (found) { + list_del(list_node); + kfree(cpld_node); + } + + mutex_unlock(&list_lock); +} + +static ssize_t show_version(struct device *dev, struct device_attribute *attr, char *buf) +{ + int val = 0; + struct i2c_client *client = to_i2c_client(dev); + + val = i2c_smbus_read_byte_data(client, 0x1); + + if (val < 0) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x1) err %d\n", client->addr, val); + } + + return sprintf(buf, "%d", val); +} + +/* + * I2C init/probing/exit functions + */ +static int as7312_54x_cpld_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); + struct as7312_54x_cpld_data *data; + int ret = -ENODEV; + const struct attribute_group *group = NULL; + + if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE)) + goto exit; + + data = kzalloc(sizeof(struct as7312_54x_cpld_data), GFP_KERNEL); + if (!data) { + ret = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->type = id->driver_data; + + /* Register sysfs hooks */ + switch (data->type) { + case as7312_54x_cpld1: + group = &as7312_54x_cpld1_group; + break; + case as7312_54x_cpld2: + group = &as7312_54x_cpld2_group; + break; + case as7312_54x_cpld3: + group = &as7312_54x_cpld3_group; + break; + default: + break; + } + + if (group) { + ret = sysfs_create_group(&client->dev.kobj, group); + if (ret) { + goto exit_free; + } + } + + as7312_54x_cpld_add_client(client); + return 0; + +exit_free: + kfree(data); +exit: + return ret; +} + +static int as7312_54x_cpld_remove(struct i2c_client *client) +{ + struct as7312_54x_cpld_data *data = i2c_get_clientdata(client); + const struct attribute_group *group = NULL; + + as7312_54x_cpld_remove_client(client); + + /* Remove sysfs hooks */ + switch (data->type) { + case as7312_54x_cpld1: + group = &as7312_54x_cpld1_group; + break; + case as7312_54x_cpld2: + group = &as7312_54x_cpld2_group; + break; + case as7312_54x_cpld3: + group = &as7312_54x_cpld3_group; + break; + default: + break; + } + + if (group) { + sysfs_remove_group(&client->dev.kobj, group); + } + + kfree(data); + + return 0; +} + +static int as7312_54x_cpld_read_internal(struct i2c_client *client, u8 reg) +{ + int status = 0, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_read_byte_data(client, reg); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + return status; +} + +static int as7312_54x_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value) +{ + int status = 0, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_write_byte_data(client, reg, value); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + return status; +} + +int as7312_54x_cpld_read(unsigned short cpld_addr, u8 reg) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EPERM; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = as7312_54x_cpld_read_internal(cpld_node->client, reg); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(as7312_54x_cpld_read); + +int as7312_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EIO; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = as7312_54x_cpld_write_internal(cpld_node->client, reg, value); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(as7312_54x_cpld_write); + +static struct i2c_driver as7312_54x_cpld_driver = { + .driver = { + .name = "as7312_54x_cpld", + .owner = THIS_MODULE, + }, + .probe = as7312_54x_cpld_probe, + .remove = as7312_54x_cpld_remove, + .id_table = as7312_54x_cpld_id, +}; + +static int __init as7312_54x_cpld_init(void) +{ + mutex_init(&list_lock); + return i2c_add_driver(&as7312_54x_cpld_driver); +} + +static void __exit as7312_54x_cpld_exit(void) +{ + i2c_del_driver(&as7312_54x_cpld_driver); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("Accton I2C CPLD driver"); +MODULE_LICENSE("GPL"); + +module_init(as7312_54x_cpld_init); +module_exit(as7312_54x_cpld_exit); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/ym2651y.c b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/ym2651y.c new file mode 120000 index 000000000000..f4d67640ccc3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/modules/ym2651y.c @@ -0,0 +1 @@ +../../common/modules/ym2651y.c \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/service/as7312-platform-monitor.service b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/service/as7312-platform-monitor.service new file mode 100755 index 000000000000..b79357665bed --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/service/as7312-platform-monitor.service @@ -0,0 +1,17 @@ +[Unit] +Description=Accton AS7312-54X Platform Monitoring service +Before=pmon.service +After=sysinit.target +DefaultDependencies=no + +[Service] +ExecStartPre=/usr/local/bin/accton_as7312_util.py install +ExecStart=/usr/local/bin/accton_as7312_monitor.py +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/setup.py b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/setup.py new file mode 100755 index 000000000000..f0518d07689d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/setup.py @@ -0,0 +1,16 @@ +#!/usr/bin/env pytho + +import os +import sys +from setuptools import setup +os.listdir + +setup( + name='as7312_54x', + version='1.0', + description='Module to initialize Accton AS7312-54X platforms', + + packages=['as7312_54x'], + package_dir={'as7312_54x': 'as7312-54x/classes'}, +) + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/README b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/README new file mode 100755 index 000000000000..66f31a030423 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/README @@ -0,0 +1,117 @@ +Copyright (C) 2016 Accton Networks, 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 3 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, see . + +Contents of this package: + patch - files under patch/ is for kernel and ONIE installer + for the kernel: + config-accton-as7312_54x.patch + for kernel configuration. + driver-i2c-muxes-pca954x-always-deselect.patch + for i2c_mux deselects after transaction. + driver-patches-for-accton-as7312-fan-psu-cpld.patch + for as7312's fan/psu/cpld/led/sfp drivers. + for ONIE: + onie_installer-accton-AS7312-54X.patch + for console port setting and copy util script o rootfs. + module - Contains source code of as7312 kernel driver modules. + +The late Sonic building scripts, pushed @Dec 5 2016, will automatically +create a docker container and run building process under it. +User is not necessary to handle docker environment creation. + +1. Download sonic-buildimage environment. + - Run "git clone https://github.com/Azure/sonic-buildimage". + - cd to sonic-buildimage and run "git submodule update --init --recursive". +2. Build kernel + - cd ./src/sonic-linux-kernel + - Copy patches and series from patch/kernel of this release to + sonic-linux-kernel/patch. + - Build kernel by "make". + - The built kernel package, linux-image-3.16.0-5-amd64_3.16.51-3+deb8u1_amd64.deb + , is generated. +3. Build installer + - Change directory back to sonic-buildimage/. + - Get onie_installer-accton-AS7312-54X.patch" from patch/installer. + - Change setting for AS7312-54X by patching build_image.sh. + "patch -p1 < onie_installer-accton-AS7312-54X.patch" + !!NOTICE, patching onie_installer-accton-AS7312-54X.patch comments out the + "git status" checking at build_image.sh. + - The account and password of installed OS can be given at rules/config. + The default user and password are "admin" & "YourPaSsWoRd" respectively. + - Run "make configure PLATFORM=broadcom" + - Copy the built kernel debian package to target/debs/. + The file is linux-image-3.16.0-5-amd64_*_amd64.deb under directory + src/sonic-linux-kernel/. + - Run "make target/sonic-generic.bin" + - Get the installer, target/sonic-generic.bin, to target machine and install. + +All Linux kernel code is licensed under the GPLv1. All other code is +licensed under the GPLv3. Please see the LICENSE file for copies of +both licenses. + +The code for integacting with Accton AS7312-54X has 2 parts, +kernel drivers and operational script. +The kernel drivers of peripherals are under module/ directory. +1. These drivers are patched into kernel by + driver-patches-for-accton-as7312-fan-psu-cpld.patch + Or you can build the driver under module/ by setting environment variable, + KERNEL_SRC, to proper linux built directory and run make. + It may be sonic-linux-kernel/linux-3.*/debian/build/build_amd64_none_amd64/. +2. A operational script, accton_as7312_util.py, for device initializatian and + peripheral accessing should be installed at /usr/bin. + This script is generated by onie_installer-accton-AS7312-54X.patch. + It's done by patching onie_installer-accton-AS7312-54X.patch at build-image. + Run "accton_as7312_util.py install" to install drivers. + +To initialize the system, run "accton_as7312_util.py install". +To clean up the drivers & devices, run "accton_as7312_util.py clean". +To dump information of sensors, run "accton_as7312_util.py show". +To dump SFP EEPROM, run "accton_as7312_util.py sff". +To set fan speed, run "accton_as7312_util.py set fan". +To enable/disable SFP emission, run "accton_as7312_util.py set sfp". +To set system LEDs' color, run "accton_as7312_util.py set led" +For more information, run "accton_as7312_util.py --help". + +==================================================================== +Besides applying accton_as7312_util.py to access peripherals, you can +access peripherals by sysfs nodes directly after the installation is run. + +System LED: + There are 5 system LEDs at the lower-left corner of front panel. + They are loc, diag, fan, ps1, and ps2. + The sysfs interface color mappings are as follows: + Brightness: + 0 => off + 1 => green + 2 => amber + 3 => red + 4 => blue + But not all colors are available for each LED. + +Fan Control: + There are 10 fans inside 5 fan modules. + All fans share 1 duty setting, ranged from 0~100. + +Thermal sensers: + 3 temperature sensors are controlled by the lm75 kernel modules. + +PSUs: + There 2 power supplies slot at the left/right side of the back. + Once if a PSU is not plugged, the status of it is shown failed. + +There are 48 SFP+ and 6 QSFP modules are equipped. +Before operating on PSU and QSFP+, please make sure it is well plugged. +Otherwise, operation is going to fail. + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/accton_as7312_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/accton_as7312_monitor.py new file mode 100755 index 000000000000..bdab0d4b8bff --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/accton_as7312_monitor.py @@ -0,0 +1,208 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 Accton Technology Corporation +# +# 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 3 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, see . + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 11/13/2017: Polly Hsu, Create +# 1/10/2018: Jostar modify for as7716_32 +# 2/27/2018: Roy Lee modify for as7312_54x +# ------------------------------------------------------------------ + +try: + import os + import sys, getopt + import subprocess + import click + import imp + import logging + import logging.config + import types + import time # this is only being used as part of the example + import traceback + from tabulate import tabulate + from as7312_54x.fanutil import FanUtil + from as7312_54x.thermalutil import ThermalUtil +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + +# Deafults +VERSION = '1.0' +FUNCTION_NAME = 'accton_as7312_monitor' + +global log_file +global log_level + +# (LM75_1+ LM75_2+ LM75_3) is LM75 at i2c addresses 0x48, 0x49, and 0x4A. +# TMP = (LM75_1+ LM75_2+ LM75_3)/3 +#1. If TMP < 35, All fans run with duty 31.25%. +#2. If TMP>=35 or the temperature of any one of fan is higher than 40, +# All fans run with duty 50% +#3. If TMP >= 40 or the temperature of any one of fan is higher than 45, +# All fans run with duty 62.5%. +#4. If TMP >= 45 or the temperature of any one of fan is higher than 50, +# All fans run with duty 100%. +#5. Any one of 6 fans is fault, set duty = 100%. +#6. Direction factor. If it is B2F direction, duty + 12%. + + # MISC: + # 1.Check single LM75 before applied average. + # 2.If no matched fan speed is found from the policy, + # use FAN_DUTY_CYCLE_MIN as default speed + # Get current temperature + # 4.Decision 3: Decide new fan speed depend on fan direction/current fan speed/temperature + + + + +# Make a class we can use to capture stdout and sterr in the log +class accton_as7312_monitor(object): + # static temp var + _ori_temp = 0 + _new_perc = 0 + _ori_perc = 0 + + def __init__(self, log_file, log_level): + """Needs a logger and a logger level.""" + # set up logging to file + logging.basicConfig( + filename=log_file, + filemode='w', + level=log_level, + format= '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s', + datefmt='%H:%M:%S' + ) + + # set up logging to console + if log_level == logging.DEBUG: + console = logging.StreamHandler() + console.setLevel(log_level) + formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') + console.setFormatter(formatter) + logging.getLogger('').addHandler(console) + + logging.debug('SET. logfile:%s / loglevel:%d', log_file, log_level) + + def manage_fans(self): + max_duty = 100 + fan_policy_f2b = { + 0: [32, 0, 105000], + 1: [50, 105000, 120000], + 2: [63, 120000, 135000], + 3: [max_duty, 135000, sys.maxsize], + } + fan_policy_b2f = { + 0: [44, 0, 105000], + 1: [63, 105000, 120000], + 2: [75, 120000, 135000], + 3: [max_duty, 135000, sys.maxsize], + } + fan_policy_single = { + 0: 40000, + 1: 45000, + 2: 50000, + } + + thermal = ThermalUtil() + fan = FanUtil() + for x in range(fan.get_idx_fan_start(), fan.get_num_fans()+1): + fan_status = fan.get_fan_status(x) + if fan_status is None: + logging.debug('INFO. SET new_perc to %d (FAN stauts is None. fan_num:%d)', max_duty, x) + return False + if fan_status is False: + logging.debug('INFO. SET new_perc to %d (FAN fault. fan_num:%d)', max_duty, x) + fan.set_fan_duty_cycle(max_duty) + return True + #logging.debug('INFO. fan_status is True (fan_num:%d)', x) + + fan_dir=fan.get_fan_dir(1) + if fan_dir == 1: + fan_policy = fan_policy_f2b + else: + fan_policy = fan_policy_b2f + + #Decide fan duty by if any of sensors > fan_policy_single. + new_duty_cycle = fan_policy[0][0] + for x in range(thermal.get_idx_thermal_start(), thermal.get_num_thermals()+1): + single_thm = thermal._get_thermal_node_val(x) + for y in range(0, len(fan_policy_single)): + if single_thm > fan_policy_single[y]: + if fan_policy[y+1][0] > new_duty_cycle: + new_duty_cycle = fan_policy[y+1][0] + logging.debug('INFO. Single thermal sensor %d with temp %d > %d , new_duty_cycle=%d', + x, single_thm, fan_policy_single[y], new_duty_cycle) + single_result = new_duty_cycle + + + #Find if current duty matched any of define duty. + #If not, set it to highest one. + cur_duty_cycle = fan.get_fan_duty_cycle() + for x in range(0, len(fan_policy)): + if cur_duty_cycle == fan_policy[x][0]: + break + if x == len(fan_policy) : + fan.set_fan_duty_cycle(fan_policy[0][0]) + cur_duty_cycle = max_duty + + #Decide fan duty by if sum of sensors falls into any of fan_policy{} + get_temp = thermal.get_thermal_temp() + new_duty_cycle = cur_duty_cycle + for x in range(0, len(fan_policy)): + y = len(fan_policy) - x -1 #checked from highest + if get_temp > fan_policy[y][1] and get_temp < fan_policy[y][2] : + new_duty_cycle= fan_policy[y][0] + logging.debug('INFO. Sum of temp %d > %d , new_duty_cycle=%d', get_temp, fan_policy[y][1], new_duty_cycle) + + sum_result = new_duty_cycle + if (sum_result>single_result): + new_duty_cycle = sum_result; + else: + new_duty_cycle = single_result + + logging.debug('INFO. Final duty_cycle=%d', new_duty_cycle) + if(new_duty_cycle != cur_duty_cycle): + fan.set_fan_duty_cycle(new_duty_cycle) + return True + +def main(argv): + log_file = '%s.log' % FUNCTION_NAME + log_level = logging.INFO + if len(sys.argv) != 1: + try: + opts, args = getopt.getopt(argv,'hdl:',['lfile=']) + except getopt.GetoptError: + print 'Usage: %s [-d] [-l ]' % sys.argv[0] + return 0 + for opt, arg in opts: + if opt == '-h': + print 'Usage: %s [-d] [-l ]' % sys.argv[0] + return 0 + elif opt in ('-d', '--debug'): + log_level = logging.DEBUG + elif opt in ('-l', '--lfile'): + log_file = arg + + monitor = accton_as7312_monitor(log_file, log_level) + + # Loop forever, doing something useful hopefully: + while True: + monitor.manage_fans() + time.sleep(10) + +if __name__ == '__main__': + main(sys.argv[1:]) diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/accton_as7312_util.py b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/accton_as7312_util.py new file mode 100755 index 000000000000..b8107c47afea --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/accton_as7312_util.py @@ -0,0 +1,588 @@ +#!/usr/bin/env python +# +# Copyright (C) 2016 Accton Networks, 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 3 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, see . + +""" +Usage: %(scriptName)s [options] command object + +options: + -h | --help : this help message + -d | --debug : run with debug mode + -f | --force : ignore error during installation or clean +command: + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes + show : show all systen status + sff : dump SFP eeprom + set : change board setting with fan|led|sfp +""" + +import os +import commands +import sys, getopt +import logging +import re +import time +from collections import namedtuple + + + + +PROJECT_NAME = 'as7312_54x' +version = '0.1.0' +verbose = False +DEBUG = False +args = [] +ALL_DEVICE = {} +DEVICE_NO = {'led':5, 'fan':6,'thermal':4, 'psu':2, 'sfp':54} +FORCE = 0 +#logging.basicConfig(filename= PROJECT_NAME+'.log', filemode='w',level=logging.DEBUG) +#logging.basicConfig(level=logging.INFO) + + +if DEBUG == True: + print sys.argv[0] + print 'ARGV :', sys.argv[1:] + + +def main(): + global DEBUG + global args + global FORCE + + if len(sys.argv)<2: + show_help() + + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', + 'debug', + 'force', + ]) + if DEBUG == True: + print options + print args + print len(sys.argv) + + for opt, arg in options: + if opt in ('-h', '--help'): + show_help() + elif opt in ('-d', '--debug'): + DEBUG = True + logging.basicConfig(level=logging.INFO) + elif opt in ('-f', '--force'): + FORCE = 1 + else: + logging.info('no option') + for arg in args: + if arg == 'install': + do_install() + elif arg == 'clean': + do_uninstall() + elif arg == 'show': + device_traversal() + elif arg == 'sff': + if len(args)!=2: + show_eeprom_help() + elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']: + show_eeprom_help() + else: + show_eeprom(args[1]) + return + elif arg == 'set': + if len(args)<3: + show_set_help() + else: + set_device(args[1:]) + return + else: + show_help() + + + return 0 + +def show_help(): + print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + sys.exit(0) + +def show_set_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print cmd +" [led|sfp|fan]" + print " use \""+ cmd + " led 0-4 \" to set led color" + print " use \""+ cmd + " fan 0-100\" to set fan duty percetage" + print " use \""+ cmd + " sfp 1-54 {0|1}\" to set sfp# tx_disable" + sys.exit(0) + +def show_eeprom_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print " use \""+ cmd + " 1-54 \" to dump sfp# eeprom" + sys.exit(0) + +def my_log(txt): + if DEBUG == True: + print "[ROY]"+txt + return + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) + my_log (cmd +"with result:" + str(status)) + my_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + +def driver_check(): + ret, lsmod = log_os_system("lsmod| grep accton", 0) + logging.info('mods:'+lsmod) + if len(lsmod) ==0: + return False + return True + + + +kos = [ +'modprobe i2c_dev', +'modprobe i2c_mux_pca954x force_deselect_on_exit=1', +'modprobe accton_i2c_cpld' , +'modprobe ym2651y' , +'modprobe accton_as7312_54x_fan' , +'modprobe optoe' , +'modprobe accton_as7312_54x_leds' , +'modprobe accton_as7312_54x_psu' ] + +def driver_install(): + global FORCE + status, output = log_os_system("depmod", 1) + for i in range(0,len(kos)): + status, output = log_os_system(kos[i], 1) + if status: + if FORCE == 0: + return status + return 0 + +def driver_uninstall(): + global FORCE + for i in range(0,len(kos)): + rm = kos[-(i+1)].replace("modprobe", "modprobe -rq") + rm = rm.replace("insmod", "rmmod") + lst = rm.split(" ") + if len(lst) > 3: + del(lst[3]) + rm = " ".join(lst) + status, output = log_os_system(rm, 1) + if status: + if FORCE == 0: + return status + return 0 + +led_prefix ='/sys/class/leds/accton_'+PROJECT_NAME+'_led::' +hwmon_types = {'led': ['diag','fan','loc','psu1','psu2']} +hwmon_nodes = {'led': ['brightness'] } +hwmon_prefix ={'led': led_prefix} + +i2c_prefix = '/sys/bus/i2c/devices/' +i2c_bus = {'fan': ['2-0066'] , + 'thermal': ['3-0048','3-0049', '3-004a', '3-004b'] , + 'psu': ['10-0051','11-0053'], + 'sfp': ['-0050']} +i2c_nodes = {'fan': ['present', 'front_speed_rpm', 'rear_speed_rpm'] , + 'thermal': ['hwmon/hwmon*/temp1_input'] , + 'psu': ['psu_present ', 'psu_power_good'] , + 'sfp': ['sfp_is_present', 'sfp_tx_disable']} + +sfp_map = [18,19,20,21,22,23,24,25,26,27, + 28,29,30,31,32,33,34,35,36,37, + 38,39,40,41,42,43,44,45,46,47, + 48,49,50,51,52,53,54,55,56,57, + 58,59,60,61,62,63,64,65,66,67, + 68,69,70,71] + +qsfp_start = 48 + +mknod =[ +'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-0/new_device' , +'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-1/new_device' , +'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-1/new_device' , +'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo pca9548 0x75 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-1/new_device', + +'echo as7312_54x_fan 0x66 > /sys/bus/i2c/devices/i2c-2/new_device ', +'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-3/new_device', +'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-3/new_device', +'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-3/new_device', +'echo lm75 0x4b > /sys/bus/i2c/devices/i2c-3/new_device', +'echo as7312_54x_psu1 0x53 > /sys/bus/i2c/devices/i2c-11/new_device', +'echo ym2651 0x5b > /sys/bus/i2c/devices/i2c-11/new_device', +'echo as7312_54x_psu2 0x50 > /sys/bus/i2c/devices/i2c-10/new_device', +'echo ym2651 0x58 > /sys/bus/i2c/devices/i2c-10/new_device', +'echo as7312_54x_cpld1 0x60 > /sys/bus/i2c/devices/i2c-4/new_device', +'echo as7312_54x_cpld2 0x62 > /sys/bus/i2c/devices/i2c-5/new_device', +'echo as7312_54x_cpld3 0x64 > /sys/bus/i2c/devices/i2c-6/new_device'] + +mknod2 =[ +'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-1/new_device' , +'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-0/new_device' , +'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-0/new_device' , +'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo pca9548 0x75 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-0/new_device', + +'echo as7312_54x_fan 0x66 > /sys/bus/i2c/devices/i2c-2/new_device ', +'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-3/new_device', +'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-3/new_device', +'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-3/new_device', +'echo lm75 0x4b > /sys/bus/i2c/devices/i2c-3/new_device', +'echo as7312_54x_psu1 0x53 > /sys/bus/i2c/devices/i2c-11/new_device', +'echo ym2651 0x5b > /sys/bus/i2c/devices/i2c-11/new_device', +'echo as7312_54x_psu2 0x50 > /sys/bus/i2c/devices/i2c-10/new_device', +'echo ym2651 0x58 > /sys/bus/i2c/devices/i2c-10/new_device', +'echo as7312_54x_cpld1 0x60 > /sys/bus/i2c/devices/i2c-4/new_device', +'echo as7312_54x_cpld2 0x62 > /sys/bus/i2c/devices/i2c-5/new_device', +'echo as7312_54x_cpld3 0x64 > /sys/bus/i2c/devices/i2c-6/new_device'] + + + +def i2c_order_check(): + # i2c bus 0 and 1 might be installed in different order. + # Here check if 0x70 is exist @ i2c-1 + tmp = "echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-1/new_device" + status, output = log_os_system(tmp, 0) + if not device_exist(): + order = 1 + else: + order = 0 + tmp = "echo 0x70 > /sys/bus/i2c/devices/i2c-1/delete_device" + status, output = log_os_system(tmp, 0) + return order + +def device_install(): + global FORCE + + order = i2c_order_check() + + # if 0x70 is not exist @i2c-1, use reversed bus order + if order: + for i in range(0,len(mknod2)): + #for pca954x need times to built new i2c buses + if mknod2[i].find('pca954') != -1: + time.sleep(1) + + status, output = log_os_system(mknod2[i], 1) + if status: + print output + if FORCE == 0: + return status + else: + for i in range(0,len(mknod)): + #for pca954x need times to built new i2c buses + if mknod[i].find('pca954') != -1: + time.sleep(1) + + status, output = log_os_system(mknod[i], 1) + if status: + print output + if FORCE == 0: + return status + for i in range(0,len(sfp_map)): + if i < qsfp_start: + status, output =log_os_system("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + else: + status, output =log_os_system("echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + return + +def device_uninstall(): + global FORCE + + status, output =log_os_system("ls /sys/bus/i2c/devices/1-0076", 0) + if status==0: + I2C_ORDER=1 + else: + I2C_ORDER=0 + + for i in range(0,len(sfp_map)): + target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device" + status, output =log_os_system("echo 0x50 > "+ target, 1) + if status: + print output + if FORCE == 0: + return status + + if I2C_ORDER==0: + nodelist = mknod + else: + nodelist = mknod2 + + for i in range(len(nodelist)): + target = nodelist[-(i+1)] + temp = target.split() + del temp[1] + temp[-1] = temp[-1].replace('new_device', 'delete_device') + status, output = log_os_system(" ".join(temp), 1) + if status: + print output + if FORCE == 0: + return status + + return + +def system_ready(): + if driver_check() == False: + return False + if not device_exist(): + return False + return True + +def do_install(): + print "Checking system...." + if driver_check() == False: + print "No driver, installing...." + status = driver_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" drivers detected...." + if not device_exist(): + print "No device, installing...." + status = device_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" devices detected...." + return + +def do_uninstall(): + print "Checking system...." + if not device_exist(): + print PROJECT_NAME.upper() +" has no device installed...." + else: + print "Removing device...." + status = device_uninstall() + if status: + if FORCE == 0: + return status + + if driver_check()== False : + print PROJECT_NAME.upper() +" has no driver installed...." + else: + print "Removing installed driver...." + status = driver_uninstall() + if status: + if FORCE == 0: + return status + + return + +def devices_info(): + global DEVICE_NO + global ALL_DEVICE + global i2c_bus, hwmon_types + for key in DEVICE_NO: + ALL_DEVICE[key]= {} + for i in range(0,DEVICE_NO[key]): + ALL_DEVICE[key][key+str(i+1)] = [] + + for key in i2c_bus: + buses = i2c_bus[key] + nodes = i2c_nodes[key] + for i in range(0,len(buses)): + for j in range(0,len(nodes)): + if 'fan' == key: + for k in range(0,DEVICE_NO[key]): + node = key+str(k+1) + path = i2c_prefix+ buses[i]+"/fan"+str(k+1)+"_"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + elif 'sfp' == key: + for k in range(0,DEVICE_NO[key]): + node = key+str(k+1) + path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + else: + node = key+str(i+1) + path = i2c_prefix+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + + for key in hwmon_types: + itypes = hwmon_types[key] + nodes = hwmon_nodes[key] + for i in range(0,len(itypes)): + for j in range(0,len(nodes)): + node = key+"_"+itypes[i] + path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][ key+str(i+1)].append(path) + + #show dict all in the order + if DEBUG == True: + for i in sorted(ALL_DEVICE.keys()): + print(i+": ") + for j in sorted(ALL_DEVICE[i].keys()): + print(" "+j) + for k in (ALL_DEVICE[i][j]): + print(" "+" "+k) + return + +def show_eeprom(index): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0] + node = node.replace(node.split("/")[-1], 'sfp_eeprom') + # check if got hexdump command in current environment + ret, log = log_os_system("which hexdump", 0) + ret, log2 = log_os_system("which busybox hexdump", 0) + if len(log): + hex_cmd = 'hexdump' + elif len(log2): + hex_cmd = ' busybox hexdump' + else: + log = 'Failed : no hexdump cmd!!' + logging.info(log) + print log + return 1 + + print node + ":" + ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1) + if ret==0: + print log + else: + print "**********device no found**********" + return + +def set_device(args): + global DEVICE_NO + global ALL_DEVICE + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + + if args[0]=='led': + if int(args[1])>4: + show_set_help() + return + #print ALL_DEVICE['led'] + for i in range(0,len(ALL_DEVICE['led'])): + for k in (ALL_DEVICE['led']['led'+str(i+1)]): + ret, log = log_os_system("echo "+args[1]+" >"+k, 1) + if ret: + return ret + elif args[0]=='fan': + if int(args[1])>100: + show_set_help() + return + #print ALL_DEVICE['fan'] + #fan1~6 is all fine, all fan share same setting + node = ALL_DEVICE['fan'] ['fan1'][0] + node = node.replace(node.split("/")[-1], 'fan_duty_cycle_percentage') + ret, log = log_os_system("cat "+ node, 1) + if ret==0: + print ("Previous fan duty: " + log.strip() +"%") + ret, log = log_os_system("echo "+args[1]+" >"+node, 1) + if ret==0: + print ("Current fan duty: " + args[1] +"%") + return ret + elif args[0]=='sfp': + if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0: + show_set_help() + return + if len(args)<2: + show_set_help() + return + + if int(args[2])>1: + show_set_help() + return + + #print ALL_DEVICE[args[0]] + for i in range(0,len(ALL_DEVICE[args[0]])): + for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]: + if j.find('tx_disable')!= -1: + ret, log = log_os_system("echo "+args[2]+" >"+ j, 1) + if ret: + return ret + + return + +#get digits inside a string. +#Ex: 31 for "sfp31" +def get_value(input): + digit = re.findall('\d+', input) + return int(digit[0]) + +def device_traversal(): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + for i in sorted(ALL_DEVICE.keys()): + print("============================================") + print(i.upper()+": ") + print("============================================") + + for j in sorted(ALL_DEVICE[i].keys(), key=get_value): + print " "+j+":", + for k in (ALL_DEVICE[i][j]): + ret, log = log_os_system("cat "+k, 0) + func = k.split("/")[-1].strip() + func = re.sub(j+'_','',func,1) + func = re.sub(i.lower()+'_','',func,1) + if ret==0: + print func+"="+log+" ", + else: + print func+"="+"X"+" ", + print + print("----------------------------------------------------------------") + + + print + return + +def device_exist(): + ret1, log = log_os_system("ls "+i2c_prefix+"*0070", 0) + ret2, log = log_os_system("ls "+i2c_prefix+"i2c-2", 0) + return not(ret1 or ret2) + +if __name__ == "__main__": + main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/classes/__init__.py b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/classes/__init__.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/classes/fanutil.py b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/classes/fanutil.py new file mode 100755 index 000000000000..06ebbb777920 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/classes/fanutil.py @@ -0,0 +1,254 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 Accton Technology Corporation +# +# 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 3 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, see . + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 11/13/2017: Polly Hsu, Create +# 1/10/2018: Jostar modify for as7716_32 +# 3/32/2018: Roy Lee modify for as7326_56x +# ------------------------------------------------------------------ + +try: + import time + import logging + from collections import namedtuple +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + + +class FanUtil(object): + """Platform-specific FanUtil class""" + + FAN_NUM_ON_MAIN_BROAD = 6 + FAN_NUM_1_IDX = 1 + FAN_NUM_2_IDX = 2 + FAN_NUM_3_IDX = 3 + FAN_NUM_4_IDX = 4 + FAN_NUM_5_IDX = 5 + FAN_NUM_6_IDX = 6 + + FAN_NODE_NUM_OF_MAP = 2 + FAN_NODE_FAULT_IDX_OF_MAP = 1 + #FAN_NODE_SPEED_IDX_OF_MAP = 2 + FAN_NODE_DIR_IDX_OF_MAP = 2 + #FAN_NODE_DUTY_IDX_OF_MAP = 4 + #FANR_NODE_FAULT_IDX_OF_MAP = 5 + + BASE_VAL_PATH = '/sys/bus/i2c/devices/11-0066/{0}' + FAN_DUTY_PATH = '/sys/bus/i2c/devices/11-0066/fan_duty_cycle_percentage' + + #logfile = '' + #loglevel = logging.INFO + + """ Dictionary where + key1 = fan id index (integer) starting from 1 + key2 = fan node index (interger) starting from 1 + value = path to fan device file (string) """ + _fan_to_device_path_mapping = {} + +#fan1_direction +#fan1_fault +#fan1_present + + #(FAN_NUM_2_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan2_duty_cycle_percentage', + _fan_to_device_node_mapping = { + (FAN_NUM_1_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan1_fault', + (FAN_NUM_1_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan1_direction', + + (FAN_NUM_2_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan2_fault', + (FAN_NUM_2_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan2_direction', + + (FAN_NUM_3_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan3_fault', + (FAN_NUM_3_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan3_direction', + + (FAN_NUM_4_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan4_fault', + (FAN_NUM_4_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan4_direction', + + (FAN_NUM_5_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan5_fault', + (FAN_NUM_5_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan5_direction', + + (FAN_NUM_6_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan6_fault', + (FAN_NUM_6_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan6_direction', + } + + def _get_fan_to_device_node(self, fan_num, node_num): + return self._fan_to_device_node_mapping[(fan_num, node_num)] + + def _get_fan_node_val(self, fan_num, node_num): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. fan_num:%d', fan_num) + return None + + if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP: + logging.debug('GET. Parameter error. node_num:%d', node_num) + return None + + device_path = self.get_fan_to_device_path(fan_num, node_num) + + try: + val_file = open(device_path, 'r') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None + + content = val_file.readline().rstrip() + + if content == '': + logging.debug('GET. content is NULL. device_path:%s', device_path) + return None + + try: + val_file.close() + except: + logging.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return int(content) + + def _set_fan_node_val(self, fan_num, node_num, val): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. fan_num:%d', fan_num) + return None + + if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP: + logging.debug('GET. Parameter error. node_num:%d', node_num) + return None + + content = str(val) + if content == '': + logging.debug('GET. content is NULL. device_path:%s', device_path) + return None + + device_path = self.get_fan_to_device_path(fan_num, node_num) + try: + val_file = open(device_path, 'w') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None + + val_file.write(content) + + try: + val_file.close() + except: + logging.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return True + + def __init__(self): + fan_path = self.BASE_VAL_PATH + + for fan_num in range(self.FAN_NUM_1_IDX, self.FAN_NUM_ON_MAIN_BROAD+1): + for node_num in range(self.FAN_NODE_FAULT_IDX_OF_MAP, self.FAN_NODE_NUM_OF_MAP+1): + self._fan_to_device_path_mapping[(fan_num, node_num)] = fan_path.format( + self._fan_to_device_node_mapping[(fan_num, node_num)]) + + def get_num_fans(self): + return self.FAN_NUM_ON_MAIN_BROAD + + def get_idx_fan_start(self): + return self.FAN_NUM_1_IDX + + def get_num_nodes(self): + return self.FAN_NODE_NUM_OF_MAP + + def get_idx_node_start(self): + return self.FAN_NODE_FAULT_IDX_OF_MAP + + def get_size_node_map(self): + return len(self._fan_to_device_node_mapping) + + def get_size_path_map(self): + return len(self._fan_to_device_path_mapping) + + def get_fan_to_device_path(self, fan_num, node_num): + return self._fan_to_device_path_mapping[(fan_num, node_num)] + + def get_fan_fault(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_FAULT_IDX_OF_MAP) + + #def get_fan_speed(self, fan_num): + # return self._get_fan_node_val(fan_num, self.FAN_NODE_SPEED_IDX_OF_MAP) + + def get_fan_dir(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_DIR_IDX_OF_MAP) + + def get_fan_duty_cycle(self): + #duty_path = self.FAN_DUTY_PATH + try: + val_file = open(self.FAN_DUTY_PATH) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = val_file.readline().rstrip() + val_file.close() + + return int(content) + #self._get_fan_node_val(fan_num, self.FAN_NODE_DUTY_IDX_OF_MAP) +#static u32 reg_val_to_duty_cycle(u8 reg_val) +#{ +# reg_val &= FAN_DUTY_CYCLE_REG_MASK; +# return ((u32)(reg_val+1) * 625 + 75)/ 100; +#} +# + def set_fan_duty_cycle(self, val): + + try: + fan_file = open(self.FAN_DUTY_PATH, 'r+') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + #val = ((val + 1 ) * 625 +75 ) / 100 + fan_file.write(str(val)) + fan_file.close() + return True + + #def get_fanr_fault(self, fan_num): + # return self._get_fan_node_val(fan_num, self.FANR_NODE_FAULT_IDX_OF_MAP) + + def get_fanr_speed(self, fan_num): + return self._get_fan_node_val(fan_num, self.FANR_NODE_SPEED_IDX_OF_MAP) + + def get_fan_status(self, fan_num): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. fan_num, %d', fan_num) + return None + + if self.get_fan_fault(fan_num) is not None and self.get_fan_fault(fan_num) > 0: + logging.debug('GET. FAN fault. fan_num, %d', fan_num) + return False + + #if self.get_fanr_fault(fan_num) is not None and self.get_fanr_fault(fan_num) > 0: + # logging.debug('GET. FANR fault. fan_num, %d', fan_num) + # return False + + return True + +#def main(): +# fan = FanUtil() +# +# print 'get_size_node_map : %d' % fan.get_size_node_map() +# print 'get_size_path_map : %d' % fan.get_size_path_map() +# for x in range(fan.get_idx_fan_start(), fan.get_num_fans()+1): +# for y in range(fan.get_idx_node_start(), fan.get_num_nodes()+1): +# print fan.get_fan_to_device_path(x, y) +# +#if __name__ == '__main__': +# main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/classes/thermalutil.py b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/classes/thermalutil.py new file mode 100755 index 000000000000..e4329b8b9783 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/classes/thermalutil.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 Accton Technology Corporation +# +# 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 3 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, see . + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 11/13/2017: Polly Hsu, Create +# 1/10/2018:Jostar modify for as7716_32x +# 3/23/2018: Roy Lee modify for as7326_56x +# ------------------------------------------------------------------ + +try: + import time + import logging + import glob + from collections import namedtuple +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + + +class ThermalUtil(object): + """Platform-specific ThermalUtil class""" + + THERMAL_NUM_ON_MAIN_BROAD = 3 + THERMAL_NUM_1_IDX = 1 # 1_ON_MAIN_BROAD + THERMAL_NUM_2_IDX = 2 # 2_ON_MAIN_BROAD + THERMAL_NUM_3_IDX = 3 # 3_ON_MAIN_BROAD + + BASE_VAL_PATH = '/sys/bus/i2c/devices/{0}-00{1}/hwmon/hwmon*/temp1_input' + + """ Dictionary where + key1 = thermal id index (integer) starting from 1 + value = path to fan device file (string) """ + _thermal_to_device_path_mapping = {} + + _thermal_to_device_node_mapping = { + THERMAL_NUM_1_IDX: ['15', '48'], + THERMAL_NUM_2_IDX: ['15', '49'], + THERMAL_NUM_3_IDX: ['15', '4a'], + } + + def __init__(self): + thermal_path = self.BASE_VAL_PATH + + for x in range(self.THERMAL_NUM_1_IDX, self.THERMAL_NUM_ON_MAIN_BROAD+1): + self._thermal_to_device_path_mapping[x] = thermal_path.format( + self._thermal_to_device_node_mapping[x][0], + self._thermal_to_device_node_mapping[x][1]) + + def _get_thermal_node_val(self, thermal_num): + if thermal_num < self.THERMAL_NUM_1_IDX or thermal_num > self.THERMAL_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. thermal_num, %d', thermal_num) + return None + + device_path = self.get_thermal_to_device_path(thermal_num) + for filename in glob.glob(device_path): + try: + val_file = open(filename, 'r') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None + + content = val_file.readline().rstrip() + + if content == '': + logging.debug('GET. content is NULL. device_path:%s', device_path) + return None + + try: + val_file.close() + except: + logging.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return int(content) + + + def get_num_thermals(self): + return self.THERMAL_NUM_ON_MAIN_BROAD + + def get_idx_thermal_start(self): + return self.THERMAL_NUM_1_IDX + + def get_size_node_map(self): + return len(self._thermal_to_device_node_mapping) + + def get_size_path_map(self): + return len(self._thermal_to_device_path_mapping) + + def get_thermal_to_device_path(self, thermal_num): + return self._thermal_to_device_path_mapping[thermal_num] + + def get_thermal_1_val(self): + return self._get_thermal_node_val(self.THERMAL_NUM_1_IDX) + + def get_thermal_2_val(self): + return self._get_thermal_node_val(self.THERMAL_NUM_2_IDX) + def get_thermal_temp(self): + return (self._get_thermal_node_val(self.THERMAL_NUM_1_IDX) + self._get_thermal_node_val(self.THERMAL_NUM_2_IDX) +self._get_thermal_node_val(self.THERMAL_NUM_3_IDX)) + +#def main(): +# thermal = ThermalUtil() +# +# print 'get_size_node_map : %d' % thermal.get_size_node_map() +# print 'get_size_path_map : %d' % thermal.get_size_path_map() +# for x in range(thermal.get_idx_thermal_start(), thermal.get_num_thermals()+1): +# print thermal.get_thermal_to_device_path(x) +# +#if __name__ == '__main__': +# main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/Makefile b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/Makefile new file mode 100755 index 000000000000..85c066571c2f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/Makefile @@ -0,0 +1,17 @@ +ifneq ($(KERNELRELEASE),) +obj-m:= accton_i2c_cpld.o \ + accton_as7326_56x_fan.o accton_as7326_56x_leds.o \ + accton_as7326_56x_psu.o ym2651y.o + +else +ifeq (,$(KERNEL_SRC)) +$(error KERNEL_SRC is not defined) +else +KERNELDIR:=$(KERNEL_SRC) +endif +PWD:=$(shell pwd) +default: + $(MAKE) -C $(KERNELDIR) M=$(PWD) modules +clean: + rm -rf *.o *.mod.o *.mod.o *.ko .*cmd .tmp_versions Module.markers Module.symvers modules.order +endif diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_fan.c b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_fan.c new file mode 100755 index 000000000000..606019f3ea44 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_fan.c @@ -0,0 +1,815 @@ +/* + * A hwmon driver for the Accton as7326 56x fan + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "as7326_56x_fan" + +#define NUM_THERMAL_SENSORS (3) /* Get sum of this number of sensors.*/ +#define THERMAL_SENSORS_DRIVER "lm75" +#define THERMAL_SENSORS_ADDRS {0x48, 0x49, 0x4a} + +#define IN +#define OUT + +static struct as7326_56x_fan_data *as7326_56x_fan_update_device(struct device *dev); +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t get_enable(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_enable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t get_sys_temp(struct device *dev, struct device_attribute *da, char *buf); +extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +/* fan related data, the index should match sysfs_fan_attributes + */ +static const u8 fan_reg[] = { + 0x0F, /* fan 1-6 present status */ + 0x10, /* fan 1-6 direction(0:F2B 1:B2F) */ + 0x11, /* fan PWM(for all fan) */ + 0x12, /* front fan 1 speed(rpm) */ + 0x13, /* front fan 2 speed(rpm) */ + 0x14, /* front fan 3 speed(rpm) */ + 0x15, /* front fan 4 speed(rpm) */ + 0x16, /* front fan 5 speed(rpm) */ + 0x17, /* front fan 6 speed(rpm) */ + 0x22, /* rear fan 1 speed(rpm) */ + 0x23, /* rear fan 2 speed(rpm) */ + 0x24, /* rear fan 3 speed(rpm) */ + 0x25, /* rear fan 4 speed(rpm) */ + 0x26, /* rear fan 5 speed(rpm) */ + 0x27, /* rear fan 6 speed(rpm) */ +}; + +/* Each client has this additional data */ +struct as7326_56x_fan_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[ARRAY_SIZE(fan_reg)]; /* Register value */ + u8 enable; + int system_temp; /*In unit of mini-Celsius*/ + int sensors_found; +}; + +enum fan_id { + FAN1_ID, + FAN2_ID, + FAN3_ID, + FAN4_ID, + FAN5_ID, + FAN6_ID +}; + +enum sysfs_fan_attributes { + FAN_PRESENT_REG, + FAN_DIRECTION_REG, + FAN_DUTY_CYCLE_PERCENTAGE, /* Only one CPLD register to control duty cycle for all fans */ + FAN1_FRONT_SPEED_RPM, + FAN2_FRONT_SPEED_RPM, + FAN3_FRONT_SPEED_RPM, + FAN4_FRONT_SPEED_RPM, + FAN5_FRONT_SPEED_RPM, + FAN6_FRONT_SPEED_RPM, + FAN1_REAR_SPEED_RPM, + FAN2_REAR_SPEED_RPM, + FAN3_REAR_SPEED_RPM, + FAN4_REAR_SPEED_RPM, + FAN5_REAR_SPEED_RPM, + FAN6_REAR_SPEED_RPM, + FAN1_DIRECTION, + FAN2_DIRECTION, + FAN3_DIRECTION, + FAN4_DIRECTION, + FAN5_DIRECTION, + FAN6_DIRECTION, + FAN1_PRESENT, + FAN2_PRESENT, + FAN3_PRESENT, + FAN4_PRESENT, + FAN5_PRESENT, + FAN6_PRESENT, + FAN1_FAULT, + FAN2_FAULT, + FAN3_FAULT, + FAN4_FAULT, + FAN5_FAULT, + FAN6_FAULT +}; + +/* Define attributes + */ +#define DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(index, index2) \ + static SENSOR_DEVICE_ATTR(fan##index##_fault, S_IRUGO, fan_show_value, NULL, FAN##index##_FAULT);\ + static SENSOR_DEVICE_ATTR(fan##index2##_fault, S_IRUGO, fan_show_value, NULL, FAN##index##_FAULT) +#define DECLARE_FAN_FAULT_ATTR(index, index2) &sensor_dev_attr_fan##index##_fault.dev_attr.attr, \ + &sensor_dev_attr_fan##index2##_fault.dev_attr.attr + +#define DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_direction, S_IRUGO, fan_show_value, NULL, FAN##index##_DIRECTION) +#define DECLARE_FAN_DIRECTION_ATTR(index) &sensor_dev_attr_fan##index##_direction.dev_attr.attr + +#define DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan_duty_cycle_percentage, S_IWUSR | S_IRUGO, fan_show_value, set_duty_cycle, FAN_DUTY_CYCLE_PERCENTAGE);\ + static SENSOR_DEVICE_ATTR(pwm##index, S_IWUSR | S_IRUGO, fan_show_value, set_duty_cycle, FAN_DUTY_CYCLE_PERCENTAGE);\ + static SENSOR_DEVICE_ATTR(pwm##index##_enable, S_IWUSR | S_IRUGO, get_enable, set_enable, FAN_DUTY_CYCLE_PERCENTAGE) + +#define DECLARE_FAN_DUTY_CYCLE_ATTR(index) &sensor_dev_attr_fan_duty_cycle_percentage.dev_attr.attr, \ + &sensor_dev_attr_pwm##index.dev_attr.attr, \ + &sensor_dev_attr_pwm##index##_enable.dev_attr.attr + +#define DECLARE_FAN_SYSTEM_TEMP_SENSOR_DEV_ATTR() \ + static SENSOR_DEVICE_ATTR(sys_temp, S_IRUGO, get_sys_temp, NULL, FAN_DUTY_CYCLE_PERCENTAGE) + +#define DECLARE_FAN_SYSTEM_TEMP_ATTR() &sensor_dev_attr_sys_temp.dev_attr.attr + + +#define DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_present, S_IRUGO, fan_show_value, NULL, FAN##index##_PRESENT) +#define DECLARE_FAN_PRESENT_ATTR(index) &sensor_dev_attr_fan##index##_present.dev_attr.attr + +#define DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(index, index2) \ + static SENSOR_DEVICE_ATTR(fan##index##_front_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_FRONT_SPEED_RPM);\ + static SENSOR_DEVICE_ATTR(fan##index##_rear_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_REAR_SPEED_RPM);\ + static SENSOR_DEVICE_ATTR(fan##index##_input, S_IRUGO, fan_show_value, NULL, FAN##index##_FRONT_SPEED_RPM);\ + static SENSOR_DEVICE_ATTR(fan##index2##_input, S_IRUGO, fan_show_value, NULL, FAN##index##_REAR_SPEED_RPM) +#define DECLARE_FAN_SPEED_RPM_ATTR(index, index2) &sensor_dev_attr_fan##index##_front_speed_rpm.dev_attr.attr, \ + &sensor_dev_attr_fan##index##_rear_speed_rpm.dev_attr.attr, \ + &sensor_dev_attr_fan##index##_input.dev_attr.attr, \ + &sensor_dev_attr_fan##index2##_input.dev_attr.attr + +/* 6 fan fault attributes in this platform */ +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(1,11); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(2,12); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(3,13); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(4,14); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(5,15); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(6,16); +/* 6 fan speed(rpm) attributes in this platform */ +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(1,11); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(2,12); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(3,13); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(4,14); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(5,15); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(6,16); +/* 6 fan present attributes in this platform */ +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(1); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(2); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(3); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(4); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(5); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(6); +/* 6 fan direction attribute in this platform */ +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(1); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(2); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(3); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(4); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(5); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(6); +/* 1 fan duty cycle attribute in this platform */ +DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(1); +/* System temperature for fancontrol */ +DECLARE_FAN_SYSTEM_TEMP_SENSOR_DEV_ATTR(); + +static struct attribute *as7326_56x_fan_attributes[] = { + /* fan related attributes */ + DECLARE_FAN_FAULT_ATTR(1,11), + DECLARE_FAN_FAULT_ATTR(2,12), + DECLARE_FAN_FAULT_ATTR(3,13), + DECLARE_FAN_FAULT_ATTR(4,14), + DECLARE_FAN_FAULT_ATTR(5,15), + DECLARE_FAN_FAULT_ATTR(6,16), + DECLARE_FAN_SPEED_RPM_ATTR(1,11), + DECLARE_FAN_SPEED_RPM_ATTR(2,12), + DECLARE_FAN_SPEED_RPM_ATTR(3,13), + DECLARE_FAN_SPEED_RPM_ATTR(4,14), + DECLARE_FAN_SPEED_RPM_ATTR(5,15), + DECLARE_FAN_SPEED_RPM_ATTR(6,16), + DECLARE_FAN_PRESENT_ATTR(1), + DECLARE_FAN_PRESENT_ATTR(2), + DECLARE_FAN_PRESENT_ATTR(3), + DECLARE_FAN_PRESENT_ATTR(4), + DECLARE_FAN_PRESENT_ATTR(5), + DECLARE_FAN_PRESENT_ATTR(6), + DECLARE_FAN_DIRECTION_ATTR(1), + DECLARE_FAN_DIRECTION_ATTR(2), + DECLARE_FAN_DIRECTION_ATTR(3), + DECLARE_FAN_DIRECTION_ATTR(4), + DECLARE_FAN_DIRECTION_ATTR(5), + DECLARE_FAN_DIRECTION_ATTR(6), + DECLARE_FAN_DUTY_CYCLE_ATTR(1), + DECLARE_FAN_SYSTEM_TEMP_ATTR(), + NULL +}; + +#define FAN_DUTY_CYCLE_REG_MASK 0xF +#define FAN_MAX_DUTY_CYCLE 100 +#define FAN_REG_VAL_TO_SPEED_RPM_STEP 100 + +static int as7326_56x_fan_read_value(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int as7326_56x_fan_write_value(struct i2c_client *client, u8 reg, u8 value) +{ + return i2c_smbus_write_byte_data(client, reg, value); +} + +/* fan utility functions + */ +static u32 reg_val_to_duty_cycle(u8 reg_val) +{ + reg_val &= FAN_DUTY_CYCLE_REG_MASK; + return ((u32)(reg_val+1) * 625 + 75)/ 100; +} + +static u8 duty_cycle_to_reg_val(u8 duty_cycle) +{ + return ((u32)duty_cycle * 100 / 625) - 1; +} + +static u32 reg_val_to_speed_rpm(u8 reg_val) +{ + return (u32)reg_val * FAN_REG_VAL_TO_SPEED_RPM_STEP; +} + +static u8 reg_val_to_direction(u8 reg_val, enum fan_id id) +{ + u8 mask = (1 << id); + + reg_val &= mask; + + return reg_val ? 1 : 0; +} +static u8 reg_val_to_is_present(u8 reg_val, enum fan_id id) +{ + u8 mask = (1 << id); + + reg_val &= mask; + + return reg_val ? 0 : 1; +} + +static u8 is_fan_fault(struct as7326_56x_fan_data *data, enum fan_id id) +{ + u8 ret = 1; + int front_fan_index = FAN1_FRONT_SPEED_RPM + id; + int rear_fan_index = FAN1_REAR_SPEED_RPM + id; + + /* Check if the speed of front or rear fan is ZERO, + */ + if (reg_val_to_speed_rpm(data->reg_val[front_fan_index]) && + reg_val_to_speed_rpm(data->reg_val[rear_fan_index])) { + ret = 0; + } + + return ret; +} + +static ssize_t set_enable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct as7326_56x_fan_data *data = as7326_56x_fan_update_device(dev); + int error, value; + + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (value < 0 || value > 1) + return -EINVAL; + + data->enable = value; + if (value == 0) + { + return set_duty_cycle(dev, da, buf, FAN_MAX_DUTY_CYCLE); + } + return count; +} + + +static ssize_t get_enable(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct as7326_56x_fan_data *data = as7326_56x_fan_update_device(dev); + + return sprintf(buf, "%u\n", data->enable); +} +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int error, value; + struct i2c_client *client = to_i2c_client(dev); + + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (value < 0) + return -EINVAL; + + value = (value > FAN_MAX_DUTY_CYCLE)? FAN_MAX_DUTY_CYCLE : value; + + as7326_56x_fan_write_value(client, 0x33, 0); /* Disable fan speed watch dog */ + as7326_56x_fan_write_value(client, fan_reg[FAN_DUTY_CYCLE_PERCENTAGE], duty_cycle_to_reg_val(value)); + return count; +} + +/* Due to this struct is declared at lm75.c, it cannot be include + * under Sonic environment. I duplicate it from lm75.c. + */ +struct lm75_data { + struct i2c_client *client; + struct device *hwmon_dev; + struct thermal_zone_device *tz; + struct mutex update_lock; + u8 orig_conf; + u8 resolution; /* In bits, between 9 and 12 */ + u8 resolution_limits; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + unsigned long sample_time; /* In jiffies */ + s16 temp[3]; /* Register values, + 0 = input + 1 = max + 2 = hyst */ +}; + +/*Copied from lm75.c*/ +static inline long lm75_reg_to_mc(s16 temp, u8 resolution) +{ + return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8); +} + +/*Get hwmon_dev from i2c_client, set hwmon_dev = NULL is failed.*/ +static struct device * get_hwmon_dev( + struct i2c_client *client) +{ + struct lm75_data *data = NULL; + + data = i2c_get_clientdata(client); + if(data) + { + if( data->valid == 1 && data->hwmon_dev) + { + return data->hwmon_dev; + } + + } + return NULL; +} + +/* To find hwmon index by opening hwmon under that i2c address. + */ +static int find_hwmon_index_by_FileOpen( + int bus_nr, + unsigned short addr, + OUT int *index) +{ +#define MAX_HWMON_DEVICE (10) /* Find hwmon device in 0~10*/ + struct file *sfd; + char client_name[96]; + int i=0; + + do { + snprintf(client_name, sizeof(client_name), + "/sys/bus/i2c/devices/%d-%04x/hwmon/hwmon%d/temp1_input", + bus_nr, addr, i); + + sfd = filp_open(client_name, O_RDONLY, 0); + i++; + } while( IS_ERR(sfd) && i < MAX_HWMON_DEVICE); + + if (IS_ERR(sfd)) { + pr_err("Failed to open file(%s)#%d\r\n", client_name, __LINE__); + return -ENOENT; + } + filp_close(sfd, 0); + *index = i - 1; + return 0; + +#undef MAX_HWMON_DEVICE +} + +static int get_temp_file_path( + int bus_nr, unsigned short addr, + struct device *hwmon_dev + ,char *path, int max_len) +{ + + if(hwmon_dev && strlen(dev_name(hwmon_dev))) + { + snprintf(path, max_len, + "/sys/bus/i2c/devices/%d-%04x/hwmon/%s/temp1_input", + bus_nr, addr, dev_name(hwmon_dev)); + } + else + { + int i=0; + if(find_hwmon_index_by_FileOpen( bus_nr, addr, &i)) + { + return -EIO; + } + snprintf(path, max_len, + "/sys/bus/i2c/devices/%d-%04x/hwmon/hwmon%d/temp1_input", + bus_nr, addr, i); + } + return 0; +} + +/*File read the dev file at user space.*/ +static int read_devfile_temp1_input( + struct device *dev, + int bus_nr, + unsigned short addr, + struct device *hwmon_dev, + int *miniCelsius) +{ + struct file *sfd; + char buffer[96]; + char devfile[96]; + int rc, status; + int rdlen, value; + mm_segment_t old_fs; + + rc = 0; + get_temp_file_path(bus_nr, addr, hwmon_dev, devfile, sizeof(devfile)); + sfd = filp_open(devfile, O_RDONLY, 0); + if (IS_ERR(sfd)) { + pr_err("Failed to open file(%s)#%d\r\n", devfile, __LINE__); + return -ENOENT; + } + dev_dbg(dev, "Found device:%s\n",devfile); + + if(!(sfd->f_op) || !(sfd->f_op->read) ) { + pr_err("file %s cann't readable ?\n",devfile); + return -ENOENT; + } + + old_fs = get_fs(); + set_fs(KERNEL_DS); + rdlen = sfd->f_op->read(sfd, buffer, sizeof(buffer), &sfd->f_pos); + if (rdlen == 0) { + pr_err( "File(%s) empty!\n", devfile); + rc = -EIO; + goto exit; + } + status = sscanf(buffer, "%d", &value); + if (status != 1) { + rc = -EIO; + goto exit; + } + *miniCelsius = value; + dev_dbg(dev,"found sensors: %d @i2c %d-%04x\n", value, bus_nr, addr); + +exit: + set_fs(old_fs); + filp_close(sfd, 0); + return rc; +} + +static u8 is_lm75_data_due(struct i2c_client *client) +{ + struct lm75_data *data = NULL; + + data = i2c_get_clientdata(client); + if (time_after(jiffies, data->last_updated + data->sample_time)) + { + return 1; + } + return 0; +} +static int get_lm75_temp(struct i2c_client *client, int *miniCelsius) +{ + struct lm75_data *data = NULL; + + data = i2c_get_clientdata(client); + *miniCelsius = lm75_reg_to_mc(data->temp[0], data->resolution); + + return 0; +} + +static bool lm75_addr_mached(unsigned short addr) +{ + int i; + unsigned short addrs[] = THERMAL_SENSORS_ADDRS; + + for (i = 0; i < ARRAY_SIZE(addrs); i++) + { + if( addr == addrs[i]) + return 1; + } + return 0; +} + +static int _find_lm75_device(struct device *dev, void *data) +{ + struct device_driver *driver; + struct as7326_56x_fan_data *prv = data; + char *driver_name = THERMAL_SENSORS_DRIVER; + + driver = dev->driver; + if (driver && driver->name && + strcmp(driver->name, driver_name) == 0) + { + struct i2c_client *client; + client = to_i2c_client(dev); + if (client) + { + /*cannot use "struct i2c_adapter *adap = to_i2c_adapter(dev);"*/ + struct i2c_adapter *adap = client->adapter; + int miniCelsius = 0; + + if (! lm75_addr_mached(client->addr)) + { + return 0; + } + + if (!adap) { + return -ENXIO; + } + + /* If the data is not updated, read them from devfile + to drive them updateing data from chip.*/ + if (is_lm75_data_due(client)) + { + struct device *hwmon_dev; + + hwmon_dev = get_hwmon_dev(client); + if(0 == read_devfile_temp1_input(dev, adap->nr, + client->addr, hwmon_dev, &miniCelsius)) + { + prv->system_temp += miniCelsius; + prv->sensors_found++; + } + + } + else + { + get_lm75_temp(client, &miniCelsius); + prv->system_temp += miniCelsius; + prv->sensors_found++; + + } + } + } + return 0; +} + +/*Find all lm75 devices and return sum of temperatures.*/ +static ssize_t get_sys_temp(struct device *dev, struct device_attribute *da, + char *buf) +{ + ssize_t ret = 0; + struct as7326_56x_fan_data *data = as7326_56x_fan_update_device(dev); + + data->system_temp=0; + data->sensors_found=0; + i2c_for_each_dev(data, _find_lm75_device); + if (NUM_THERMAL_SENSORS != data->sensors_found) + { + dev_dbg(dev,"only %d of %d temps are found\n", + data->sensors_found, NUM_THERMAL_SENSORS); + data->system_temp = INT_MAX; + } + ret = sprintf(buf, "%d\n",data->system_temp); + return ret; +} + +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct as7326_56x_fan_data *data = as7326_56x_fan_update_device(dev); + ssize_t ret = 0; + + if (data->valid) { + switch (attr->index) { + case FAN_DUTY_CYCLE_PERCENTAGE: + { + u32 duty_cycle = reg_val_to_duty_cycle(data->reg_val[FAN_DUTY_CYCLE_PERCENTAGE]); + ret = sprintf(buf, "%u\n", duty_cycle); + break; + } + case FAN1_FRONT_SPEED_RPM: + case FAN2_FRONT_SPEED_RPM: + case FAN3_FRONT_SPEED_RPM: + case FAN4_FRONT_SPEED_RPM: + case FAN5_FRONT_SPEED_RPM: + case FAN6_FRONT_SPEED_RPM: + case FAN1_REAR_SPEED_RPM: + case FAN2_REAR_SPEED_RPM: + case FAN3_REAR_SPEED_RPM: + case FAN4_REAR_SPEED_RPM: + case FAN5_REAR_SPEED_RPM: + case FAN6_REAR_SPEED_RPM: + ret = sprintf(buf, "%u\n", reg_val_to_speed_rpm(data->reg_val[attr->index])); + break; + case FAN1_PRESENT: + case FAN2_PRESENT: + case FAN3_PRESENT: + case FAN4_PRESENT: + case FAN5_PRESENT: + case FAN6_PRESENT: + ret = sprintf(buf, "%d\n", + reg_val_to_is_present(data->reg_val[FAN_PRESENT_REG], + attr->index - FAN1_PRESENT)); + break; + case FAN1_FAULT: + case FAN2_FAULT: + case FAN3_FAULT: + case FAN4_FAULT: + case FAN5_FAULT: + case FAN6_FAULT: + ret = sprintf(buf, "%d\n", is_fan_fault(data, attr->index - FAN1_FAULT)); + break; + case FAN1_DIRECTION: + case FAN2_DIRECTION: + case FAN3_DIRECTION: + case FAN4_DIRECTION: + case FAN5_DIRECTION: + case FAN6_DIRECTION: + ret = sprintf(buf, "%d\n", + reg_val_to_direction(data->reg_val[FAN_DIRECTION_REG], + attr->index - FAN1_DIRECTION)); + break; + default: + break; + } + } + + return ret; +} + +static const struct attribute_group as7326_56x_fan_group = { + .attrs = as7326_56x_fan_attributes, +}; + +static struct as7326_56x_fan_data *as7326_56x_fan_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as7326_56x_fan_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || + !data->valid) { + int i; + + dev_dbg(&client->dev, "Starting as7326_56x_fan update\n"); + data->valid = 0; + + /* Update fan data + */ + for (i = 0; i < ARRAY_SIZE(data->reg_val); i++) { + int status = as7326_56x_fan_read_value(client, fan_reg[i]); + + if (status < 0) { + data->valid = 0; + mutex_unlock(&data->update_lock); + dev_dbg(&client->dev, "reg %d, err %d\n", fan_reg[i], status); + return data; + } + else { + data->reg_val[i] = status; + } + } + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +static int as7326_56x_fan_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct as7326_56x_fan_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct as7326_56x_fan_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + data->enable = 0; + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as7326_56x_fan_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: fan '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as7326_56x_fan_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as7326_56x_fan_remove(struct i2c_client *client) +{ + struct as7326_56x_fan_data *data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as7326_56x_fan_group); + + return 0; +} + +/* Addresses to scan */ +static const unsigned short normal_i2c[] = { 0x66, I2C_CLIENT_END }; + +static const struct i2c_device_id as7326_56x_fan_id[] = { + { "as7326_56x_fan", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, as7326_56x_fan_id); + +static struct i2c_driver as7326_56x_fan_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = DRVNAME, + }, + .probe = as7326_56x_fan_probe, + .remove = as7326_56x_fan_remove, + .id_table = as7326_56x_fan_id, + .address_list = normal_i2c, +}; + +static int __init as7326_56x_fan_init(void) +{ + return i2c_add_driver(&as7326_56x_fan_driver); +} + +static void __exit as7326_56x_fan_exit(void) +{ + i2c_del_driver(&as7326_56x_fan_driver); +} + +module_init(as7326_56x_fan_init); +module_exit(as7326_56x_fan_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("as7326_56x_fan driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_leds.c b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_leds.c new file mode 100644 index 000000000000..4cb7f1fa25a5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_leds.c @@ -0,0 +1,438 @@ +/* + * A LED driver for the accton_as7326_56x_led + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*#define DEBUG*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +extern int as7326_56x_cpld_read (unsigned short cpld_addr, u8 reg); +extern int as7326_56x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +extern void led_classdev_unregister(struct led_classdev *led_cdev); +extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); +extern void led_classdev_resume(struct led_classdev *led_cdev); +extern void led_classdev_suspend(struct led_classdev *led_cdev); + +#define DRVNAME "accton_as7326_56x_led" + +struct accton_as7326_56x_led_data { + struct platform_device *pdev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[1]; /* only 1 register*/ +}; + +static struct accton_as7326_56x_led_data *ledctl = NULL; + +/* LED related data + */ + +#define LED_CNTRLER_I2C_ADDRESS (0x60) + +#define LED_TYPE_DIAG_REG_MASK (0x3) +#define LED_MODE_DIAG_GREEN_VALUE (0x02) +#define LED_MODE_DIAG_RED_VALUE (0x01) +#define LED_MODE_DIAG_AMBER_VALUE (0x00) /*It's yellow actually. Green+Red=Yellow*/ +#define LED_MODE_DIAG_OFF_VALUE (0x03) + + +#define LED_TYPE_LOC_REG_MASK (0x80) +#define LED_MODE_LOC_ON_VALUE (0) +#define LED_MODE_LOC_OFF_VALUE (0x80) + +enum led_type { + LED_TYPE_DIAG, + LED_TYPE_LOC, + LED_TYPE_FAN, + LED_TYPE_PSU1, + LED_TYPE_PSU2 +}; + +struct led_reg { + u32 types; + u8 reg_addr; +}; + +static const struct led_reg led_reg_map[] = { + {(1<update_lock); + + if (time_after(jiffies, ledctl->last_updated + HZ + HZ / 2) + || !ledctl->valid) { + int i; + + dev_dbg(&ledctl->pdev->dev, "Starting accton_as7326_56x_led update\n"); + + /* Update LED data + */ + for (i = 0; i < ARRAY_SIZE(ledctl->reg_val); i++) { + int status = accton_as7326_56x_led_read_value(led_reg_map[i].reg_addr); + + if (status < 0) { + ledctl->valid = 0; + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", led_reg_map[i].reg_addr, status); + goto exit; + } + else + { + ledctl->reg_val[i] = status; + } + } + + ledctl->last_updated = jiffies; + ledctl->valid = 1; + } + +exit: + mutex_unlock(&ledctl->update_lock); +} + +static void accton_as7326_56x_led_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode, + enum led_type type) +{ + int reg_val; + u8 reg ; + mutex_lock(&ledctl->update_lock); + + if( !accton_getLedReg(type, ®)) + { + dev_dbg(&ledctl->pdev->dev, "Not match item for %d.\n", type); + } + + reg_val = accton_as7326_56x_led_read_value(reg); + + if (reg_val < 0) { + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", reg, reg_val); + goto exit; + } + reg_val = led_light_mode_to_reg_val(type, led_light_mode, reg_val); + accton_as7326_56x_led_write_value(reg, reg_val); + + /* to prevent the slow-update issue */ + ledctl->valid = 0; + +exit: + mutex_unlock(&ledctl->update_lock); +} + + +static void accton_as7326_56x_led_diag_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + accton_as7326_56x_led_set(led_cdev, led_light_mode, LED_TYPE_DIAG); +} + +static enum led_brightness accton_as7326_56x_led_diag_get(struct led_classdev *cdev) +{ + accton_as7326_56x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_DIAG, ledctl->reg_val[0]); +} + +static void accton_as7326_56x_led_loc_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + accton_as7326_56x_led_set(led_cdev, led_light_mode, LED_TYPE_LOC); +} + +static enum led_brightness accton_as7326_56x_led_loc_get(struct led_classdev *cdev) +{ + accton_as7326_56x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_LOC, ledctl->reg_val[0]); +} + +static void accton_as7326_56x_led_auto_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ +} + +static enum led_brightness accton_as7326_56x_led_auto_get(struct led_classdev *cdev) +{ + return LED_MODE_AUTO; +} + +static struct led_classdev accton_as7326_56x_leds[] = { + [LED_TYPE_DIAG] = { + .name = "accton_as7326_56x_led::diag", + .default_trigger = "unused", + .brightness_set = accton_as7326_56x_led_diag_set, + .brightness_get = accton_as7326_56x_led_diag_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_RED, + }, + [LED_TYPE_LOC] = { + .name = "accton_as7326_56x_led::loc", + .default_trigger = "unused", + .brightness_set = accton_as7326_56x_led_loc_set, + .brightness_get = accton_as7326_56x_led_loc_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_BLUE, + }, + [LED_TYPE_FAN] = { + .name = "accton_as7326_56x_led::fan", + .default_trigger = "unused", + .brightness_set = accton_as7326_56x_led_auto_set, + .brightness_get = accton_as7326_56x_led_auto_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_PSU1] = { + .name = "accton_as7326_56x_led::psu1", + .default_trigger = "unused", + .brightness_set = accton_as7326_56x_led_auto_set, + .brightness_get = accton_as7326_56x_led_auto_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_PSU2] = { + .name = "accton_as7326_56x_led::psu2", + .default_trigger = "unused", + .brightness_set = accton_as7326_56x_led_auto_set, + .brightness_get = accton_as7326_56x_led_auto_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, +}; + +static int accton_as7326_56x_led_suspend(struct platform_device *dev, + pm_message_t state) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(accton_as7326_56x_leds); i++) { + led_classdev_suspend(&accton_as7326_56x_leds[i]); + } + + return 0; +} + +static int accton_as7326_56x_led_resume(struct platform_device *dev) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(accton_as7326_56x_leds); i++) { + led_classdev_resume(&accton_as7326_56x_leds[i]); + } + + return 0; +} + +static int accton_as7326_56x_led_probe(struct platform_device *pdev) +{ + int ret, i; + + for (i = 0; i < ARRAY_SIZE(accton_as7326_56x_leds); i++) { + ret = led_classdev_register(&pdev->dev, &accton_as7326_56x_leds[i]); + + if (ret < 0) + break; + } + + /* Check if all LEDs were successfully registered */ + if (i != ARRAY_SIZE(accton_as7326_56x_leds)) { + int j; + + /* only unregister the LEDs that were successfully registered */ + for (j = 0; j < i; j++) { + led_classdev_unregister(&accton_as7326_56x_leds[i]); + } + } + + return ret; +} + +static int accton_as7326_56x_led_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(accton_as7326_56x_leds); i++) { + led_classdev_unregister(&accton_as7326_56x_leds[i]); + } + + return 0; +} + +static struct platform_driver accton_as7326_56x_led_driver = { + .probe = accton_as7326_56x_led_probe, + .remove = accton_as7326_56x_led_remove, + .suspend = accton_as7326_56x_led_suspend, + .resume = accton_as7326_56x_led_resume, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +static int __init accton_as7326_56x_led_init(void) +{ + int ret; + + ret = platform_driver_register(&accton_as7326_56x_led_driver); + if (ret < 0) { + goto exit; + } + + ledctl = kzalloc(sizeof(struct accton_as7326_56x_led_data), GFP_KERNEL); + if (!ledctl) { + ret = -ENOMEM; + platform_driver_unregister(&accton_as7326_56x_led_driver); + goto exit; + } + + mutex_init(&ledctl->update_lock); + + ledctl->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(ledctl->pdev)) { + ret = PTR_ERR(ledctl->pdev); + platform_driver_unregister(&accton_as7326_56x_led_driver); + kfree(ledctl); + goto exit; + } + +exit: + return ret; +} + +static void __exit accton_as7326_56x_led_exit(void) +{ + platform_device_unregister(ledctl->pdev); + platform_driver_unregister(&accton_as7326_56x_led_driver); + kfree(ledctl); +} + +module_init(accton_as7326_56x_led_init); +module_exit(accton_as7326_56x_led_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton_as7326_56x_led driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_psu.c b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_psu.c new file mode 100644 index 000000000000..8c2ece6200fe --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_as7326_56x_psu.c @@ -0,0 +1,277 @@ +/* + * An hwmon driver for accton as7326_56x Power Module + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_model_name(struct device *dev, struct device_attribute *da, char *buf); +static int as7326_56x_psu_read_block(struct i2c_client *client, u8 command, u8 *data,int data_len); +extern int as7326_56x_cpld_read(unsigned short cpld_addr, u8 reg); + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { 0x50, 0x53, I2C_CLIENT_END }; + +/* Each client has this additional data + */ +struct as7326_56x_psu_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 index; /* PSU index */ + u8 status; /* Status(present/power_good) register read from CPLD */ + char model_name[9]; /* Model name, read from eeprom */ +}; + +static struct as7326_56x_psu_data *as7326_56x_psu_update_device(struct device *dev); + +enum as7326_56x_psu_sysfs_attributes { + PSU_PRESENT, + PSU_MODEL_NAME, + PSU_POWER_GOOD +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, show_status, NULL, PSU_PRESENT); +static SENSOR_DEVICE_ATTR(psu_model_name, S_IRUGO, show_model_name,NULL, PSU_MODEL_NAME); +static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_status, NULL, PSU_POWER_GOOD); + +static struct attribute *as7326_56x_psu_attributes[] = { + &sensor_dev_attr_psu_present.dev_attr.attr, + &sensor_dev_attr_psu_model_name.dev_attr.attr, + &sensor_dev_attr_psu_power_good.dev_attr.attr, + NULL +}; + +static ssize_t show_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct as7326_56x_psu_data *data = as7326_56x_psu_update_device(dev); + u8 status = 0; + + if (attr->index == PSU_PRESENT) { + status = !(data->status >> (1-data->index) & 0x1); + } + else { /* PSU_POWER_GOOD */ + status = (data->status >> (3-data->index) & 0x1); + } + + return sprintf(buf, "%d\n", status); +} + +static ssize_t show_model_name(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct as7326_56x_psu_data *data = as7326_56x_psu_update_device(dev); + + return sprintf(buf, "%s\n", data->model_name); +} + +static const struct attribute_group as7326_56x_psu_group = { + .attrs = as7326_56x_psu_attributes, +}; + +static int as7326_56x_psu_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct as7326_56x_psu_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct as7326_56x_psu_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + data->index = dev_id->driver_data; + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as7326_56x_psu_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as7326_56x_psu_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as7326_56x_psu_remove(struct i2c_client *client) +{ + struct as7326_56x_psu_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as7326_56x_psu_group); + kfree(data); + + return 0; +} + +enum psu_index +{ + as7326_56x_psu1, + as7326_56x_psu2 +}; + +static const struct i2c_device_id as7326_56x_psu_id[] = { + { "as7326_56x_psu1", as7326_56x_psu1 }, + { "as7326_56x_psu2", as7326_56x_psu2 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, as7326_56x_psu_id); + +static struct i2c_driver as7326_56x_psu_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "as7326_56x_psu", + }, + .probe = as7326_56x_psu_probe, + .remove = as7326_56x_psu_remove, + .id_table = as7326_56x_psu_id, + .address_list = normal_i2c, +}; + +static int as7326_56x_psu_read_block(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ + int result = 0; + int retry_count = 5; + + while (retry_count) { + retry_count--; + + result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + + if (unlikely(result < 0)) { + msleep(10); + continue; + } + + if (unlikely(result != data_len)) { + result = -EIO; + msleep(10); + continue; + } + + result = 0; + break; + } + + return result; +} + +static struct as7326_56x_psu_data *as7326_56x_psu_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as7326_56x_psu_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int status; + int power_good = 0; + + dev_dbg(&client->dev, "Starting as7326_56x update\n"); + + /* Read psu status */ + status = as7326_56x_cpld_read(0x60, 0x2); + + if (status < 0) { + dev_dbg(&client->dev, "cpld reg 0x60 err %d\n", status); + } + else { + data->status = status; + } + + /* Read model name */ + memset(data->model_name, 0, sizeof(data->model_name)); + power_good = (data->status >> (3-data->index) & 0x1); + + if (power_good) { + status = as7326_56x_psu_read_block(client, 0x20, data->model_name, + ARRAY_SIZE(data->model_name)-1); + + if (status < 0) { + data->model_name[0] = '\0'; + dev_dbg(&client->dev, "unable to read model name from (0x%x)\n", client->addr); + } + else { + data->model_name[ARRAY_SIZE(data->model_name)-1] = '\0'; + } + } + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +module_i2c_driver(as7326_56x_psu_driver); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("as7326_56x_psu driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_i2c_cpld.c b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_i2c_cpld.c new file mode 100644 index 000000000000..2274c4a934c0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/accton_i2c_cpld.c @@ -0,0 +1,1080 @@ +/* + * Copyright (C) Brandon Chuang + * + * This module supports the accton cpld that hold the channel select + * mechanism for other i2c slave devices, such as SFP. + * This includes the: + * Accton as7326_56x CPLD1/CPLD2/CPLD3 + * + * Based on: + * pca954x.c from Kumar Gala + * Copyright (C) 2006 + * + * Based on: + * pca954x.c from Ken Harrenstien + * Copyright (C) 2004 Google, Inc. (Ken Harrenstien) + * + * Based on: + * i2c-virtual_cb.c from Brian Kuschak + * and + * pca9540.c from Jean Delvare . + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define I2C_RW_RETRY_COUNT 10 +#define I2C_RW_RETRY_INTERVAL 60 /* ms */ + +static LIST_HEAD(cpld_client_list); +static struct mutex list_lock; + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; + +enum cpld_type { + as7326_56x_cpld1, + as7326_56x_cpld2, + as7326_56x_cpld3 +}; + +struct as7326_56x_cpld_data { + enum cpld_type type; + struct device *hwmon_dev; + struct mutex update_lock; +}; + +static const struct i2c_device_id as7326_56x_cpld_id[] = { + { "as7326_56x_cpld1", as7326_56x_cpld1 }, + { "as7326_56x_cpld2", as7326_56x_cpld2 }, + { "as7326_56x_cpld3", as7326_56x_cpld3 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, as7326_56x_cpld_id); + +#define TRANSCEIVER_PRESENT_ATTR_ID(index) MODULE_PRESENT_##index +#define TRANSCEIVER_TXDISABLE_ATTR_ID(index) MODULE_TXDISABLE_##index +#define TRANSCEIVER_RXLOS_ATTR_ID(index) MODULE_RXLOS_##index +#define TRANSCEIVER_TXFAULT_ATTR_ID(index) MODULE_TXFAULT_##index +#define TRANSCEIVER_RESET_ATTR_ID(index) MODULE_RESET_##index + +enum as7326_56x_cpld_sysfs_attributes { + CPLD_VERSION, + ACCESS, + MODULE_PRESENT_ALL, + MODULE_RXLOS_ALL, + /* transceiver attributes */ + TRANSCEIVER_PRESENT_ATTR_ID(1), + TRANSCEIVER_PRESENT_ATTR_ID(2), + TRANSCEIVER_PRESENT_ATTR_ID(3), + TRANSCEIVER_PRESENT_ATTR_ID(4), + TRANSCEIVER_PRESENT_ATTR_ID(5), + TRANSCEIVER_PRESENT_ATTR_ID(6), + TRANSCEIVER_PRESENT_ATTR_ID(7), + TRANSCEIVER_PRESENT_ATTR_ID(8), + TRANSCEIVER_PRESENT_ATTR_ID(9), + TRANSCEIVER_PRESENT_ATTR_ID(10), + TRANSCEIVER_PRESENT_ATTR_ID(11), + TRANSCEIVER_PRESENT_ATTR_ID(12), + TRANSCEIVER_PRESENT_ATTR_ID(13), + TRANSCEIVER_PRESENT_ATTR_ID(14), + TRANSCEIVER_PRESENT_ATTR_ID(15), + TRANSCEIVER_PRESENT_ATTR_ID(16), + TRANSCEIVER_PRESENT_ATTR_ID(17), + TRANSCEIVER_PRESENT_ATTR_ID(18), + TRANSCEIVER_PRESENT_ATTR_ID(19), + TRANSCEIVER_PRESENT_ATTR_ID(20), + TRANSCEIVER_PRESENT_ATTR_ID(21), + TRANSCEIVER_PRESENT_ATTR_ID(22), + TRANSCEIVER_PRESENT_ATTR_ID(23), + TRANSCEIVER_PRESENT_ATTR_ID(24), + TRANSCEIVER_PRESENT_ATTR_ID(25), + TRANSCEIVER_PRESENT_ATTR_ID(26), + TRANSCEIVER_PRESENT_ATTR_ID(27), + TRANSCEIVER_PRESENT_ATTR_ID(28), + TRANSCEIVER_PRESENT_ATTR_ID(29), + TRANSCEIVER_PRESENT_ATTR_ID(30), + TRANSCEIVER_PRESENT_ATTR_ID(31), + TRANSCEIVER_PRESENT_ATTR_ID(32), + TRANSCEIVER_PRESENT_ATTR_ID(33), + TRANSCEIVER_PRESENT_ATTR_ID(34), + TRANSCEIVER_PRESENT_ATTR_ID(35), + TRANSCEIVER_PRESENT_ATTR_ID(36), + TRANSCEIVER_PRESENT_ATTR_ID(37), + TRANSCEIVER_PRESENT_ATTR_ID(38), + TRANSCEIVER_PRESENT_ATTR_ID(39), + TRANSCEIVER_PRESENT_ATTR_ID(40), + TRANSCEIVER_PRESENT_ATTR_ID(41), + TRANSCEIVER_PRESENT_ATTR_ID(42), + TRANSCEIVER_PRESENT_ATTR_ID(43), + TRANSCEIVER_PRESENT_ATTR_ID(44), + TRANSCEIVER_PRESENT_ATTR_ID(45), + TRANSCEIVER_PRESENT_ATTR_ID(46), + TRANSCEIVER_PRESENT_ATTR_ID(47), + TRANSCEIVER_PRESENT_ATTR_ID(48), + TRANSCEIVER_PRESENT_ATTR_ID(49), + TRANSCEIVER_PRESENT_ATTR_ID(50), + TRANSCEIVER_PRESENT_ATTR_ID(51), + TRANSCEIVER_PRESENT_ATTR_ID(52), + TRANSCEIVER_PRESENT_ATTR_ID(53), + TRANSCEIVER_PRESENT_ATTR_ID(54), + TRANSCEIVER_PRESENT_ATTR_ID(55), + TRANSCEIVER_PRESENT_ATTR_ID(56), + TRANSCEIVER_PRESENT_ATTR_ID(57), + TRANSCEIVER_PRESENT_ATTR_ID(58), + TRANSCEIVER_TXDISABLE_ATTR_ID(1), + TRANSCEIVER_TXDISABLE_ATTR_ID(2), + TRANSCEIVER_TXDISABLE_ATTR_ID(3), + TRANSCEIVER_TXDISABLE_ATTR_ID(4), + TRANSCEIVER_TXDISABLE_ATTR_ID(5), + TRANSCEIVER_TXDISABLE_ATTR_ID(6), + TRANSCEIVER_TXDISABLE_ATTR_ID(7), + TRANSCEIVER_TXDISABLE_ATTR_ID(8), + TRANSCEIVER_TXDISABLE_ATTR_ID(9), + TRANSCEIVER_TXDISABLE_ATTR_ID(10), + TRANSCEIVER_TXDISABLE_ATTR_ID(11), + TRANSCEIVER_TXDISABLE_ATTR_ID(12), + TRANSCEIVER_TXDISABLE_ATTR_ID(13), + TRANSCEIVER_TXDISABLE_ATTR_ID(14), + TRANSCEIVER_TXDISABLE_ATTR_ID(15), + TRANSCEIVER_TXDISABLE_ATTR_ID(16), + TRANSCEIVER_TXDISABLE_ATTR_ID(17), + TRANSCEIVER_TXDISABLE_ATTR_ID(18), + TRANSCEIVER_TXDISABLE_ATTR_ID(19), + TRANSCEIVER_TXDISABLE_ATTR_ID(20), + TRANSCEIVER_TXDISABLE_ATTR_ID(21), + TRANSCEIVER_TXDISABLE_ATTR_ID(22), + TRANSCEIVER_TXDISABLE_ATTR_ID(23), + TRANSCEIVER_TXDISABLE_ATTR_ID(24), + TRANSCEIVER_TXDISABLE_ATTR_ID(25), + TRANSCEIVER_TXDISABLE_ATTR_ID(26), + TRANSCEIVER_TXDISABLE_ATTR_ID(27), + TRANSCEIVER_TXDISABLE_ATTR_ID(28), + TRANSCEIVER_TXDISABLE_ATTR_ID(29), + TRANSCEIVER_TXDISABLE_ATTR_ID(30), + TRANSCEIVER_TXDISABLE_ATTR_ID(31), + TRANSCEIVER_TXDISABLE_ATTR_ID(32), + TRANSCEIVER_TXDISABLE_ATTR_ID(33), + TRANSCEIVER_TXDISABLE_ATTR_ID(34), + TRANSCEIVER_TXDISABLE_ATTR_ID(35), + TRANSCEIVER_TXDISABLE_ATTR_ID(36), + TRANSCEIVER_TXDISABLE_ATTR_ID(37), + TRANSCEIVER_TXDISABLE_ATTR_ID(38), + TRANSCEIVER_TXDISABLE_ATTR_ID(39), + TRANSCEIVER_TXDISABLE_ATTR_ID(40), + TRANSCEIVER_TXDISABLE_ATTR_ID(41), + TRANSCEIVER_TXDISABLE_ATTR_ID(42), + TRANSCEIVER_TXDISABLE_ATTR_ID(43), + TRANSCEIVER_TXDISABLE_ATTR_ID(44), + TRANSCEIVER_TXDISABLE_ATTR_ID(45), + TRANSCEIVER_TXDISABLE_ATTR_ID(46), + TRANSCEIVER_TXDISABLE_ATTR_ID(47), + TRANSCEIVER_TXDISABLE_ATTR_ID(48), + TRANSCEIVER_TXDISABLE_ATTR_ID(57), + TRANSCEIVER_TXDISABLE_ATTR_ID(58), + TRANSCEIVER_RXLOS_ATTR_ID(1), + TRANSCEIVER_RXLOS_ATTR_ID(2), + TRANSCEIVER_RXLOS_ATTR_ID(3), + TRANSCEIVER_RXLOS_ATTR_ID(4), + TRANSCEIVER_RXLOS_ATTR_ID(5), + TRANSCEIVER_RXLOS_ATTR_ID(6), + TRANSCEIVER_RXLOS_ATTR_ID(7), + TRANSCEIVER_RXLOS_ATTR_ID(8), + TRANSCEIVER_RXLOS_ATTR_ID(9), + TRANSCEIVER_RXLOS_ATTR_ID(10), + TRANSCEIVER_RXLOS_ATTR_ID(11), + TRANSCEIVER_RXLOS_ATTR_ID(12), + TRANSCEIVER_RXLOS_ATTR_ID(13), + TRANSCEIVER_RXLOS_ATTR_ID(14), + TRANSCEIVER_RXLOS_ATTR_ID(15), + TRANSCEIVER_RXLOS_ATTR_ID(16), + TRANSCEIVER_RXLOS_ATTR_ID(17), + TRANSCEIVER_RXLOS_ATTR_ID(18), + TRANSCEIVER_RXLOS_ATTR_ID(19), + TRANSCEIVER_RXLOS_ATTR_ID(20), + TRANSCEIVER_RXLOS_ATTR_ID(21), + TRANSCEIVER_RXLOS_ATTR_ID(22), + TRANSCEIVER_RXLOS_ATTR_ID(23), + TRANSCEIVER_RXLOS_ATTR_ID(24), + TRANSCEIVER_RXLOS_ATTR_ID(25), + TRANSCEIVER_RXLOS_ATTR_ID(26), + TRANSCEIVER_RXLOS_ATTR_ID(27), + TRANSCEIVER_RXLOS_ATTR_ID(28), + TRANSCEIVER_RXLOS_ATTR_ID(29), + TRANSCEIVER_RXLOS_ATTR_ID(30), + TRANSCEIVER_RXLOS_ATTR_ID(31), + TRANSCEIVER_RXLOS_ATTR_ID(32), + TRANSCEIVER_RXLOS_ATTR_ID(33), + TRANSCEIVER_RXLOS_ATTR_ID(34), + TRANSCEIVER_RXLOS_ATTR_ID(35), + TRANSCEIVER_RXLOS_ATTR_ID(36), + TRANSCEIVER_RXLOS_ATTR_ID(37), + TRANSCEIVER_RXLOS_ATTR_ID(38), + TRANSCEIVER_RXLOS_ATTR_ID(39), + TRANSCEIVER_RXLOS_ATTR_ID(40), + TRANSCEIVER_RXLOS_ATTR_ID(41), + TRANSCEIVER_RXLOS_ATTR_ID(42), + TRANSCEIVER_RXLOS_ATTR_ID(43), + TRANSCEIVER_RXLOS_ATTR_ID(44), + TRANSCEIVER_RXLOS_ATTR_ID(45), + TRANSCEIVER_RXLOS_ATTR_ID(46), + TRANSCEIVER_RXLOS_ATTR_ID(47), + TRANSCEIVER_RXLOS_ATTR_ID(48), + TRANSCEIVER_RXLOS_ATTR_ID(57), + TRANSCEIVER_RXLOS_ATTR_ID(58), + TRANSCEIVER_TXFAULT_ATTR_ID(1), + TRANSCEIVER_TXFAULT_ATTR_ID(2), + TRANSCEIVER_TXFAULT_ATTR_ID(3), + TRANSCEIVER_TXFAULT_ATTR_ID(4), + TRANSCEIVER_TXFAULT_ATTR_ID(5), + TRANSCEIVER_TXFAULT_ATTR_ID(6), + TRANSCEIVER_TXFAULT_ATTR_ID(7), + TRANSCEIVER_TXFAULT_ATTR_ID(8), + TRANSCEIVER_TXFAULT_ATTR_ID(9), + TRANSCEIVER_TXFAULT_ATTR_ID(10), + TRANSCEIVER_TXFAULT_ATTR_ID(11), + TRANSCEIVER_TXFAULT_ATTR_ID(12), + TRANSCEIVER_TXFAULT_ATTR_ID(13), + TRANSCEIVER_TXFAULT_ATTR_ID(14), + TRANSCEIVER_TXFAULT_ATTR_ID(15), + TRANSCEIVER_TXFAULT_ATTR_ID(16), + TRANSCEIVER_TXFAULT_ATTR_ID(17), + TRANSCEIVER_TXFAULT_ATTR_ID(18), + TRANSCEIVER_TXFAULT_ATTR_ID(19), + TRANSCEIVER_TXFAULT_ATTR_ID(20), + TRANSCEIVER_TXFAULT_ATTR_ID(21), + TRANSCEIVER_TXFAULT_ATTR_ID(22), + TRANSCEIVER_TXFAULT_ATTR_ID(23), + TRANSCEIVER_TXFAULT_ATTR_ID(24), + TRANSCEIVER_TXFAULT_ATTR_ID(25), + TRANSCEIVER_TXFAULT_ATTR_ID(26), + TRANSCEIVER_TXFAULT_ATTR_ID(27), + TRANSCEIVER_TXFAULT_ATTR_ID(28), + TRANSCEIVER_TXFAULT_ATTR_ID(29), + TRANSCEIVER_TXFAULT_ATTR_ID(30), + TRANSCEIVER_TXFAULT_ATTR_ID(31), + TRANSCEIVER_TXFAULT_ATTR_ID(32), + TRANSCEIVER_TXFAULT_ATTR_ID(33), + TRANSCEIVER_TXFAULT_ATTR_ID(34), + TRANSCEIVER_TXFAULT_ATTR_ID(35), + TRANSCEIVER_TXFAULT_ATTR_ID(36), + TRANSCEIVER_TXFAULT_ATTR_ID(37), + TRANSCEIVER_TXFAULT_ATTR_ID(38), + TRANSCEIVER_TXFAULT_ATTR_ID(39), + TRANSCEIVER_TXFAULT_ATTR_ID(40), + TRANSCEIVER_TXFAULT_ATTR_ID(41), + TRANSCEIVER_TXFAULT_ATTR_ID(42), + TRANSCEIVER_TXFAULT_ATTR_ID(43), + TRANSCEIVER_TXFAULT_ATTR_ID(44), + TRANSCEIVER_TXFAULT_ATTR_ID(45), + TRANSCEIVER_TXFAULT_ATTR_ID(46), + TRANSCEIVER_TXFAULT_ATTR_ID(47), + TRANSCEIVER_TXFAULT_ATTR_ID(48), + TRANSCEIVER_TXFAULT_ATTR_ID(57), + TRANSCEIVER_TXFAULT_ATTR_ID(58), +}; + +/* sysfs attributes for hwmon + */ +static ssize_t show_status(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_present_all(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t access(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t show_version(struct device *dev, struct device_attribute *da, + char *buf); +static int as7326_56x_cpld_read_internal(struct i2c_client *client, u8 reg); +static int as7326_56x_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value); + +/* transceiver attributes */ +#define DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(index) \ + static SENSOR_DEVICE_ATTR(module_present_##index, S_IRUGO, show_status, NULL, MODULE_PRESENT_##index) +#define DECLARE_TRANSCEIVER_PRESENT_ATTR(index) &sensor_dev_attr_module_present_##index.dev_attr.attr + +#define DECLARE_TRANSCEIVER_RESET_SENSOR_DEVICE_ATTR(index) \ + static SENSOR_DEVICE_ATTR(module_reset_##index, S_IRUGO | S_IWUSR, show_status, set_reset, MODULE_RESET_##index) +#define DECLARE_TRANSCEIVER_RESET_ATTR(index) &sensor_dev_attr_module_reset_##index.dev_attr.attr + +#define DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(index) \ + static SENSOR_DEVICE_ATTR(module_tx_disable_##index, S_IRUGO | S_IWUSR, show_status, set_tx_disable, MODULE_TXDISABLE_##index); \ + static SENSOR_DEVICE_ATTR(module_rx_los_##index, S_IRUGO, show_status, NULL, MODULE_RXLOS_##index); \ + static SENSOR_DEVICE_ATTR(module_tx_fault_##index, S_IRUGO, show_status, NULL, MODULE_TXFAULT_##index) +#define DECLARE_SFP_TRANSCEIVER_ATTR(index) \ + &sensor_dev_attr_module_tx_disable_##index.dev_attr.attr, \ + &sensor_dev_attr_module_rx_los_##index.dev_attr.attr, \ + &sensor_dev_attr_module_tx_fault_##index.dev_attr.attr + +static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, CPLD_VERSION); +static SENSOR_DEVICE_ATTR(access, S_IWUSR, NULL, access, ACCESS); +/* transceiver attributes */ +static SENSOR_DEVICE_ATTR(module_present_all, S_IRUGO, show_present_all, NULL, MODULE_PRESENT_ALL); +static SENSOR_DEVICE_ATTR(module_rx_los_all, S_IRUGO, show_rxlos_all, NULL, MODULE_RXLOS_ALL); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(1); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(2); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(3); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(4); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(5); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(6); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(7); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(8); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(9); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(10); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(11); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(12); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(13); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(14); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(15); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(16); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(17); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(18); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(19); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(20); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(21); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(22); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(23); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(24); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(25); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(26); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(27); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(28); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(29); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(30); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(31); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(32); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(33); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(34); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(35); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(36); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(37); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(38); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(39); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(40); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(41); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(42); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(43); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(44); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(45); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(46); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(47); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(48); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(49); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(50); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(51); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(52); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(53); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(54); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(55); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(56); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(57); +DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(58); + +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(1); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(2); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(3); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(4); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(5); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(6); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(7); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(8); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(9); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(10); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(11); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(12); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(13); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(14); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(15); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(16); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(17); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(18); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(19); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(20); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(21); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(22); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(23); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(24); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(25); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(26); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(27); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(28); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(29); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(30); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(31); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(32); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(33); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(34); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(35); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(36); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(37); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(38); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(39); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(40); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(41); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(42); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(43); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(44); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(45); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(46); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(47); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(48); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(57); +DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(58); + +static struct attribute *as7326_56x_cpld3_attributes[] = { + &sensor_dev_attr_version.dev_attr.attr, + &sensor_dev_attr_access.dev_attr.attr, + NULL +}; + +static const struct attribute_group as7326_56x_cpld3_group = { + .attrs = as7326_56x_cpld3_attributes, +}; + +static struct attribute *as7326_56x_cpld2_attributes[] = { + &sensor_dev_attr_version.dev_attr.attr, + &sensor_dev_attr_access.dev_attr.attr, + /* transceiver attributes */ + &sensor_dev_attr_module_present_all.dev_attr.attr, + &sensor_dev_attr_module_rx_los_all.dev_attr.attr, + DECLARE_TRANSCEIVER_PRESENT_ATTR(1), + DECLARE_TRANSCEIVER_PRESENT_ATTR(2), + DECLARE_TRANSCEIVER_PRESENT_ATTR(3), + DECLARE_TRANSCEIVER_PRESENT_ATTR(4), + DECLARE_TRANSCEIVER_PRESENT_ATTR(5), + DECLARE_TRANSCEIVER_PRESENT_ATTR(6), + DECLARE_TRANSCEIVER_PRESENT_ATTR(7), + DECLARE_TRANSCEIVER_PRESENT_ATTR(8), + DECLARE_TRANSCEIVER_PRESENT_ATTR(9), + DECLARE_TRANSCEIVER_PRESENT_ATTR(10), + DECLARE_TRANSCEIVER_PRESENT_ATTR(11), + DECLARE_TRANSCEIVER_PRESENT_ATTR(12), + DECLARE_TRANSCEIVER_PRESENT_ATTR(13), + DECLARE_TRANSCEIVER_PRESENT_ATTR(14), + DECLARE_TRANSCEIVER_PRESENT_ATTR(15), + DECLARE_TRANSCEIVER_PRESENT_ATTR(16), + DECLARE_TRANSCEIVER_PRESENT_ATTR(17), + DECLARE_TRANSCEIVER_PRESENT_ATTR(18), + DECLARE_TRANSCEIVER_PRESENT_ATTR(19), + DECLARE_TRANSCEIVER_PRESENT_ATTR(20), + DECLARE_TRANSCEIVER_PRESENT_ATTR(21), + DECLARE_TRANSCEIVER_PRESENT_ATTR(22), + DECLARE_TRANSCEIVER_PRESENT_ATTR(23), + DECLARE_TRANSCEIVER_PRESENT_ATTR(24), + DECLARE_TRANSCEIVER_PRESENT_ATTR(25), + DECLARE_TRANSCEIVER_PRESENT_ATTR(26), + DECLARE_TRANSCEIVER_PRESENT_ATTR(27), + DECLARE_TRANSCEIVER_PRESENT_ATTR(28), + DECLARE_TRANSCEIVER_PRESENT_ATTR(29), + DECLARE_TRANSCEIVER_PRESENT_ATTR(30), + DECLARE_SFP_TRANSCEIVER_ATTR(1), + DECLARE_SFP_TRANSCEIVER_ATTR(2), + DECLARE_SFP_TRANSCEIVER_ATTR(3), + DECLARE_SFP_TRANSCEIVER_ATTR(4), + DECLARE_SFP_TRANSCEIVER_ATTR(5), + DECLARE_SFP_TRANSCEIVER_ATTR(6), + DECLARE_SFP_TRANSCEIVER_ATTR(7), + DECLARE_SFP_TRANSCEIVER_ATTR(8), + DECLARE_SFP_TRANSCEIVER_ATTR(9), + DECLARE_SFP_TRANSCEIVER_ATTR(10), + DECLARE_SFP_TRANSCEIVER_ATTR(11), + DECLARE_SFP_TRANSCEIVER_ATTR(12), + DECLARE_SFP_TRANSCEIVER_ATTR(13), + DECLARE_SFP_TRANSCEIVER_ATTR(14), + DECLARE_SFP_TRANSCEIVER_ATTR(15), + DECLARE_SFP_TRANSCEIVER_ATTR(16), + DECLARE_SFP_TRANSCEIVER_ATTR(17), + DECLARE_SFP_TRANSCEIVER_ATTR(18), + DECLARE_SFP_TRANSCEIVER_ATTR(19), + DECLARE_SFP_TRANSCEIVER_ATTR(20), + DECLARE_SFP_TRANSCEIVER_ATTR(21), + DECLARE_SFP_TRANSCEIVER_ATTR(22), + DECLARE_SFP_TRANSCEIVER_ATTR(23), + DECLARE_SFP_TRANSCEIVER_ATTR(24), + DECLARE_SFP_TRANSCEIVER_ATTR(25), + DECLARE_SFP_TRANSCEIVER_ATTR(26), + DECLARE_SFP_TRANSCEIVER_ATTR(27), + DECLARE_SFP_TRANSCEIVER_ATTR(28), + DECLARE_SFP_TRANSCEIVER_ATTR(29), + DECLARE_SFP_TRANSCEIVER_ATTR(30), + NULL +}; + +static const struct attribute_group as7326_56x_cpld2_group = { + .attrs = as7326_56x_cpld2_attributes, +}; + +static struct attribute *as7326_56x_cpld1_attributes[] = { + &sensor_dev_attr_version.dev_attr.attr, + &sensor_dev_attr_access.dev_attr.attr, + /* transceiver attributes */ + &sensor_dev_attr_module_present_all.dev_attr.attr, + &sensor_dev_attr_module_rx_los_all.dev_attr.attr, + DECLARE_TRANSCEIVER_PRESENT_ATTR(31), + DECLARE_TRANSCEIVER_PRESENT_ATTR(32), + DECLARE_TRANSCEIVER_PRESENT_ATTR(33), + DECLARE_TRANSCEIVER_PRESENT_ATTR(34), + DECLARE_TRANSCEIVER_PRESENT_ATTR(35), + DECLARE_TRANSCEIVER_PRESENT_ATTR(36), + DECLARE_TRANSCEIVER_PRESENT_ATTR(37), + DECLARE_TRANSCEIVER_PRESENT_ATTR(38), + DECLARE_TRANSCEIVER_PRESENT_ATTR(39), + DECLARE_TRANSCEIVER_PRESENT_ATTR(40), + DECLARE_TRANSCEIVER_PRESENT_ATTR(41), + DECLARE_TRANSCEIVER_PRESENT_ATTR(42), + DECLARE_TRANSCEIVER_PRESENT_ATTR(43), + DECLARE_TRANSCEIVER_PRESENT_ATTR(44), + DECLARE_TRANSCEIVER_PRESENT_ATTR(45), + DECLARE_TRANSCEIVER_PRESENT_ATTR(46), + DECLARE_TRANSCEIVER_PRESENT_ATTR(47), + DECLARE_TRANSCEIVER_PRESENT_ATTR(48), + DECLARE_TRANSCEIVER_PRESENT_ATTR(49), + DECLARE_TRANSCEIVER_PRESENT_ATTR(50), + DECLARE_TRANSCEIVER_PRESENT_ATTR(51), + DECLARE_TRANSCEIVER_PRESENT_ATTR(52), + DECLARE_TRANSCEIVER_PRESENT_ATTR(53), + DECLARE_TRANSCEIVER_PRESENT_ATTR(54), + DECLARE_TRANSCEIVER_PRESENT_ATTR(55), + DECLARE_TRANSCEIVER_PRESENT_ATTR(56), + DECLARE_TRANSCEIVER_PRESENT_ATTR(57), + DECLARE_TRANSCEIVER_PRESENT_ATTR(58), + DECLARE_SFP_TRANSCEIVER_ATTR(31), + DECLARE_SFP_TRANSCEIVER_ATTR(32), + DECLARE_SFP_TRANSCEIVER_ATTR(33), + DECLARE_SFP_TRANSCEIVER_ATTR(34), + DECLARE_SFP_TRANSCEIVER_ATTR(35), + DECLARE_SFP_TRANSCEIVER_ATTR(36), + DECLARE_SFP_TRANSCEIVER_ATTR(37), + DECLARE_SFP_TRANSCEIVER_ATTR(38), + DECLARE_SFP_TRANSCEIVER_ATTR(39), + DECLARE_SFP_TRANSCEIVER_ATTR(40), + DECLARE_SFP_TRANSCEIVER_ATTR(41), + DECLARE_SFP_TRANSCEIVER_ATTR(42), + DECLARE_SFP_TRANSCEIVER_ATTR(43), + DECLARE_SFP_TRANSCEIVER_ATTR(44), + DECLARE_SFP_TRANSCEIVER_ATTR(45), + DECLARE_SFP_TRANSCEIVER_ATTR(46), + DECLARE_SFP_TRANSCEIVER_ATTR(47), + DECLARE_SFP_TRANSCEIVER_ATTR(48), + DECLARE_SFP_TRANSCEIVER_ATTR(57), + DECLARE_SFP_TRANSCEIVER_ATTR(58), + NULL +}; + +static const struct attribute_group as7326_56x_cpld1_group = { + .attrs = as7326_56x_cpld1_attributes, +}; + +static ssize_t show_present_all(struct device *dev, struct device_attribute *da, + char *buf) +{ + int i, status; + u8 values[4] = {0}; + u8 regs[] = {0x9, 0xA, 0xB, 0x18}; + struct i2c_client *client = to_i2c_client(dev); + struct as7326_56x_cpld_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + for (i = 0; i < ARRAY_SIZE(regs); i++) { + status = as7326_56x_cpld_read_internal(client, regs[i]); + + if (status < 0) { + goto exit; + } + + values[i] = ~(u8)status; + } + + mutex_unlock(&data->update_lock); + + /* Return values 1 -> 56 in order */ + if (data->type == as7326_56x_cpld2) { + values[3] &= 0xF; + } + else { /* as7326_56x_cpld3 */ + values[3] &= 0x3; + } + + return sprintf(buf, "%.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], values[3]); + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da, + char *buf) +{ + int i, status; + u8 values[3] = {0}; + u8 regs[] = {0x12, 0x13, 0x14}; + struct i2c_client *client = to_i2c_client(dev); + struct as7326_56x_cpld_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + for (i = 0; i < ARRAY_SIZE(regs); i++) { + status = as7326_56x_cpld_read_internal(client, regs[i]); + + if (status < 0) { + goto exit; + } + + values[i] = (u8)status; + } + + mutex_unlock(&data->update_lock); + + /* Return values 1 -> 24 in order */ + return sprintf(buf, "%.2x %.2x %.2x\n", values[0], values[1], values[2]); + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t show_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as7326_56x_cpld_data *data = i2c_get_clientdata(client); + int status = 0; + u8 reg = 0, mask = 0, revert = 0; + + switch (attr->index) { + case MODULE_PRESENT_1 ... MODULE_PRESENT_30: + reg = 0x0f + (attr->index-MODULE_PRESENT_1)/8; + mask = 0x1 << ((attr->index - MODULE_PRESENT_1)%8); + break; + case MODULE_PRESENT_31 ... MODULE_PRESENT_48: + reg = 0x10 + (attr->index-MODULE_PRESENT_31)/8; + mask = 0x1 << ((attr->index - MODULE_PRESENT_31)%8); + break; + case MODULE_PRESENT_57 ... MODULE_PRESENT_58: + reg = 0x12; + mask = 0x1 << (( MODULE_PRESENT_58 - attr->index)+2); + break; + case MODULE_PRESENT_49 ... MODULE_PRESENT_56: /*QSFP*/ + reg = 0x13 ; + mask = 0x1 << ((attr->index - MODULE_PRESENT_49)%8); + break; + case MODULE_TXFAULT_1 ... MODULE_TXFAULT_30: + reg = 0x03 + (attr->index - MODULE_TXFAULT_1)/8; + mask = 0x1 << ((attr->index - MODULE_TXFAULT_1)%8); + break; + case MODULE_TXFAULT_31 ... MODULE_TXFAULT_48: + reg = 0x1a + (attr->index-MODULE_TXFAULT_31)/8; + mask = 0x1 << ((attr->index - MODULE_TXFAULT_31)%8); + break; + case MODULE_TXFAULT_57 ... MODULE_TXFAULT_58: + reg = 0x1c; + mask = 0x1 << (( attr->index - MODULE_TXFAULT_57)+2); + break; + case MODULE_TXDISABLE_1 ... MODULE_TXDISABLE_30: + reg = 0x07 + (attr->index - MODULE_TXDISABLE_1)/8; + mask = 0x1 << ((attr->index - MODULE_TXDISABLE_1)%8); + break; + case MODULE_TXDISABLE_31 ... MODULE_TXDISABLE_48: + reg = 0x14 + (attr->index-MODULE_TXDISABLE_31)/8; + mask = 0x1 << ((attr->index - MODULE_TXDISABLE_31)%8); + break; + case MODULE_TXDISABLE_57 ... MODULE_TXDISABLE_58: + reg = 0x16; + mask = 0x1 << ((attr->index - MODULE_TXDISABLE_57)+2); + break; + case MODULE_RXLOS_1 ... MODULE_RXLOS_30: + reg = 0x0b + (attr->index - MODULE_RXLOS_1)/8; + mask = 0x1 << ((attr->index - MODULE_RXLOS_1)%8); + break; + case MODULE_RXLOS_31 ... MODULE_RXLOS_48: + reg = 0x17 + (attr->index-MODULE_RXLOS_31)/8; + mask = 0x1 << ((attr->index - MODULE_RXLOS_31)%8); + break; + case MODULE_RXLOS_57 ... MODULE_RXLOS_58: + reg = 0x19; + mask = 0x1 << (( attr->index - MODULE_RXLOS_57)+2); + break; + default: + return 0; + } + + if (attr->index >= MODULE_PRESENT_1 && attr->index <= MODULE_PRESENT_56) { + revert = 1; + } + + mutex_lock(&data->update_lock); + status = as7326_56x_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", revert ? !(status & mask) : !!(status & mask)); + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as7326_56x_cpld_data *data = i2c_get_clientdata(client); + long disable; + int status; + u8 reg = 0, mask = 0; + + status = kstrtol(buf, 10, &disable); + if (status) { + return status; + } + + switch (attr->index) { + case MODULE_TXDISABLE_1 ... MODULE_TXDISABLE_30: + reg = 0x07 + (attr->index - MODULE_TXDISABLE_1)/8; + mask = 0x1 << ((attr->index - MODULE_TXDISABLE_1)%8); + break; + case MODULE_TXDISABLE_31 ... MODULE_TXDISABLE_48: + reg = 0x14 + (attr->index - MODULE_TXDISABLE_31)/8; + mask = 0x1 << ((attr->index - MODULE_TXDISABLE_31)%8); + break; + case MODULE_TXDISABLE_57 ... MODULE_TXDISABLE_58: + reg = 0x16; + mask = 0x1 << ((attr->index - MODULE_TXDISABLE_57)+2); + break; + default: + return 0; + } + + /* Read current status */ + mutex_lock(&data->update_lock); + status = as7326_56x_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + + /* Update tx_disable status */ + if (disable) { + status |= mask; + } + else { + status &= ~mask; + } + + status = as7326_56x_cpld_write_internal(client, reg, status); + if (unlikely(status < 0)) { + goto exit; + } + + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t access(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int status; + u32 addr, val; + struct i2c_client *client = to_i2c_client(dev); + struct as7326_56x_cpld_data *data = i2c_get_clientdata(client); + + if (sscanf(buf, "0x%x 0x%x", &addr, &val) != 2) { + return -EINVAL; + } + + if (addr > 0xFF || val > 0xFF) { + return -EINVAL; + } + + mutex_lock(&data->update_lock); + status = as7326_56x_cpld_write_internal(client, addr, val); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static void as7326_56x_cpld_add_client(struct i2c_client *client) +{ + struct cpld_client_node *node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", client->addr); + return; + } + + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &cpld_client_list); + mutex_unlock(&list_lock); +} + +static void as7326_56x_cpld_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client == client) { + found = 1; + break; + } + } + + if (found) { + list_del(list_node); + kfree(cpld_node); + } + + mutex_unlock(&list_lock); +} + +static ssize_t show_version(struct device *dev, struct device_attribute *attr, char *buf) +{ + int val = 0; + struct i2c_client *client = to_i2c_client(dev); + + val = i2c_smbus_read_byte_data(client, 0x1); + + if (val < 0) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x1) err %d\n", client->addr, val); + } + + return sprintf(buf, "%d", val); +} + +/* + * I2C init/probing/exit functions + */ +static int as7326_56x_cpld_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); + struct as7326_56x_cpld_data *data; + int ret = -ENODEV; + const struct attribute_group *group = NULL; + + if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE)) + goto exit; + + data = kzalloc(sizeof(struct as7326_56x_cpld_data), GFP_KERNEL); + if (!data) { + ret = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->type = id->driver_data; + + /* Register sysfs hooks */ + switch (data->type) { + case as7326_56x_cpld1: + group = &as7326_56x_cpld1_group; + break; + case as7326_56x_cpld2: + group = &as7326_56x_cpld2_group; + break; + case as7326_56x_cpld3: + group = &as7326_56x_cpld3_group; + break; + default: + break; + } + + if (group) { + ret = sysfs_create_group(&client->dev.kobj, group); + if (ret) { + goto exit_free; + } + } + + as7326_56x_cpld_add_client(client); + return 0; + +exit_free: + kfree(data); +exit: + return ret; +} + +static int as7326_56x_cpld_remove(struct i2c_client *client) +{ + struct as7326_56x_cpld_data *data = i2c_get_clientdata(client); + const struct attribute_group *group = NULL; + + as7326_56x_cpld_remove_client(client); + + /* Remove sysfs hooks */ + switch (data->type) { + case as7326_56x_cpld1: + group = &as7326_56x_cpld1_group; + break; + case as7326_56x_cpld2: + group = &as7326_56x_cpld2_group; + break; + case as7326_56x_cpld3: + group = &as7326_56x_cpld3_group; + break; + default: + break; + } + + if (group) { + sysfs_remove_group(&client->dev.kobj, group); + } + + kfree(data); + + return 0; +} + +static int as7326_56x_cpld_read_internal(struct i2c_client *client, u8 reg) +{ + int status = 0, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_read_byte_data(client, reg); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + return status; +} + +static int as7326_56x_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value) +{ + int status = 0, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_write_byte_data(client, reg, value); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + return status; +} + +int as7326_56x_cpld_read(unsigned short cpld_addr, u8 reg) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EPERM; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = as7326_56x_cpld_read_internal(cpld_node->client, reg); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(as7326_56x_cpld_read); + +int as7326_56x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EIO; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = as7326_56x_cpld_write_internal(cpld_node->client, reg, value); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(as7326_56x_cpld_write); + +static struct i2c_driver as7326_56x_cpld_driver = { + .driver = { + .name = "as7326_56x_cpld", + .owner = THIS_MODULE, + }, + .probe = as7326_56x_cpld_probe, + .remove = as7326_56x_cpld_remove, + .id_table = as7326_56x_cpld_id, +}; + +static int __init as7326_56x_cpld_init(void) +{ + mutex_init(&list_lock); + return i2c_add_driver(&as7326_56x_cpld_driver); +} + +static void __exit as7326_56x_cpld_exit(void) +{ + i2c_del_driver(&as7326_56x_cpld_driver); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("Accton I2C CPLD driver"); +MODULE_LICENSE("GPL"); + +module_init(as7326_56x_cpld_init); +module_exit(as7326_56x_cpld_exit); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/ym2651y.c b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/ym2651y.c new file mode 120000 index 000000000000..f4d67640ccc3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/modules/ym2651y.c @@ -0,0 +1 @@ +../../common/modules/ym2651y.c \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/service/as7326-platform-monitor.service b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/service/as7326-platform-monitor.service new file mode 100755 index 000000000000..3af4405fb493 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/service/as7326-platform-monitor.service @@ -0,0 +1,17 @@ +[Unit] +Description=Accton AS7326-56X Platform Monitoring service +Before=pmon.service +After=sysinit.target +DefaultDependencies=no + +[Service] +ExecStartPre=/usr/local/bin/accton_as7326_util.py install +ExecStart=/usr/local/bin/accton_as7326_monitor.py +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/setup.py b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/setup.py new file mode 100755 index 000000000000..77114c71285b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/setup.py @@ -0,0 +1,16 @@ +#!/usr/bin/env pytho + +import os +import sys +from setuptools import setup +os.listdir + +setup( + name='as7326_56x', + version='1.0', + description='Module to initialize Accton AS7326-56X platforms', + + packages=['as7326_56x'], + package_dir={'as7326_56x': 'as7326-56x/classes'}, +) + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/README b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/README new file mode 100755 index 000000000000..ef0d03cf5e45 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/README @@ -0,0 +1,74 @@ +Copyright (C) 2016 Accton Networks, 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 3 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, see . + +Contents of this package: + module - Contains source code of as7326 kernel driver modules. + util - operational scripts. + +Sonic creates a docker container and run building process under it. +If user tries to built new drivers, please get into that docker and +dpkg-buildpackage for them. + +All Linux kernel code is licensed under the GPLv1. All other code is +licensed under the GPLv3. Please see the LICENSE file for copies of +both licenses. + +The code for integacting with Accton AS7326-56X has 2 parts, +kernel drivers and operational script. +The kernel drivers of peripherals are under module/ directory. +1. These drivers can be built to individual ko during dpkg-buildpackage. +2. A operational script, accton_as7326_util.py, for device initializatian. + Run "accton_as7326_util.py install" to install drivers. + +To initialize the system, run "accton_as7326_util.py install". +To clean up the drivers & devices, run "accton_as7326_util.py clean". +To dump information of sensors, run "accton_as7326_util.py show". +To dump SFP EEPROM, run "accton_as7326_util.py sff". +To set fan speed, run "accton_as7326_util.py set fan". +To enable/disable SFP emission, run "accton_as7326_util.py set sfp". +To set system LEDs' color, run "accton_as7326_util.py set led" +For more information, run "accton_as7326_util.py --help". + +==================================================================== +Besides applying accton_as7326_util.py to access peripherals, you can +access peripherals by sysfs nodes directly after the installation is run. + +System LED: + There are 5 system LEDs at the lower-left corner of front panel. + They are loc, diag, fan, ps1, and ps2. + The sysfs interface color mappings are as follows: + Brightness: + 0 => off + 1 => green + 2 => amber + 3 => red + 4 => blue + But not all colors are available for each LED. + +Fan Control: + There are 10 fans inside 6 fan modules. + All fans share 1 duty setting, ranged from 0~100. + +Thermal sensers: + 3 temperature sensors are controlled by the lm75 kernel modules. + +PSUs: + There 2 power supplies slot at the left/right side of the back. + Once if a PSU is not plugged, the status of it is shown failed. + +There are 48 SFP+ and 8 QSFP modules are equipped. +Before operating on PSU and QSFP+, please make sure it is well plugged. +Otherwise, operation is going to fail. + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_monitor.py new file mode 100755 index 000000000000..856f194c5e53 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_monitor.py @@ -0,0 +1,208 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 Accton Technology Corporation +# +# 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 3 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, see . + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 11/13/2017: Polly Hsu, Create +# 1/10/2018: Jostar modify for as7716_32 +# 3/23/2018: Roy Lee modify for as7326_56x +# ------------------------------------------------------------------ + +try: + import os + import sys, getopt + import subprocess + import click + import imp + import logging + import logging.config + import types + import time # this is only being used as part of the example + import traceback + from tabulate import tabulate + from as7326_56x.fanutil import FanUtil + from as7326_56x.thermalutil import ThermalUtil +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + +# Deafults +VERSION = '1.0' +FUNCTION_NAME = 'accton_as7326_monitor' + +global log_file +global log_level + +# (LM75_1+ LM75_2+ LM75_3) is LM75 at i2c addresses 0x48, 0x49, and 0x4A. +# TMP = (LM75_1+ LM75_2+ LM75_3)/3 +#1. If TMP < 35, All fans run with duty 31.25%. +#2. If TMP>=35 or the temperature of any one of fan is higher than 40, +# All fans run with duty 50% +#3. If TMP >= 40 or the temperature of any one of fan is higher than 45, +# All fans run with duty 62.5%. +#4. If TMP >= 45 or the temperature of any one of fan is higher than 50, +# All fans run with duty 100%. +#5. Any one of 6 fans is fault, set duty = 100%. +#6. Direction factor. If it is B2F direction, duty + 12%. + + # MISC: + # 1.Check single LM75 before applied average. + # 2.If no matched fan speed is found from the policy, + # use FAN_DUTY_CYCLE_MIN as default speed + # Get current temperature + # 4.Decision 3: Decide new fan speed depend on fan direction/current fan speed/temperature + + + + +# Make a class we can use to capture stdout and sterr in the log +class accton_as7326_monitor(object): + # static temp var + _ori_temp = 0 + _new_perc = 0 + _ori_perc = 0 + + def __init__(self, log_file, log_level): + """Needs a logger and a logger level.""" + # set up logging to file + logging.basicConfig( + filename=log_file, + filemode='w', + level=log_level, + format= '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s', + datefmt='%H:%M:%S' + ) + + # set up logging to console + if log_level == logging.DEBUG: + console = logging.StreamHandler() + console.setLevel(log_level) + formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') + console.setFormatter(formatter) + logging.getLogger('').addHandler(console) + + logging.debug('SET. logfile:%s / loglevel:%d', log_file, log_level) + + def manage_fans(self): + max_duty = 100 + fan_policy_f2b = { + 0: [32, 0, 105000], + 1: [50, 105000, 120000], + 2: [63, 120000, 135000], + 3: [max_duty, 135000, sys.maxsize], + } + fan_policy_b2f = { + 0: [44, 0, 105000], + 1: [63, 105000, 120000], + 2: [75, 120000, 135000], + 3: [max_duty, 135000, sys.maxsize], + } + fan_policy_single = { + 0: 40000, + 1: 45000, + 2: 50000, + } + + thermal = ThermalUtil() + fan = FanUtil() + for x in range(fan.get_idx_fan_start(), fan.get_num_fans()+1): + fan_status = fan.get_fan_status(x) + if fan_status is None: + logging.debug('INFO. SET new_perc to %d (FAN stauts is None. fan_num:%d)', max_duty, x) + return False + if fan_status is False: + logging.debug('INFO. SET new_perc to %d (FAN fault. fan_num:%d)', max_duty, x) + fan.set_fan_duty_cycle(max_duty) + return True + #logging.debug('INFO. fan_status is True (fan_num:%d)', x) + + fan_dir=fan.get_fan_dir(1) + if fan_dir == 1: + fan_policy = fan_policy_f2b + else: + fan_policy = fan_policy_b2f + + #Decide fan duty by if any of sensors > fan_policy_single. + new_duty_cycle = fan_policy[0][0] + for x in range(thermal.get_idx_thermal_start(), thermal.get_num_thermals()+1): + single_thm = thermal._get_thermal_node_val(x) + for y in range(0, len(fan_policy_single)): + if single_thm > fan_policy_single[y]: + if fan_policy[y+1][0] > new_duty_cycle: + new_duty_cycle = fan_policy[y+1][0] + logging.debug('INFO. Single thermal sensor %d with temp %d > %d , new_duty_cycle=%d', + x, single_thm, fan_policy_single[y], new_duty_cycle) + single_result = new_duty_cycle + + + #Find if current duty matched any of define duty. + #If not, set it to highest one. + cur_duty_cycle = fan.get_fan_duty_cycle() + for x in range(0, len(fan_policy)): + if cur_duty_cycle == fan_policy[x][0]: + break + if x == len(fan_policy) : + fan.set_fan_duty_cycle(fan_policy[0][0]) + cur_duty_cycle = max_duty + + #Decide fan duty by if sum of sensors falls into any of fan_policy{} + get_temp = thermal.get_thermal_temp() + new_duty_cycle = cur_duty_cycle + for x in range(0, len(fan_policy)): + y = len(fan_policy) - x -1 #checked from highest + if get_temp > fan_policy[y][1] and get_temp < fan_policy[y][2] : + new_duty_cycle= fan_policy[y][0] + logging.debug('INFO. Sum of temp %d > %d , new_duty_cycle=%d', get_temp, fan_policy[y][1], new_duty_cycle) + + sum_result = new_duty_cycle + if (sum_result>single_result): + new_duty_cycle = sum_result; + else: + new_duty_cycle = single_result + + logging.debug('INFO. Final duty_cycle=%d', new_duty_cycle) + if(new_duty_cycle != cur_duty_cycle): + fan.set_fan_duty_cycle(new_duty_cycle) + return True + +def main(argv): + log_file = '%s.log' % FUNCTION_NAME + log_level = logging.INFO + if len(sys.argv) != 1: + try: + opts, args = getopt.getopt(argv,'hdl:',['lfile=']) + except getopt.GetoptError: + print 'Usage: %s [-d] [-l ]' % sys.argv[0] + return 0 + for opt, arg in opts: + if opt == '-h': + print 'Usage: %s [-d] [-l ]' % sys.argv[0] + return 0 + elif opt in ('-d', '--debug'): + log_level = logging.DEBUG + elif opt in ('-l', '--lfile'): + log_file = arg + + monitor = accton_as7326_monitor(log_file, log_level) + + # Loop forever, doing something useful hopefully: + while True: + monitor.manage_fans() + time.sleep(10) + +if __name__ == '__main__': + main(sys.argv[1:]) diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_util.py b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_util.py new file mode 100755 index 000000000000..900bfa805a21 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/utils/accton_as7326_util.py @@ -0,0 +1,577 @@ +#!/usr/bin/env python +# +# Copyright (C) 2016 Accton Networks, 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 3 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, see . +# +# +# Description: +# Due to adoption of optoe drivers, sideband signals of SFPs are moved +# into cpld drivers. Add a new dict, cpld_of_module, for mapping this +# attributes to corresponding cpld nodes. +# + + + +""" +Usage: %(scriptName)s [options] command object + +options: + -h | --help : this help message + -d | --debug : run with debug mode + -f | --force : ignore error during installation or clean +command: + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes + show : show all systen status + sff : dump SFP eeprom + set : change board setting with fan|led|sfp +""" + +import os +import commands +import sys, getopt +import logging +import re +import time +from collections import namedtuple + + + + +PROJECT_NAME = 'as7326_56x' +version = '0.1.0' +verbose = False +DEBUG = False +args = [] +ALL_DEVICE = {} +DEVICE_NO = {'led':5, 'fan':6,'thermal':4, 'psu':2, 'sfp':58} +FORCE = 0 +#logging.basicConfig(filename= PROJECT_NAME+'.log', filemode='w',level=logging.DEBUG) +#logging.basicConfig(level=logging.INFO) + + +if DEBUG == True: + print sys.argv[0] + print 'ARGV :', sys.argv[1:] + + +def main(): + global DEBUG + global args + global FORCE + + if len(sys.argv)<2: + show_help() + + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', + 'debug', + 'force', + ]) + if DEBUG == True: + print options + print args + print len(sys.argv) + + for opt, arg in options: + if opt in ('-h', '--help'): + show_help() + elif opt in ('-d', '--debug'): + DEBUG = True + logging.basicConfig(level=logging.INFO) + elif opt in ('-f', '--force'): + FORCE = 1 + else: + logging.info('no option') + for arg in args: + if arg == 'install': + do_install() + elif arg == 'clean': + do_uninstall() + elif arg == 'show': + device_traversal() + elif arg == 'sff': + if len(args)!=2: + show_eeprom_help() + elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']: + show_eeprom_help() + else: + show_eeprom(args[1]) + return + elif arg == 'set': + if len(args)<3: + show_set_help() + else: + set_device(args[1:]) + return + else: + show_help() + + + return 0 + +def show_help(): + print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + sys.exit(0) + +def show_set_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print cmd +" [led|sfp|fan]" + print " use \""+ cmd + " led 0-4 \" to set led color" + print " use \""+ cmd + " fan 0-100\" to set fan duty percetage" + print " use \""+ cmd + " sfp 1-56 {0|1}\" to set sfp# tx_disable" + sys.exit(0) + +def show_eeprom_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print " use \""+ cmd + " 1-56 \" to dump sfp# eeprom" + sys.exit(0) + +def my_log(txt): + if DEBUG == True: + print "[ROY]"+txt + return + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) + my_log (cmd +"with result:" + str(status)) + my_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + +def driver_check(): + ret, lsmod = log_os_system("lsmod| grep accton", 0) + logging.info('mods:'+lsmod) + if len(lsmod) ==0: + return False + return True + + + +kos = [ +'modprobe i2c_dev', +'modprobe i2c_mux_pca954x force_deselect_on_exit=1', +'modprobe accton_i2c_cpld' , +'modprobe ym2651y' , +'modprobe accton_as7326_56x_fan' , +'modprobe optoe' , +'modprobe accton_as7326_56x_leds' , +'modprobe accton_as7326_56x_psu' ] + +def driver_install(): + global FORCE + status, output = log_os_system("depmod", 1) + for i in range(0,len(kos)): + status, output = log_os_system(kos[i], 1) + if status: + if FORCE == 0: + return status + return 0 + +def driver_uninstall(): + global FORCE + for i in range(0,len(kos)): + rm = kos[-(i+1)].replace("modprobe", "modprobe -rq") + rm = rm.replace("insmod", "rmmod") + lst = rm.split(" ") + if len(lst) > 3: + del(lst[3]) + rm = " ".join(lst) + status, output = log_os_system(rm, 1) + if status: + if FORCE == 0: + return status + return 0 + +led_prefix ='/sys/class/leds/accton_'+PROJECT_NAME+'_led::' +hwmon_types = {'led': ['diag','fan','loc','psu1','psu2']} +hwmon_nodes = {'led': ['brightness'] } +hwmon_prefix ={'led': led_prefix} + +i2c_prefix = '/sys/bus/i2c/devices/' +i2c_bus = {'fan': ['11-0066'] , + 'thermal': ['15-0048','15-0049', '15-004a', '15-004b'] , + 'psu': ['17-0051','13-0053'], + 'sfp': ['-0050']} +i2c_nodes = {'fan': ['present', 'front_speed_rpm', 'rear_speed_rpm'] , + 'thermal': ['hwmon/hwmon*/temp1_input'] , + 'psu': ['psu_present ', 'psu_power_good'] , + 'sfp': ['module_present_', 'module_tx_disable_']} + +sfp_map = [ + 42,41,44,43,47,45,46,50, + 48,49,51,52,53,56,55,54, + 58,57,59,60,61,63,62,64, + 66,68,65,67,69,71,72,70, + 74,73,76,75,77,79,78,80, + 81,82,84,85,83,87,88,86, #port 41~48 + 25,26,27,28,29,30,31,32, #port 49~56 QSFP + 22,23] #port 57~58 SFP+ from CPU NIF. +qsfp_start = 48 +qsfp_end = 56 + +#For sideband signals of SFP/QSFP modules. +cpld_of_module = {'12-0062': list(range(0,30)), + '18-0060': list(range(30,58)) } + + +mknod =[ +'echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-1/new_device' , +'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-1/new_device' , +'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-24/new_device' , +'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-2/new_device' , +'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-33/new_device', +'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-34/new_device', +'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-35/new_device', +'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-36/new_device', +'echo pca9548 0x75 > /sys/bus/i2c/devices/i2c-37/new_device', +'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-38/new_device', +'echo 24c04 0x56 > /sys/bus/i2c/devices/i2c-0/new_device', + +'echo as7326_56x_fan 0x66 > /sys/bus/i2c/devices/i2c-11/new_device ', +'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-15/new_device', +'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-15/new_device', +'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-15/new_device', +'echo lm75 0x4b > /sys/bus/i2c/devices/i2c-15/new_device', +'echo as7326_56x_psu1 0x51 > /sys/bus/i2c/devices/i2c-17/new_device', +'echo ym2651 0x59 > /sys/bus/i2c/devices/i2c-17/new_device', +'echo as7326_56x_psu2 0x53 > /sys/bus/i2c/devices/i2c-13/new_device', +'echo ym2651 0x5b > /sys/bus/i2c/devices/i2c-13/new_device', +'echo as7326_56x_cpld1 0x60 > /sys/bus/i2c/devices/i2c-18/new_device', +'echo as7326_56x_cpld2 0x62 > /sys/bus/i2c/devices/i2c-12/new_device', +'echo as7326_56x_cpld3 0x64 > /sys/bus/i2c/devices/i2c-19/new_device'] + +mknod2 =[ +] + + + +def i2c_order_check(): + # This project has only 1 i2c bus. + return 0 + +def device_install(): + global FORCE + + order = i2c_order_check() + + # if 0x70 is not exist @i2c-1, use reversed bus order + if order: + for i in range(0,len(mknod2)): + #for pca954x need times to built new i2c buses + if mknod2[i].find('pca954') != -1: + time.sleep(1) + + status, output = log_os_system(mknod2[i], 1) + if status: + print output + if FORCE == 0: + return status + else: + for i in range(0,len(mknod)): + #for pca954x need times to built new i2c buses + if mknod[i].find('pca954') != -1: + time.sleep(1) + + status, output = log_os_system(mknod[i], 1) + if status: + print output + if FORCE == 0: + return status + for i in range(0,len(sfp_map)): + if i < qsfp_start or i >= qsfp_end: + status, output =log_os_system("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + else: + status, output =log_os_system("echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + return + +def device_uninstall(): + global FORCE + + status, output =log_os_system("ls /sys/bus/i2c/devices/1-0076", 0) + if status==0: + I2C_ORDER=1 + else: + I2C_ORDER=0 + + for i in range(0,len(sfp_map)): + target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device" + status, output =log_os_system("echo 0x50 > "+ target, 1) + if status: + print output + if FORCE == 0: + return status + + if I2C_ORDER==0: + nodelist = mknod + else: + nodelist = mknod2 + + for i in range(len(nodelist)): + target = nodelist[-(i+1)] + temp = target.split() + del temp[1] + temp[-1] = temp[-1].replace('new_device', 'delete_device') + status, output = log_os_system(" ".join(temp), 1) + if status: + print output + if FORCE == 0: + return status + + return + +def system_ready(): + if driver_check() == False: + return False + if not device_exist(): + return False + return True + +def do_install(): + print "Checking system...." + if driver_check() == False: + print "No driver, installing...." + status = driver_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" drivers detected...." + if not device_exist(): + print "No device, installing...." + status = device_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" devices detected...." + return + +def do_uninstall(): + print "Checking system...." + if not device_exist(): + print PROJECT_NAME.upper() +" has no device installed...." + else: + print "Removing device...." + status = device_uninstall() + if status: + if FORCE == 0: + return status + + if driver_check()== False : + print PROJECT_NAME.upper() +" has no driver installed...." + else: + print "Removing installed driver...." + status = driver_uninstall() + if status: + if FORCE == 0: + return status + + return + +def devices_info(): + global DEVICE_NO + global ALL_DEVICE + global i2c_bus, hwmon_types + for key in DEVICE_NO: + ALL_DEVICE[key]= {} + for i in range(0,DEVICE_NO[key]): + ALL_DEVICE[key][key+str(i+1)] = [] + + for key in i2c_bus: + buses = i2c_bus[key] + nodes = i2c_nodes[key] + for i in range(0,len(buses)): + for j in range(0,len(nodes)): + if 'fan' == key: + for k in range(0,DEVICE_NO[key]): + node = key+str(k+1) + path = i2c_prefix+ buses[i]+"/fan"+str(k+1)+"_"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + elif 'sfp' == key: + for k in range(0,DEVICE_NO[key]): + for lk in cpld_of_module: + if k in cpld_of_module[lk]: + cpld_str = lk + node = key+str(k+1) + path = i2c_prefix+ lk + "/"+ nodes[j] + str(k+1) + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + else: + node = key+str(i+1) + path = i2c_prefix+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + + for key in hwmon_types: + itypes = hwmon_types[key] + nodes = hwmon_nodes[key] + for i in range(0,len(itypes)): + for j in range(0,len(nodes)): + node = key+"_"+itypes[i] + path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][ key+str(i+1)].append(path) + + #show dict all in the order + if DEBUG == True: + for i in sorted(ALL_DEVICE.keys()): + print(i+": ") + for j in sorted(ALL_DEVICE[i].keys()): + print(" "+j) + for k in (ALL_DEVICE[i][j]): + print(" "+" "+k) + return + +def show_eeprom(index): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0] + node = node.replace(node.split("/")[-1], 'eeprom') + # check if got hexdump command in current environment + ret, log = log_os_system("which hexdump", 0) + ret, log2 = log_os_system("which busybox hexdump", 0) + if len(log): + hex_cmd = 'hexdump' + elif len(log2): + hex_cmd = ' busybox hexdump' + else: + log = 'Failed : no hexdump cmd!!' + logging.info(log) + print log + return 1 + + print node + ":" + ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1) + if ret==0: + print log + else: + print "**********device no found**********" + return + +def set_device(args): + global DEVICE_NO + global ALL_DEVICE + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + + if args[0]=='led': + if int(args[1])>4: + show_set_help() + return + #print ALL_DEVICE['led'] + for i in range(0,len(ALL_DEVICE['led'])): + for k in (ALL_DEVICE['led']['led'+str(i+1)]): + ret, log = log_os_system("echo "+args[1]+" >"+k, 1) + if ret: + return ret + elif args[0]=='fan': + if int(args[1])>100: + show_set_help() + return + #print ALL_DEVICE['fan'] + #fan1~6 is all fine, all fan share same setting + node = ALL_DEVICE['fan'] ['fan1'][0] + node = node.replace(node.split("/")[-1], 'fan_duty_cycle_percentage') + ret, log = log_os_system("cat "+ node, 1) + if ret==0: + print ("Previous fan duty: " + log.strip() +"%") + ret, log = log_os_system("echo "+args[1]+" >"+node, 1) + if ret==0: + print ("Current fan duty: " + args[1] +"%") + return ret + elif args[0]=='sfp': + if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0: + show_set_help() + return + if len(args)<2: + show_set_help() + return + + if int(args[2])>1: + show_set_help() + return + + #print ALL_DEVICE[args[0]] + for i in range(0,len(ALL_DEVICE[args[0]])): + for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]: + if j.find('tx_disable')!= -1: + ret, log = log_os_system("echo "+args[2]+" >"+ j, 1) + if ret: + return ret + return + +#get digits inside a string. +#Ex: 31 for "sfp31" +def get_value(input): + digit = re.findall('\d+', input) + return int(digit[0]) + +def device_traversal(): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + for i in sorted(ALL_DEVICE.keys()): + print("============================================") + print(i.upper()+": ") + print("============================================") + + for j in sorted(ALL_DEVICE[i].keys(), key=get_value): + print " "+j+":", + for k in (ALL_DEVICE[i][j]): + ret, log = log_os_system("cat "+k, 0) + func = k.split("/")[-1].strip() + func = re.sub(j+'_','',func,1) + func = re.sub(i.lower()+'_','',func,1) + if ret==0: + print func+"="+log+" ", + else: + print func+"="+"X"+" ", + print + print("----------------------------------------------------------------") + + print + return + +def device_exist(): + ret1, log = log_os_system("ls "+i2c_prefix+"*0070", 0) + ret2, log = log_os_system("ls "+i2c_prefix+"i2c-2", 0) + return not(ret1 or ret2) + +if __name__ == "__main__": + main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as7712-32x/classes/__init__.py b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/classes/__init__.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/Makefile b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/Makefile new file mode 100644 index 000000000000..d9566355b849 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/Makefile @@ -0,0 +1,2 @@ +obj-m:=accton_as7712_32x_fan.o accton_as7712_32x_sfp.o leds-accton_as7712_32x.o \ + accton_as7712_32x_psu.o accton_i2c_cpld.o ym2651y.o diff --git a/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/accton_as7712_32x_fan.c b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/accton_as7712_32x_fan.c new file mode 100644 index 000000000000..3eae51cbcea7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/accton_as7712_32x_fan.c @@ -0,0 +1,776 @@ +/* + * A hwmon driver for the Accton as7712 32x fan + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "as7712_32x_fan" + +#define NUM_THERMAL_SENSORS (3) /* Get sum of this number of sensors.*/ +#define THERMAL_SENSORS_DRIVER "lm75" +#define THERMAL_SENSORS_ADDRS {0x48, 0x49, 0x4a} + +#define IN +#define OUT + +static struct as7712_32x_fan_data *as7712_32x_fan_update_device(struct device *dev); +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t get_enable(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_enable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t get_sys_temp(struct device *dev, struct device_attribute *da, char *buf); +extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +/* fan related data, the index should match sysfs_fan_attributes + */ +static const u8 fan_reg[] = { + 0x0F, /* fan 1-6 present status */ + 0x11, /* fan PWM(for all fan) */ + 0x12, /* front fan 1 speed(rpm) */ + 0x13, /* front fan 2 speed(rpm) */ + 0x14, /* front fan 3 speed(rpm) */ + 0x15, /* front fan 4 speed(rpm) */ + 0x16, /* front fan 5 speed(rpm) */ + 0x17, /* front fan 6 speed(rpm) */ + 0x22, /* rear fan 1 speed(rpm) */ + 0x23, /* rear fan 2 speed(rpm) */ + 0x24, /* rear fan 3 speed(rpm) */ + 0x25, /* rear fan 4 speed(rpm) */ + 0x26, /* rear fan 5 speed(rpm) */ + 0x27, /* rear fan 6 speed(rpm) */ +}; + +/* Each client has this additional data */ +struct as7712_32x_fan_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[ARRAY_SIZE(fan_reg)]; /* Register value */ + u8 enable; + int system_temp; /*In unit of mini-Celsius*/ + int sensors_found; +}; + +enum fan_id { + FAN1_ID, + FAN2_ID, + FAN3_ID, + FAN4_ID, + FAN5_ID, + FAN6_ID +}; + +enum sysfs_fan_attributes { + FAN_PRESENT_REG, + FAN_DUTY_CYCLE_PERCENTAGE, /* Only one CPLD register to control duty cycle for all fans */ + FAN1_FRONT_SPEED_RPM, + FAN2_FRONT_SPEED_RPM, + FAN3_FRONT_SPEED_RPM, + FAN4_FRONT_SPEED_RPM, + FAN5_FRONT_SPEED_RPM, + FAN6_FRONT_SPEED_RPM, + FAN1_REAR_SPEED_RPM, + FAN2_REAR_SPEED_RPM, + FAN3_REAR_SPEED_RPM, + FAN4_REAR_SPEED_RPM, + FAN5_REAR_SPEED_RPM, + FAN6_REAR_SPEED_RPM, + FAN1_PRESENT, + FAN2_PRESENT, + FAN3_PRESENT, + FAN4_PRESENT, + FAN5_PRESENT, + FAN6_PRESENT, + FAN1_FAULT, + FAN2_FAULT, + FAN3_FAULT, + FAN4_FAULT, + FAN5_FAULT, + FAN6_FAULT +}; + +/* Define attributes + */ +#define DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(index, index2) \ + static SENSOR_DEVICE_ATTR(fan##index##_fault, S_IRUGO, fan_show_value, NULL, FAN##index##_FAULT);\ + static SENSOR_DEVICE_ATTR(fan##index2##_fault, S_IRUGO, fan_show_value, NULL, FAN##index##_FAULT) +#define DECLARE_FAN_FAULT_ATTR(index, index2) &sensor_dev_attr_fan##index##_fault.dev_attr.attr, \ + &sensor_dev_attr_fan##index2##_fault.dev_attr.attr + +#define DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_direction, S_IRUGO, fan_show_value, NULL, FAN##index##_DIRECTION) +#define DECLARE_FAN_DIRECTION_ATTR(index) &sensor_dev_attr_fan##index##_direction.dev_attr.attr + +#define DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan_duty_cycle_percentage, S_IWUSR | S_IRUGO, fan_show_value, set_duty_cycle, FAN_DUTY_CYCLE_PERCENTAGE);\ + static SENSOR_DEVICE_ATTR(pwm##index, S_IWUSR | S_IRUGO, fan_show_value, set_duty_cycle, FAN_DUTY_CYCLE_PERCENTAGE);\ + static SENSOR_DEVICE_ATTR(pwm##index##_enable, S_IWUSR | S_IRUGO, get_enable, set_enable, FAN_DUTY_CYCLE_PERCENTAGE) + +#define DECLARE_FAN_DUTY_CYCLE_ATTR(index) &sensor_dev_attr_fan_duty_cycle_percentage.dev_attr.attr, \ + &sensor_dev_attr_pwm##index.dev_attr.attr, \ + &sensor_dev_attr_pwm##index##_enable.dev_attr.attr + +#define DECLARE_FAN_SYSTEM_TEMP_SENSOR_DEV_ATTR() \ + static SENSOR_DEVICE_ATTR(sys_temp, S_IRUGO, get_sys_temp, NULL, FAN_DUTY_CYCLE_PERCENTAGE) + +#define DECLARE_FAN_SYSTEM_TEMP_ATTR() &sensor_dev_attr_sys_temp.dev_attr.attr + + +#define DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_present, S_IRUGO, fan_show_value, NULL, FAN##index##_PRESENT) +#define DECLARE_FAN_PRESENT_ATTR(index) &sensor_dev_attr_fan##index##_present.dev_attr.attr + +#define DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(index, index2) \ + static SENSOR_DEVICE_ATTR(fan##index##_front_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_FRONT_SPEED_RPM);\ + static SENSOR_DEVICE_ATTR(fan##index##_rear_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_REAR_SPEED_RPM);\ + static SENSOR_DEVICE_ATTR(fan##index##_input, S_IRUGO, fan_show_value, NULL, FAN##index##_FRONT_SPEED_RPM);\ + static SENSOR_DEVICE_ATTR(fan##index2##_input, S_IRUGO, fan_show_value, NULL, FAN##index##_REAR_SPEED_RPM) +#define DECLARE_FAN_SPEED_RPM_ATTR(index, index2) &sensor_dev_attr_fan##index##_front_speed_rpm.dev_attr.attr, \ + &sensor_dev_attr_fan##index##_rear_speed_rpm.dev_attr.attr, \ + &sensor_dev_attr_fan##index##_input.dev_attr.attr, \ + &sensor_dev_attr_fan##index2##_input.dev_attr.attr + +/* 6 fan fault attributes in this platform */ +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(1,11); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(2,12); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(3,13); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(4,14); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(5,15); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(6,16); +/* 6 fan speed(rpm) attributes in this platform */ +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(1,11); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(2,12); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(3,13); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(4,14); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(5,15); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(6,16); +/* 6 fan present attributes in this platform */ +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(1); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(2); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(3); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(4); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(5); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(6); +/* 1 fan duty cycle attribute in this platform */ +DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(1); +/* System temperature for fancontrol */ +DECLARE_FAN_SYSTEM_TEMP_SENSOR_DEV_ATTR(); + +static struct attribute *as7712_32x_fan_attributes[] = { + /* fan related attributes */ + DECLARE_FAN_FAULT_ATTR(1,11), + DECLARE_FAN_FAULT_ATTR(2,12), + DECLARE_FAN_FAULT_ATTR(3,13), + DECLARE_FAN_FAULT_ATTR(4,14), + DECLARE_FAN_FAULT_ATTR(5,15), + DECLARE_FAN_FAULT_ATTR(6,16), + DECLARE_FAN_SPEED_RPM_ATTR(1,11), + DECLARE_FAN_SPEED_RPM_ATTR(2,12), + DECLARE_FAN_SPEED_RPM_ATTR(3,13), + DECLARE_FAN_SPEED_RPM_ATTR(4,14), + DECLARE_FAN_SPEED_RPM_ATTR(5,15), + DECLARE_FAN_SPEED_RPM_ATTR(6,16), + DECLARE_FAN_PRESENT_ATTR(1), + DECLARE_FAN_PRESENT_ATTR(2), + DECLARE_FAN_PRESENT_ATTR(3), + DECLARE_FAN_PRESENT_ATTR(4), + DECLARE_FAN_PRESENT_ATTR(5), + DECLARE_FAN_PRESENT_ATTR(6), + DECLARE_FAN_DUTY_CYCLE_ATTR(1), + DECLARE_FAN_SYSTEM_TEMP_ATTR(), + NULL +}; + +#define FAN_DUTY_CYCLE_REG_MASK 0xF +#define FAN_MAX_DUTY_CYCLE 100 +#define FAN_REG_VAL_TO_SPEED_RPM_STEP 100 + +static int as7712_32x_fan_read_value(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int as7712_32x_fan_write_value(struct i2c_client *client, u8 reg, u8 value) +{ + return i2c_smbus_write_byte_data(client, reg, value); +} + +/* fan utility functions + */ +static u32 reg_val_to_duty_cycle(u8 reg_val) +{ + reg_val &= FAN_DUTY_CYCLE_REG_MASK; + return ((u32)(reg_val+1) * 625 + 75)/ 100; +} + +static u8 duty_cycle_to_reg_val(u8 duty_cycle) +{ + return ((u32)duty_cycle * 100 / 625) - 1; +} + +static u32 reg_val_to_speed_rpm(u8 reg_val) +{ + return (u32)reg_val * FAN_REG_VAL_TO_SPEED_RPM_STEP; +} + +static u8 reg_val_to_is_present(u8 reg_val, enum fan_id id) +{ + u8 mask = (1 << id); + + reg_val &= mask; + + return reg_val ? 0 : 1; +} + +static u8 is_fan_fault(struct as7712_32x_fan_data *data, enum fan_id id) +{ + u8 ret = 1; + int front_fan_index = FAN1_FRONT_SPEED_RPM + id; + int rear_fan_index = FAN1_REAR_SPEED_RPM + id; + + /* Check if the speed of front or rear fan is ZERO, + */ + if (reg_val_to_speed_rpm(data->reg_val[front_fan_index]) && + reg_val_to_speed_rpm(data->reg_val[rear_fan_index])) { + ret = 0; + } + + return ret; +} + +static ssize_t set_enable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct as7712_32x_fan_data *data = as7712_32x_fan_update_device(dev); + int error, value; + + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (value < 0 || value > 1) + return -EINVAL; + + data->enable = value; + if (value == 0) + { + return set_duty_cycle(dev, da, buf, FAN_MAX_DUTY_CYCLE); + } + return count; +} + + +static ssize_t get_enable(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct as7712_32x_fan_data *data = as7712_32x_fan_update_device(dev); + + return sprintf(buf, "%u\n", data->enable); +} +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int error, value; + struct i2c_client *client = to_i2c_client(dev); + + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (value < 0) + return -EINVAL; + + value = (value > FAN_MAX_DUTY_CYCLE)? FAN_MAX_DUTY_CYCLE : value; + + as7712_32x_fan_write_value(client, 0x33, 0); /* Disable fan speed watch dog */ + as7712_32x_fan_write_value(client, fan_reg[FAN_DUTY_CYCLE_PERCENTAGE], duty_cycle_to_reg_val(value)); + return count; +} + +/* Due to this struct is declared at lm75.c, it cannot be include + * under Sonic environment. I duplicate it from lm75.c. + */ +struct lm75_data { + struct i2c_client *client; + struct device *hwmon_dev; + struct thermal_zone_device *tz; + struct mutex update_lock; + u8 orig_conf; + u8 resolution; /* In bits, between 9 and 12 */ + u8 resolution_limits; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + unsigned long sample_time; /* In jiffies */ + s16 temp[3]; /* Register values, + 0 = input + 1 = max + 2 = hyst */ +}; + +/*Copied from lm75.c*/ +static inline long lm75_reg_to_mc(s16 temp, u8 resolution) +{ + return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8); +} + +/*Get hwmon_dev from i2c_client, set hwmon_dev = NULL is failed.*/ +static struct device * get_hwmon_dev( + struct i2c_client *client) +{ + struct lm75_data *data = NULL; + + data = i2c_get_clientdata(client); + if(data) + { + if( data->valid == 1 && data->hwmon_dev) + { + return data->hwmon_dev; + } + + } + return NULL; +} + +/* To find hwmon index by opening hwmon under that i2c address. + */ +static int find_hwmon_index_by_FileOpen( + int bus_nr, + unsigned short addr, + OUT int *index) +{ +#define MAX_HWMON_DEVICE (10) /* Find hwmon device in 0~10*/ + struct file *sfd; + char client_name[96]; + int i=0; + + do { + snprintf(client_name, sizeof(client_name), + "/sys/bus/i2c/devices/%d-%04x/hwmon/hwmon%d/temp1_input", + bus_nr, addr, i); + + sfd = filp_open(client_name, O_RDONLY, 0); + i++; + } while( IS_ERR(sfd) && i < MAX_HWMON_DEVICE); + + if (IS_ERR(sfd)) { + pr_err("Failed to open file(%s)#%d\r\n", client_name, __LINE__); + return -ENOENT; + } + filp_close(sfd, 0); + *index = i - 1; + return 0; + +#undef MAX_HWMON_DEVICE +} + +static int get_temp_file_path( + int bus_nr, unsigned short addr, + struct device *hwmon_dev + ,char *path, int max_len) +{ + + if(hwmon_dev && strlen(dev_name(hwmon_dev))) + { + snprintf(path, max_len, + "/sys/bus/i2c/devices/%d-%04x/hwmon/%s/temp1_input", + bus_nr, addr, dev_name(hwmon_dev)); + } + else + { + int i=0; + if(find_hwmon_index_by_FileOpen( bus_nr, addr, &i)) + { + return -EIO; + } + snprintf(path, max_len, + "/sys/bus/i2c/devices/%d-%04x/hwmon/hwmon%d/temp1_input", + bus_nr, addr, i); + } + return 0; +} + +/*File read the dev file at user space.*/ +static int read_devfile_temp1_input( + struct device *dev, + int bus_nr, + unsigned short addr, + struct device *hwmon_dev, + int *miniCelsius) +{ + struct file *sfd; + char buffer[96]; + char devfile[96]; + int rc, status; + int rdlen, value; + mm_segment_t old_fs; + + rc = 0; + get_temp_file_path(bus_nr, addr, hwmon_dev, devfile, sizeof(devfile)); + sfd = filp_open(devfile, O_RDONLY, 0); + if (IS_ERR(sfd)) { + pr_err("Failed to open file(%s)#%d\r\n", devfile, __LINE__); + return -ENOENT; + } + dev_dbg(dev, "Found device:%s\n",devfile); + + if(!(sfd->f_op) || !(sfd->f_op->read) ) { + pr_err("file %s cann't readable ?\n",devfile); + return -ENOENT; + } + + old_fs = get_fs(); + set_fs(KERNEL_DS); + rdlen = sfd->f_op->read(sfd, buffer, sizeof(buffer), &sfd->f_pos); + if (rdlen == 0) { + pr_err( "File(%s) empty!\n", devfile); + rc = -EIO; + goto exit; + } + status = sscanf(buffer, "%d", &value); + if (status != 1) { + rc = -EIO; + goto exit; + } + *miniCelsius = value; + dev_dbg(dev,"found sensors: %d @i2c %d-%04x\n", value, bus_nr, addr); + +exit: + set_fs(old_fs); + filp_close(sfd, 0); + return rc; +} + +static u8 is_lm75_data_due(struct i2c_client *client) +{ + struct lm75_data *data = NULL; + + data = i2c_get_clientdata(client); + if (time_after(jiffies, data->last_updated + data->sample_time)) + { + return 1; + } + return 0; +} +static int get_lm75_temp(struct i2c_client *client, int *miniCelsius) +{ + struct lm75_data *data = NULL; + + data = i2c_get_clientdata(client); + *miniCelsius = lm75_reg_to_mc(data->temp[0], data->resolution); + + return 0; +} + +static bool lm75_addr_mached(unsigned short addr) +{ + int i; + unsigned short addrs[] = THERMAL_SENSORS_ADDRS; + + for (i = 0; i < ARRAY_SIZE(addrs); i++) + { + if( addr == addrs[i]) + return 1; + } + return 0; +} + +static int _find_lm75_device(struct device *dev, void *data) +{ + struct device_driver *driver; + struct as7712_32x_fan_data *prv = data; + char *driver_name = THERMAL_SENSORS_DRIVER; + + driver = dev->driver; + if (driver && driver->name && + strcmp(driver->name, driver_name) == 0) + { + struct i2c_client *client; + client = to_i2c_client(dev); + if (client) + { + /*cannot use "struct i2c_adapter *adap = to_i2c_adapter(dev);"*/ + struct i2c_adapter *adap = client->adapter; + int miniCelsius = 0; + + if (! lm75_addr_mached(client->addr)) + { + return 0; + } + + if (!adap) { + return -ENXIO; + } + + /* If the data is not updated, read them from devfile + to drive them updateing data from chip.*/ + if (is_lm75_data_due(client)) + { + struct device *hwmon_dev; + + hwmon_dev = get_hwmon_dev(client); + if(0 == read_devfile_temp1_input(dev, adap->nr, + client->addr, hwmon_dev, &miniCelsius)) + { + prv->system_temp += miniCelsius; + prv->sensors_found++; + } + + } + else + { + get_lm75_temp(client, &miniCelsius); + prv->system_temp += miniCelsius; + prv->sensors_found++; + + } + } + } + return 0; +} + +/*Find all lm75 devices and return sum of temperatures.*/ +static ssize_t get_sys_temp(struct device *dev, struct device_attribute *da, + char *buf) +{ + ssize_t ret = 0; + struct as7712_32x_fan_data *data = as7712_32x_fan_update_device(dev); + + data->system_temp=0; + data->sensors_found=0; + i2c_for_each_dev(data, _find_lm75_device); + if (NUM_THERMAL_SENSORS != data->sensors_found) + { + dev_dbg(dev,"only %d of %d temps are found\n", + data->sensors_found, NUM_THERMAL_SENSORS); + data->system_temp = INT_MAX; + } + ret = sprintf(buf, "%d\n",data->system_temp); + return ret; +} + +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct as7712_32x_fan_data *data = as7712_32x_fan_update_device(dev); + ssize_t ret = 0; + + if (data->valid) { + switch (attr->index) { + case FAN_DUTY_CYCLE_PERCENTAGE: + { + u32 duty_cycle = reg_val_to_duty_cycle(data->reg_val[FAN_DUTY_CYCLE_PERCENTAGE]); + ret = sprintf(buf, "%u\n", duty_cycle); + break; + } + case FAN1_FRONT_SPEED_RPM: + case FAN2_FRONT_SPEED_RPM: + case FAN3_FRONT_SPEED_RPM: + case FAN4_FRONT_SPEED_RPM: + case FAN5_FRONT_SPEED_RPM: + case FAN6_FRONT_SPEED_RPM: + case FAN1_REAR_SPEED_RPM: + case FAN2_REAR_SPEED_RPM: + case FAN3_REAR_SPEED_RPM: + case FAN4_REAR_SPEED_RPM: + case FAN5_REAR_SPEED_RPM: + case FAN6_REAR_SPEED_RPM: + ret = sprintf(buf, "%u\n", reg_val_to_speed_rpm(data->reg_val[attr->index])); + break; + case FAN1_PRESENT: + case FAN2_PRESENT: + case FAN3_PRESENT: + case FAN4_PRESENT: + case FAN5_PRESENT: + case FAN6_PRESENT: + ret = sprintf(buf, "%d\n", + reg_val_to_is_present(data->reg_val[FAN_PRESENT_REG], + attr->index - FAN1_PRESENT)); + break; + case FAN1_FAULT: + case FAN2_FAULT: + case FAN3_FAULT: + case FAN4_FAULT: + case FAN5_FAULT: + case FAN6_FAULT: + ret = sprintf(buf, "%d\n", is_fan_fault(data, attr->index - FAN1_FAULT)); + break; + default: + break; + } + } + + return ret; +} + +static const struct attribute_group as7712_32x_fan_group = { + .attrs = as7712_32x_fan_attributes, +}; + +static struct as7712_32x_fan_data *as7712_32x_fan_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as7712_32x_fan_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || + !data->valid) { + int i; + + dev_dbg(&client->dev, "Starting as7712_32x_fan update\n"); + data->valid = 0; + + /* Update fan data + */ + for (i = 0; i < ARRAY_SIZE(data->reg_val); i++) { + int status = as7712_32x_fan_read_value(client, fan_reg[i]); + + if (status < 0) { + data->valid = 0; + mutex_unlock(&data->update_lock); + dev_dbg(&client->dev, "reg %d, err %d\n", fan_reg[i], status); + return data; + } + else { + data->reg_val[i] = status; + } + } + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +static int as7712_32x_fan_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct as7712_32x_fan_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct as7712_32x_fan_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + data->enable = 0; + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as7712_32x_fan_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: fan '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as7712_32x_fan_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as7712_32x_fan_remove(struct i2c_client *client) +{ + struct as7712_32x_fan_data *data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as7712_32x_fan_group); + + return 0; +} + +/* Addresses to scan */ +static const unsigned short normal_i2c[] = { 0x66, I2C_CLIENT_END }; + +static const struct i2c_device_id as7712_32x_fan_id[] = { + { "as7712_32x_fan", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, as7712_32x_fan_id); + +static struct i2c_driver as7712_32x_fan_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = DRVNAME, + }, + .probe = as7712_32x_fan_probe, + .remove = as7712_32x_fan_remove, + .id_table = as7712_32x_fan_id, + .address_list = normal_i2c, +}; + +static int __init as7712_32x_fan_init(void) +{ + return i2c_add_driver(&as7712_32x_fan_driver); +} + +static void __exit as7712_32x_fan_exit(void) +{ + i2c_del_driver(&as7712_32x_fan_driver); +} + +module_init(as7712_32x_fan_init); +module_exit(as7712_32x_fan_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("as7712_32x_fan driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/accton_as7712_32x_psu.c b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/accton_as7712_32x_psu.c new file mode 100644 index 000000000000..233aef78e09f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/accton_as7712_32x_psu.c @@ -0,0 +1,288 @@ +/* + * An hwmon driver for accton as7712_32x Power Module + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_model_name(struct device *dev, struct device_attribute *da, char *buf); +static int as7712_32x_psu_read_block(struct i2c_client *client, u8 command, u8 *data,int data_len); +extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg); + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { 0x50, 0x53, I2C_CLIENT_END }; + +/* Each client has this additional data + */ +struct as7712_32x_psu_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 index; /* PSU index */ + u8 status; /* Status(present/power_good) register read from CPLD */ + char model_name[9]; /* Model name, read from eeprom */ +}; + +static struct as7712_32x_psu_data *as7712_32x_psu_update_device(struct device *dev); + +enum as7712_32x_psu_sysfs_attributes { + PSU_PRESENT, + PSU_MODEL_NAME, + PSU_POWER_GOOD +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, show_status, NULL, PSU_PRESENT); +static SENSOR_DEVICE_ATTR(psu_model_name, S_IRUGO, show_model_name,NULL, PSU_MODEL_NAME); +static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_status, NULL, PSU_POWER_GOOD); + +static struct attribute *as7712_32x_psu_attributes[] = { + &sensor_dev_attr_psu_present.dev_attr.attr, + &sensor_dev_attr_psu_model_name.dev_attr.attr, + &sensor_dev_attr_psu_power_good.dev_attr.attr, + NULL +}; + +static ssize_t show_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct as7712_32x_psu_data *data = as7712_32x_psu_update_device(dev); + u8 status = 0; + + if (attr->index == PSU_PRESENT) { + status = !(data->status >> (1-data->index) & 0x1); + } + else { /* PSU_POWER_GOOD */ + status = (data->status >> (3-data->index) & 0x1); + } + + return sprintf(buf, "%d\n", status); +} + +static ssize_t show_model_name(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct as7712_32x_psu_data *data = as7712_32x_psu_update_device(dev); + + return sprintf(buf, "%s\n", data->model_name); +} + +static const struct attribute_group as7712_32x_psu_group = { + .attrs = as7712_32x_psu_attributes, +}; + +static int as7712_32x_psu_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct as7712_32x_psu_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct as7712_32x_psu_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + data->index = dev_id->driver_data; + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as7712_32x_psu_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as7712_32x_psu_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as7712_32x_psu_remove(struct i2c_client *client) +{ + struct as7712_32x_psu_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as7712_32x_psu_group); + kfree(data); + + return 0; +} + +enum psu_index +{ + as7712_32x_psu1, + as7712_32x_psu2 +}; + +static const struct i2c_device_id as7712_32x_psu_id[] = { + { "as7712_32x_psu1", as7712_32x_psu1 }, + { "as7712_32x_psu2", as7712_32x_psu2 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, as7712_32x_psu_id); + +static struct i2c_driver as7712_32x_psu_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "as7712_32x_psu", + }, + .probe = as7712_32x_psu_probe, + .remove = as7712_32x_psu_remove, + .id_table = as7712_32x_psu_id, + .address_list = normal_i2c, +}; + +static int as7712_32x_psu_read_block(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ + int result = 0; + int retry_count = 5; + + while (retry_count) { + retry_count--; + + result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + + if (unlikely(result < 0)) { + msleep(10); + continue; + } + + if (unlikely(result != data_len)) { + result = -EIO; + msleep(10); + continue; + } + + result = 0; + break; + } + + return result; +} + +static struct as7712_32x_psu_data *as7712_32x_psu_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as7712_32x_psu_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int status; + int power_good = 0; + + dev_dbg(&client->dev, "Starting as7712_32x update\n"); + + /* Read psu status */ + status = accton_i2c_cpld_read(0x60, 0x2); + + if (status < 0) { + dev_dbg(&client->dev, "cpld reg 0x60 err %d\n", status); + } + else { + data->status = status; + } + + /* Read model name */ + memset(data->model_name, 0, sizeof(data->model_name)); + power_good = (data->status >> (3-data->index) & 0x1); + + if (power_good) { + status = as7712_32x_psu_read_block(client, 0x20, data->model_name, + ARRAY_SIZE(data->model_name)-1); + + if (status < 0) { + data->model_name[0] = '\0'; + dev_dbg(&client->dev, "unable to read model name from (0x%x)\n", client->addr); + } + else { + data->model_name[ARRAY_SIZE(data->model_name)-1] = '\0'; + } + } + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +static int __init as7712_32x_psu_init(void) +{ + return i2c_add_driver(&as7712_32x_psu_driver); +} + +static void __exit as7712_32x_psu_exit(void) +{ + i2c_del_driver(&as7712_32x_psu_driver); +} + +module_init(as7712_32x_psu_init); +module_exit(as7712_32x_psu_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("as7712_32x_psu driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/accton_as7712_32x_sfp.c b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/accton_as7712_32x_sfp.c new file mode 100644 index 000000000000..4668f5a7f050 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/accton_as7712_32x_sfp.c @@ -0,0 +1,1171 @@ +/* + * SFP driver for accton as7712_32x sfp + * + * Copyright (C) Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "as7712_32x_sfp" + +#define DEBUG_MODE 0 + +#if (DEBUG_MODE == 1) + #define DEBUG_PRINT(fmt, args...) \ + printk (KERN_INFO "%s:%s[%d]: " fmt "\r\n", __FILE__, __FUNCTION__, __LINE__, ##args) +#else + #define DEBUG_PRINT(fmt, args...) +#endif + +#define NUM_OF_SFP_PORT 32 +#define EEPROM_NAME "sfp_eeprom" +#define EEPROM_SIZE 256 /* 256 byte eeprom */ +#define BIT_INDEX(i) (1ULL << (i)) +#define USE_I2C_BLOCK_READ 1 +#define I2C_RW_RETRY_COUNT 3 +#define I2C_RW_RETRY_INTERVAL 100 /* ms */ + +#define SFP_EEPROM_A0_I2C_ADDR (0xA0 >> 1) +#define SFP_EEPROM_A2_I2C_ADDR (0xA2 >> 1) + +#define SFF8024_PHYSICAL_DEVICE_ID_ADDR 0x0 +#define SFF8024_DEVICE_ID_SFP 0x3 +#define SFF8024_DEVICE_ID_QSFP 0xC +#define SFF8024_DEVICE_ID_QSFP_PLUS 0xD +#define SFF8024_DEVICE_ID_QSFP28 0x11 + +#define SFF8472_DIAG_MON_TYPE_ADDR 92 +#define SFF8472_DIAG_MON_TYPE_DDM_MASK 0x40 +#define SFF8472_10G_ETH_COMPLIANCE_ADDR 0x3 +#define SFF8472_10G_BASE_MASK 0xF0 + +#define SFF8436_RX_LOS_ADDR 3 +#define SFF8436_TX_FAULT_ADDR 4 +#define SFF8436_TX_DISABLE_ADDR 86 + +static ssize_t sfp_eeprom_read(struct i2c_client *, u8, u8 *,int); +static ssize_t sfp_eeprom_write(struct i2c_client *, u8 , const char *,int); +extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { SFP_EEPROM_A0_I2C_ADDR, SFP_EEPROM_A2_I2C_ADDR, I2C_CLIENT_END }; + +#define CPLD_PORT_TO_FRONT_PORT(port) (port+1) + +enum port_numbers { +sfp1, sfp2, sfp3, sfp4, sfp5, sfp6, sfp7, sfp8, +sfp9, sfp10, sfp11, sfp12, sfp13, sfp14, sfp15, sfp16, +sfp17, sfp18, sfp19, sfp20, sfp21, sfp22, sfp23, sfp24, +sfp25, sfp26, sfp27, sfp28, sfp29, sfp30, sfp31, sfp32 +}; + +static const struct i2c_device_id sfp_device_id[] = { +{ "sfp1", sfp1 }, { "sfp2", sfp2 }, { "sfp3", sfp3 }, { "sfp4", sfp4 }, +{ "sfp5", sfp5 }, { "sfp6", sfp6 }, { "sfp7", sfp7 }, { "sfp8", sfp8 }, +{ "sfp9", sfp9 }, { "sfp10", sfp10 }, { "sfp11", sfp11 }, { "sfp12", sfp12 }, +{ "sfp13", sfp13 }, { "sfp14", sfp14 }, { "sfp15", sfp15 }, { "sfp16", sfp16 }, +{ "sfp17", sfp17 }, { "sfp18", sfp18 }, { "sfp19", sfp19 }, { "sfp20", sfp20 }, +{ "sfp21", sfp21 }, { "sfp22", sfp22 }, { "sfp23", sfp23 }, { "sfp24", sfp24 }, +{ "sfp25", sfp25 }, { "sfp26", sfp26 }, { "sfp27", sfp27 }, { "sfp28", sfp28 }, +{ "sfp29", sfp29 }, { "sfp30", sfp30 }, { "sfp31", sfp31 }, { "sfp32", sfp32 }, +{} +}; +MODULE_DEVICE_TABLE(i2c, sfp_device_id); + +/* + * list of valid port types + * note OOM_PORT_TYPE_NOT_PRESENT to indicate no + * module is present in this port + */ +typedef enum oom_driver_port_type_e { + OOM_DRIVER_PORT_TYPE_INVALID, + OOM_DRIVER_PORT_TYPE_NOT_PRESENT, + OOM_DRIVER_PORT_TYPE_SFP, + OOM_DRIVER_PORT_TYPE_SFP_PLUS, + OOM_DRIVER_PORT_TYPE_QSFP, + OOM_DRIVER_PORT_TYPE_QSFP_PLUS, + OOM_DRIVER_PORT_TYPE_QSFP28 +} oom_driver_port_type_t; + +enum driver_type_e { + DRIVER_TYPE_SFP_MSA, + DRIVER_TYPE_SFP_DDM, + DRIVER_TYPE_QSFP +}; + +/* Each client has this additional data + */ +struct eeprom_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + struct bin_attribute bin; /* eeprom data */ +}; + +struct sfp_msa_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u64 status[2]; /* index 0 => device id + 1 => 10G Ethernet Compliance Codes + to distinguish SFP or SFP+ + 2 => DIAGNOSTIC MONITORING TYPE */ + struct eeprom_data eeprom; +}; + +struct sfp_ddm_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u64 status[3]; /* bit0:port0, bit1:port1 and so on */ + /* index 0 => tx_fail + 1 => tx_disable + 2 => rx_loss */ + struct eeprom_data eeprom; +}; + +struct qsfp_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 status[3]; /* bit0:port0, bit1:port1 and so on */ + /* index 0 => tx_fail + 1 => tx_disable + 2 => rx_loss */ + + u8 device_id; + struct eeprom_data eeprom; +}; + +struct sfp_port_data { + struct mutex update_lock; + enum driver_type_e driver_type; + int port; /* CPLD port index */ + oom_driver_port_type_t port_type; + u64 present; /* present status, bit0:port0, bit1:port1 and so on */ + u64 port_reset; /* reset status, bit0:port0, bit1:port1 and so on */ + + struct sfp_msa_data *msa; + struct sfp_ddm_data *ddm; + struct qsfp_data *qsfp; + + struct i2c_client *client; +}; + +enum sfp_sysfs_attributes { + PRESENT, + PRESENT_ALL, + PORT_NUMBER, + PORT_TYPE, + DDM_IMPLEMENTED, + TX_FAULT, + TX_FAULT1, + TX_FAULT2, + TX_FAULT3, + TX_FAULT4, + TX_DISABLE, + TX_DISABLE1, + TX_DISABLE2, + TX_DISABLE3, + TX_DISABLE4, + TX_DISABLE_ALL, + RX_LOS, + RX_LOS1, + RX_LOS2, + RX_LOS3, + RX_LOS4, + RX_LOS_ALL, + PORT_RESET +}; + +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + return sprintf(buf, "%d\n", CPLD_PORT_TO_FRONT_PORT(data->port)); +} + +static struct sfp_port_data *sfp_update_present(struct i2c_client *client) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + int i = 0; + int status = -1; + u8 regs[] = {0x30, 0x31, 0x32, 0x33}; + + DEBUG_PRINT("Starting sfp present status update"); + mutex_lock(&data->update_lock); + + /* Read present status of port 1~32 */ + data->present = 0; + + for (i = 0; i < ARRAY_SIZE(regs); i++) { + status = accton_i2c_cpld_read(0x60, regs[i]); + + if (status < 0) { + DEBUG_PRINT("cpld(0x60) reg(0x%x) err %d", regs[i], status); + goto exit; + } + + DEBUG_PRINT("Present status = 0x%llx", data->present); + data->present |= (u64)status << (i*8); + } + + DEBUG_PRINT("Present status = 0x%llx", data->present); +exit: + mutex_unlock(&data->update_lock); + return data; +} + +static struct sfp_port_data *sfp_update_tx_rx_status(struct device *dev) +{ + return NULL; +} + +static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + return 0; +} + +static int sfp_is_port_present(struct i2c_client *client, int port) +{ + struct sfp_port_data *data = sfp_update_present(client); + return (data->present & BIT_INDEX(data->port)) ? 0 : 1; +} + +static ssize_t show_present(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + if (PRESENT_ALL == attr->index) { + + } + + /* PRESENT */ + return sprintf(buf, "%d\n", sfp_is_port_present(client, data->port)); +} + +static struct sfp_port_data *sfp_update_port_type(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + u8 buf = 0; + int status; + + mutex_lock(&data->update_lock); + + switch (data->driver_type) { + case DRIVER_TYPE_SFP_MSA: + { + status = sfp_eeprom_read(data->client, SFF8024_PHYSICAL_DEVICE_ID_ADDR, &buf, sizeof(buf)); + if (status < 0) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + if (buf != SFF8024_DEVICE_ID_SFP) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + status = sfp_eeprom_read(data->client, SFF8472_10G_ETH_COMPLIANCE_ADDR, &buf, sizeof(buf)); + if (status < 0) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + DEBUG_PRINT("sfp port type (0x3) data = (0x%x)", buf); + data->port_type = buf & SFF8472_10G_BASE_MASK ? OOM_DRIVER_PORT_TYPE_SFP_PLUS : OOM_DRIVER_PORT_TYPE_SFP; + break; + } + case DRIVER_TYPE_QSFP: + { + status = sfp_eeprom_read(data->client, SFF8024_PHYSICAL_DEVICE_ID_ADDR, &buf, sizeof(buf)); + if (status < 0) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + DEBUG_PRINT("qsfp port type (0x0) buf = (0x%x)", buf); + switch (buf) { + case SFF8024_DEVICE_ID_QSFP: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP; + break; + case SFF8024_DEVICE_ID_QSFP_PLUS: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP_PLUS; + break; + case SFF8024_DEVICE_ID_QSFP28: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP_PLUS; + break; + default: + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + break; + } + default: + break; + } + + mutex_unlock(&data->update_lock); + return data; +} + +static ssize_t show_port_type(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + if (!sfp_is_port_present(client, data->port)) { + return sprintf(buf, "%d\n", OOM_DRIVER_PORT_TYPE_NOT_PRESENT); + } + + sfp_update_port_type(dev); + return sprintf(buf, "%d\n", data->port_type); +} + + +static struct sfp_port_data *sfp_update_port_reset(struct i2c_client *client) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + int i = 0; + int status = -1; + u8 regs[] = {0x4, 0x5, 0x6, 0x7}; + + mutex_lock(&data->update_lock); + + /* Read reset status of port 1~32 */ + data->port_reset = 0; + + for (i = 0; i < ARRAY_SIZE(regs); i++) { + status = accton_i2c_cpld_read(0x60, regs[i]); + + if (status < 0) { + DEBUG_PRINT("cpld(0x60) reg(0x%x) err %d", regs[i], status); + goto exit; + } + + DEBUG_PRINT("reset status = 0x%x", status); + data->port_reset |= (u64)status << (i*8); + } + + DEBUG_PRINT("reset status = 0x%llx", data->port_reset); +exit: + mutex_unlock(&data->update_lock); + return data; +} + +static ssize_t show_port_reset(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int is_reset = 0; + + if (!sfp_is_port_present(client, data->port)) { + return sprintf(buf, "%d\n", OOM_DRIVER_PORT_TYPE_NOT_PRESENT); + } + + sfp_update_port_reset(client); + is_reset = (data->port_reset & BIT_INDEX(data->port))? 0 : 1; + + return sprintf(buf, "%d\n", is_reset); +} + +static ssize_t sfp_set_port_reset(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + u8 cpld_reg = 0, cpld_val = 0, cpld_bit = 0; + long is_reset; + int error; + + error = kstrtol(buf, 10, &is_reset); + if (error) { + return error; + } + + mutex_lock(&data->update_lock); + + cpld_reg = 0x4 + data->port / 8; + cpld_bit = 1 << (data->port % 8); + + cpld_val = accton_i2c_cpld_read(0x60, cpld_reg); + DEBUG_PRINT("current cpld reg = 0x%x value = 0x%x", cpld_reg, cpld_val); + + /* Update reset status. CPLD defined 0 is reset state, 1 is normal state. + * is_reset: 0 is not reset. 1 is reset. + */ + if (is_reset == 0) { + data->port_reset |= BIT_INDEX(data->port); + cpld_val |= cpld_bit; + } + else { + data->port_reset &= ~BIT_INDEX(data->port); + cpld_val &= ~cpld_bit; + } + + accton_i2c_cpld_write(0x60, cpld_reg, cpld_val); + DEBUG_PRINT("write cpld reg = 0x%x value = 0x%x cpld_bit = 0x%x", cpld_reg, cpld_val,cpld_bit); + + mutex_unlock(&data->update_lock); + + return count; +} + +static struct sfp_port_data *qsfp_update_tx_rx_status(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int i, status = -1; + u8 buf = 0; + u8 reg[] = {SFF8436_TX_FAULT_ADDR, SFF8436_TX_DISABLE_ADDR, SFF8436_RX_LOS_ADDR}; + + if (time_before(jiffies, data->qsfp->last_updated + HZ + HZ / 2) && data->qsfp->valid) { + return data; + } + + dev_dbg(dev, "Starting sfp tx rx status update"); + mutex_lock(&data->update_lock); + data->qsfp->valid = 0; + memset(data->qsfp->status, 0, sizeof(data->qsfp->status)); + + /* Notify device to update tx fault/ tx disable/ rx los status */ + for (i = 0; i < ARRAY_SIZE(reg); i++) { + status = sfp_eeprom_read(data->client, reg[i], &buf, sizeof(buf)); + if (status < 0) { + goto exit; + } + } + msleep(200); + + /* Read actual tx fault/ tx disable/ rx los status */ + for (i = 0; i < ARRAY_SIZE(reg); i++) { + status = sfp_eeprom_read(data->client, reg[i], &buf, sizeof(buf)); + if (status < 0) { + goto exit; + } + + DEBUG_PRINT("qsfp reg(0x%x) status = (0x%x)", reg[i], data->qsfp->status[i]); + data->qsfp->status[i] = (buf & 0xF); + } + + data->qsfp->valid = 1; + data->qsfp->last_updated = jiffies; + mutex_unlock(&data->update_lock); + return data; + +exit: + mutex_unlock(&data->update_lock); + return NULL; +} + +static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + u8 val = 0; + struct i2c_client *client = to_i2c_client(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct sfp_port_data *data = i2c_get_clientdata(client); + + if (!sfp_is_port_present(client, data->port)) { + return -ENODEV; + } + + data = qsfp_update_tx_rx_status(dev); + if (!data) { + return -EIO; + } + + switch (attr->index) { + case TX_FAULT1: + case TX_FAULT2: + case TX_FAULT3: + case TX_FAULT4: + val = (data->qsfp->status[2] & BIT_INDEX(attr->index - TX_FAULT1)) ? 1 : 0; + break; + case TX_DISABLE1: + case TX_DISABLE2: + case TX_DISABLE3: + case TX_DISABLE4: + val = (data->qsfp->status[1] & BIT_INDEX(attr->index - TX_DISABLE1)) ? 1 : 0; + break; + case TX_DISABLE_ALL: + val = ((data->qsfp->status[1] & 0xF) == 0xF) ? 1 : 0; + break; + + case RX_LOS1: + case RX_LOS2: + case RX_LOS3: + case RX_LOS4: + val = (data->qsfp->status[0] & BIT_INDEX(attr->index - RX_LOS1)) ? 1 : 0; + break; + default: + break; + } + + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + long disable; + int result; + struct i2c_client *client = to_i2c_client(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct sfp_port_data *data; + + result = kstrtol(buf, 10, &disable); + if (result) { + return result; + } + + data = qsfp_update_tx_rx_status(dev); + if (!data) { + return -EIO; + } + + mutex_lock(&data->update_lock); + + DEBUG_PRINT ("disable:%ld %d==%d %u\r\n", disable, attr->index, TX_DISABLE_ALL, data->qsfp->status[1]); + + if (attr->index == TX_DISABLE_ALL) + { + data->qsfp->status[1] = disable? 0xF:0; + } + else + { + if (disable) { + data->qsfp->status[1] |= (1 << (attr->index - TX_DISABLE1)); + } + else { + data->qsfp->status[1] &= ~(1 << (attr->index - TX_DISABLE1)); + } + } + DEBUG_PRINT("index = (%d), status = (0x%x)", attr->index, data->qsfp->status[1]); + result = sfp_eeprom_write(client, SFF8436_TX_DISABLE_ADDR, &data->qsfp->status[1], sizeof(data->qsfp->status[1])); + mutex_unlock(&data->update_lock); + return count; +} + +static ssize_t sfp_show_ddm_implemented(struct device *dev, struct device_attribute *da, + char *buf) +{ + int status; + char ddm; + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + if (!sfp_is_port_present(client, data->port)) { + return -ENODEV; + } + + status = sfp_eeprom_read(data->client, SFF8472_DIAG_MON_TYPE_ADDR, &ddm, sizeof(ddm)); + if (status < 0) { + return -EIO; + } + + return sprintf(buf, "%d\n", (ddm & SFF8472_DIAG_MON_TYPE_DDM_MASK) ? 1 : 0); +} + +static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + u8 val = 0, index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct sfp_port_data *data; + + data = sfp_update_tx_rx_status(dev); + if (!data) { + return -EIO; + } + + switch (attr->index) { + case TX_FAULT: + index = 0; + break; + case TX_DISABLE: + index = 1; + break; + case RX_LOS: + index = 2; + break; + default: + break; + } + + val = (data->ddm->status[index] & BIT_INDEX(data->port)) ? 1 : 0; + return sprintf(buf, "%d\n", val); +} + +/* SFP/QSFP common attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_port_number, S_IRUGO, show_port_number, NULL, PORT_NUMBER); +static SENSOR_DEVICE_ATTR(sfp_is_present, S_IRUGO, show_present, NULL, PRESENT); +static SENSOR_DEVICE_ATTR(sfp_port_type, S_IRUGO, show_port_type, NULL, PORT_TYPE); +static SENSOR_DEVICE_ATTR(sfp_is_present_all, S_IRUGO, show_present, NULL, PRESENT); +static SENSOR_DEVICE_ATTR(sfp_port_reset, S_IWUSR | S_IRUGO, show_port_reset, sfp_set_port_reset, PORT_RESET); + +/* QSFP attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_rx_los1, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS1); +static SENSOR_DEVICE_ATTR(sfp_rx_los2, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS2); +static SENSOR_DEVICE_ATTR(sfp_rx_los3, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS3); +static SENSOR_DEVICE_ATTR(sfp_rx_los4, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS4); +static SENSOR_DEVICE_ATTR(sfp_tx_disable1, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE1); +static SENSOR_DEVICE_ATTR(sfp_tx_disable2, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE2); +static SENSOR_DEVICE_ATTR(sfp_tx_disable3, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE3); +static SENSOR_DEVICE_ATTR(sfp_tx_disable4, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE4); +static SENSOR_DEVICE_ATTR(sfp_tx_disable_all, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE_ALL); +static SENSOR_DEVICE_ATTR(sfp_tx_fault1, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT1); +static SENSOR_DEVICE_ATTR(sfp_tx_fault2, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT2); +static SENSOR_DEVICE_ATTR(sfp_tx_fault3, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT3); +static SENSOR_DEVICE_ATTR(sfp_tx_fault4, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT4); +static struct attribute *qsfp_attributes[] = { + &sensor_dev_attr_sfp_port_number.dev_attr.attr, + &sensor_dev_attr_sfp_port_type.dev_attr.attr, + &sensor_dev_attr_sfp_is_present.dev_attr.attr, + &sensor_dev_attr_sfp_port_reset.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los1.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los2.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los3.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los4.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable1.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable2.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable3.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable4.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable_all.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault1.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault2.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault3.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault4.dev_attr.attr, + NULL +}; + +/* SFP msa attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_ddm_implemented, S_IRUGO, sfp_show_ddm_implemented, NULL, DDM_IMPLEMENTED); +static struct attribute *sfp_msa_attributes[] = { + &sensor_dev_attr_sfp_port_number.dev_attr.attr, + &sensor_dev_attr_sfp_port_type.dev_attr.attr, + &sensor_dev_attr_sfp_is_present.dev_attr.attr, + &sensor_dev_attr_sfp_ddm_implemented.dev_attr.attr, + NULL +}; + +/* SFP ddm attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_rx_los, S_IRUGO, sfp_show_tx_rx_status, NULL, RX_LOS); +static SENSOR_DEVICE_ATTR(sfp_tx_disable, S_IWUSR | S_IRUGO, sfp_show_tx_rx_status, sfp_set_tx_disable, TX_DISABLE); +static SENSOR_DEVICE_ATTR(sfp_tx_fault, S_IRUGO, sfp_show_tx_rx_status, NULL, TX_FAULT); +static struct attribute *sfp_ddm_attributes[] = { + &sensor_dev_attr_sfp_tx_fault.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable.dev_attr.attr, + NULL +}; + +static ssize_t sfp_eeprom_write(struct i2c_client *client, u8 command, const char *data, + int data_len) +{ +#if USE_I2C_BLOCK_READ + int result, retry = I2C_RW_RETRY_COUNT; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + result = i2c_smbus_write_i2c_block_data(client, command, data_len, data); + if (result < 0) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(result < 0)) { + return result; + } + + return data_len; +#else + int result, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + result = i2c_smbus_write_byte_data(client, command, *data); + if (result < 0) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(result < 0)) { + return result; + } + + return 1; +#endif + + +} + + +static ssize_t sfp_port_write(struct sfp_port_data *data, + const char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + return count; + } + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&data->update_lock); + + while (count) { + ssize_t status; + + status = sfp_eeprom_write(data->client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&data->update_lock); + return retval; +} + + +static ssize_t sfp_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + struct sfp_port_data *data; + DEBUG_PRINT("offset = (%d), count = (%d)", off, count); + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + return sfp_port_write(data, buf, off, count); +} + +static ssize_t sfp_eeprom_read(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ +#if USE_I2C_BLOCK_READ + int result, retry = I2C_RW_RETRY_COUNT; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + if (result < 0) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(result < 0)) + goto abort; + if (unlikely(result != data_len)) { + result = -EIO; + goto abort; + } + + //result = data_len; + +abort: + return result; +#else + int result, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + result = i2c_smbus_read_byte_data(client, command); + if (result < 0) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(result < 0)) { + dev_dbg(&client->dev, "sfp read byte data failed, command(0x%2x), data(0x%2x)\r\n", command, result); + goto abort; + } + + *data = (u8)result; + result = 1; + +abort: + return result; +#endif +} + +static ssize_t sfp_port_read(struct sfp_port_data *data, + char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + DEBUG_PRINT("Count = 0, return"); + return count; + } + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&data->update_lock); + + while (count) { + ssize_t status; + + status = sfp_eeprom_read(data->client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&data->update_lock); + return retval; + +} + +static ssize_t sfp_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + struct sfp_port_data *data; + DEBUG_PRINT("offset = (%d), count = (%d)", off, count); + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + return sfp_port_read(data, buf, off, count); +} + +static int sfp_sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom) +{ + int err; + + sysfs_bin_attr_init(eeprom); + eeprom->attr.name = EEPROM_NAME; + eeprom->attr.mode = S_IWUSR | S_IRUGO; + eeprom->read = sfp_bin_read; + eeprom->write = sfp_bin_write; + eeprom->size = EEPROM_SIZE; + + /* Create eeprom file */ + err = sysfs_create_bin_file(kobj, eeprom); + if (err) { + return err; + } + + return 0; +} + +static int sfp_sysfs_eeprom_cleanup(struct kobject *kobj, struct bin_attribute *eeprom) +{ + sysfs_remove_bin_file(kobj, eeprom); + return 0; +} + +static const struct attribute_group sfp_msa_group = { + .attrs = sfp_msa_attributes, +}; + +static int sfp_i2c_check_functionality(struct i2c_client *client) +{ +#if USE_I2C_BLOCK_READ + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK); +#else + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA); +#endif +} + +static int sfp_msa_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct sfp_msa_data **data) +{ + int status; + struct sfp_msa_data *msa; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + msa = kzalloc(sizeof(struct sfp_msa_data), GFP_KERNEL); + if (!msa) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &sfp_msa_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &msa->eeprom.bin); + if (status) { + goto exit_remove; + } + + *data = msa; + dev_info(&client->dev, "sfp msa '%s'\n", client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &sfp_msa_group); +exit_free: + kfree(msa); +exit: + + return status; +} + +static const struct attribute_group sfp_ddm_group = { + .attrs = sfp_ddm_attributes, +}; + +static int sfp_ddm_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct sfp_ddm_data **data) +{ + int status; + struct sfp_ddm_data *ddm; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + ddm = kzalloc(sizeof(struct sfp_ddm_data), GFP_KERNEL); + if (!ddm) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &sfp_ddm_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &ddm->eeprom.bin); + if (status) { + goto exit_remove; + } + + *data = ddm; + dev_info(&client->dev, "sfp ddm '%s'\n", client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &sfp_ddm_group); +exit_free: + kfree(ddm); +exit: + + return status; +} + +static const struct attribute_group qsfp_group = { + .attrs = qsfp_attributes, +}; + +static int qsfp_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct qsfp_data **data) +{ + int status; + struct qsfp_data *qsfp; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + qsfp = kzalloc(sizeof(struct qsfp_data), GFP_KERNEL); + if (!qsfp) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &qsfp_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &qsfp->eeprom.bin); + if (status) { + goto exit_remove; + } + + /* Bring QSFPs out of reset + as6712_32x_i2c_cpld_write(0x62, 0x4, 0xFF); + as6712_32x_i2c_cpld_write(0x62, 0x5, 0xFF); + as6712_32x_i2c_cpld_write(0x64, 0x4, 0xFF); + as6712_32x_i2c_cpld_write(0x64, 0x5, 0xFF);*/ + + *data = qsfp; + dev_info(&client->dev, "qsfp '%s'\n", client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &qsfp_group); +exit_free: + kfree(qsfp); +exit: + + return status; +} + +static int sfp_device_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct sfp_port_data *data = NULL; + + data = kzalloc(sizeof(struct sfp_port_data), GFP_KERNEL); + if (!data) { + return -ENOMEM; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->port = dev_id->driver_data; + data->client = client; + + if (client->addr != SFP_EEPROM_A0_I2C_ADDR) { + return -ENODEV; + } + + data->driver_type = DRIVER_TYPE_QSFP; + return qsfp_probe(client, dev_id, &data->qsfp); +} + +static int sfp_msa_remove(struct i2c_client *client, struct sfp_msa_data *data) +{ + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + sysfs_remove_group(&client->dev.kobj, &sfp_msa_group); + kfree(data); + return 0; +} + +static int sfp_ddm_remove(struct i2c_client *client, struct sfp_ddm_data *data) +{ + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + sysfs_remove_group(&client->dev.kobj, &sfp_ddm_group); + kfree(data); + return 0; +} + +static int qfp_remove(struct i2c_client *client, struct qsfp_data *data) +{ + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + sysfs_remove_group(&client->dev.kobj, &qsfp_group); + kfree(data); + return 0; +} + +static int sfp_device_remove(struct i2c_client *client) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + + switch (data->driver_type) { + case DRIVER_TYPE_SFP_MSA: + return sfp_msa_remove(client, data->msa); + case DRIVER_TYPE_SFP_DDM: + return sfp_ddm_remove(client, data->ddm); + case DRIVER_TYPE_QSFP: + return qfp_remove(client, data->qsfp); + } + + return 0; +} + +static struct i2c_driver sfp_driver = { + .driver = { + .name = DRIVER_NAME, + }, + .probe = sfp_device_probe, + .remove = sfp_device_remove, + .id_table = sfp_device_id, + .address_list = normal_i2c, +}; + +static int __init sfp_init(void) +{ + return i2c_add_driver(&sfp_driver); +} + +static void __exit sfp_exit(void) +{ + i2c_del_driver(&sfp_driver); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton as7712_32x_sfp driver"); +MODULE_LICENSE("GPL"); + +module_init(sfp_init); +module_exit(sfp_exit); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/accton_i2c_cpld.c b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/accton_i2c_cpld.c new file mode 120000 index 000000000000..39c0826d16fd --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/accton_i2c_cpld.c @@ -0,0 +1 @@ +../../common/modules/accton_i2c_cpld.c \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/accton_pmbus_3y.c b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/accton_pmbus_3y.c new file mode 120000 index 000000000000..7504a0556e18 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/accton_pmbus_3y.c @@ -0,0 +1 @@ +../../common/modules/accton_pmbus_3y.c \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/leds-accton_as7712_32x.c b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/leds-accton_as7712_32x.c new file mode 100644 index 000000000000..5e1a9282db0e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/leds-accton_as7712_32x.c @@ -0,0 +1,690 @@ +/* + * A LED driver for the accton_as7712_32x_led + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*#define DEBUG*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +extern int accton_i2c_cpld_read (unsigned short cpld_addr, u8 reg); +extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +extern void led_classdev_unregister(struct led_classdev *led_cdev); +extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); +extern void led_classdev_resume(struct led_classdev *led_cdev); +extern void led_classdev_suspend(struct led_classdev *led_cdev); + +#define DRVNAME "accton_as7712_32x_led" +#define ENABLE_PORT_LED 1 + +struct accton_as7712_32x_led_data { + struct platform_device *pdev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[1]; /* only 1 register*/ +}; + +static struct accton_as7712_32x_led_data *ledctl = NULL; + +/* LED related data + */ + +#define LED_CNTRLER_I2C_ADDRESS (0x60) + +#define LED_TYPE_DIAG_REG_MASK (0x3) +#define LED_MODE_DIAG_GREEN_VALUE (0x02) +#define LED_MODE_DIAG_RED_VALUE (0x01) +#define LED_MODE_DIAG_AMBER_VALUE (0x00) /*It's yellow actually. Green+Red=Yellow*/ +#define LED_MODE_DIAG_OFF_VALUE (0x03) + +#define LED_TYPE_LOC_REG_MASK (0x80) +#define LED_MODE_LOC_ON_VALUE (0) +#define LED_MODE_LOC_OFF_VALUE (0x80) + +#if (ENABLE_PORT_LED == 1) +#define LED_TYPE_PORT_LED(port) \ + LED_TYPE_PORT##port##_LED0, \ + LED_TYPE_PORT##port##_LED1, \ + LED_TYPE_PORT##port##_LED2, \ + LED_TYPE_PORT##port##_LED3 +#endif + +enum led_type { + LED_TYPE_DIAG, + LED_TYPE_LOC, + LED_TYPE_FAN, + LED_TYPE_PSU1, + LED_TYPE_PSU2, +#if (ENABLE_PORT_LED == 1) + LED_TYPE_PORT_LED(0), + LED_TYPE_PORT_LED(1), + LED_TYPE_PORT_LED(2), + LED_TYPE_PORT_LED(3), + LED_TYPE_PORT_LED(4), + LED_TYPE_PORT_LED(5), + LED_TYPE_PORT_LED(6), + LED_TYPE_PORT_LED(7), + LED_TYPE_PORT_LED(8), + LED_TYPE_PORT_LED(9), + LED_TYPE_PORT_LED(10), + LED_TYPE_PORT_LED(11), + LED_TYPE_PORT_LED(12), + LED_TYPE_PORT_LED(13), + LED_TYPE_PORT_LED(14), + LED_TYPE_PORT_LED(15), + LED_TYPE_PORT_LED(16), + LED_TYPE_PORT_LED(17), + LED_TYPE_PORT_LED(18), + LED_TYPE_PORT_LED(19), + LED_TYPE_PORT_LED(20), + LED_TYPE_PORT_LED(21), + LED_TYPE_PORT_LED(22), + LED_TYPE_PORT_LED(23), + LED_TYPE_PORT_LED(24), + LED_TYPE_PORT_LED(25), + LED_TYPE_PORT_LED(26), + LED_TYPE_PORT_LED(27), + LED_TYPE_PORT_LED(28), + LED_TYPE_PORT_LED(29), + LED_TYPE_PORT_LED(30), + LED_TYPE_PORT_LED(31), +#endif +}; + +struct led_reg { + u32 types; + u8 reg_addr; +}; + +static const struct led_reg led_reg_map[] = { + {(1<update_lock); + + if (time_after(jiffies, ledctl->last_updated + HZ + HZ / 2) + || !ledctl->valid) { + int i; + + dev_dbg(&ledctl->pdev->dev, "Starting accton_as7712_32x_led update\n"); + + /* Update LED data + */ + for (i = 0; i < ARRAY_SIZE(ledctl->reg_val); i++) { + int status = accton_as7712_32x_led_read_value(led_reg_map[i].reg_addr); + + if (status < 0) { + ledctl->valid = 0; + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", led_reg_map[i].reg_addr, status); + goto exit; + } + else + { + ledctl->reg_val[i] = status; + } + } + + ledctl->last_updated = jiffies; + ledctl->valid = 1; + } + +exit: + mutex_unlock(&ledctl->update_lock); +} + +static void accton_as7712_32x_led_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode, + enum led_type type) +{ + int reg_val; + u8 reg ; + mutex_lock(&ledctl->update_lock); + + if( !accton_getLedReg(type, ®)) + { + dev_dbg(&ledctl->pdev->dev, "Not match item for %d.\n", type); + } + + reg_val = accton_as7712_32x_led_read_value(reg); + + if (reg_val < 0) { + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", reg, reg_val); + goto exit; + } + reg_val = led_light_mode_to_reg_val(type, led_light_mode, reg_val); + accton_as7712_32x_led_write_value(reg, reg_val); + + /* to prevent the slow-update issue */ + ledctl->valid = 0; + +exit: + mutex_unlock(&ledctl->update_lock); +} + + +static void accton_as7712_32x_led_diag_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + accton_as7712_32x_led_set(led_cdev, led_light_mode, LED_TYPE_DIAG); +} + +static enum led_brightness accton_as7712_32x_led_diag_get(struct led_classdev *cdev) +{ + accton_as7712_32x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_DIAG, ledctl->reg_val[0]); +} + +static void accton_as7712_32x_led_loc_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + accton_as7712_32x_led_set(led_cdev, led_light_mode, LED_TYPE_LOC); +} + +static enum led_brightness accton_as7712_32x_led_loc_get(struct led_classdev *cdev) +{ + accton_as7712_32x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_LOC, ledctl->reg_val[0]); +} + +static void accton_as7712_32x_led_auto_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ +} + +static enum led_brightness accton_as7712_32x_led_auto_get(struct led_classdev *cdev) +{ + return LED_MODE_AUTO; +} + +#if (ENABLE_PORT_LED == 1) +#define PORT_LED_COLOR_MASK (0x7 << 2) +#define PORT_LED_COLOR1_REG_VAL (0x0 << 2) +#define PORT_LED_COLOR2_REG_VAL (0x1 << 2) +#define PORT_LED_COLOR3_REG_VAL (0x2 << 2) +#define PORT_LED_COLOR4_REG_VAL (0x3 << 2) +#define PORT_LED_COLOR5_REG_VAL (0x4 << 2) +#define PORT_LED_COLOR6_REG_VAL (0x5 << 2) +#define PORT_LED_COLOR7_REG_VAL (0x6 << 2) +#define PORT_LED_COLOR8_REG_VAL (0x7 << 2) + +static int accton_as7712_32x_port_led_read_value(unsigned short cpld_addr, u8 reg) +{ + return accton_i2c_cpld_read(cpld_addr, reg); +} + +static int accton_as7712_32x_port_led_write_value(unsigned short cpld_addr, u8 reg, u8 value) +{ + return accton_i2c_cpld_write(cpld_addr, reg, value); +} + +static int port_led_mode_to_cpld_val(int mode) +{ + u8 color = 0; + u8 blinking = 0; + u8 on = 1 << 0; + + switch (mode) { + case LED_MODE_WHITE_BLINKING: blinking = 1 << 1; /* fall through */ + case LED_MODE_WHITE: color = 0x0 << 2; + break; + case LED_MODE_YELLOW_BLINKING: blinking = 1 << 1; /* fall through */ + case LED_MODE_YELLOW: color = 0x1 << 2; + break; + case LED_MODE_ORANGE_BLINKING: blinking = 1 << 1; /* fall through */ + case LED_MODE_ORANGE: color = 0x2 << 2; + break; + case LED_MODE_PURPLE_BLINKING: blinking = 1 << 1; /* fall through */ + case LED_MODE_PURPLE: color = 0x3 << 2; + break; + case LED_MODE_CYAN_BLINKING: blinking = 1 << 1; /* fall through */ + case LED_MODE_CYAN: color = 0x4 << 2; + break; + case LED_MODE_RED_BLINKING: blinking = 1 << 1; /* fall through */ + case LED_MODE_RED: color = 0x5 << 2; + break; + case LED_MODE_GREEN_BLINKING: blinking = 1 << 1; /* fall through */ + case LED_MODE_GREEN: color = 0x6 << 2; + break; + case LED_MODE_BLUE_BLINKING: blinking = 1 << 1; /* fall through */ + case LED_MODE_BLUE: color = 0x7 << 2; + break; + case LED_MODE_OFF: on = 0 << 0; + break; + default: + return -EINVAL; + } + + return (color | blinking | on); +} + +static int cpld_val_to_port_led_mode(uint8_t value) +{ + int on = (value & 0x1); + int blinking = (value & 0x2); + int color = (value & PORT_LED_COLOR_MASK) ; + + if (!on) { + return LED_MODE_OFF; + } + + switch (color) { + case PORT_LED_COLOR1_REG_VAL: + return blinking ? LED_MODE_WHITE_BLINKING : LED_MODE_WHITE; + case PORT_LED_COLOR2_REG_VAL: + return blinking ? LED_MODE_YELLOW_BLINKING : LED_MODE_YELLOW; + case PORT_LED_COLOR3_REG_VAL: + return blinking ? LED_MODE_ORANGE_BLINKING : LED_MODE_ORANGE; + case PORT_LED_COLOR4_REG_VAL: + return blinking ? LED_MODE_PURPLE_BLINKING : LED_MODE_PURPLE; + case PORT_LED_COLOR5_REG_VAL: + return blinking ? LED_MODE_CYAN_BLINKING : LED_MODE_CYAN; + case PORT_LED_COLOR6_REG_VAL: + return blinking ? LED_MODE_RED_BLINKING : LED_MODE_RED; + case PORT_LED_COLOR7_REG_VAL: + return blinking ? LED_MODE_GREEN_BLINKING : LED_MODE_GREEN; + case PORT_LED_COLOR8_REG_VAL: + return blinking ? LED_MODE_BLUE_BLINKING : LED_MODE_BLUE; + default: + return -EINVAL;; + } +} + + +static void accton_as7712_32x_port_led_set(struct led_classdev *cdev, + enum led_brightness led_light_mode) +{ + unsigned int port, lid; + unsigned short cpld_addr; + u8 reg, value; + sscanf(cdev->name, "accton_as7712_32x_led::port%u_led%u", &port, &lid); + + if (port > 32 || lid > 4) { + dev_dbg(&ledctl->pdev->dev, "Port(%u), Led_id(%u) not match\n", port, lid); + return; + } + + cpld_addr = (port < 16) ? 0x64 : 0x62; + reg = (0x50 + (port % 16) * 4 + lid); + value = port_led_mode_to_cpld_val(led_light_mode); + + if (value < 0) { + dev_dbg(&ledctl->pdev->dev, "Unknow port led mode(%d)\n", led_light_mode); + return; + } + + accton_as7712_32x_port_led_write_value(cpld_addr, reg, value); +} + +static enum led_brightness accton_as7712_32x_port_led_get(struct led_classdev *cdev) +{ + unsigned int port, lid; + unsigned short cpld_addr; + u8 reg, value; + sscanf(cdev->name, "accton_as7712_32x_led::port%u_led%u", &port, &lid); + + if (port > 32 || lid > 4) { + dev_dbg(&ledctl->pdev->dev, "Port(%u), Led_id(%u) not match\n", port, lid); + return -EINVAL; + } + + cpld_addr = (port < 16) ? 0x64 : 0x62; + reg = (0x50 + (port % 16) * 4 + lid); + value = accton_as7712_32x_port_led_read_value(cpld_addr, reg); + + if (value < 0) { + dev_dbg(&ledctl->pdev->dev, "Unable to read reg value from cpld(0x%x), reg(0x%x)\n", cpld_addr, reg); + return value; + } + + return cpld_val_to_port_led_mode(value); +} + +#define _PORT_LED_CLASSDEV(port, lid) \ + [LED_TYPE_PORT##port##_LED##lid] = { \ + .name = "accton_as7712_32x_led::port"#port"_led"#lid,\ + .default_trigger = "unused", \ + .brightness_set = accton_as7712_32x_port_led_set, \ + .brightness_get = accton_as7712_32x_port_led_get, \ + .max_brightness = LED_MODE_CYAN_BLINKING, \ + } + +#define PORT_LED_CLASSDEV(port) \ + _PORT_LED_CLASSDEV(port, 0),\ + _PORT_LED_CLASSDEV(port, 1),\ + _PORT_LED_CLASSDEV(port, 2),\ + _PORT_LED_CLASSDEV(port, 3) +#endif + +static struct led_classdev accton_as7712_32x_leds[] = { + [LED_TYPE_DIAG] = { + .name = "accton_as7712_32x_led::diag", + .default_trigger = "unused", + .brightness_set = accton_as7712_32x_led_diag_set, + .brightness_get = accton_as7712_32x_led_diag_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_RED, + }, + [LED_TYPE_LOC] = { + .name = "accton_as7712_32x_led::loc", + .default_trigger = "unused", + .brightness_set = accton_as7712_32x_led_loc_set, + .brightness_get = accton_as7712_32x_led_loc_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_BLUE, + }, + [LED_TYPE_FAN] = { + .name = "accton_as7712_32x_led::fan", + .default_trigger = "unused", + .brightness_set = accton_as7712_32x_led_auto_set, + .brightness_get = accton_as7712_32x_led_auto_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_PSU1] = { + .name = "accton_as7712_32x_led::psu1", + .default_trigger = "unused", + .brightness_set = accton_as7712_32x_led_auto_set, + .brightness_get = accton_as7712_32x_led_auto_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_PSU2] = { + .name = "accton_as7712_32x_led::psu2", + .default_trigger = "unused", + .brightness_set = accton_as7712_32x_led_auto_set, + .brightness_get = accton_as7712_32x_led_auto_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, +#if (ENABLE_PORT_LED == 1) + PORT_LED_CLASSDEV(0), + PORT_LED_CLASSDEV(1), + PORT_LED_CLASSDEV(2), + PORT_LED_CLASSDEV(3), + PORT_LED_CLASSDEV(4), + PORT_LED_CLASSDEV(5), + PORT_LED_CLASSDEV(6), + PORT_LED_CLASSDEV(7), + PORT_LED_CLASSDEV(8), + PORT_LED_CLASSDEV(9), + PORT_LED_CLASSDEV(10), + PORT_LED_CLASSDEV(11), + PORT_LED_CLASSDEV(12), + PORT_LED_CLASSDEV(13), + PORT_LED_CLASSDEV(14), + PORT_LED_CLASSDEV(15), + PORT_LED_CLASSDEV(16), + PORT_LED_CLASSDEV(17), + PORT_LED_CLASSDEV(18), + PORT_LED_CLASSDEV(19), + PORT_LED_CLASSDEV(20), + PORT_LED_CLASSDEV(21), + PORT_LED_CLASSDEV(22), + PORT_LED_CLASSDEV(23), + PORT_LED_CLASSDEV(24), + PORT_LED_CLASSDEV(25), + PORT_LED_CLASSDEV(26), + PORT_LED_CLASSDEV(27), + PORT_LED_CLASSDEV(28), + PORT_LED_CLASSDEV(29), + PORT_LED_CLASSDEV(30), + PORT_LED_CLASSDEV(31), +#endif +}; + +static int accton_as7712_32x_led_suspend(struct platform_device *dev, + pm_message_t state) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(accton_as7712_32x_leds); i++) { + led_classdev_suspend(&accton_as7712_32x_leds[i]); + } + + return 0; +} + +static int accton_as7712_32x_led_resume(struct platform_device *dev) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(accton_as7712_32x_leds); i++) { + led_classdev_resume(&accton_as7712_32x_leds[i]); + } + + return 0; +} + +static int accton_as7712_32x_led_probe(struct platform_device *pdev) +{ + int ret, i; + + for (i = 0; i < ARRAY_SIZE(accton_as7712_32x_leds); i++) { + ret = led_classdev_register(&pdev->dev, &accton_as7712_32x_leds[i]); + + if (ret < 0) + break; + } + + /* Check if all LEDs were successfully registered */ + if (i != ARRAY_SIZE(accton_as7712_32x_leds)){ + int j; + + /* only unregister the LEDs that were successfully registered */ + for (j = 0; j < i; j++) { + led_classdev_unregister(&accton_as7712_32x_leds[i]); + } + } + + return ret; +} + +static int accton_as7712_32x_led_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(accton_as7712_32x_leds); i++) { + led_classdev_unregister(&accton_as7712_32x_leds[i]); + } + + return 0; +} + +static struct platform_driver accton_as7712_32x_led_driver = { + .probe = accton_as7712_32x_led_probe, + .remove = accton_as7712_32x_led_remove, + .suspend = accton_as7712_32x_led_suspend, + .resume = accton_as7712_32x_led_resume, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +static int __init accton_as7712_32x_led_init(void) +{ + int ret; + + ret = platform_driver_register(&accton_as7712_32x_led_driver); + if (ret < 0) { + goto exit; + } + + ledctl = kzalloc(sizeof(struct accton_as7712_32x_led_data), GFP_KERNEL); + if (!ledctl) { + ret = -ENOMEM; + platform_driver_unregister(&accton_as7712_32x_led_driver); + goto exit; + } + + mutex_init(&ledctl->update_lock); + + ledctl->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(ledctl->pdev)) { + ret = PTR_ERR(ledctl->pdev); + platform_driver_unregister(&accton_as7712_32x_led_driver); + kfree(ledctl); + goto exit; + } + +exit: + return ret; +} + +static void __exit accton_as7712_32x_led_exit(void) +{ + platform_device_unregister(ledctl->pdev); + platform_driver_unregister(&accton_as7712_32x_led_driver); + kfree(ledctl); +} + +module_init(accton_as7712_32x_led_init); +module_exit(accton_as7712_32x_led_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton_as7712_32x_led driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/pmbus.h b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/pmbus.h new file mode 120000 index 000000000000..b0e1a57107fd --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/pmbus.h @@ -0,0 +1 @@ +../../common/modules/pmbus.h \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/ym2651y.c b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/ym2651y.c new file mode 120000 index 000000000000..f4d67640ccc3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/modules/ym2651y.c @@ -0,0 +1 @@ +../../common/modules/ym2651y.c \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-accton/as7712-32x/service/as7712-platform-init.service b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/service/as7712-platform-init.service new file mode 100755 index 000000000000..d5d25b6cde04 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/service/as7712-platform-init.service @@ -0,0 +1,13 @@ +[Unit] +Description=Accton AS7712-32X Platform initialization service +Before=pmon.service +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/accton_as7712_util.py install +ExecStop=/usr/local/bin/accton_as7712_util.py clean +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-accton/as7712-32x/setup.py b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/setup.py new file mode 100755 index 000000000000..09c763c84f01 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/setup.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python + +import os +import sys +from setuptools import setup +os.listdir + +setup( + name='as7712_32x', + version='1.0', + description='Module to initialize Accton AS7712-32X platforms', + + packages=['as7712_32x'], + package_dir={'as7712_32x': 'as7712-32x/classes'}, +) + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7712-32x/utils/README b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/utils/README new file mode 100755 index 000000000000..0b9fc1633999 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/utils/README @@ -0,0 +1,60 @@ +Copyright (C) 2016 Accton Networks, 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 3 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, see . + +To initialize the system, run "accton_as7712_util.py install". +To clean up the drivers & devices, run "accton_as7712_util.py clean". +To dump information of sensors, run "accton_as7712_util.py show". +To dump SFP EEPROM, run "accton_as7712_util.py sff". +To set fan speed, run "accton_as7712_util.py set fan". +To enable/disable SFP emission, run "accton_as7712_util.py set sfp". +To set system LEDs' color, run "accton_as7712_util.py set led" +For more information, run "accton_as7712_util.py --help". + +==================================================================== +Besides applying accton_as7712_util.py to access peripherals, you can +access peripherals by sysfs nodes directly after the installation is run. + +LED controls can be found under /sys/class/leds. The sysfs interface +color mappings are as follows: +Brightness: + 0 => off + 1 => green + 2 => amber + 3 => red + 4 => blue + +There are 5 system LEDs, loc, diag, fan, ps1, and ps2. +They are lit automatically by CPLD, but the loc and diag. +The loc led has only 1 color, blue. +The diag one has 3 colors: red, amber, and green. + +Fan controls can be found in /sys/bus/i2c/devices/2-0066. +There are 12 fans inside 6 fan modules. +All fans share 1 duty setting, ranged from 0~100. + +Three temperature sensors are controlled by the lm75 kernel modules. +They should already be visible under /sys/bus/i2c/drivers/lm75/. + +Two power supplies are controlled by the CPLD. +Here provide their status under +/sys/bus/i2c/devices/10-0050 and /sys/bus/i2c/devices/11-0053. + +There are 32 QSFP+ modules are equipped. +Apply "accton_as7712_util.py show" to get their status. +Apply "accton_as7712_util.py set sfp" to turn on/off light transmission. +Apply "accton_as7712_util.py sff" to dump EEPROM information. +Before operating on that QSFP+, please make sure it is well plugged. +Otherwise, operation is going to fail. + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7712-32x/utils/accton_as7712_util.py b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/utils/accton_as7712_util.py new file mode 100755 index 000000000000..c8b755b85b69 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/utils/accton_as7712_util.py @@ -0,0 +1,569 @@ +#!/usr/bin/env python +# +# Copyright (C) 2016 Accton Networks, 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 3 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, see . + +""" +Usage: %(scriptName)s [options] command object + +options: + -h | --help : this help message + -d | --debug : run with debug mode + -f | --force : ignore error during installation or clean +command: + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes + show : show all systen status + sff : dump SFP eeprom + set : change board setting with fan|led|sfp +""" + +import os +import commands +import sys, getopt +import logging +import re +import time +from collections import namedtuple + + + + +PROJECT_NAME = 'as7712_32x' +version = '0.1.0' +verbose = False +DEBUG = False +args = [] +ALL_DEVICE = {} +DEVICE_NO = {'led':5, 'fan':6,'thermal':4, 'psu':2, 'sfp':32} +FORCE = 0 +#logging.basicConfig(filename= PROJECT_NAME+'.log', filemode='w',level=logging.DEBUG) +#logging.basicConfig(level=logging.INFO) + + +if DEBUG == True: + print sys.argv[0] + print 'ARGV :', sys.argv[1:] + + +def main(): + global DEBUG + global args + global FORCE + + if len(sys.argv)<2: + show_help() + + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', + 'debug', + 'force', + ]) + if DEBUG == True: + print options + print args + print len(sys.argv) + + for opt, arg in options: + if opt in ('-h', '--help'): + show_help() + elif opt in ('-d', '--debug'): + DEBUG = True + logging.basicConfig(level=logging.INFO) + elif opt in ('-f', '--force'): + FORCE = 1 + else: + logging.info('no option') + for arg in args: + if arg == 'install': + do_install() + elif arg == 'clean': + do_uninstall() + elif arg == 'show': + device_traversal() + elif arg == 'sff': + if len(args)!=2: + show_eeprom_help() + elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']: + show_eeprom_help() + else: + show_eeprom(args[1]) + return + elif arg == 'set': + if len(args)<3: + show_set_help() + else: + set_device(args[1:]) + return + else: + show_help() + + + return 0 + +def show_help(): + print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + sys.exit(0) + +def show_set_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print cmd +" [led|sfp|fan]" + print " use \""+ cmd + " led 0-4 \" to set led color" + print " use \""+ cmd + " fan 0-100\" to set fan duty percetage" + print " use \""+ cmd + " sfp 1-32 {0|1}\" to set sfp# tx_disable" + sys.exit(0) + +def show_eeprom_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print " use \""+ cmd + " 1-32 \" to dump sfp# eeprom" + sys.exit(0) + +def my_log(txt): + if DEBUG == True: + print "[ROY]"+txt + return + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) + my_log (cmd +"with result:" + str(status)) + my_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + +def driver_check(): + ret, lsmod = log_os_system("lsmod| grep accton", 0) + logging.info('mods:'+lsmod) + if len(lsmod) ==0: + return False + return True + + + +kos = [ +'modprobe i2c_dev', +'modprobe i2c_mux_pca954x force_deselect_on_exit=1', +'modprobe accton_i2c_cpld' , +'modprobe ym2651y' , +'modprobe accton_as7712_32x_fan' , +'modprobe optoe' , +'modprobe leds-accton_as7712_32x' , +'modprobe accton_as7712_32x_psu' ] + +def driver_install(): + global FORCE + status, output = log_os_system("depmod", 1) + for i in range(0,len(kos)): + status, output = log_os_system(kos[i], 1) + if status: + if FORCE == 0: + return status + return 0 + +def driver_uninstall(): + global FORCE + for i in range(0,len(kos)): + rm = kos[-(i+1)].replace("modprobe", "modprobe -rq") + rm = rm.replace("insmod", "rmmod") + status, output = log_os_system(rm, 1) + if status: + if FORCE == 0: + return status + return 0 + +led_prefix ='/sys/class/leds/accton_'+PROJECT_NAME+'_led::' +hwmon_types = {'led': ['diag','fan','loc','psu1','psu2']} +hwmon_nodes = {'led': ['brightness'] } +hwmon_prefix ={'led': led_prefix} + +i2c_prefix = '/sys/bus/i2c/devices/' +i2c_bus = {'fan': ['2-0066'] , + 'thermal': ['3-0048','3-0049', '3-004a', '3-004b'] , + 'psu': ['10-0050','11-0053'], + 'sfp': ['-0050']} +i2c_nodes = {'fan': ['present', 'front_speed_rpm', 'rear_speed_rpm'] , + 'thermal': ['hwmon/hwmon*/temp1_input'] , + 'psu': ['psu_present ', 'psu_power_good'] , + 'sfp': ['module_present', 'sfp_tx_disable_all']} + +sfp_map = [22,23,24,25,27,26,29,28, + 18,19,20,21,30,31,32,33, + 34,35,36,37,46,47,48,49, + 38,39,40,41,42,43,44,45] +mknod =[ +'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-1/new_device' , +'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-1/new_device' , +'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-1/new_device' , +'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo pca9548 0x75 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-1/new_device', + +'echo as7712_32x_fan 0x66 > /sys/bus/i2c/devices/i2c-2/new_device ', +'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-3/new_device', +'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-3/new_device', +'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-3/new_device', +'echo lm75 0x4b > /sys/bus/i2c/devices/i2c-3/new_device', +'echo as7712_32x_psu1 0x53 > /sys/bus/i2c/devices/i2c-11/new_device', +'echo ym2651 0x5b > /sys/bus/i2c/devices/i2c-11/new_device', +'echo as7712_32x_psu2 0x50 > /sys/bus/i2c/devices/i2c-10/new_device', +'echo ym2651 0x58 > /sys/bus/i2c/devices/i2c-10/new_device', +'echo cpld_as7712 0x60 > /sys/bus/i2c/devices/i2c-4/new_device', +'echo cpld_plain 0x62 > /sys/bus/i2c/devices/i2c-5/new_device', +'echo cpld_plain 0x64 > /sys/bus/i2c/devices/i2c-6/new_device'] + +mknod2 =[ +'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-0/new_device' , +'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-0/new_device' , +'echo pca9548 0X73 > /sys/bus/i2c/devices/i2c-0/new_device' , +'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo pca9548 0x75 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-0/new_device', + +'echo as7712_32x_fan 0x66 > /sys/bus/i2c/devices/i2c-2/new_device ', +'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-3/new_device', +'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-3/new_device', +'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-3/new_device', +'echo lm75 0x4b > /sys/bus/i2c/devices/i2c-3/new_device', +'echo as7712_32x_psu1 0x53 > /sys/bus/i2c/devices/i2c-11/new_device', +'echo ym2651 0x5b > /sys/bus/i2c/devices/i2c-11/new_device', +'echo as7712_32x_psu2 0x50 > /sys/bus/i2c/devices/i2c-10/new_device', +'echo ym2651 0x58 > /sys/bus/i2c/devices/i2c-10/new_device', +'echo cpld_as7712 0x60 > /sys/bus/i2c/devices/i2c-4/new_device', +'echo cpld_plain 0x62 > /sys/bus/i2c/devices/i2c-5/new_device', +'echo cpld_plain 0x64 > /sys/bus/i2c/devices/i2c-6/new_device'] + + +def i2c_order_check(): + # i2c bus 0 and 1 might be installed in different order. + # Here check if 0x76 is exist @ i2c-0 + tmp = "echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-0/new_device" + status, output = log_os_system(tmp, 0) + if not device_exist(): + order = 1 + else: + order = 0 + tmp = "echo 0x76 > /sys/bus/i2c/devices/i2c-0/delete_device" + status, output = log_os_system(tmp, 0) + return order + +def device_install(): + global FORCE + + order = i2c_order_check() + + # if 0x76 is not exist @i2c-0, use reversed bus order + if order: + for i in range(0,len(mknod2)): + #for pca954x need times to built new i2c buses + if mknod2[i].find('pca954') != -1: + time.sleep(1) + + status, output = log_os_system(mknod2[i], 1) + if status: + print output + if FORCE == 0: + return status + else: + for i in range(0,len(mknod)): + #for pca954x need times to built new i2c buses + if mknod[i].find('pca954') != -1: + time.sleep(1) + + status, output = log_os_system(mknod[i], 1) + if status: + print output + if FORCE == 0: + return status + for i in range(0,len(sfp_map)): + status, output =log_os_system("echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + return + +def device_uninstall(): + global FORCE + + status, output =log_os_system("ls /sys/bus/i2c/devices/1-0076", 0) + if status==0: + I2C_ORDER=1 + else: + I2C_ORDER=0 + + for i in range(0,len(sfp_map)): + target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device" + status, output =log_os_system("echo 0x50 > "+ target, 1) + if status: + print output + if FORCE == 0: + return status + + if I2C_ORDER==0: + nodelist = mknod + else: + nodelist = mknod2 + + for i in range(len(nodelist)): + target = nodelist[-(i+1)] + temp = target.split() + del temp[1] + temp[-1] = temp[-1].replace('new_device', 'delete_device') + status, output = log_os_system(" ".join(temp), 1) + if status: + print output + if FORCE == 0: + return status + + return + +def system_ready(): + if driver_check() == False: + return False + if not device_exist(): + return False + return True + +def do_install(): + print "Checking system...." + if driver_check() == False: + print "No driver, installing...." + status = driver_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" drivers detected...." + if not device_exist(): + print "No device, installing...." + status = device_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" devices detected...." + return + +def do_uninstall(): + print "Checking system...." + if not device_exist(): + print PROJECT_NAME.upper() +" has no device installed...." + else: + print "Removing device...." + status = device_uninstall() + if status: + if FORCE == 0: + return status + + if driver_check()== False : + print PROJECT_NAME.upper() +" has no driver installed...." + else: + print "Removing installed driver...." + status = driver_uninstall() + if status: + if FORCE == 0: + return status + + return + +def devices_info(): + global DEVICE_NO + global ALL_DEVICE + global i2c_bus, hwmon_types + for key in DEVICE_NO: + ALL_DEVICE[key]= {} + for i in range(0,DEVICE_NO[key]): + ALL_DEVICE[key][key+str(i+1)] = [] + + for key in i2c_bus: + buses = i2c_bus[key] + nodes = i2c_nodes[key] + for i in range(0,len(buses)): + for j in range(0,len(nodes)): + if 'fan' == key: + for k in range(0,DEVICE_NO[key]): + node = key+str(k+1) + path = i2c_prefix+ buses[i]+"/fan"+str(k+1)+"_"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + elif 'sfp' == key: + for k in range(0,DEVICE_NO[key]): + node = key+str(k+1) + path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + else: + node = key+str(i+1) + path = i2c_prefix+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + + for key in hwmon_types: + itypes = hwmon_types[key] + nodes = hwmon_nodes[key] + for i in range(0,len(itypes)): + for j in range(0,len(nodes)): + node = key+"_"+itypes[i] + path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][ key+str(i+1)].append(path) + + #show dict all in the order + if DEBUG == True: + for i in sorted(ALL_DEVICE.keys()): + print(i+": ") + for j in sorted(ALL_DEVICE[i].keys()): + print(" "+j) + for k in (ALL_DEVICE[i][j]): + print(" "+" "+k) + return + +def show_eeprom(index): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0] + node = node.replace(node.split("/")[-1], 'sfp_eeprom') + # check if got hexdump command in current environment + ret, log = log_os_system("which hexdump", 0) + ret, log2 = log_os_system("which busybox hexdump", 0) + if len(log): + hex_cmd = 'hexdump' + elif len(log2): + hex_cmd = ' busybox hexdump' + else: + log = 'Failed : no hexdump cmd!!' + logging.info(log) + print log + return 1 + + print node + ":" + ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1) + if ret==0: + print log + else: + print "**********device no found**********" + return + +def set_device(args): + global DEVICE_NO + global ALL_DEVICE + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + + if args[0]=='led': + if int(args[1])>4: + show_set_help() + return + #print ALL_DEVICE['led'] + for i in range(0,len(ALL_DEVICE['led'])): + for k in (ALL_DEVICE['led']['led'+str(i+1)]): + ret, log = log_os_system("echo "+args[1]+" >"+k, 1) + if ret: + return ret + elif args[0]=='fan': + if int(args[1])>100: + show_set_help() + return + #print ALL_DEVICE['fan'] + #fan1~6 is all fine, all fan share same setting + node = ALL_DEVICE['fan'] ['fan1'][0] + node = node.replace(node.split("/")[-1], 'fan_duty_cycle_percentage') + ret, log = log_os_system("cat "+ node, 1) + if ret==0: + print ("Previous fan duty: " + log.strip() +"%") + ret, log = log_os_system("echo "+args[1]+" >"+node, 1) + if ret==0: + print ("Current fan duty: " + args[1] +"%") + return ret + elif args[0]=='sfp': + if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0: + show_set_help() + return + if len(args)<2: + show_set_help() + return + + if int(args[2])>1: + show_set_help() + return + + #print ALL_DEVICE[args[0]] + for i in range(0,len(ALL_DEVICE[args[0]])): + for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]: + if j.find('tx_disable')!= -1: + ret, log = log_os_system("echo "+args[2]+" >"+ j, 1) + if ret: + return ret + + return + +#get digits inside a string. +#Ex: 31 for "sfp31" +def get_value(input): + digit = re.findall('\d+', input) + return int(digit[0]) + +def device_traversal(): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + for i in sorted(ALL_DEVICE.keys()): + print("============================================") + print(i.upper()+": ") + print("============================================") + + for j in sorted(ALL_DEVICE[i].keys(), key=get_value): + print " "+j+":", + for k in (ALL_DEVICE[i][j]): + ret, log = log_os_system("cat "+k, 0) + func = k.split("/")[-1].strip() + func = re.sub(j+'_','',func,1) + func = re.sub(i.lower()+'_','',func,1) + if ret==0: + print func+"="+log+" ", + else: + print func+"="+"X"+" ", + print + print("----------------------------------------------------------------") + + + print + return + +def device_exist(): + ret1, log = log_os_system("ls "+i2c_prefix+"*0076", 0) + ret2, log = log_os_system("ls "+i2c_prefix+"i2c-2", 0) + return not(ret1 or ret2) + +if __name__ == "__main__": + main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/classes/__init__.py b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/classes/__init__.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/classes/fanutil.py b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/classes/fanutil.py new file mode 100755 index 000000000000..9a69f6e1d537 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/classes/fanutil.py @@ -0,0 +1,254 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 Accton Technology Corporation +# +# 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 3 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, see . + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 11/13/2017: Polly Hsu, Create +# 1/10/2018: Jostar modify for as7716_32 +# ------------------------------------------------------------------ + +try: + import time + import logging + from collections import namedtuple +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + + +class FanUtil(object): + """Platform-specific FanUtil class""" + + FAN_NUM_ON_MAIN_BROAD = 6 + FAN_NUM_1_IDX = 1 + FAN_NUM_2_IDX = 2 + FAN_NUM_3_IDX = 3 + FAN_NUM_4_IDX = 4 + FAN_NUM_5_IDX = 5 + FAN_NUM_6_IDX = 6 + + FAN_NODE_NUM_OF_MAP = 2 + FAN_NODE_FAULT_IDX_OF_MAP = 1 + #FAN_NODE_SPEED_IDX_OF_MAP = 2 + FAN_NODE_DIR_IDX_OF_MAP = 2 + #FAN_NODE_DUTY_IDX_OF_MAP = 4 + #FANR_NODE_FAULT_IDX_OF_MAP = 5 + + #BASE_VAL_PATH = '/sys/devices/platform/as5712_54x_fan/{0}' + BASE_VAL_PATH = '/sys/bus/i2c/devices/9-0066/{0}' + FAN_DUTY_PATH = '/sys/bus/i2c/devices/9-0066/fan_duty_cycle_percentage' + + #logfile = '' + #loglevel = logging.INFO + + """ Dictionary where + key1 = fan id index (integer) starting from 1 + key2 = fan node index (interger) starting from 1 + value = path to fan device file (string) """ + _fan_to_device_path_mapping = {} + +#fan1_direction +#fan1_fault +#fan1_present + + #(FAN_NUM_2_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan2_duty_cycle_percentage', + _fan_to_device_node_mapping = { + (FAN_NUM_1_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan1_fault', + (FAN_NUM_1_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan1_direction', + + (FAN_NUM_2_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan2_fault', + (FAN_NUM_2_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan2_direction', + + (FAN_NUM_3_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan3_fault', + (FAN_NUM_3_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan3_direction', + + (FAN_NUM_4_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan4_fault', + (FAN_NUM_4_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan4_direction', + + (FAN_NUM_5_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan5_fault', + (FAN_NUM_5_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan5_direction', + + (FAN_NUM_6_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan6_fault', + (FAN_NUM_6_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan6_direction', + } + + def _get_fan_to_device_node(self, fan_num, node_num): + return self._fan_to_device_node_mapping[(fan_num, node_num)] + + def _get_fan_node_val(self, fan_num, node_num): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. fan_num:%d', fan_num) + return None + + if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP: + logging.debug('GET. Parameter error. node_num:%d', node_num) + return None + + device_path = self.get_fan_to_device_path(fan_num, node_num) + + try: + val_file = open(device_path, 'r') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None + + content = val_file.readline().rstrip() + + if content == '': + logging.debug('GET. content is NULL. device_path:%s', device_path) + return None + + try: + val_file.close() + except: + logging.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return int(content) + + def _set_fan_node_val(self, fan_num, node_num, val): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. fan_num:%d', fan_num) + return None + + if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP: + logging.debug('GET. Parameter error. node_num:%d', node_num) + return None + + content = str(val) + if content == '': + logging.debug('GET. content is NULL. device_path:%s', device_path) + return None + + device_path = self.get_fan_to_device_path(fan_num, node_num) + try: + val_file = open(device_path, 'w') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None + + val_file.write(content) + + try: + val_file.close() + except: + logging.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return True + + def __init__(self): + fan_path = self.BASE_VAL_PATH + + for fan_num in range(self.FAN_NUM_1_IDX, self.FAN_NUM_ON_MAIN_BROAD+1): + for node_num in range(self.FAN_NODE_FAULT_IDX_OF_MAP, self.FAN_NODE_NUM_OF_MAP+1): + self._fan_to_device_path_mapping[(fan_num, node_num)] = fan_path.format( + self._fan_to_device_node_mapping[(fan_num, node_num)]) + + def get_num_fans(self): + return self.FAN_NUM_ON_MAIN_BROAD + + def get_idx_fan_start(self): + return self.FAN_NUM_1_IDX + + def get_num_nodes(self): + return self.FAN_NODE_NUM_OF_MAP + + def get_idx_node_start(self): + return self.FAN_NODE_FAULT_IDX_OF_MAP + + def get_size_node_map(self): + return len(self._fan_to_device_node_mapping) + + def get_size_path_map(self): + return len(self._fan_to_device_path_mapping) + + def get_fan_to_device_path(self, fan_num, node_num): + return self._fan_to_device_path_mapping[(fan_num, node_num)] + + def get_fan_fault(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_FAULT_IDX_OF_MAP) + + #def get_fan_speed(self, fan_num): + # return self._get_fan_node_val(fan_num, self.FAN_NODE_SPEED_IDX_OF_MAP) + + def get_fan_dir(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_DIR_IDX_OF_MAP) + + def get_fan_duty_cycle(self): + #duty_path = self.FAN_DUTY_PATH + try: + val_file = open(self.FAN_DUTY_PATH) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = val_file.readline().rstrip() + val_file.close() + + return int(content) + #self._get_fan_node_val(fan_num, self.FAN_NODE_DUTY_IDX_OF_MAP) +#static u32 reg_val_to_duty_cycle(u8 reg_val) +#{ +# reg_val &= FAN_DUTY_CYCLE_REG_MASK; +# return ((u32)(reg_val+1) * 625 + 75)/ 100; +#} +# + def set_fan_duty_cycle(self, val): + + try: + fan_file = open(self.FAN_DUTY_PATH, 'r+') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + #val = ((val + 1 ) * 625 +75 ) / 100 + fan_file.write(str(val)) + fan_file.close() + return True + + #def get_fanr_fault(self, fan_num): + # return self._get_fan_node_val(fan_num, self.FANR_NODE_FAULT_IDX_OF_MAP) + + def get_fanr_speed(self, fan_num): + return self._get_fan_node_val(fan_num, self.FANR_NODE_SPEED_IDX_OF_MAP) + + def get_fan_status(self, fan_num): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. fan_num, %d', fan_num) + return None + + if self.get_fan_fault(fan_num) is not None and self.get_fan_fault(fan_num) > 0: + logging.debug('GET. FAN fault. fan_num, %d', fan_num) + return False + + #if self.get_fanr_fault(fan_num) is not None and self.get_fanr_fault(fan_num) > 0: + # logging.debug('GET. FANR fault. fan_num, %d', fan_num) + # return False + + return True + +#def main(): +# fan = FanUtil() +# +# print 'get_size_node_map : %d' % fan.get_size_node_map() +# print 'get_size_path_map : %d' % fan.get_size_path_map() +# for x in range(fan.get_idx_fan_start(), fan.get_num_fans()+1): +# for y in range(fan.get_idx_node_start(), fan.get_num_nodes()+1): +# print fan.get_fan_to_device_path(x, y) +# +#if __name__ == '__main__': +# main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/classes/thermalutil.py b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/classes/thermalutil.py new file mode 100755 index 000000000000..50d8c85d94ca --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/classes/thermalutil.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 Accton Technology Corporation +# +# 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 3 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, see . + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 11/13/2017: Polly Hsu, Create +# 1/10/2018:Jostar modify for as7716_32x +# ------------------------------------------------------------------ + +try: + import time + import logging + import glob + from collections import namedtuple +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + + +class ThermalUtil(object): + """Platform-specific ThermalUtil class""" + + THERMAL_NUM_ON_MAIN_BROAD = 3 + THERMAL_NUM_1_IDX = 1 # 1_ON_MAIN_BROAD + THERMAL_NUM_2_IDX = 2 # 2_ON_MAIN_BROAD + THERMAL_NUM_3_IDX = 3 # 3_ON_MAIN_BROAD + + BASE_VAL_PATH = '/sys/bus/i2c/devices/{0}-00{1}/hwmon/hwmon*/temp1_input' + + """ Dictionary where + key1 = thermal id index (integer) starting from 1 + value = path to fan device file (string) """ + _thermal_to_device_path_mapping = {} + + _thermal_to_device_node_mapping = { + THERMAL_NUM_1_IDX: ['10', '48'], + THERMAL_NUM_2_IDX: ['10', '49'], + THERMAL_NUM_3_IDX: ['10', '4a'], + } + + def __init__(self): + thermal_path = self.BASE_VAL_PATH + + for x in range(self.THERMAL_NUM_1_IDX, self.THERMAL_NUM_ON_MAIN_BROAD+1): + self._thermal_to_device_path_mapping[x] = thermal_path.format( + self._thermal_to_device_node_mapping[x][0], + self._thermal_to_device_node_mapping[x][1]) + + def _get_thermal_node_val(self, thermal_num): + if thermal_num < self.THERMAL_NUM_1_IDX or thermal_num > self.THERMAL_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. thermal_num, %d', thermal_num) + return None + + device_path = self.get_thermal_to_device_path(thermal_num) + for filename in glob.glob(device_path): + try: + val_file = open(filename, 'r') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None + + content = val_file.readline().rstrip() + + if content == '': + logging.debug('GET. content is NULL. device_path:%s', device_path) + return None + + try: + val_file.close() + except: + logging.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return int(content) + + + def get_num_thermals(self): + return self.THERMAL_NUM_ON_MAIN_BROAD + + def get_idx_thermal_start(self): + return self.THERMAL_NUM_1_IDX + + def get_size_node_map(self): + return len(self._thermal_to_device_node_mapping) + + def get_size_path_map(self): + return len(self._thermal_to_device_path_mapping) + + def get_thermal_to_device_path(self, thermal_num): + return self._thermal_to_device_path_mapping[thermal_num] + + def get_thermal_1_val(self): + return self._get_thermal_node_val(self.THERMAL_NUM_1_IDX) + + def get_thermal_2_val(self): + return self._get_thermal_node_val(self.THERMAL_NUM_2_IDX) + def get_thermal_temp(self): + return (self._get_thermal_node_val(self.THERMAL_NUM_1_IDX) + self._get_thermal_node_val(self.THERMAL_NUM_2_IDX) +self._get_thermal_node_val(self.THERMAL_NUM_3_IDX)) + +#def main(): +# thermal = ThermalUtil() +# +# print 'get_size_node_map : %d' % thermal.get_size_node_map() +# print 'get_size_path_map : %d' % thermal.get_size_path_map() +# for x in range(thermal.get_idx_thermal_start(), thermal.get_num_thermals()+1): +# print thermal.get_thermal_to_device_path(x) +# +#if __name__ == '__main__': +# main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/Makefile b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/Makefile new file mode 100755 index 000000000000..4c0942afb97e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/Makefile @@ -0,0 +1,21 @@ +ifneq ($(KERNELRELEASE),) +obj-m:= accton_as7716_32x_cpld1.o accton_as7716_32x_fan.o \ + accton_as7716_32x_leds.o accton_as7716_32x_psu.o cpr_4011_4mxx.o ym2651y.o \ + optoe.o accton_i2c_cpld.o + +else +ifeq (,$(KERNEL_SRC)) +#$(error KERNEL_SRC is not defined) +KVERSION := $(shell uname -r) +KERNEL_DIR = /usr/src/linux-headers-$(KVERSION)/ +KERNELDIR:=$(KERNEL_DIR) +#export KERNELDIR:=${PWD}/../../../../../src/sonic-linux-kernel/linux-3.16.43/ +else +KERNELDIR:=$(KERNEL_SRC) +endif +PWD:=$(shell pwd) +default: + $(MAKE) -C $(KERNELDIR) M=$(PWD) modules +clean: + rm -rf *.o *.mod.o *.mod.o *.ko .*cmd .tmp_versions Module.markers Module.symvers modules.order +endif diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_cpld1.c b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_cpld1.c new file mode 100755 index 000000000000..cbab013f5860 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_cpld1.c @@ -0,0 +1,781 @@ +/* + * A hwmon driver for the as7716_32x_cpld + * + * Copyright (C) 2013 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static LIST_HEAD(cpld_client_list); +static struct mutex list_lock; + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; + +#define I2C_RW_RETRY_COUNT 10 +#define I2C_RW_RETRY_INTERVAL 60 /* ms */ + +static ssize_t show_present(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_present_all(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t access(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t show_version(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t get_mode_reset(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t set_mode_reset(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); + +static int as7716_32x_cpld_read_internal(struct i2c_client *client, u8 reg); +static int as7716_32x_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value); + +struct as7716_32x_cpld_data { + struct device *hwmon_dev; + struct mutex update_lock; +}; + +/* Addresses scanned for as7716_32x_cpld + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +#define TRANSCEIVER_PRESENT_ATTR_ID(index) MODULE_PRESENT_##index +#define TRANSCEIVER_RESET_ATTR_ID(index) MODULE_RESET_##index + +enum as7716_32x_cpld_sysfs_attributes { + CPLD_VERSION, + ACCESS, + MODULE_PRESENT_ALL, + /* transceiver attributes */ + TRANSCEIVER_PRESENT_ATTR_ID(1), + TRANSCEIVER_PRESENT_ATTR_ID(2), + TRANSCEIVER_PRESENT_ATTR_ID(3), + TRANSCEIVER_PRESENT_ATTR_ID(4), + TRANSCEIVER_PRESENT_ATTR_ID(5), + TRANSCEIVER_PRESENT_ATTR_ID(6), + TRANSCEIVER_PRESENT_ATTR_ID(7), + TRANSCEIVER_PRESENT_ATTR_ID(8), + TRANSCEIVER_PRESENT_ATTR_ID(9), + TRANSCEIVER_PRESENT_ATTR_ID(10), + TRANSCEIVER_PRESENT_ATTR_ID(11), + TRANSCEIVER_PRESENT_ATTR_ID(12), + TRANSCEIVER_PRESENT_ATTR_ID(13), + TRANSCEIVER_PRESENT_ATTR_ID(14), + TRANSCEIVER_PRESENT_ATTR_ID(15), + TRANSCEIVER_PRESENT_ATTR_ID(16), + TRANSCEIVER_PRESENT_ATTR_ID(17), + TRANSCEIVER_PRESENT_ATTR_ID(18), + TRANSCEIVER_PRESENT_ATTR_ID(19), + TRANSCEIVER_PRESENT_ATTR_ID(20), + TRANSCEIVER_PRESENT_ATTR_ID(21), + TRANSCEIVER_PRESENT_ATTR_ID(22), + TRANSCEIVER_PRESENT_ATTR_ID(23), + TRANSCEIVER_PRESENT_ATTR_ID(24), + TRANSCEIVER_PRESENT_ATTR_ID(25), + TRANSCEIVER_PRESENT_ATTR_ID(26), + TRANSCEIVER_PRESENT_ATTR_ID(27), + TRANSCEIVER_PRESENT_ATTR_ID(28), + TRANSCEIVER_PRESENT_ATTR_ID(29), + TRANSCEIVER_PRESENT_ATTR_ID(30), + TRANSCEIVER_PRESENT_ATTR_ID(31), + TRANSCEIVER_PRESENT_ATTR_ID(32), + TRANSCEIVER_RESET_ATTR_ID(1), + TRANSCEIVER_RESET_ATTR_ID(2), + TRANSCEIVER_RESET_ATTR_ID(3), + TRANSCEIVER_RESET_ATTR_ID(4), + TRANSCEIVER_RESET_ATTR_ID(5), + TRANSCEIVER_RESET_ATTR_ID(6), + TRANSCEIVER_RESET_ATTR_ID(7), + TRANSCEIVER_RESET_ATTR_ID(8), + TRANSCEIVER_RESET_ATTR_ID(9), + TRANSCEIVER_RESET_ATTR_ID(10), + TRANSCEIVER_RESET_ATTR_ID(11), + TRANSCEIVER_RESET_ATTR_ID(12), + TRANSCEIVER_RESET_ATTR_ID(13), + TRANSCEIVER_RESET_ATTR_ID(14), + TRANSCEIVER_RESET_ATTR_ID(15), + TRANSCEIVER_RESET_ATTR_ID(16), + TRANSCEIVER_RESET_ATTR_ID(17), + TRANSCEIVER_RESET_ATTR_ID(18), + TRANSCEIVER_RESET_ATTR_ID(19), + TRANSCEIVER_RESET_ATTR_ID(20), + TRANSCEIVER_RESET_ATTR_ID(21), + TRANSCEIVER_RESET_ATTR_ID(22), + TRANSCEIVER_RESET_ATTR_ID(23), + TRANSCEIVER_RESET_ATTR_ID(24), + TRANSCEIVER_RESET_ATTR_ID(25), + TRANSCEIVER_RESET_ATTR_ID(26), + TRANSCEIVER_RESET_ATTR_ID(27), + TRANSCEIVER_RESET_ATTR_ID(28), + TRANSCEIVER_RESET_ATTR_ID(29), + TRANSCEIVER_RESET_ATTR_ID(30), + TRANSCEIVER_RESET_ATTR_ID(31), + TRANSCEIVER_RESET_ATTR_ID(32), +}; + +/* sysfs attributes for hwmon + */ + +/* transceiver attributes */ +/*present*/ +#define DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(index) \ + static SENSOR_DEVICE_ATTR(module_present_##index, S_IRUGO, show_present, NULL, MODULE_PRESENT_##index) +#define DECLARE_TRANSCEIVER_ATTR(index) &sensor_dev_attr_module_present_##index.dev_attr.attr + +/*reset*/ +#define DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(index) \ + static SENSOR_DEVICE_ATTR(module_reset_##index, S_IWUSR | S_IRUGO, get_mode_reset, set_mode_reset, MODULE_RESET_##index) +#define DECLARE_TRANSCEIVER_RESET_ATTR(index) &sensor_dev_attr_module_reset_##index.dev_attr.attr + +static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, CPLD_VERSION); +static SENSOR_DEVICE_ATTR(access, S_IWUSR, NULL, access, ACCESS); +/* transceiver attributes */ +static SENSOR_DEVICE_ATTR(module_present_all, S_IRUGO, show_present_all, NULL, MODULE_PRESENT_ALL); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(1); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(2); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(3); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(4); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(5); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(6); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(7); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(8); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(9); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(10); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(11); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(12); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(13); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(14); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(15); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(16); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(17); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(18); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(19); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(20); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(21); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(22); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(23); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(24); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(25); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(26); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(27); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(28); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(29); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(30); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(31); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(32); + +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(1); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(2); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(3); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(4); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(5); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(6); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(7); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(8); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(9); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(10); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(11); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(12); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(13); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(14); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(15); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(16); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(17); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(18); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(19); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(20); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(21); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(22); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(23); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(24); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(25); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(26); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(27); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(28); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(29); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(30); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(31); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(32); + + +static struct attribute *as7716_32x_cpld_attributes[] = { + &sensor_dev_attr_version.dev_attr.attr, + &sensor_dev_attr_access.dev_attr.attr, + /* transceiver attributes */ + &sensor_dev_attr_module_present_all.dev_attr.attr, + DECLARE_TRANSCEIVER_ATTR(1), + DECLARE_TRANSCEIVER_ATTR(2), + DECLARE_TRANSCEIVER_ATTR(3), + DECLARE_TRANSCEIVER_ATTR(4), + DECLARE_TRANSCEIVER_ATTR(5), + DECLARE_TRANSCEIVER_ATTR(6), + DECLARE_TRANSCEIVER_ATTR(7), + DECLARE_TRANSCEIVER_ATTR(8), + DECLARE_TRANSCEIVER_ATTR(9), + DECLARE_TRANSCEIVER_ATTR(10), + DECLARE_TRANSCEIVER_ATTR(11), + DECLARE_TRANSCEIVER_ATTR(12), + DECLARE_TRANSCEIVER_ATTR(13), + DECLARE_TRANSCEIVER_ATTR(14), + DECLARE_TRANSCEIVER_ATTR(15), + DECLARE_TRANSCEIVER_ATTR(16), + DECLARE_TRANSCEIVER_ATTR(17), + DECLARE_TRANSCEIVER_ATTR(18), + DECLARE_TRANSCEIVER_ATTR(19), + DECLARE_TRANSCEIVER_ATTR(20), + DECLARE_TRANSCEIVER_ATTR(21), + DECLARE_TRANSCEIVER_ATTR(22), + DECLARE_TRANSCEIVER_ATTR(23), + DECLARE_TRANSCEIVER_ATTR(24), + DECLARE_TRANSCEIVER_ATTR(25), + DECLARE_TRANSCEIVER_ATTR(26), + DECLARE_TRANSCEIVER_ATTR(27), + DECLARE_TRANSCEIVER_ATTR(28), + DECLARE_TRANSCEIVER_ATTR(29), + DECLARE_TRANSCEIVER_ATTR(30), + DECLARE_TRANSCEIVER_ATTR(31), + DECLARE_TRANSCEIVER_ATTR(32), + DECLARE_TRANSCEIVER_RESET_ATTR(1), + DECLARE_TRANSCEIVER_RESET_ATTR(2), + DECLARE_TRANSCEIVER_RESET_ATTR(3), + DECLARE_TRANSCEIVER_RESET_ATTR(4), + DECLARE_TRANSCEIVER_RESET_ATTR(5), + DECLARE_TRANSCEIVER_RESET_ATTR(6), + DECLARE_TRANSCEIVER_RESET_ATTR(7), + DECLARE_TRANSCEIVER_RESET_ATTR(8), + DECLARE_TRANSCEIVER_RESET_ATTR(9), + DECLARE_TRANSCEIVER_RESET_ATTR(10), + DECLARE_TRANSCEIVER_RESET_ATTR(11), + DECLARE_TRANSCEIVER_RESET_ATTR(12), + DECLARE_TRANSCEIVER_RESET_ATTR(13), + DECLARE_TRANSCEIVER_RESET_ATTR(14), + DECLARE_TRANSCEIVER_RESET_ATTR(15), + DECLARE_TRANSCEIVER_RESET_ATTR(16), + DECLARE_TRANSCEIVER_RESET_ATTR(17), + DECLARE_TRANSCEIVER_RESET_ATTR(18), + DECLARE_TRANSCEIVER_RESET_ATTR(19), + DECLARE_TRANSCEIVER_RESET_ATTR(20), + DECLARE_TRANSCEIVER_RESET_ATTR(21), + DECLARE_TRANSCEIVER_RESET_ATTR(22), + DECLARE_TRANSCEIVER_RESET_ATTR(23), + DECLARE_TRANSCEIVER_RESET_ATTR(24), + DECLARE_TRANSCEIVER_RESET_ATTR(25), + DECLARE_TRANSCEIVER_RESET_ATTR(26), + DECLARE_TRANSCEIVER_RESET_ATTR(27), + DECLARE_TRANSCEIVER_RESET_ATTR(28), + DECLARE_TRANSCEIVER_RESET_ATTR(29), + DECLARE_TRANSCEIVER_RESET_ATTR(30), + DECLARE_TRANSCEIVER_RESET_ATTR(31), + DECLARE_TRANSCEIVER_RESET_ATTR(32), + NULL +}; + +static const struct attribute_group as7716_32x_cpld_group = { + .attrs = as7716_32x_cpld_attributes, +}; + +static ssize_t show_present_all(struct device *dev, struct device_attribute *da, + char *buf) +{ + int i, status; + u8 values[4] = {0}; + u8 regs[] = {0x30, 0x31, 0x32, 0x33}; + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32x_cpld_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + for (i = 0; i < ARRAY_SIZE(regs); i++) { + status = as7716_32x_cpld_read_internal(client, regs[i]); + + if (status < 0) { + goto exit; + } + + values[i] = ~(u8)status; + } + + mutex_unlock(&data->update_lock); + + /* Return values 1 -> 32 in order */ + return sprintf(buf, "%.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], + values[3]); + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t show_present(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32x_cpld_data *data = i2c_get_clientdata(client); + int status = 0; + u8 reg = 0, mask = 0; + + switch (attr->index) { + case MODULE_PRESENT_1 ... MODULE_PRESENT_8: + reg = 0x30; + mask = 0x1 << (attr->index - MODULE_PRESENT_1); + break; + case MODULE_PRESENT_9 ... MODULE_PRESENT_16: + reg = 0x31; + mask = 0x1 << (attr->index - MODULE_PRESENT_9); + break; + case MODULE_PRESENT_17 ... MODULE_PRESENT_24: + reg = 0x32; + mask = 0x1 << (attr->index - MODULE_PRESENT_17); + break; + case MODULE_PRESENT_25 ... MODULE_PRESENT_32: + reg = 0x33; + mask = 0x1 << (attr->index - MODULE_PRESENT_25); + break; + default: + return 0; + } + + + mutex_lock(&data->update_lock); + status = as7716_32x_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", !(status & mask)); + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t show_version(struct device *dev, struct device_attribute *da, + char *buf) +{ + u8 reg = 0, mask = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32x_cpld_data *data = i2c_get_clientdata(client); + int status = 0; + + switch (attr->index) { + case CPLD_VERSION: + reg = 0x1; + mask = 0xFF; + break; + default: + break; + } + + mutex_lock(&data->update_lock); + status = as7716_32x_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + return sprintf(buf, "%d\n", (status & mask)); + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t access(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int status; + u32 addr, val; + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32x_cpld_data *data = i2c_get_clientdata(client); + + if (sscanf(buf, "0x%x 0x%x", &addr, &val) != 2) { + return -EINVAL; + } + + if (addr > 0xFF || val > 0xFF) { + return -EINVAL; + } + + mutex_lock(&data->update_lock); + status = as7716_32x_cpld_write_internal(client, addr, val); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static int as7716_32x_cpld_read_internal(struct i2c_client *client, u8 reg) +{ + int status = 0, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_read_byte_data(client, reg); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + return status; +} + +static int as7716_32x_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value) +{ + int status = 0, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_write_byte_data(client, reg, value); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + return status; +} + +static void as7716_32x_cpld_add_client(struct i2c_client *client) +{ + struct cpld_client_node *node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", client->addr); + return; + } + + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &cpld_client_list); + mutex_unlock(&list_lock); +} + +static void as7716_32x_cpld_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client == client) { + found = 1; + break; + } + } + + if (found) { + list_del(list_node); + kfree(cpld_node); + } + + mutex_unlock(&list_lock); +} + +static int as7716_32x_cpld_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int status; + struct as7716_32x_cpld_data *data = NULL; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_dbg(&client->dev, "i2c_check_functionality failed (0x%x)\n", client->addr); + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct as7716_32x_cpld_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as7716_32x_cpld_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + as7716_32x_cpld_add_client(client); + + dev_info(&client->dev, "%s: cpld '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as7716_32x_cpld_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as7716_32x_cpld_remove(struct i2c_client *client) +{ + struct as7716_32x_cpld_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as7716_32x_cpld_group); + kfree(data); + as7716_32x_cpld_remove_client(client); + + return 0; +} + +int as7716_32x_cpld_read(unsigned short cpld_addr, u8 reg) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EPERM; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = i2c_smbus_read_byte_data(cpld_node->client, reg); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(as7716_32x_cpld_read); + +int as7716_32x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EIO; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = i2c_smbus_write_byte_data(cpld_node->client, reg, value); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(as7716_32x_cpld_write); + +static ssize_t get_mode_reset(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32x_cpld_data *data = i2c_get_clientdata(client); + int status = 0; + u8 reg = 0, mask = 0; + + switch (attr->index) { + case MODULE_RESET_1 ... MODULE_RESET_8: + reg = 0x04; + mask = 0x1 << (attr->index - MODULE_RESET_1); + break; + case MODULE_RESET_9 ... MODULE_RESET_16: + reg = 0x05; + mask = 0x1 << (attr->index - MODULE_RESET_9); + break; + case MODULE_RESET_17 ... MODULE_RESET_24: + reg = 0x06; + mask = 0x1 << (attr->index - MODULE_RESET_17); + break; + case MODULE_RESET_25 ... MODULE_RESET_32: + reg = 0x07; + mask = 0x1 << (attr->index - MODULE_RESET_25); + break; + default: + return 0; + } + + + mutex_lock(&data->update_lock); + status = as7716_32x_cpld_read_internal(client, reg); + + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\r\n", !(status & mask)); + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t set_mode_reset(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32x_cpld_data *data = i2c_get_clientdata(client); + long reset; + int status=0, val, error; + u8 reg = 0, mask = 0; + + + error = kstrtol(buf, 10, &reset); + if (error) { + return error; + } + + switch (attr->index) { + case MODULE_RESET_1 ... MODULE_RESET_8: + reg = 0x04; + mask = 0x1 << (attr->index - MODULE_RESET_1); + break; + case MODULE_RESET_9 ... MODULE_RESET_16: + reg = 0x05; + mask = 0x1 << (attr->index - MODULE_RESET_9); + break; + case MODULE_RESET_17 ... MODULE_RESET_24: + reg = 0x06; + mask = 0x1 << (attr->index - MODULE_RESET_17); + break; + case MODULE_RESET_25 ... MODULE_RESET_32: + reg = 0x07; + mask = 0x1 << (attr->index - MODULE_RESET_25); + break; + default: + return 0; + } + mutex_lock(&data->update_lock); + + status = as7716_32x_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + + /* Update lp_mode status */ + if (reset) + { + val = status&(~mask); + } + else + { + val =status | (mask); + } + + status = as7716_32x_cpld_write_internal(client, reg, val); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + + + +static const struct i2c_device_id as7716_32x_cpld_id[] = { + { "as7716_32x_cpld1", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, as7716_32x_cpld_id); + +static struct i2c_driver as7716_32x_cpld_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "as7716_32x_cpld1", + }, + .probe = as7716_32x_cpld_probe, + .remove = as7716_32x_cpld_remove, + .id_table = as7716_32x_cpld_id, + .address_list = normal_i2c, +}; + +static int __init as7716_32x_cpld_init(void) +{ + mutex_init(&list_lock); + return i2c_add_driver(&as7716_32x_cpld_driver); +} + +static void __exit as7716_32x_cpld_exit(void) +{ + i2c_del_driver(&as7716_32x_cpld_driver); +} + +module_init(as7716_32x_cpld_init); +module_exit(as7716_32x_cpld_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("as7716_32x_cpld driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_fan.c b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_fan.c new file mode 100755 index 000000000000..83b7bceeb99e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_fan.c @@ -0,0 +1,794 @@ +/* + * A hwmon driver for the Accton as7716 32x fan + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "as7716_32x_fan" + +#define NUM_THERMAL_SENSORS (3) /* Get sum of this number of sensors.*/ +#define THERMAL_SENSORS_DRIVER "lm75" + +#define IN +#define OUT + +static struct as7716_32x_fan_data *as7716_32x_fan_update_device(struct device *dev); +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t get_enable(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_enable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t get_sys_temp(struct device *dev, struct device_attribute *da, char *buf); +extern int as7716_32x_cpld_read(unsigned short cpld_addr, u8 reg); +extern int as7716_32x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +/* fan related data, the index should match sysfs_fan_attributes + */ +static const u8 fan_reg[] = { + 0x0F, /* fan 1-6 present status */ + 0x10, /* fan 1-6 direction(0:B2F 1:F2B) */ + 0x11, /* fan PWM(for all fan) */ + 0x12, /* front fan 1 speed(rpm) */ + 0x13, /* front fan 2 speed(rpm) */ + 0x14, /* front fan 3 speed(rpm) */ + 0x15, /* front fan 4 speed(rpm) */ + 0x16, /* front fan 5 speed(rpm) */ + 0x17, /* front fan 6 speed(rpm) */ + 0x22, /* rear fan 1 speed(rpm) */ + 0x23, /* rear fan 2 speed(rpm) */ + 0x24, /* rear fan 3 speed(rpm) */ + 0x25, /* rear fan 4 speed(rpm) */ + 0x26, /* rear fan 5 speed(rpm) */ + 0x27, /* rear fan 6 speed(rpm) */ +}; + +/* Each client has this additional data */ +struct as7716_32x_fan_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[ARRAY_SIZE(fan_reg)]; /* Register value */ + u8 enable; + int system_temp; /*In unit of mini-Celsius*/ + int sensors_found; +}; + +enum fan_id { + FAN1_ID, + FAN2_ID, + FAN3_ID, + FAN4_ID, + FAN5_ID, + FAN6_ID +}; + +enum sysfs_fan_attributes { + FAN_PRESENT_REG, + FAN_DIRECTION_REG, + FAN_DUTY_CYCLE_PERCENTAGE, /* Only one CPLD register to control duty cycle for all fans */ + FAN1_FRONT_SPEED_RPM, + FAN2_FRONT_SPEED_RPM, + FAN3_FRONT_SPEED_RPM, + FAN4_FRONT_SPEED_RPM, + FAN5_FRONT_SPEED_RPM, + FAN6_FRONT_SPEED_RPM, + FAN1_REAR_SPEED_RPM, + FAN2_REAR_SPEED_RPM, + FAN3_REAR_SPEED_RPM, + FAN4_REAR_SPEED_RPM, + FAN5_REAR_SPEED_RPM, + FAN6_REAR_SPEED_RPM, + FAN1_DIRECTION, + FAN2_DIRECTION, + FAN3_DIRECTION, + FAN4_DIRECTION, + FAN5_DIRECTION, + FAN6_DIRECTION, + FAN1_PRESENT, + FAN2_PRESENT, + FAN3_PRESENT, + FAN4_PRESENT, + FAN5_PRESENT, + FAN6_PRESENT, + FAN1_FAULT, + FAN2_FAULT, + FAN3_FAULT, + FAN4_FAULT, + FAN5_FAULT, + FAN6_FAULT +}; + +/* Define attributes + */ +#define DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(index, index2) \ + static SENSOR_DEVICE_ATTR(fan##index##_fault, S_IRUGO, fan_show_value, NULL, FAN##index##_FAULT);\ + static SENSOR_DEVICE_ATTR(fan##index2##_fault, S_IRUGO, fan_show_value, NULL, FAN##index##_FAULT) +#define DECLARE_FAN_FAULT_ATTR(index, index2) &sensor_dev_attr_fan##index##_fault.dev_attr.attr, \ + &sensor_dev_attr_fan##index2##_fault.dev_attr.attr + +#define DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_direction, S_IRUGO, fan_show_value, NULL, FAN##index##_DIRECTION) +#define DECLARE_FAN_DIRECTION_ATTR(index) &sensor_dev_attr_fan##index##_direction.dev_attr.attr + +#define DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan_duty_cycle_percentage, S_IWUSR | S_IRUGO, fan_show_value, set_duty_cycle, FAN_DUTY_CYCLE_PERCENTAGE);\ + static SENSOR_DEVICE_ATTR(pwm##index, S_IWUSR | S_IRUGO, fan_show_value, set_duty_cycle, FAN_DUTY_CYCLE_PERCENTAGE);\ + static SENSOR_DEVICE_ATTR(pwm##index##_enable, S_IWUSR | S_IRUGO, get_enable, set_enable, FAN_DUTY_CYCLE_PERCENTAGE) + +#define DECLARE_FAN_DUTY_CYCLE_ATTR(index) &sensor_dev_attr_fan_duty_cycle_percentage.dev_attr.attr, \ + &sensor_dev_attr_pwm##index.dev_attr.attr, \ + &sensor_dev_attr_pwm##index##_enable.dev_attr.attr + +#define DECLARE_FAN_SYSTEM_TEMP_SENSOR_DEV_ATTR() \ + static SENSOR_DEVICE_ATTR(sys_temp, S_IRUGO, get_sys_temp, NULL, FAN_DUTY_CYCLE_PERCENTAGE) + +#define DECLARE_FAN_SYSTEM_TEMP_ATTR() &sensor_dev_attr_sys_temp.dev_attr.attr + + +#define DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_present, S_IRUGO, fan_show_value, NULL, FAN##index##_PRESENT) +#define DECLARE_FAN_PRESENT_ATTR(index) &sensor_dev_attr_fan##index##_present.dev_attr.attr + +#define DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(index, index2) \ + static SENSOR_DEVICE_ATTR(fan##index##_front_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_FRONT_SPEED_RPM);\ + static SENSOR_DEVICE_ATTR(fan##index##_rear_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_REAR_SPEED_RPM);\ + static SENSOR_DEVICE_ATTR(fan##index##_input, S_IRUGO, fan_show_value, NULL, FAN##index##_FRONT_SPEED_RPM);\ + static SENSOR_DEVICE_ATTR(fan##index2##_input, S_IRUGO, fan_show_value, NULL, FAN##index##_REAR_SPEED_RPM) +#define DECLARE_FAN_SPEED_RPM_ATTR(index, index2) &sensor_dev_attr_fan##index##_front_speed_rpm.dev_attr.attr, \ + &sensor_dev_attr_fan##index##_rear_speed_rpm.dev_attr.attr, \ + &sensor_dev_attr_fan##index##_input.dev_attr.attr, \ + &sensor_dev_attr_fan##index2##_input.dev_attr.attr + +/* 6 fan fault attributes in this platform */ +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(1,11); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(2,12); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(3,13); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(4,14); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(5,15); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(6,16); +/* 6 fan speed(rpm) attributes in this platform */ +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(1,11); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(2,12); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(3,13); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(4,14); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(5,15); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(6,16); +/* 6 fan present attributes in this platform */ +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(1); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(2); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(3); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(4); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(5); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(6); + +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(1); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(2); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(3); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(4); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(5); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(6); + +/* 1 fan duty cycle attribute in this platform */ +DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(1); +/* System temperature for fancontrol */ +DECLARE_FAN_SYSTEM_TEMP_SENSOR_DEV_ATTR(); + +static struct attribute *as7716_32x_fan_attributes[] = { + /* fan related attributes */ + DECLARE_FAN_FAULT_ATTR(1,11), + DECLARE_FAN_FAULT_ATTR(2,12), + DECLARE_FAN_FAULT_ATTR(3,13), + DECLARE_FAN_FAULT_ATTR(4,14), + DECLARE_FAN_FAULT_ATTR(5,15), + DECLARE_FAN_FAULT_ATTR(6,16), + DECLARE_FAN_SPEED_RPM_ATTR(1,11), + DECLARE_FAN_SPEED_RPM_ATTR(2,12), + DECLARE_FAN_SPEED_RPM_ATTR(3,13), + DECLARE_FAN_SPEED_RPM_ATTR(4,14), + DECLARE_FAN_SPEED_RPM_ATTR(5,15), + DECLARE_FAN_SPEED_RPM_ATTR(6,16), + DECLARE_FAN_PRESENT_ATTR(1), + DECLARE_FAN_PRESENT_ATTR(2), + DECLARE_FAN_PRESENT_ATTR(3), + DECLARE_FAN_PRESENT_ATTR(4), + DECLARE_FAN_PRESENT_ATTR(5), + DECLARE_FAN_PRESENT_ATTR(6), + DECLARE_FAN_DIRECTION_ATTR(1), + DECLARE_FAN_DIRECTION_ATTR(2), + DECLARE_FAN_DIRECTION_ATTR(3), + DECLARE_FAN_DIRECTION_ATTR(4), + DECLARE_FAN_DIRECTION_ATTR(5), + DECLARE_FAN_DIRECTION_ATTR(6), + DECLARE_FAN_DUTY_CYCLE_ATTR(1), + DECLARE_FAN_SYSTEM_TEMP_ATTR(), + NULL +}; + +#define FAN_DUTY_CYCLE_REG_MASK 0xF +#define FAN_MAX_DUTY_CYCLE 100 +#define FAN_REG_VAL_TO_SPEED_RPM_STEP 100 + +static int as7716_32x_fan_read_value(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int as7716_32x_fan_write_value(struct i2c_client *client, u8 reg, u8 value) +{ + return i2c_smbus_write_byte_data(client, reg, value); +} + +/* fan utility functions + */ +static u32 reg_val_to_duty_cycle(u8 reg_val) +{ + reg_val &= FAN_DUTY_CYCLE_REG_MASK; + return ((u32)(reg_val+1) * 625 + 75)/ 100; +} + +static u8 duty_cycle_to_reg_val(u8 duty_cycle) +{ + return ((u32)duty_cycle * 100 / 625) - 1; +} + +static u32 reg_val_to_speed_rpm(u8 reg_val) +{ + return (u32)reg_val * FAN_REG_VAL_TO_SPEED_RPM_STEP; +} + +static u8 reg_val_to_direction(u8 reg_val, enum fan_id id) +{ + u8 mask = (1 << id); + + reg_val &= mask; + + return reg_val ? 1 : 0; +} +static u8 reg_val_to_is_present(u8 reg_val, enum fan_id id) +{ + u8 mask = (1 << id); + + reg_val &= mask; + + return reg_val ? 0 : 1; +} + +static u8 is_fan_fault(struct as7716_32x_fan_data *data, enum fan_id id) +{ + u8 ret = 1; + int front_fan_index = FAN1_FRONT_SPEED_RPM + id; + int rear_fan_index = FAN1_REAR_SPEED_RPM + id; + + /* Check if the speed of front or rear fan is ZERO, + */ + if (reg_val_to_speed_rpm(data->reg_val[front_fan_index]) && + reg_val_to_speed_rpm(data->reg_val[rear_fan_index])) { + ret = 0; + } + + return ret; +} + +static ssize_t set_enable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct as7716_32x_fan_data *data = as7716_32x_fan_update_device(dev); + int error, value; + + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (value < 0 || value > 1) + return -EINVAL; + + data->enable = value; + if (value == 0) + { + return set_duty_cycle(dev, da, buf, FAN_MAX_DUTY_CYCLE); + } + return count; +} + + +static ssize_t get_enable(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct as7716_32x_fan_data *data = as7716_32x_fan_update_device(dev); + + return sprintf(buf, "%u\n", data->enable); +} +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int error, value; + struct i2c_client *client = to_i2c_client(dev); + + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (value < 0 || value > FAN_MAX_DUTY_CYCLE) + return -EINVAL; + + as7716_32x_fan_write_value(client, 0x33, 0); /* Disable fan speed watch dog */ + as7716_32x_fan_write_value(client, fan_reg[FAN_DUTY_CYCLE_PERCENTAGE], duty_cycle_to_reg_val(value)); + return count; +} + +/* Due to this struct is declared at lm75.c, it cannot be include + * under Sonic environment. I duplicate it from lm75.c. + */ +struct lm75_data { + struct i2c_client *client; + struct device *hwmon_dev; + struct thermal_zone_device *tz; + struct mutex update_lock; + u8 orig_conf; + u8 resolution; /* In bits, between 9 and 12 */ + u8 resolution_limits; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + unsigned long sample_time; /* In jiffies */ + s16 temp[3]; /* Register values, + 0 = input + 1 = max + 2 = hyst */ +}; + +/*Copied from lm75.c*/ +static inline long lm75_reg_to_mc(s16 temp, u8 resolution) +{ + return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8); +} + +/*Get hwmon_dev from i2c_client, set hwmon_dev = NULL is failed.*/ +static struct device * get_hwmon_dev( + struct i2c_client *client) +{ + struct lm75_data *data = NULL; + + data = i2c_get_clientdata(client); + if(data) + { + if( data->valid == 1 && data->hwmon_dev) + { + return data->hwmon_dev; + } + + } + return NULL; +} + +/* To find hwmon index by opening hwmon under that i2c address. + */ +static int find_hwmon_index_by_FileOpen( + int bus_nr, + unsigned short addr, + OUT int *index) +{ +#define MAX_HWMON_DEVICE (10) /* Find hwmon device in 0~10*/ + struct file *sfd; + char client_name[96]; + int i=0; + + do { + snprintf(client_name, sizeof(client_name), + "/sys/bus/i2c/devices/%d-%04x/hwmon/hwmon%d/temp1_input", + bus_nr, addr, i); + + sfd = filp_open(client_name, O_RDONLY, 0); + i++; + } while( IS_ERR(sfd) && i < MAX_HWMON_DEVICE); + + if (IS_ERR(sfd)) { + pr_err("Failed to open file(%s)#%d\r\n", client_name, __LINE__); + return -ENOENT; + } + filp_close(sfd, 0); + *index = i - 1; + return 0; + +#undef MAX_HWMON_DEVICE +} + +static int get_temp_file_path( + int bus_nr, unsigned short addr, + struct device *hwmon_dev + ,char *path, int max_len) +{ + + if(hwmon_dev && strlen(dev_name(hwmon_dev))) + { + snprintf(path, max_len, + "/sys/bus/i2c/devices/%d-%04x/hwmon/%s/temp1_input", + bus_nr, addr, dev_name(hwmon_dev)); + } + else + { + int i=0; + if(find_hwmon_index_by_FileOpen( bus_nr, addr, &i)) + { + return -EIO; + } + snprintf(path, max_len, + "/sys/bus/i2c/devices/%d-%04x/hwmon/hwmon%d/temp1_input", + bus_nr, addr, i); + } + return 0; +} + +/*File read the dev file at user space.*/ +static int read_devfile_temp1_input( + struct device *dev, + int bus_nr, + unsigned short addr, + struct device *hwmon_dev, + int *miniCelsius) +{ + struct file *sfd; + char buffer[96]; + char devfile[96]; + int rc, status; + int rdlen, value; + mm_segment_t old_fs; + + rc = 0; + get_temp_file_path(bus_nr, addr, hwmon_dev, devfile, sizeof(devfile)); + sfd = filp_open(devfile, O_RDONLY, 0); + if (IS_ERR(sfd)) { + pr_err("Failed to open file(%s)#%d\r\n", devfile, __LINE__); + return -ENOENT; + } + dev_dbg(dev, "Found device:%s\n",devfile); + + if(!(sfd->f_op) || !(sfd->f_op->read) ) { + pr_err("file %s cann't readable ?\n",devfile); + return -ENOENT; + } + + old_fs = get_fs(); + set_fs(KERNEL_DS); + rdlen = sfd->f_op->read(sfd, buffer, sizeof(buffer), &sfd->f_pos); + if (rdlen == 0) { + pr_err( "File(%s) empty!\n", devfile); + rc = -EIO; + goto exit; + } + status = sscanf(buffer, "%d", &value); + if (status != 1) { + rc = -EIO; + goto exit; + } + *miniCelsius = value; + dev_dbg(dev,"found sensors: %d @i2c %d-%04x\n", value, bus_nr, addr); + +exit: + set_fs(old_fs); + filp_close(sfd, 0); + return rc; +} + +static u8 is_lm75_data_due(struct i2c_client *client) +{ + struct lm75_data *data = NULL; + + data = i2c_get_clientdata(client); + if (time_after(jiffies, data->last_updated + data->sample_time)) + { + return 1; + } + return 0; +} +static int get_lm75_temp(struct i2c_client *client, int *miniCelsius) +{ + struct lm75_data *data = NULL; + + data = i2c_get_clientdata(client); + *miniCelsius = lm75_reg_to_mc(data->temp[0], data->resolution); + + return 0; +} + +static int _find_lm75_device(struct device *dev, void *data) +{ + struct device_driver *driver; + struct as7716_32x_fan_data *prv = data; + char *driver_name = THERMAL_SENSORS_DRIVER; + + driver = dev->driver; + if (driver && driver->name && + strcmp(driver->name, driver_name) == 0) + { + struct i2c_client *client; + client = to_i2c_client(dev); + if (client) + { + /*cannot use "struct i2c_adapter *adap = to_i2c_adapter(dev);"*/ + struct i2c_adapter *adap = client->adapter; + int miniCelsius = 0; + + + if (!adap) { + return -ENXIO; + } + + /* If the data is not updated, read them from devfile + to drive them updateing data from chip.*/ + if (is_lm75_data_due(client)) + { + struct device *hwmon_dev; + + hwmon_dev = get_hwmon_dev(client); + if(0 == read_devfile_temp1_input(dev, adap->nr, + client->addr, hwmon_dev, &miniCelsius)) + { + prv->system_temp += miniCelsius; + prv->sensors_found++; + } + + } + else + { + get_lm75_temp(client, &miniCelsius); + prv->system_temp += miniCelsius; + prv->sensors_found++; + + } + } + } + return 0; +} + +/*Find all lm75 devices and return sum of temperatures.*/ +static ssize_t get_sys_temp(struct device *dev, struct device_attribute *da, + char *buf) +{ + ssize_t ret = 0; + struct as7716_32x_fan_data *data = as7716_32x_fan_update_device(dev); + + data->system_temp=0; + data->sensors_found=0; + i2c_for_each_dev(data, _find_lm75_device); + if (NUM_THERMAL_SENSORS != data->sensors_found) + { + dev_dbg(dev,"only %d of %d temps are found\n", + data->sensors_found, NUM_THERMAL_SENSORS); + data->system_temp = 0; + } + ret = sprintf(buf, "%d\n",data->system_temp); + return ret; +} +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct as7716_32x_fan_data *data = as7716_32x_fan_update_device(dev); + ssize_t ret = 0; + + if (data->valid) { + switch (attr->index) { + case FAN_DUTY_CYCLE_PERCENTAGE: + { + u32 duty_cycle = reg_val_to_duty_cycle(data->reg_val[FAN_DUTY_CYCLE_PERCENTAGE]); + ret = sprintf(buf, "%u\n", duty_cycle); + break; + } + case FAN1_FRONT_SPEED_RPM: + case FAN2_FRONT_SPEED_RPM: + case FAN3_FRONT_SPEED_RPM: + case FAN4_FRONT_SPEED_RPM: + case FAN5_FRONT_SPEED_RPM: + case FAN6_FRONT_SPEED_RPM: + case FAN1_REAR_SPEED_RPM: + case FAN2_REAR_SPEED_RPM: + case FAN3_REAR_SPEED_RPM: + case FAN4_REAR_SPEED_RPM: + case FAN5_REAR_SPEED_RPM: + case FAN6_REAR_SPEED_RPM: + ret = sprintf(buf, "%u\n", reg_val_to_speed_rpm(data->reg_val[attr->index])); + break; + case FAN1_PRESENT: + case FAN2_PRESENT: + case FAN3_PRESENT: + case FAN4_PRESENT: + case FAN5_PRESENT: + case FAN6_PRESENT: + ret = sprintf(buf, "%d\n", + reg_val_to_is_present(data->reg_val[FAN_PRESENT_REG], + attr->index - FAN1_PRESENT)); + break; + case FAN1_FAULT: + case FAN2_FAULT: + case FAN3_FAULT: + case FAN4_FAULT: + case FAN5_FAULT: + case FAN6_FAULT: + ret = sprintf(buf, "%d\n", is_fan_fault(data, attr->index - FAN1_FAULT)); + break; + case FAN1_DIRECTION: + case FAN2_DIRECTION: + case FAN3_DIRECTION: + case FAN4_DIRECTION: + case FAN5_DIRECTION: + case FAN6_DIRECTION: + ret = sprintf(buf, "%d\n", + reg_val_to_direction(data->reg_val[FAN_DIRECTION_REG], + attr->index - FAN1_DIRECTION)); + break; + default: + break; + } + } + + return ret; +} + +static const struct attribute_group as7716_32x_fan_group = { + .attrs = as7716_32x_fan_attributes, +}; + +static struct as7716_32x_fan_data *as7716_32x_fan_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32x_fan_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || + !data->valid) { + int i; + + dev_dbg(&client->dev, "Starting as7716_32x_fan update\n"); + data->valid = 0; + + /* Update fan data + */ + for (i = 0; i < ARRAY_SIZE(data->reg_val); i++) { + int status = as7716_32x_fan_read_value(client, fan_reg[i]); + + if (status < 0) { + data->valid = 0; + mutex_unlock(&data->update_lock); + dev_dbg(&client->dev, "reg %d, err %d\n", fan_reg[i], status); + return data; + } + else { + data->reg_val[i] = status; + } + } + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +static int as7716_32x_fan_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct as7716_32x_fan_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct as7716_32x_fan_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as7716_32x_fan_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: fan '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as7716_32x_fan_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as7716_32x_fan_remove(struct i2c_client *client) +{ + struct as7716_32x_fan_data *data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as7716_32x_fan_group); + + return 0; +} + +/* Addresses to scan */ +static const unsigned short normal_i2c[] = { 0x66, I2C_CLIENT_END }; + +static const struct i2c_device_id as7716_32x_fan_id[] = { + { "as7716_32x_fan", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, as7716_32x_fan_id); + +static struct i2c_driver as7716_32x_fan_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = DRVNAME, + }, + .probe = as7716_32x_fan_probe, + .remove = as7716_32x_fan_remove, + .id_table = as7716_32x_fan_id, + .address_list = normal_i2c, +}; + +static int __init as7716_32x_fan_init(void) +{ + return i2c_add_driver(&as7716_32x_fan_driver); +} + +static void __exit as7716_32x_fan_exit(void) +{ + i2c_del_driver(&as7716_32x_fan_driver); +} + +module_init(as7716_32x_fan_init); +module_exit(as7716_32x_fan_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("as7716_32x_fan driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_leds.c b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_leds.c new file mode 100755 index 000000000000..da3d9442035f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_leds.c @@ -0,0 +1,442 @@ +/* + * A LED driver for the as7716_32x_led + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*#define DEBUG*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +extern int as7716_32x_cpld_read (unsigned short cpld_addr, u8 reg); +extern int as7716_32x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +extern void led_classdev_unregister(struct led_classdev *led_cdev); +extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); +extern void led_classdev_resume(struct led_classdev *led_cdev); +extern void led_classdev_suspend(struct led_classdev *led_cdev); + +#define DRVNAME "as7716_32x_led" + +struct as7716_32x_led_data { + struct platform_device *pdev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[1]; /* only 1 register*/ +}; + +static struct as7716_32x_led_data *ledctl = NULL; + +/* LED related data + */ + +#define LED_CNTRLER_I2C_ADDRESS (0x60) + +#define LED_TYPE_DIAG_REG_MASK (0x3) +#define LED_MODE_DIAG_GREEN_VALUE (0x02) +#define LED_MODE_DIAG_RED_VALUE (0x01) +#define LED_MODE_DIAG_AMBER_VALUE (0x00) /*It's yellow actually. Green+Red=Yellow*/ +#define LED_MODE_DIAG_OFF_VALUE (0x03) + + +#define LED_TYPE_LOC_REG_MASK (0x80) +#define LED_MODE_LOC_ON_VALUE (0) +#define LED_MODE_LOC_OFF_VALUE (0x80) + +enum led_type { + LED_TYPE_DIAG, + LED_TYPE_LOC, + LED_TYPE_FAN, + LED_TYPE_PSU1, + LED_TYPE_PSU2 +}; + +struct led_reg { + u32 types; + u8 reg_addr; +}; + +static const struct led_reg led_reg_map[] = { + {(1<update_lock); + + if (time_after(jiffies, ledctl->last_updated + HZ + HZ / 2) + || !ledctl->valid) { + int i; + + dev_dbg(&ledctl->pdev->dev, "Starting as7716_32x_led update\n"); + + /* Update LED data + */ + for (i = 0; i < ARRAY_SIZE(ledctl->reg_val); i++) { + int status = as7716_32x_led_read_value(led_reg_map[i].reg_addr); + + if (status < 0) { + ledctl->valid = 0; + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", led_reg_map[i].reg_addr, status); + goto exit; + } + else + { + ledctl->reg_val[i] = status; + } + } + + ledctl->last_updated = jiffies; + ledctl->valid = 1; + } + +exit: + mutex_unlock(&ledctl->update_lock); +} + +static void as7716_32x_led_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode, + enum led_type type) +{ + int reg_val; + u8 reg ; + mutex_lock(&ledctl->update_lock); + + if( !getLedReg(type, ®)) + { + dev_dbg(&ledctl->pdev->dev, "Not match item for %d.\n", type); + } + + reg_val = as7716_32x_led_read_value(reg); + + if (reg_val < 0) { + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", reg, reg_val); + goto exit; + } + reg_val = led_light_mode_to_reg_val(type, led_light_mode, reg_val); + as7716_32x_led_write_value(reg, reg_val); + + /* to prevent the slow-update issue */ + ledctl->valid = 0; + +exit: + mutex_unlock(&ledctl->update_lock); +} + + +static void as7716_32x_led_diag_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + as7716_32x_led_set(led_cdev, led_light_mode, LED_TYPE_DIAG); +} + +static enum led_brightness as7716_32x_led_diag_get(struct led_classdev *cdev) +{ + as7716_32x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_DIAG, ledctl->reg_val[0]); +} + +static void as7716_32x_led_loc_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + as7716_32x_led_set(led_cdev, led_light_mode, LED_TYPE_LOC); +} + +static enum led_brightness as7716_32x_led_loc_get(struct led_classdev *cdev) +{ + as7716_32x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_LOC, ledctl->reg_val[0]); +} + +static void as7716_32x_led_auto_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ +} + +static enum led_brightness as7716_32x_led_auto_get(struct led_classdev *cdev) +{ + return LED_MODE_AUTO; +} + +static struct led_classdev as7716_32x_leds[] = { + [LED_TYPE_DIAG] = { + .name = "as7716_32x_led::diag", + .default_trigger = "unused", + .brightness_set = as7716_32x_led_diag_set, + .brightness_get = as7716_32x_led_diag_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_RED, + }, + [LED_TYPE_LOC] = { + .name = "as7716_32x_led::loc", + .default_trigger = "unused", + .brightness_set = as7716_32x_led_loc_set, + .brightness_get = as7716_32x_led_loc_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_BLUE, + }, + [LED_TYPE_FAN] = { + .name = "as7716_32x_led::fan", + .default_trigger = "unused", + .brightness_set = as7716_32x_led_auto_set, + .brightness_get = as7716_32x_led_auto_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_PSU1] = { + .name = "as7716_32x_led::psu1", + .default_trigger = "unused", + .brightness_set = as7716_32x_led_auto_set, + .brightness_get = as7716_32x_led_auto_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_PSU2] = { + .name = "as7716_32x_led::psu2", + .default_trigger = "unused", + .brightness_set = as7716_32x_led_auto_set, + .brightness_get = as7716_32x_led_auto_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, +}; + +static int as7716_32x_led_suspend(struct platform_device *dev, + pm_message_t state) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(as7716_32x_leds); i++) { + led_classdev_suspend(&as7716_32x_leds[i]); + } + + return 0; +} + +static int as7716_32x_led_resume(struct platform_device *dev) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(as7716_32x_leds); i++) { + led_classdev_resume(&as7716_32x_leds[i]); + } + + return 0; +} + +static int as7716_32x_led_probe(struct platform_device *pdev) +{ + int ret, i; + + for (i = 0; i < ARRAY_SIZE(as7716_32x_leds); i++) { + ret = led_classdev_register(&pdev->dev, &as7716_32x_leds[i]); + + if (ret < 0) + { + break; + } + } + + /* Check if all LEDs were successfully registered */ + if (i != ARRAY_SIZE(as7716_32x_leds)){ + int j; + + /* only unregister the LEDs that were successfully registered */ + for (j = 0; j < i; j++) { + led_classdev_unregister(&as7716_32x_leds[i]); + } + } + + return 0; +} + +static int as7716_32x_led_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(as7716_32x_leds); i++) { + led_classdev_unregister(&as7716_32x_leds[i]); + } + + return 0; +} + +static struct platform_driver as7716_32x_led_driver = { + .probe = as7716_32x_led_probe, + .remove = as7716_32x_led_remove, + .suspend = as7716_32x_led_suspend, + .resume = as7716_32x_led_resume, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +static int __init as7716_32x_led_init(void) +{ + int ret; + + + ret = platform_driver_register(&as7716_32x_led_driver); + if (ret < 0) { + + goto exit; + } + + ledctl = kzalloc(sizeof(struct as7716_32x_led_data), GFP_KERNEL); + if (!ledctl) { + ret = -ENOMEM; + platform_driver_unregister(&as7716_32x_led_driver); + goto exit; + } + + mutex_init(&ledctl->update_lock); + + ledctl->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(ledctl->pdev)) { + ret = PTR_ERR(ledctl->pdev); + platform_driver_unregister(&as7716_32x_led_driver); + kfree(ledctl); + goto exit; + } + +exit: + return 0; +} + +static void __exit as7716_32x_led_exit(void) +{ + platform_device_unregister(ledctl->pdev); + platform_driver_unregister(&as7716_32x_led_driver); + kfree(ledctl); +} + +module_init(as7716_32x_led_init); +module_exit(as7716_32x_led_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("as7716_32x_led driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_psu.c b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_psu.c new file mode 100755 index 000000000000..78a58b820b2a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_psu.c @@ -0,0 +1,381 @@ +/* + * An hwmon driver for accton as7716_32x Power Module + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_MODEL_NAME 16 + +#define DC12V_FAN_DIR_OFFSET 0x34 +#define DC12V_FAN_DIR_LEN 3 + +static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_string(struct device *dev, struct device_attribute *da, char *buf); +static int as7716_32x_psu_read_block(struct i2c_client *client, u8 command, u8 *data,int data_len); +extern int as7716_32x_cpld_read (unsigned short cpld_addr, u8 reg); + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +/* Each client has this additional data + */ +struct as7716_32x_psu_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 index; /* PSU index */ + u8 status; /* Status(present/power_good) register read from CPLD */ + char model_name[MAX_MODEL_NAME+1]; /* Model name, read from eeprom */ + char fan_dir[DC12V_FAN_DIR_LEN+1]; /* DC12V fan direction */ +}; + +static struct as7716_32x_psu_data *as7716_32x_psu_update_device(struct device *dev); + +enum as7716_32x_psu_sysfs_attributes { + PSU_PRESENT, + PSU_MODEL_NAME, + PSU_POWER_GOOD, + PSU_FAN_DIR /* For DC12V only */ +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, show_status, NULL, PSU_PRESENT); +static SENSOR_DEVICE_ATTR(psu_model_name, S_IRUGO, show_string, NULL, PSU_MODEL_NAME); +static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_status, NULL, PSU_POWER_GOOD); +static SENSOR_DEVICE_ATTR(psu_fan_dir, S_IRUGO, show_string, NULL, PSU_FAN_DIR); + +static struct attribute *as7716_32x_psu_attributes[] = { + &sensor_dev_attr_psu_present.dev_attr.attr, + &sensor_dev_attr_psu_model_name.dev_attr.attr, + &sensor_dev_attr_psu_power_good.dev_attr.attr, + &sensor_dev_attr_psu_fan_dir.dev_attr.attr, + NULL +}; + +static ssize_t show_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct as7716_32x_psu_data *data = as7716_32x_psu_update_device(dev); + u8 status = 0; + + if (!data->valid) { + return -EIO; + } + + if (attr->index == PSU_PRESENT) { + status = !(data->status >> (1-data->index) & 0x1); + } + else { /* PSU_POWER_GOOD */ + status = (data->status >> (3-data->index) & 0x1); + } + + return sprintf(buf, "%d\n", status); +} + +static ssize_t show_string(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct as7716_32x_psu_data *data = as7716_32x_psu_update_device(dev); + char *ptr = NULL; + + if (!data->valid) { + return -EIO; + } + + if (attr->index == PSU_MODEL_NAME) { + ptr = data->model_name; + } + else { /* PSU_FAN_DIR */ + ptr = data->fan_dir; + } + + return sprintf(buf, "%s\n", ptr); +} + +static const struct attribute_group as7716_32x_psu_group = { + .attrs = as7716_32x_psu_attributes, +}; + +static int as7716_32x_psu_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct as7716_32x_psu_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct as7716_32x_psu_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + data->index = dev_id->driver_data; + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as7716_32x_psu_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as7716_32x_psu_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as7716_32x_psu_remove(struct i2c_client *client) +{ + struct as7716_32x_psu_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as7716_32x_psu_group); + kfree(data); + + return 0; +} + +enum psu_index +{ + as7716_32x_psu1, + as7716_32x_psu2 +}; + +static const struct i2c_device_id as7716_32x_psu_id[] = { + { "as7716_32x_psu1", as7716_32x_psu1 }, + { "as7716_32x_psu2", as7716_32x_psu2 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, as7716_32x_psu_id); + +static struct i2c_driver as7716_32x_psu_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "as7716_32x_psu", + }, + .probe = as7716_32x_psu_probe, + .remove = as7716_32x_psu_remove, + .id_table = as7716_32x_psu_id, + .address_list = normal_i2c, +}; + +static int as7716_32x_psu_read_block(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ + int result = 0; + int retry_count = 5; + + while (retry_count) { + retry_count--; + + result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + + if (unlikely(result < 0)) { + msleep(10); + continue; + } + + if (unlikely(result != data_len)) { + result = -EIO; + msleep(10); + continue; + } + + result = 0; + break; + } + + return result; +} + +enum psu_type { + PSU_TYPE_AC_110V, + PSU_TYPE_DC_48V, + PSU_TYPE_DC_12V +}; + +struct model_name_info { + enum psu_type type; + u8 offset; + u8 length; + char* model_name; +}; + +struct model_name_info models[] = { +{PSU_TYPE_AC_110V, 0x20, 8, "YM-2651Y"}, +{PSU_TYPE_DC_48V, 0x20, 8, "YM-2651V"}, +{PSU_TYPE_DC_12V, 0x00, 11, "PSU-12V-750"}, +}; + +static int as7716_32x_psu_model_name_get(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32x_psu_data *data = i2c_get_clientdata(client); + int i, status; + + for (i = 0; i < ARRAY_SIZE(models); i++) { + memset(data->model_name, 0, sizeof(data->model_name)); + + status = as7716_32x_psu_read_block(client, models[i].offset, + data->model_name, models[i].length); + if (status < 0) { + data->model_name[0] = '\0'; + dev_dbg(&client->dev, "unable to read model name from (0x%x) offset(0x%x)\n", + client->addr, models[i].offset); + return status; + } + else { + data->model_name[models[i].length] = '\0'; + } + + /* Determine if the model name is known, if not, read next index + */ + if (strncmp(data->model_name, models[i].model_name, models[i].length) == 0) { + return 0; + } + else { + data->model_name[0] = '\0'; + } + } + + return -ENODATA; +} + +static struct as7716_32x_psu_data *as7716_32x_psu_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32x_psu_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int status; + int power_good = 0; + + data->valid = 0; + dev_dbg(&client->dev, "Starting as7716_32x update\n"); + + /* Read psu status */ + status = as7716_32x_cpld_read(0x60, 0x2); + + if (status < 0) { + dev_dbg(&client->dev, "cpld reg 0x60 err %d\n", status); + goto exit; + } + else { + data->status = status; + } + + /* Read model name */ + memset(data->model_name, 0, sizeof(data->model_name)); + memset(data->fan_dir, 0, sizeof(data->fan_dir)); + power_good = (data->status >> (3-data->index) & 0x1); + + if (power_good) { + if (as7716_32x_psu_model_name_get(dev) < 0) { + goto exit; + } + + if (strncmp(data->model_name, + models[PSU_TYPE_DC_12V].model_name, + models[PSU_TYPE_DC_12V].length) == 0) + { + /* Read fan direction */ + + status = as7716_32x_psu_read_block(client, DC12V_FAN_DIR_OFFSET, + data->fan_dir, DC12V_FAN_DIR_LEN); + + if (status < 0) { + data->fan_dir[0] = '\0'; + dev_dbg(&client->dev, "unable to read fan direction from (0x%x) offset(0x%x)\n", + client->addr, DC12V_FAN_DIR_OFFSET); + goto exit; + } + } + } + + data->last_updated = jiffies; + data->valid = 1; + } + +exit: + mutex_unlock(&data->update_lock); + + return data; +} + +static int __init as7716_32x_psu_init(void) +{ + return i2c_add_driver(&as7716_32x_psu_driver); +} + +static void __exit as7716_32x_psu_exit(void) +{ + i2c_del_driver(&as7716_32x_psu_driver); +} + +module_init(as7716_32x_psu_init); +module_exit(as7716_32x_psu_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("as7716_32x_psu driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_sfp.c b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_sfp.c new file mode 100755 index 000000000000..9c7a05632154 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_as7716_32x_sfp.c @@ -0,0 +1,365 @@ +/* + * An hwmon driver for accton as7716_32x sfp + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BIT_INDEX(i) (1UL << (i)) +#define I2C_ADDR_CPLD1 0x60 +#define I2C_ADDR_CPLD2 0x62 +#define I2C_ADDR_CPLD3 0x64 +#define CPLD1_OFFSET_QSFP_PRESET1 0x30 +#define CPLD1_OFFSET_QSFP_PRESET2 0x31 +#define CPLD1_OFFSET_QSFP_PRESET3 0x32 +#define CPLD1_OFFSET_QSFP_PRESET4 0x33 + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { 0x50, I2C_CLIENT_END }; + +/* Each client has this additional data + */ +struct as7716_32x_sfp_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + int port; /* Front port index */ + char eeprom[256]; /* eeprom data */ + u32 is_present; /* present status */ +}; + +static struct as7716_32x_sfp_data *as7716_32x_sfp_update_device(struct device *dev); +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_present(struct device *dev, struct device_attribute *da,char *buf); +static ssize_t show_eeprom(struct device *dev, struct device_attribute *da, char *buf); +extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +enum as7716_32x_sfp_sysfs_attributes { + SFP_PORT_NUMBER, + SFP_IS_PRESENT, + SFP_IS_PRESENT_ALL, + SFP_EEPROM +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(sfp_port_number, S_IRUGO, show_port_number, NULL, SFP_PORT_NUMBER); +static SENSOR_DEVICE_ATTR(sfp_is_present, S_IRUGO, show_present, NULL, SFP_IS_PRESENT); +static SENSOR_DEVICE_ATTR(sfp_is_present_all, S_IRUGO, show_present, NULL, SFP_IS_PRESENT_ALL); +static SENSOR_DEVICE_ATTR(sfp_eeprom, S_IRUGO, show_eeprom, NULL, SFP_EEPROM); + +static struct attribute *as7716_32x_sfp_attributes[] = { + &sensor_dev_attr_sfp_port_number.dev_attr.attr, + &sensor_dev_attr_sfp_is_present.dev_attr.attr, + &sensor_dev_attr_sfp_is_present_all.dev_attr.attr, + &sensor_dev_attr_sfp_eeprom.dev_attr.attr, + NULL +}; + +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32x_sfp_data *data = i2c_get_clientdata(client); + + return sprintf(buf, "%d\n", data->port+1); +} + +/* Error-check the CPLD read results. */ +#define VALIDATED_READ(_buf, _rv, _read_expr, _invert) \ +do { \ + _rv = (_read_expr); \ + if(_rv < 0) { \ + return sprintf(_buf, "READ ERROR\n"); \ + } \ + if(_invert) { \ + _rv = ~_rv; \ + } \ + _rv &= 0xFF; \ +} while(0) + +static ssize_t show_present(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + if(attr->index == SFP_IS_PRESENT_ALL) { + int values[4]; + /* + * Report the SFP_PRESENCE status for all ports. + */ + + /* QSFP_PRESENT Ports 1-8 */ + //VALIDATED_READ(buf, values[0], accton_i2c_cpld_read(0x62, 0x9), 1); + VALIDATED_READ(buf, values[0], accton_i2c_cpld_read(I2C_ADDR_CPLD1, CPLD1_OFFSET_QSFP_PRESET1), 1); + /* QSFP_PRESENT Ports 9-16 */ + VALIDATED_READ(buf, values[1], accton_i2c_cpld_read(I2C_ADDR_CPLD1, CPLD1_OFFSET_QSFP_PRESET2), 1); + /* QSFP_PRESENT Ports 17-24 */ + VALIDATED_READ(buf, values[2], accton_i2c_cpld_read(I2C_ADDR_CPLD1, CPLD1_OFFSET_QSFP_PRESET3), 1); + /* QSFP_PRESENT Ports 25-32 */ + VALIDATED_READ(buf, values[3], accton_i2c_cpld_read(I2C_ADDR_CPLD1, CPLD1_OFFSET_QSFP_PRESET4), 1); + + /* Return values 1 -> 32 in order */ + return sprintf(buf, "%.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], values[3]); + } + else { /* SFP_IS_PRESENT */ + struct as7716_32x_sfp_data *data = as7716_32x_sfp_update_device(dev); + + if (!data->valid) { + printk("return -EIO\n"); + return -EIO; + } + + return sprintf(buf, "%d\n", data->is_present); + } +} + +static ssize_t show_eeprom(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct as7716_32x_sfp_data *data = as7716_32x_sfp_update_device(dev); + + if (!data->valid) { + return 0; + } + + if (!data->is_present) { + return 0; + } + + memcpy(buf, data->eeprom, sizeof(data->eeprom)); + + return sizeof(data->eeprom); +} + +static const struct attribute_group as7716_32x_sfp_group = { + .attrs = as7716_32x_sfp_attributes, +}; + +static int as7716_32x_sfp_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct as7716_32x_sfp_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct as7716_32x_sfp_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + mutex_init(&data->update_lock); + data->port = dev_id->driver_data; + i2c_set_clientdata(client, data); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as7716_32x_sfp_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: sfp '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as7716_32x_sfp_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as7716_32x_sfp_remove(struct i2c_client *client) +{ + struct as7716_32x_sfp_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as7716_32x_sfp_group); + kfree(data); + + return 0; +} + +enum port_numbers { +as7716_32x_sfp1, as7716_32x_sfp2, as7716_32x_sfp3, as7716_32x_sfp4, +as7716_32x_sfp5, as7716_32x_sfp6, as7716_32x_sfp7, as7716_32x_sfp8, +as7716_32x_sfp9, as7716_32x_sfp10,as7716_32x_sfp11,as7716_32x_sfp12, +as7716_32x_sfp13,as7716_32x_sfp14,as7716_32x_sfp15,as7716_32x_sfp16, +as7716_32x_sfp17,as7716_32x_sfp18,as7716_32x_sfp19,as7716_32x_sfp20, +as7716_32x_sfp21,as7716_32x_sfp22,as7716_32x_sfp23,as7716_32x_sfp24, +as7716_32x_sfp25,as7716_32x_sfp26,as7716_32x_sfp27,as7716_32x_sfp28, +as7716_32x_sfp29,as7716_32x_sfp30,as7716_32x_sfp31,as7716_32x_sfp32 +}; + +static const struct i2c_device_id as7716_32x_sfp_id[] = { +{ "as7716_32x_sfp1", as7716_32x_sfp1 }, { "as7716_32x_sfp2", as7716_32x_sfp2 }, +{ "as7716_32x_sfp3", as7716_32x_sfp3 }, { "as7716_32x_sfp4", as7716_32x_sfp4 }, +{ "as7716_32x_sfp5", as7716_32x_sfp5 }, { "as7716_32x_sfp6", as7716_32x_sfp6 }, +{ "as7716_32x_sfp7", as7716_32x_sfp7 }, { "as7716_32x_sfp8", as7716_32x_sfp8 }, +{ "as7716_32x_sfp9", as7716_32x_sfp9 }, { "as7716_32x_sfp10", as7716_32x_sfp10 }, +{ "as7716_32x_sfp11", as7716_32x_sfp11 }, { "as7716_32x_sfp12", as7716_32x_sfp12 }, +{ "as7716_32x_sfp13", as7716_32x_sfp13 }, { "as7716_32x_sfp14", as7716_32x_sfp14 }, +{ "as7716_32x_sfp15", as7716_32x_sfp15 }, { "as7716_32x_sfp16", as7716_32x_sfp16 }, +{ "as7716_32x_sfp17", as7716_32x_sfp17 }, { "as7716_32x_sfp18", as7716_32x_sfp18 }, +{ "as7716_32x_sfp19", as7716_32x_sfp19 }, { "as7716_32x_sfp20", as7716_32x_sfp20 }, +{ "as7716_32x_sfp21", as7716_32x_sfp21 }, { "as7716_32x_sfp22", as7716_32x_sfp22 }, +{ "as7716_32x_sfp23", as7716_32x_sfp23 }, { "as7716_32x_sfp24", as7716_32x_sfp24 }, +{ "as7716_32x_sfp25", as7716_32x_sfp25 }, { "as7716_32x_sfp26", as7716_32x_sfp26 }, +{ "as7716_32x_sfp27", as7716_32x_sfp27 }, { "as7716_32x_sfp28", as7716_32x_sfp28 }, +{ "as7716_32x_sfp29", as7716_32x_sfp29 }, { "as7716_32x_sfp30", as7716_32x_sfp30 }, +{ "as7716_32x_sfp31", as7716_32x_sfp31 }, { "as7716_32x_sfp32", as7716_32x_sfp32 }, +{} +}; +MODULE_DEVICE_TABLE(i2c, as7716_32x_sfp_id); + +static struct i2c_driver as7716_32x_sfp_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "as7716_32x_sfp", + }, + .probe = as7716_32x_sfp_probe, + .remove = as7716_32x_sfp_remove, + .id_table = as7716_32x_sfp_id, + .address_list = normal_i2c, +}; + +static int as7716_32x_sfp_read_block(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ + int result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + + if (unlikely(result < 0)) + goto abort; + if (unlikely(result != data_len)) { + result = -EIO; + goto abort; + } + + result = 0; + +abort: + return result; +} + +static struct as7716_32x_sfp_data *as7716_32x_sfp_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32x_sfp_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int status = -1; + int i = 0; + u8 cpld_reg = 0x30 + (data->port/8); + + data->valid = 0; + + /* Read present status of the specified port number */ + data->is_present = 0; + status = accton_i2c_cpld_read(I2C_ADDR_CPLD1, cpld_reg); + + if (status < 0) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", I2C_ADDR_CPLD1, cpld_reg, status); + goto exit; + } + + data->is_present = (status & (1 << (data->port % 8))) ? 0 : 1; + printk("data->is_present=%d, data->port=%d, status=0x%x\n",data->is_present, data->port, status); + /* Read eeprom data based on port number */ + memset(data->eeprom, 0, sizeof(data->eeprom)); + + /* Check if the port is present */ + if (data->is_present) { + /* read eeprom */ + for (i = 0; i < sizeof(data->eeprom)/I2C_SMBUS_BLOCK_MAX; i++) { + status = as7716_32x_sfp_read_block(client, i*I2C_SMBUS_BLOCK_MAX, + data->eeprom+(i*I2C_SMBUS_BLOCK_MAX), + I2C_SMBUS_BLOCK_MAX); + if (status < 0) { + printk("unable to read eeprom from port(%d)\n", data->port); + dev_dbg(&client->dev, "unable to read eeprom from port(%d)\n", data->port); + goto exit; + } + } + } + + data->last_updated = jiffies; + data->valid = 1; + } + +exit: + mutex_unlock(&data->update_lock); + + return data; +} + +static int __init as7716_32x_sfp_init(void) +{ + //extern int platform_accton_as7716_32x(void); + //if (!platform_accton_as7716_32x()) { +// return -ENODEV; + //} + + return i2c_add_driver(&as7716_32x_sfp_driver); +} + +static void __exit as7716_32x_sfp_exit(void) +{ + i2c_del_driver(&as7716_32x_sfp_driver); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton as7716_32x_sfp driver"); +MODULE_LICENSE("GPL"); + +module_init(as7716_32x_sfp_init); +module_exit(as7716_32x_sfp_exit); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_i2c_cpld.c b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_i2c_cpld.c new file mode 100755 index 000000000000..46d1e2773287 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/accton_i2c_cpld.c @@ -0,0 +1,259 @@ +/* + * A hwmon driver for the accton_i2c_cpld + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CPLD_VERSION_REG 0x1 + +enum as5712_54x_cpld_sysfs_attributes { + CPLD_READ_VERSION, + CPLD_BYTE_ACCESS, + CPLD_DUMP_ALL, +}; + +static ssize_t read_cpld_version(struct device *dev, struct device_attribute *da, + char *buf); +int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg); + + +static LIST_HEAD(cpld_client_list); +static struct mutex list_lock; + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; + +/* Addresses scanned for accton_i2c_cpld + */ +static const unsigned short normal_i2c[] = { 0x31, 0x35, 0x60, 0x61, 0x62, I2C_CLIENT_END }; + +static SENSOR_DEVICE_ATTR(cpld_get_version, S_IRUGO, read_cpld_version, NULL, CPLD_READ_VERSION); + +static struct attribute *as5712_54x_cpld_attributes[] = { + &sensor_dev_attr_cpld_get_version.dev_attr.attr, + NULL +}; + +static const struct attribute_group as5712_54x_cpld_group = { + .attrs = as5712_54x_cpld_attributes, +}; + +static ssize_t read_cpld_version(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + unsigned short cpld_reg = CPLD_VERSION_REG; + u8 reg; + + if(attr->index == CPLD_READ_VERSION) { + reg = accton_i2c_cpld_read(client->addr, cpld_reg); + return sprintf(buf, "%02x\n",reg); + } + return -1 ; +} + + +static void accton_i2c_cpld_add_client(struct i2c_client *client) +{ + struct cpld_client_node *node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", client->addr); + return; + } + + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &cpld_client_list); + mutex_unlock(&list_lock); +} + +static void accton_i2c_cpld_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client == client) { + found = 1; + break; + } + } + + if (found) { + list_del(list_node); + kfree(cpld_node); + } + + mutex_unlock(&list_lock); +} + +static int accton_i2c_cpld_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_dbg(&client->dev, "i2c_check_functionality failed (0x%x)\n", client->addr); + status = -EIO; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as5712_54x_cpld_group); + if (status) { + goto exit; + } + + dev_info(&client->dev, "chip found\n"); + accton_i2c_cpld_add_client(client); + + return 0; +exit: + return status; +} + +static int accton_i2c_cpld_remove(struct i2c_client *client) +{ + sysfs_remove_group(&client->dev.kobj, &as5712_54x_cpld_group); + + accton_i2c_cpld_remove_client(client); + return 0; +} + +static const struct i2c_device_id accton_i2c_cpld_id[] = { + { "accton_i2c_cpld", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, accton_i2c_cpld_id); + +static struct i2c_driver accton_i2c_cpld_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "accton_i2c_cpld", + }, + .probe = accton_i2c_cpld_probe, + .remove = accton_i2c_cpld_remove, + .id_table = accton_i2c_cpld_id, + .address_list = normal_i2c, +}; + +int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EPERM; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = i2c_smbus_read_byte_data(cpld_node->client, reg); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(accton_i2c_cpld_read); + +int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EIO; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = i2c_smbus_write_byte_data(cpld_node->client, reg, value); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(accton_i2c_cpld_write); + +static int __init accton_i2c_cpld_init(void) +{ + mutex_init(&list_lock); + return i2c_add_driver(&accton_i2c_cpld_driver); +} + +static void __exit accton_i2c_cpld_exit(void) +{ + i2c_del_driver(&accton_i2c_cpld_driver); +} +/* +static struct dmi_system_id as7712_dmi_table[] = { + { + .ident = "Accton AS7712", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Accton"), + DMI_MATCH(DMI_PRODUCT_NAME, "AS7712"), + }, + } +}; + +int platform_accton_as7712_32x(void) +{ + return dmi_check_system(as7712_dmi_table); +} +EXPORT_SYMBOL(platform_accton_as7712_32x); +*/ +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton_i2c_cpld driver"); +MODULE_LICENSE("GPL"); + +module_init(accton_i2c_cpld_init); +module_exit(accton_i2c_cpld_exit); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/cpr_4011_4mxx.c b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/cpr_4011_4mxx.c new file mode 100755 index 000000000000..30bea914d589 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/cpr_4011_4mxx.c @@ -0,0 +1,400 @@ +/* + * An hwmon driver for the CPR-4011-4Mxx Redundant Power Module + * + * Copyright (C) Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#if 0 +#define DEBUG +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_FAN_DUTY_CYCLE 100 + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { 0x3c, 0x3d, 0x3e, 0x3f, I2C_CLIENT_END }; + +/* Each client has this additional data + */ +struct cpr_4011_4mxx_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 vout_mode; /* Register value */ + u16 v_in; /* Register value */ + u16 v_out; /* Register value */ + u16 i_in; /* Register value */ + u16 i_out; /* Register value */ + u16 p_in; /* Register value */ + u16 p_out; /* Register value */ + u16 temp_input[2]; /* Register value */ + u8 fan_fault; /* Register value */ + u16 fan_duty_cycle[2]; /* Register value */ + u16 fan_speed[2]; /* Register value */ +}; + +static ssize_t show_linear(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_vout(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static int cpr_4011_4mxx_write_word(struct i2c_client *client, u8 reg, u16 value); +static struct cpr_4011_4mxx_data *cpr_4011_4mxx_update_device(struct device *dev); + +enum cpr_4011_4mxx_sysfs_attributes { + PSU_V_IN, + PSU_V_OUT, + PSU_I_IN, + PSU_I_OUT, + PSU_P_IN, + PSU_P_OUT, + PSU_TEMP1_INPUT, + PSU_FAN1_FAULT, + PSU_FAN1_DUTY_CYCLE, + PSU_FAN1_SPEED, +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(psu_v_in, S_IRUGO, show_linear, NULL, PSU_V_IN); +static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, show_vout, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(psu_i_in, S_IRUGO, show_linear, NULL, PSU_I_IN); +static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, show_linear, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(psu_p_in, S_IRUGO, show_linear, NULL, PSU_P_IN); +static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, show_linear, NULL, PSU_P_OUT); +static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, show_fan_fault, NULL, PSU_FAN1_FAULT); +static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, show_linear, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); +static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); + +static struct attribute *cpr_4011_4mxx_attributes[] = { + &sensor_dev_attr_psu_v_in.dev_attr.attr, + &sensor_dev_attr_psu_v_out.dev_attr.attr, + &sensor_dev_attr_psu_i_in.dev_attr.attr, + &sensor_dev_attr_psu_i_out.dev_attr.attr, + &sensor_dev_attr_psu_p_in.dev_attr.attr, + &sensor_dev_attr_psu_p_out.dev_attr.attr, + &sensor_dev_attr_psu_temp1_input.dev_attr.attr, + &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, + &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, + &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, + NULL +}; + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + bool is_negative = valid_data >> (valid_bit - 1); + + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} + +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpr_4011_4mxx_data *data = i2c_get_clientdata(client); + int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; + long speed; + int error; + + error = kstrtol(buf, 10, &speed); + if (error) + return error; + + if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) + return -EINVAL; + + mutex_lock(&data->update_lock); + data->fan_duty_cycle[nr] = speed; + cpr_4011_4mxx_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t show_linear(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct cpr_4011_4mxx_data *data = cpr_4011_4mxx_update_device(dev); + + u16 value = 0; + int exponent, mantissa; + int multiplier = 1000; + + switch (attr->index) { + case PSU_V_IN: + value = data->v_in; + break; + case PSU_I_IN: + value = data->i_in; + break; + case PSU_I_OUT: + value = data->i_out; + break; + case PSU_P_IN: + value = data->p_in; + break; + case PSU_P_OUT: + value = data->p_out; + break; + case PSU_TEMP1_INPUT: + value = data->temp_input[0]; + break; + case PSU_FAN1_DUTY_CYCLE: + multiplier = 1; + value = data->fan_duty_cycle[0]; + break; + case PSU_FAN1_SPEED: + multiplier = 1; + value = data->fan_speed[0]; + break; + default: + break; + } + + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + + return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct cpr_4011_4mxx_data *data = cpr_4011_4mxx_update_device(dev); + + u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; + + return sprintf(buf, "%d\n", data->fan_fault >> shift); +} + +static ssize_t show_vout(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct cpr_4011_4mxx_data *data = cpr_4011_4mxx_update_device(dev); + int exponent, mantissa; + int multiplier = 1000; + + exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); + mantissa = data->v_out; + + return (exponent > 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static const struct attribute_group cpr_4011_4mxx_group = { + .attrs = cpr_4011_4mxx_attributes, +}; + +static int cpr_4011_4mxx_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct cpr_4011_4mxx_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct cpr_4011_4mxx_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &cpr_4011_4mxx_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &cpr_4011_4mxx_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int cpr_4011_4mxx_remove(struct i2c_client *client) +{ + struct cpr_4011_4mxx_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &cpr_4011_4mxx_group); + kfree(data); + + return 0; +} + +static const struct i2c_device_id cpr_4011_4mxx_id[] = { + { "cpr_4011_4mxx", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, cpr_4011_4mxx_id); + +static struct i2c_driver cpr_4011_4mxx_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "cpr_4011_4mxx", + }, + .probe = cpr_4011_4mxx_probe, + .remove = cpr_4011_4mxx_remove, + .id_table = cpr_4011_4mxx_id, + .address_list = normal_i2c, +}; + +static int cpr_4011_4mxx_read_byte(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int cpr_4011_4mxx_read_word(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_word_data(client, reg); +} + +static int cpr_4011_4mxx_write_word(struct i2c_client *client, u8 reg, u16 value) +{ + return i2c_smbus_write_word_data(client, reg, value); +} + +struct reg_data_byte { + u8 reg; + u8 *value; +}; + +struct reg_data_word { + u8 reg; + u16 *value; +}; + +static struct cpr_4011_4mxx_data *cpr_4011_4mxx_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpr_4011_4mxx_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int i, status; + struct reg_data_byte regs_byte[] = { {0x20, &data->vout_mode}, + {0x81, &data->fan_fault}}; + struct reg_data_word regs_word[] = { {0x88, &data->v_in}, + {0x8b, &data->v_out}, + {0x89, &data->i_in}, + {0x8c, &data->i_out}, + {0x96, &data->p_out}, + {0x97, &data->p_in}, + {0x8d, &(data->temp_input[0])}, + {0x8e, &(data->temp_input[1])}, + {0x3b, &(data->fan_duty_cycle[0])}, + {0x3c, &(data->fan_duty_cycle[1])}, + {0x90, &(data->fan_speed[0])}, + {0x91, &(data->fan_speed[1])}}; + + dev_dbg(&client->dev, "Starting cpr_4011_4mxx update\n"); + + /* Read byte data */ + for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { + status = cpr_4011_4mxx_read_byte(client, regs_byte[i].reg); + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_byte[i].reg, status); + } + else { + *(regs_byte[i].value) = status; + } + } + + /* Read word data */ + for (i = 0; i < ARRAY_SIZE(regs_word); i++) { + status = cpr_4011_4mxx_read_word(client, regs_word[i].reg); + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_word[i].reg, status); + } + else { + *(regs_word[i].value) = status; + } + } + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +static int __init cpr_4011_4mxx_init(void) +{ + return i2c_add_driver(&cpr_4011_4mxx_driver); +} + +static void __exit cpr_4011_4mxx_exit(void) +{ + i2c_del_driver(&cpr_4011_4mxx_driver); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("CPR_4011_4MXX driver"); +MODULE_LICENSE("GPL"); + +module_init(cpr_4011_4mxx_init); +module_exit(cpr_4011_4mxx_exit); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/optoe.c b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/optoe.c new file mode 100755 index 000000000000..16be2fef89b1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/optoe.c @@ -0,0 +1,1148 @@ +/* + * optoe.c - A driver to read and write the EEPROM on optical transceivers + * (SFP, QSFP and similar I2C based devices) + * + * Copyright (C) 2014 Cumulus networks Inc. + * Copyright (C) 2017 Finisar Corp. + * + * 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 Freeoftware Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +/* + * Description: + * a) Optical transceiver EEPROM read/write transactions are just like + * the at24 eeproms managed by the at24.c i2c driver + * b) The register/memory layout is up to 256 128 byte pages defined by + * a "pages valid" register and switched via a "page select" + * register as explained in below diagram. + * c) 256 bytes are mapped at a time. 'Lower page 00h' is the first 128 + * bytes of address space, and always references the same + * location, independent of the page select register. + * All mapped pages are mapped into the upper 128 bytes + * (offset 128-255) of the i2c address. + * d) Devices with one I2C address (eg QSFP) use I2C address 0x50 + * (A0h in the spec), and map all pages in the upper 128 bytes + * of that address. + * e) Devices with two I2C addresses (eg SFP) have 256 bytes of data + * at I2C address 0x50, and 256 bytes of data at I2C address + * 0x51 (A2h in the spec). Page selection and paged access + * only apply to this second I2C address (0x51). + * e) The address space is presented, by the driver, as a linear + * address space. For devices with one I2C client at address + * 0x50 (eg QSFP), offset 0-127 are in the lower + * half of address 50/A0h/client[0]. Offset 128-255 are in + * page 0, 256-383 are page 1, etc. More generally, offset + * 'n' resides in page (n/128)-1. ('page -1' is the lower + * half, offset 0-127). + * f) For devices with two I2C clients at address 0x50 and 0x51 (eg SFP), + * the address space places offset 0-127 in the lower + * half of 50/A0/client[0], offset 128-255 in the upper + * half. Offset 256-383 is in the lower half of 51/A2/client[1]. + * Offset 384-511 is in page 0, in the upper half of 51/A2/... + * Offset 512-639 is in page 1, in the upper half of 51/A2/... + * Offset 'n' is in page (n/128)-3 (for n > 383) + * + * One I2c addressed (eg QSFP) Memory Map + * + * 2-Wire Serial Address: 1010000x + * + * Lower Page 00h (128 bytes) + * ===================== + * | | + * | | + * | | + * | | + * | | + * | | + * | | + * | | + * | | + * | | + * |Page Select Byte(127)| + * ===================== + * | + * | + * | + * | + * V + * ------------------------------------------------------------ + * | | | | + * | | | | + * | | | | + * | | | | + * | | | | + * | | | | + * | | | | + * | | | | + * | | | | + * V V V V + * ------------ -------------- --------------- -------------- + * | | | | | | | | + * | Upper | | Upper | | Upper | | Upper | + * | Page 00h | | Page 01h | | Page 02h | | Page 03h | + * | | | (Optional) | | (Optional) | | (Optional | + * | | | | | | | for Cable | + * | | | | | | | Assemblies) | + * | ID | | AST | | User | | | + * | Fields | | Table | | EEPROM Data | | | + * | | | | | | | | + * | | | | | | | | + * | | | | | | | | + * ------------ -------------- --------------- -------------- + * + * The SFF 8436 (QSFP) spec only defines the 4 pages described above. + * In anticipation of future applications and devices, this driver + * supports access to the full architected range, 256 pages. + * + **/ + +/* #define DEBUG 1 */ + +#undef EEPROM_CLASS +#ifdef CONFIG_EEPROM_CLASS +#define EEPROM_CLASS +#endif +#ifdef CONFIG_EEPROM_CLASS_MODULE +#define EEPROM_CLASS +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * The optoe driver is for read/write access to the EEPROM on standard + * I2C based optical transceivers (SFP, QSFP, etc) + * + * While based on the at24 driver, it eliminates code that supports other + * types of I2C EEPROMs, and adds support for pages accessed through the + * page-select register at offset 127. + */ + +struct optoe_platform_data { + u32 byte_len; /* size (sum of all addr) */ + u16 page_size; /* for writes */ + u8 flags; + + void (*setup)(struct memory_accessor *, void *context); + void *context; +#ifdef EEPROM_CLASS + struct eeprom_platform_data *eeprom_data; /* extra data for the eeprom_class */ +#endif +}; + +#ifdef EEPROM_CLASS +#include +#endif + +#include + +/* fundamental unit of addressing for EEPROM */ +#define OPTOE_PAGE_SIZE 128 +/* + * Single address devices (eg QSFP) have 256 pages, plus the unpaged + * low 128 bytes. If the device does not support paging, it is + * only 2 'pages' long. + */ +#define OPTOE_ARCH_PAGES 256 +#define ONE_ADDR_EEPROM_SIZE ((1 + OPTOE_ARCH_PAGES) * OPTOE_PAGE_SIZE) +#define ONE_ADDR_EEPROM_UNPAGED_SIZE (2 * OPTOE_PAGE_SIZE) +/* + * Dual address devices (eg SFP) have 256 pages, plus the unpaged + * low 128 bytes, plus 256 bytes at 0x50. If the device does not + * support paging, it is 4 'pages' long. + */ +#define TWO_ADDR_EEPROM_SIZE ((3 + OPTOE_ARCH_PAGES) * OPTOE_PAGE_SIZE) +#define TWO_ADDR_EEPROM_UNPAGED_SIZE (4 * OPTOE_PAGE_SIZE) + +/* a few constants to find our way around the EEPROM */ +#define OPTOE_PAGE_SELECT_REG 0x7F +#define ONE_ADDR_PAGEABLE_REG 0x02 +#define ONE_ADDR_NOT_PAGEABLE (1<<2) +#define TWO_ADDR_PAGEABLE_REG 0x40 +#define TWO_ADDR_PAGEABLE (1<<4) +#define OPTOE_ID_REG 0 + +/* The maximum length of a port name */ +#define MAX_PORT_NAME_LEN 20 +struct optoe_data { + struct optoe_platform_data chip; + struct memory_accessor macc; + int use_smbus; + char port_name[MAX_PORT_NAME_LEN]; + + /* + * Lock protects against activities from other Linux tasks, + * but not from changes by other I2C masters. + */ + struct mutex lock; + struct bin_attribute bin; + struct attribute_group attr_group; + + u8 *writebuf; + unsigned write_max; + + unsigned num_addresses; + +#ifdef EEPROM_CLASS + struct eeprom_device *eeprom_dev; +#endif + + /* dev_class: ONE_ADDR (QSFP) or TWO_ADDR (SFP) */ + int dev_class; + + struct i2c_client *client[]; +}; + +typedef enum optoe_opcode { + OPTOE_READ_OP = 0, + OPTOE_WRITE_OP = 1 +} optoe_opcode_e; + +/* + * This parameter is to help this driver avoid blocking other drivers out + * of I2C for potentially troublesome amounts of time. With a 100 kHz I2C + * clock, one 256 byte read takes about 1/43 second which is excessive; + * but the 1/170 second it takes at 400 kHz may be quite reasonable; and + * at 1 MHz (Fm+) a 1/430 second delay could easily be invisible. + * + * This value is forced to be a power of two so that writes align on pages. + */ +static unsigned io_limit = OPTOE_PAGE_SIZE; + +/* + * specs often allow 5 msec for a page write, sometimes 20 msec; + * it's important to recover from write timeouts. + */ +static unsigned write_timeout = 25; + +/* + * flags to distinguish one-address (QSFP family) from two-address (SFP family) + * If the family is not known, figure it out when the device is accessed + */ +#define ONE_ADDR 1 +#define TWO_ADDR 2 + +static const struct i2c_device_id optoe_ids[] = { + { "optoe1", ONE_ADDR }, + { "optoe2", TWO_ADDR }, + { "sff8436", ONE_ADDR }, + { "24c04", TWO_ADDR }, + { /* END OF LIST */ } +}; +MODULE_DEVICE_TABLE(i2c, optoe_ids); + +/*-------------------------------------------------------------------------*/ +/* + * This routine computes the addressing information to be used for + * a given r/w request. + * + * Task is to calculate the client (0 = i2c addr 50, 1 = i2c addr 51), + * the page, and the offset. + * + * Handles both single address (eg QSFP) and two address (eg SFP). + * For SFP, offset 0-255 are on client[0], >255 is on client[1] + * Offset 256-383 are on the lower half of client[1] + * Pages are accessible on the upper half of client[1]. + * Offset >383 are in 128 byte pages mapped into the upper half + * + * For QSFP, all offsets are on client[0] + * offset 0-127 are on the lower half of client[0] (no paging) + * Pages are accessible on the upper half of client[1]. + * Offset >127 are in 128 byte pages mapped into the upper half + * + * Callers must not read/write beyond the end of a client or a page + * without recomputing the client/page. Hence offset (within page) + * plus length must be less than or equal to 128. (Note that this + * routine does not have access to the length of the call, hence + * cannot do the validity check.) + * + * Offset within Lower Page 00h and Upper Page 00h are not recomputed + */ + +static uint8_t optoe_translate_offset(struct optoe_data *optoe, + loff_t *offset, struct i2c_client **client) +{ + unsigned page = 0; + + *client = optoe->client[0]; + + /* if SFP style, offset > 255, shift to i2c addr 0x51 */ + if (optoe->dev_class == TWO_ADDR) { + if (*offset > 255) { + /* like QSFP, but shifted to client[1] */ + *client = optoe->client[1]; + *offset -= 256; + } + } + + /* + * if offset is in the range 0-128... + * page doesn't matter (using lower half), return 0. + * offset is already correct (don't add 128 to get to paged area) + */ + if (*offset < OPTOE_PAGE_SIZE) + return page; + + /* note, page will always be positive since *offset >= 128 */ + page = (*offset >> 7)-1; + /* 0x80 places the offset in the top half, offset is last 7 bits */ + *offset = OPTOE_PAGE_SIZE + (*offset & 0x7f); + + return page; /* note also returning client and offset */ +} + +static ssize_t optoe_eeprom_read(struct optoe_data *optoe, + struct i2c_client *client, + char *buf, unsigned offset, size_t count) +{ + struct i2c_msg msg[2]; + u8 msgbuf[2]; + unsigned long timeout, read_time; + int status, i; + + memset(msg, 0, sizeof(msg)); + + switch (optoe->use_smbus) { + case I2C_SMBUS_I2C_BLOCK_DATA: + /*smaller eeproms can work given some SMBus extension calls */ + if (count > I2C_SMBUS_BLOCK_MAX) + count = I2C_SMBUS_BLOCK_MAX; + break; + case I2C_SMBUS_WORD_DATA: + /* Check for odd length transaction */ + count = (count == 1) ? 1 : 2; + break; + case I2C_SMBUS_BYTE_DATA: + count = 1; + break; + default: + /* + * When we have a better choice than SMBus calls, use a + * combined I2C message. Write address; then read up to + * io_limit data bytes. msgbuf is u8 and will cast to our + * needs. + */ + i = 0; + msgbuf[i++] = offset; + + msg[0].addr = client->addr; + msg[0].buf = msgbuf; + msg[0].len = i; + + msg[1].addr = client->addr; + msg[1].flags = I2C_M_RD; + msg[1].buf = buf; + msg[1].len = count; + } + + /* + * Reads fail if the previous write didn't complete yet. We may + * loop a few times until this one succeeds, waiting at least + * long enough for one entire page write to work. + */ + timeout = jiffies + msecs_to_jiffies(write_timeout); + do { + read_time = jiffies; + + switch (optoe->use_smbus) { + case I2C_SMBUS_I2C_BLOCK_DATA: + status = i2c_smbus_read_i2c_block_data(client, offset, + count, buf); + break; + case I2C_SMBUS_WORD_DATA: + status = i2c_smbus_read_word_data(client, offset); + if (status >= 0) { + buf[0] = status & 0xff; + if (count == 2) + buf[1] = status >> 8; + status = count; + } + break; + case I2C_SMBUS_BYTE_DATA: + status = i2c_smbus_read_byte_data(client, offset); + if (status >= 0) { + buf[0] = status; + status = count; + } + break; + default: + status = i2c_transfer(client->adapter, msg, 2); + if (status == 2) + status = count; + } + + dev_dbg(&client->dev, "eeprom read %zu@%d --> %d (%ld)\n", + count, offset, status, jiffies); + + if (status == count) /* happy path */ + return count; + + if (status == -ENXIO) /* no module present */ + return status; + + /* REVISIT: at HZ=100, this is sloooow */ + msleep(1); + } while (time_before(read_time, timeout)); + + return -ETIMEDOUT; +} + +static ssize_t optoe_eeprom_write(struct optoe_data *optoe, + struct i2c_client *client, + const char *buf, + unsigned offset, size_t count) +{ + struct i2c_msg msg; + ssize_t status; + unsigned long timeout, write_time; + unsigned next_page_start; + int i = 0; + + /* write max is at most a page + * (In this driver, write_max is actually one byte!) + */ + if (count > optoe->write_max) + count = optoe->write_max; + + /* shorten count if necessary to avoid crossing page boundary */ + next_page_start = roundup(offset + 1, OPTOE_PAGE_SIZE); + if (offset + count > next_page_start) + count = next_page_start - offset; + + switch (optoe->use_smbus) { + case I2C_SMBUS_I2C_BLOCK_DATA: + /*smaller eeproms can work given some SMBus extension calls */ + if (count > I2C_SMBUS_BLOCK_MAX) + count = I2C_SMBUS_BLOCK_MAX; + break; + case I2C_SMBUS_WORD_DATA: + /* Check for odd length transaction */ + count = (count == 1) ? 1 : 2; + break; + case I2C_SMBUS_BYTE_DATA: + count = 1; + break; + default: + /* If we'll use I2C calls for I/O, set up the message */ + msg.addr = client->addr; + msg.flags = 0; + + /* msg.buf is u8 and casts will mask the values */ + msg.buf = optoe->writebuf; + + msg.buf[i++] = offset; + memcpy(&msg.buf[i], buf, count); + msg.len = i + count; + break; + } + + /* + * Reads fail if the previous write didn't complete yet. We may + * loop a few times until this one succeeds, waiting at least + * long enough for one entire page write to work. + */ + timeout = jiffies + msecs_to_jiffies(write_timeout); + do { + write_time = jiffies; + + switch (optoe->use_smbus) { + case I2C_SMBUS_I2C_BLOCK_DATA: + status = i2c_smbus_write_i2c_block_data(client, + offset, count, buf); + if (status == 0) + status = count; + break; + case I2C_SMBUS_WORD_DATA: + if (count == 2) { + status = i2c_smbus_write_word_data(client, + offset, (u16)((buf[0])|(buf[1] << 8))); + } else { + /* count = 1 */ + status = i2c_smbus_write_byte_data(client, + offset, buf[0]); + } + if (status == 0) + status = count; + break; + case I2C_SMBUS_BYTE_DATA: + status = i2c_smbus_write_byte_data(client, offset, + buf[0]); + if (status == 0) + status = count; + break; + default: + status = i2c_transfer(client->adapter, &msg, 1); + if (status == 1) + status = count; + break; + } + + dev_dbg(&client->dev, "eeprom write %zu@%d --> %ld (%lu)\n", + count, offset, (long int) status, jiffies); + + if (status == count) + return count; + + /* REVISIT: at HZ=100, this is sloooow */ + msleep(1); + } while (time_before(write_time, timeout)); + + return -ETIMEDOUT; +} + + +static ssize_t optoe_eeprom_update_client(struct optoe_data *optoe, + char *buf, loff_t off, + size_t count, optoe_opcode_e opcode) +{ + struct i2c_client *client; + ssize_t retval = 0; + uint8_t page = 0; + loff_t phy_offset = off; + int ret = 0; + + page = optoe_translate_offset(optoe, &phy_offset, &client); + dev_dbg(&client->dev, + "optoe_eeprom_update_client off %lld page:%d phy_offset:%lld, count:%ld, opcode:%d\n", + off, page, phy_offset, (long int) count, opcode); + if (page > 0) { + ret = optoe_eeprom_write(optoe, client, &page, + OPTOE_PAGE_SELECT_REG, 1); + if (ret < 0) { + dev_dbg(&client->dev, + "Write page register for page %d failed ret:%d!\n", + page, ret); + return ret; + } + } + + while (count) { + ssize_t status; + + if (opcode == OPTOE_READ_OP) { + status = optoe_eeprom_read(optoe, client, + buf, phy_offset, count); + } else { + status = optoe_eeprom_write(optoe, client, + buf, phy_offset, count); + } + if (status <= 0) { + if (retval == 0) + retval = status; + break; + } + buf += status; + phy_offset += status; + count -= status; + retval += status; + } + + + if (page > 0) { + /* return the page register to page 0 (why?) */ + page = 0; + ret = optoe_eeprom_write(optoe, client, &page, + OPTOE_PAGE_SELECT_REG, 1); + if (ret < 0) { + dev_err(&client->dev, + "Restore page register to 0 failed:%d!\n", ret); + /* error only if nothing has been transferred */ + if (retval == 0) retval = ret; + } + } + return retval; +} + +/* + * Figure out if this access is within the range of supported pages. + * Note this is called on every access because we don't know if the + * module has been replaced since the last call. + * If/when modules support more pages, this is the routine to update + * to validate and allow access to additional pages. + * + * Returns updated len for this access: + * - entire access is legal, original len is returned. + * - access begins legal but is too long, len is truncated to fit. + * - initial offset exceeds supported pages, return -EINVAL + */ +static ssize_t optoe_page_legal(struct optoe_data *optoe, + loff_t off, size_t len) +{ + struct i2c_client *client = optoe->client[0]; + u8 regval; + int status; + size_t maxlen; + + if (off < 0) return -EINVAL; + if (optoe->dev_class == TWO_ADDR) { + /* SFP case */ + /* if no pages needed, we're good */ + if ((off + len) <= TWO_ADDR_EEPROM_UNPAGED_SIZE) return len; + /* if offset exceeds possible pages, we're not good */ + if (off >= TWO_ADDR_EEPROM_SIZE) return -EINVAL; + /* in between, are pages supported? */ + status = optoe_eeprom_read(optoe, client, ®val, + TWO_ADDR_PAGEABLE_REG, 1); + if (status < 0) return status; /* error out (no module?) */ + if (regval & TWO_ADDR_PAGEABLE) { + /* Pages supported, trim len to the end of pages */ + maxlen = TWO_ADDR_EEPROM_SIZE - off; + } else { + /* pages not supported, trim len to unpaged size */ + if (off >= TWO_ADDR_EEPROM_UNPAGED_SIZE) return -EINVAL; + maxlen = TWO_ADDR_EEPROM_UNPAGED_SIZE - off; + } + len = (len > maxlen) ? maxlen : len; + dev_dbg(&client->dev, + "page_legal, SFP, off %lld len %ld\n", + off, (long int) len); + } else { + /* QSFP case */ + /* if no pages needed, we're good */ + if ((off + len) <= ONE_ADDR_EEPROM_UNPAGED_SIZE) return len; + /* if offset exceeds possible pages, we're not good */ + if (off >= ONE_ADDR_EEPROM_SIZE) return -EINVAL; + /* in between, are pages supported? */ + status = optoe_eeprom_read(optoe, client, ®val, + ONE_ADDR_PAGEABLE_REG, 1); + if (status < 0) return status; /* error out (no module?) */ + if (regval & ONE_ADDR_NOT_PAGEABLE) { + /* pages not supported, trim len to unpaged size */ + if (off >= ONE_ADDR_EEPROM_UNPAGED_SIZE) return -EINVAL; + maxlen = ONE_ADDR_EEPROM_UNPAGED_SIZE - off; + } else { + /* Pages supported, trim len to the end of pages */ + maxlen = ONE_ADDR_EEPROM_SIZE - off; + } + len = (len > maxlen) ? maxlen : len; + dev_dbg(&client->dev, + "page_legal, QSFP, off %lld len %ld\n", + off, (long int) len); + } + return len; +} + +static ssize_t optoe_read_write(struct optoe_data *optoe, + char *buf, loff_t off, size_t len, optoe_opcode_e opcode) +{ + struct i2c_client *client = optoe->client[0]; + int chunk; + int status = 0; + ssize_t retval; + size_t pending_len = 0, chunk_len = 0; + loff_t chunk_offset = 0, chunk_start_offset = 0; + + dev_dbg(&client->dev, + "optoe_read_write: off %lld len:%ld, opcode:%s\n", + off, (long int) len, (opcode == OPTOE_READ_OP) ? "r": "w"); + if (unlikely(!len)) + return len; + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&optoe->lock); + + /* + * Confirm this access fits within the device suppored addr range + */ + status = optoe_page_legal(optoe, off, len); + if (status < 0) { + goto err; + } + len = status; + + /* + * For each (128 byte) chunk involved in this request, issue a + * separate call to sff_eeprom_update_client(), to + * ensure that each access recalculates the client/page + * and writes the page register as needed. + * Note that chunk to page mapping is confusing, is different for + * QSFP and SFP, and never needs to be done. Don't try! + */ + pending_len = len; /* amount remaining to transfer */ + retval = 0; /* amount transferred */ + for (chunk = off >> 7; chunk <= (off + len - 1) >> 7; chunk++) { + + /* + * Compute the offset and number of bytes to be read/write + * + * 1. start at offset 0 (within the chunk), and read/write + * the entire chunk + * 2. start at offset 0 (within the chunk) and read/write less + * than entire chunk + * 3. start at an offset not equal to 0 and read/write the rest + * of the chunk + * 4. start at an offset not equal to 0 and read/write less than + * (end of chunk - offset) + */ + chunk_start_offset = chunk * OPTOE_PAGE_SIZE; + + if (chunk_start_offset < off) { + chunk_offset = off; + if ((off + pending_len) < (chunk_start_offset + + OPTOE_PAGE_SIZE)) + chunk_len = pending_len; + else + chunk_len = OPTOE_PAGE_SIZE - off; + } else { + chunk_offset = chunk_start_offset; + if (pending_len > OPTOE_PAGE_SIZE) + chunk_len = OPTOE_PAGE_SIZE; + else + chunk_len = pending_len; + } + + dev_dbg(&client->dev, + "sff_r/w: off %lld, len %ld, chunk_start_offset %lld, chunk_offset %lld, chunk_len %ld, pending_len %ld\n", + off, (long int) len, chunk_start_offset, chunk_offset, + (long int) chunk_len, (long int) pending_len); + + /* + * note: chunk_offset is from the start of the EEPROM, + * not the start of the chunk + */ + status = optoe_eeprom_update_client(optoe, buf, + chunk_offset, chunk_len, opcode); + if (status != chunk_len) { + /* This is another 'no device present' path */ + dev_dbg(&client->dev, + "optoe_update_client for chunk %d chunk_offset %lld chunk_len %ld failed %d!\n", + chunk, chunk_offset, (long int) chunk_len, status); + goto err; + } + buf += status; + pending_len -= status; + retval += status; + } + mutex_unlock(&optoe->lock); + + return retval; + +err: + mutex_unlock(&optoe->lock); + + return status; +} + +static ssize_t optoe_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = to_i2c_client(container_of(kobj, + struct device, kobj)); + struct optoe_data *optoe = i2c_get_clientdata(client); + + return optoe_read_write(optoe, buf, off, count, OPTOE_READ_OP); +} + + +static ssize_t optoe_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = to_i2c_client(container_of(kobj, + struct device, kobj)); + struct optoe_data *optoe = i2c_get_clientdata(client); + + return optoe_read_write(optoe, buf, off, count, OPTOE_WRITE_OP); +} +/*-------------------------------------------------------------------------*/ + +/* + * This lets other kernel code access the eeprom data. For example, it + * might hold a board's Ethernet address, or board-specific calibration + * data generated on the manufacturing floor. + */ + +static ssize_t optoe_macc_read(struct memory_accessor *macc, + char *buf, off_t offset, size_t count) +{ + struct optoe_data *optoe = container_of(macc, + struct optoe_data, macc); + + return optoe_read_write(optoe, buf, offset, count, OPTOE_READ_OP); +} + +static ssize_t optoe_macc_write(struct memory_accessor *macc, + const char *buf, off_t offset, size_t count) +{ + struct optoe_data *optoe = container_of(macc, + struct optoe_data, macc); + + return optoe_read_write(optoe, (char *) buf, offset, + count, OPTOE_WRITE_OP); +} + +/*-------------------------------------------------------------------------*/ + +static int optoe_remove(struct i2c_client *client) +{ + struct optoe_data *optoe; + int i; + + optoe = i2c_get_clientdata(client); + sysfs_remove_group(&client->dev.kobj, &optoe->attr_group); + sysfs_remove_bin_file(&client->dev.kobj, &optoe->bin); + + for (i = 1; i < optoe->num_addresses; i++) + i2c_unregister_device(optoe->client[i]); + +#ifdef EEPROM_CLASS + eeprom_device_unregister(optoe->eeprom_dev); +#endif + + kfree(optoe->writebuf); + kfree(optoe); + return 0; +} + +static ssize_t show_port_name(struct device *dev, + struct device_attribute *dattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct optoe_data *optoe = i2c_get_clientdata(client); + ssize_t count; + + mutex_lock(&optoe->lock); + count = sprintf(buf, "%s\n", optoe->port_name); + mutex_unlock(&optoe->lock); + + return count; +} + +static ssize_t set_port_name(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct optoe_data *optoe = i2c_get_clientdata(client); + char port_name[MAX_PORT_NAME_LEN]; + + /* no checking, this value is not used except by show_port_name */ + + if (sscanf(buf, "%19s", port_name) != 1) + return -EINVAL; + + mutex_lock(&optoe->lock); + strcpy(optoe->port_name, port_name); + mutex_unlock(&optoe->lock); + + return count; +} + +static DEVICE_ATTR(port_name, S_IRUGO | S_IWUSR, + show_port_name, set_port_name); + +static ssize_t show_dev_class(struct device *dev, + struct device_attribute *dattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct optoe_data *optoe = i2c_get_clientdata(client); + ssize_t count; + + mutex_lock(&optoe->lock); + count = sprintf(buf, "%d\n", optoe->dev_class); + mutex_unlock(&optoe->lock); + + return count; +} + +static ssize_t set_dev_class(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct optoe_data *optoe = i2c_get_clientdata(client); + int dev_class; + + /* + * dev_class is actually the number of sfp ports used, thus + * legal values are "1" (QSFP class) and "2" (SFP class) + */ + if (sscanf(buf, "%d", &dev_class) != 1 || + dev_class < 1 || dev_class > 2) + return -EINVAL; + + mutex_lock(&optoe->lock); + optoe->dev_class = dev_class; + mutex_unlock(&optoe->lock); + + return count; +} + +static DEVICE_ATTR(dev_class, S_IRUGO | S_IWUSR, + show_dev_class, set_dev_class); + +static struct attribute *optoe_attrs[] = { + &dev_attr_port_name.attr, + &dev_attr_dev_class.attr, + NULL, +}; + +static struct attribute_group optoe_attr_group = { + .attrs = optoe_attrs, +}; + +static int optoe_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int err; + int use_smbus = 0; + struct optoe_platform_data chip; + struct optoe_data *optoe; + int num_addresses = 0; + int i = 0; + + if (client->addr != 0x50) { + dev_dbg(&client->dev, "probe, bad i2c addr: 0x%x\n", + client->addr); + err = -EINVAL; + goto exit; + } + + if (client->dev.platform_data) { + chip = *(struct optoe_platform_data *)client->dev.platform_data; + dev_dbg(&client->dev, "probe, chip provided, flags:0x%x; name: %s\n", chip.flags, client->name); + } else { + if (!id->driver_data) { + err = -ENODEV; + goto exit; + } + dev_dbg(&client->dev, "probe, building chip\n"); + chip.flags = 0; + chip.setup = NULL; + chip.context = NULL; +#ifdef EEPROM_CLASS + chip.eeprom_data = NULL; +#endif + } + + /* Use I2C operations unless we're stuck with SMBus extensions. */ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { + use_smbus = I2C_SMBUS_I2C_BLOCK_DATA; + } else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_WORD_DATA)) { + use_smbus = I2C_SMBUS_WORD_DATA; + } else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_BYTE_DATA)) { + use_smbus = I2C_SMBUS_BYTE_DATA; + } else { + err = -EPFNOSUPPORT; + goto exit; + } + } + + + /* + * Make room for two i2c clients + */ + num_addresses = 2; + + optoe = kzalloc(sizeof(struct optoe_data) + + num_addresses * sizeof(struct i2c_client *), + GFP_KERNEL); + if (!optoe) { + err = -ENOMEM; + goto exit; + } + + mutex_init(&optoe->lock); + + /* determine whether this is a one-address or two-address module */ + if ((strcmp(client->name, "optoe1") == 0) || + (strcmp(client->name, "sff8436") == 0)) { + /* one-address (eg QSFP) family */ + optoe->dev_class = ONE_ADDR; + chip.byte_len = ONE_ADDR_EEPROM_SIZE; + num_addresses = 1; + } else if ((strcmp(client->name, "optoe2") == 0) || + (strcmp(client->name, "24c04") == 0)) { + /* SFP family */ + optoe->dev_class = TWO_ADDR; + chip.byte_len = TWO_ADDR_EEPROM_SIZE; + } else { /* those were the only two choices */ + err = -EINVAL; + goto exit; + } + + dev_dbg(&client->dev, "dev_class: %d\n", optoe->dev_class); + optoe->use_smbus = use_smbus; + optoe->chip = chip; + optoe->num_addresses = num_addresses; + strcpy(optoe->port_name, "unitialized"); + + /* + * Export the EEPROM bytes through sysfs, since that's convenient. + * By default, only root should see the data (maybe passwords etc) + */ + sysfs_bin_attr_init(&optoe->bin); + optoe->bin.attr.name = "eeprom"; + optoe->bin.attr.mode = S_IRUGO; + optoe->bin.read = optoe_bin_read; + optoe->bin.size = chip.byte_len; + + optoe->macc.read = optoe_macc_read; + + if (!use_smbus || + (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) || + i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_WORD_DATA) || + i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { + /* + * NOTE: AN-2079 + * Finisar recommends that the host implement 1 byte writes + * only since this module only supports 32 byte page boundaries. + * 2 byte writes are acceptable for PE and Vout changes per + * Application Note AN-2071. + */ + unsigned write_max = 1; + + optoe->macc.write = optoe_macc_write; + + optoe->bin.write = optoe_bin_write; + optoe->bin.attr.mode |= S_IWUSR; + + if (write_max > io_limit) + write_max = io_limit; + if (use_smbus && write_max > I2C_SMBUS_BLOCK_MAX) + write_max = I2C_SMBUS_BLOCK_MAX; + optoe->write_max = write_max; + + /* buffer (data + address at the beginning) */ + optoe->writebuf = kmalloc(write_max + 2, GFP_KERNEL); + if (!optoe->writebuf) { + err = -ENOMEM; + goto exit_kfree; + } + } else { + dev_warn(&client->dev, + "cannot write due to controller restrictions."); + } + + optoe->client[0] = client; + + /* use a dummy I2C device for two-address chips */ + for (i = 1; i < num_addresses; i++) { + optoe->client[i] = i2c_new_dummy(client->adapter, + client->addr + i); + if (!optoe->client[i]) { + dev_err(&client->dev, "address 0x%02x unavailable\n", + client->addr + i); + err = -EADDRINUSE; + goto err_struct; + } + } + + /* create the sysfs eeprom file */ + err = sysfs_create_bin_file(&client->dev.kobj, &optoe->bin); + if (err) + goto err_struct; + + optoe->attr_group = optoe_attr_group; + + err = sysfs_create_group(&client->dev.kobj, &optoe->attr_group); + if (err) { + dev_err(&client->dev, "failed to create sysfs attribute group.\n"); + goto err_struct; + } +#ifdef EEPROM_CLASS + optoe->eeprom_dev = eeprom_device_register(&client->dev, + chip.eeprom_data); + if (IS_ERR(optoe->eeprom_dev)) { + dev_err(&client->dev, "error registering eeprom device.\n"); + err = PTR_ERR(optoe->eeprom_dev); + goto err_sysfs_cleanup; + } +#endif + + i2c_set_clientdata(client, optoe); + + dev_info(&client->dev, "%zu byte %s EEPROM, %s\n", + optoe->bin.size, client->name, + optoe->bin.write ? "read/write" : "read-only"); + + if (use_smbus == I2C_SMBUS_WORD_DATA || + use_smbus == I2C_SMBUS_BYTE_DATA) { + dev_notice(&client->dev, "Falling back to %s reads, " + "performance will suffer\n", use_smbus == + I2C_SMBUS_WORD_DATA ? "word" : "byte"); + } + + if (chip.setup) + chip.setup(&optoe->macc, chip.context); + + return 0; + +#ifdef EEPROM_CLASS +err_sysfs_cleanup: + sysfs_remove_group(&client->dev.kobj, &optoe->attr_group); + sysfs_remove_bin_file(&client->dev.kobj, &optoe->bin); +#endif + +err_struct: + for (i = 1; i < num_addresses; i++) { + if (optoe->client[i]) + i2c_unregister_device(optoe->client[i]); + } + + kfree(optoe->writebuf); +exit_kfree: + kfree(optoe); +exit: + dev_dbg(&client->dev, "probe error %d\n", err); + + return err; +} + +/*-------------------------------------------------------------------------*/ + +static struct i2c_driver optoe_driver = { + .driver = { + .name = "optoe", + .owner = THIS_MODULE, + }, + .probe = optoe_probe, + .remove = optoe_remove, + .id_table = optoe_ids, +}; + +static int __init optoe_init(void) +{ + + if (!io_limit) { + pr_err("optoe: io_limit must not be 0!\n"); + return -EINVAL; + } + + io_limit = rounddown_pow_of_two(io_limit); + return i2c_add_driver(&optoe_driver); +} +module_init(optoe_init); + +static void __exit optoe_exit(void) +{ + i2c_del_driver(&optoe_driver); +} +module_exit(optoe_exit); + +MODULE_DESCRIPTION("Driver for optical transceiver (SFP, QSFP, ...) EEPROMs"); +MODULE_AUTHOR("DON BOLLINGER "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/ym2651y.c b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/ym2651y.c new file mode 100755 index 000000000000..8e76c56b54fc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/ym2651y.c @@ -0,0 +1,603 @@ +/* + * An hwmon driver for the 3Y Power YM-2651Y Power Module + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_FAN_DUTY_CYCLE 100 + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { 0x58, 0x5b, I2C_CLIENT_END }; + +/* Each client has this additional data + */ +struct ym2651y_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 capability; /* Register value */ + u16 status_word; /* Register value */ + u8 fan_fault; /* Register value */ + u8 over_temp; /* Register value */ + u16 v_out; /* Register value */ + u16 i_out; /* Register value */ + u16 p_out; /* Register value */ + u16 temp; /* Register value */ + u16 fan_speed; /* Register value */ + u16 fan_duty_cycle[2]; /* Register value */ + u8 fan_dir[4]; /* Register value */ + u8 pmbus_revision; /* Register value */ + u8 mfr_id[10]; /* Register value */ + u8 mfr_model[10]; /* Register value */ + u8 mfr_revsion[3]; /* Register value */ + u16 mfr_vin_min; /* Register value */ + u16 mfr_vin_max; /* Register value */ + u16 mfr_iin_max; /* Register value */ + u16 mfr_iout_max; /* Register value */ + u16 mfr_pin_max; /* Register value */ + u16 mfr_pout_max; /* Register value */ + u16 mfr_vout_min; /* Register value */ + u16 mfr_vout_max; /* Register value */ +}; + +static ssize_t show_byte(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_word(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_linear(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_over_temp(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_ascii(struct device *dev, struct device_attribute *da, + char *buf); +static struct ym2651y_data *ym2651y_update_device(struct device *dev); +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value); + +enum ym2651y_sysfs_attributes { + PSU_POWER_ON = 0, + PSU_TEMP_FAULT, + PSU_POWER_GOOD, + PSU_FAN1_FAULT, + PSU_FAN_DIRECTION, + PSU_OVER_TEMP, + PSU_V_OUT, + PSU_I_OUT, + PSU_P_OUT, + PSU_P_OUT_UV, /*In Unit of microVolt, instead of mini.*/ + PSU_TEMP1_INPUT, + PSU_FAN1_SPEED, + PSU_FAN1_DUTY_CYCLE, + PSU_PMBUS_REVISION, + PSU_MFR_ID, + PSU_MFR_MODEL, + PSU_MFR_REVISION, + PSU_MFR_VIN_MIN, + PSU_MFR_VIN_MAX, + PSU_MFR_VOUT_MIN, + PSU_MFR_VOUT_MAX, + PSU_MFR_IIN_MAX, + PSU_MFR_IOUT_MAX, + PSU_MFR_PIN_MAX, + PSU_MFR_POUT_MAX +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(psu_power_on, S_IRUGO, show_word, NULL, PSU_POWER_ON); +static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, show_word, NULL, PSU_TEMP_FAULT); +static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_word, NULL, PSU_POWER_GOOD); +static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, show_fan_fault, NULL, PSU_FAN1_FAULT); +static SENSOR_DEVICE_ATTR(psu_over_temp, S_IRUGO, show_over_temp, NULL, PSU_OVER_TEMP); +static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, show_linear, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, show_linear, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, show_linear, NULL, PSU_P_OUT); +static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); +static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, show_linear, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); +static SENSOR_DEVICE_ATTR(psu_fan_dir, S_IRUGO, show_ascii, NULL, PSU_FAN_DIRECTION); +static SENSOR_DEVICE_ATTR(psu_pmbus_revision, S_IRUGO, show_byte, NULL, PSU_PMBUS_REVISION); +static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, show_ascii, NULL, PSU_MFR_ID); +static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, show_ascii, NULL, PSU_MFR_MODEL); +static SENSOR_DEVICE_ATTR(psu_mfr_revision, S_IRUGO, show_ascii, NULL, PSU_MFR_REVISION); +static SENSOR_DEVICE_ATTR(psu_mfr_vin_min, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MIN); +static SENSOR_DEVICE_ATTR(psu_mfr_vin_max, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_vout_min, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MIN); +static SENSOR_DEVICE_ATTR(psu_mfr_vout_max, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_iin_max, S_IRUGO, show_linear, NULL, PSU_MFR_IIN_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_iout_max, S_IRUGO, show_linear, NULL, PSU_MFR_IOUT_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_pin_max, S_IRUGO, show_linear, NULL, PSU_MFR_PIN_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_pout_max, S_IRUGO, show_linear, NULL, PSU_MFR_POUT_MAX); + +/*Duplicate nodes for lm-sensors.*/ +static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, show_linear, NULL, PSU_P_OUT_UV); +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); +static SENSOR_DEVICE_ATTR(temp1_fault, S_IRUGO, show_word, NULL, PSU_TEMP_FAULT); + +static struct attribute *ym2651y_attributes[] = { + &sensor_dev_attr_psu_power_on.dev_attr.attr, + &sensor_dev_attr_psu_temp_fault.dev_attr.attr, + &sensor_dev_attr_psu_power_good.dev_attr.attr, + &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, + &sensor_dev_attr_psu_over_temp.dev_attr.attr, + &sensor_dev_attr_psu_v_out.dev_attr.attr, + &sensor_dev_attr_psu_i_out.dev_attr.attr, + &sensor_dev_attr_psu_p_out.dev_attr.attr, + &sensor_dev_attr_psu_temp1_input.dev_attr.attr, + &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, + &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, + &sensor_dev_attr_psu_fan_dir.dev_attr.attr, + &sensor_dev_attr_psu_pmbus_revision.dev_attr.attr, + &sensor_dev_attr_psu_mfr_id.dev_attr.attr, + &sensor_dev_attr_psu_mfr_model.dev_attr.attr, + &sensor_dev_attr_psu_mfr_revision.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vin_min.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vin_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_pout_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_iin_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_pin_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vout_min.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vout_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_iout_max.dev_attr.attr, + /*Duplicate nodes for lm-sensors.*/ + &sensor_dev_attr_power1_input.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_temp1_fault.dev_attr.attr, + NULL +}; + +static ssize_t show_byte(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + + return (attr->index == PSU_PMBUS_REVISION) ? sprintf(buf, "%d\n", data->pmbus_revision) : + sprintf(buf, "0\n"); +} + +static ssize_t show_word(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + u16 status = 0; + + switch (attr->index) { + case PSU_POWER_ON: /* psu_power_on, low byte bit 6 of status_word, 0=>ON, 1=>OFF */ + status = (data->status_word & 0x40) ? 0 : 1; + break; + case PSU_TEMP_FAULT: /* psu_temp_fault, low byte bit 2 of status_word, 0=>Normal, 1=>temp fault */ + status = (data->status_word & 0x4) >> 2; + break; + case PSU_POWER_GOOD: /* psu_power_good, high byte bit 3 of status_word, 0=>OK, 1=>FAIL */ + status = (data->status_word & 0x800) ? 0 : 1; + break; + } + + return sprintf(buf, "%d\n", status); +} + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + bool is_negative = valid_data >> (valid_bit - 1); + + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} + +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct ym2651y_data *data = i2c_get_clientdata(client); + int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; + long speed; + int error; + + error = kstrtol(buf, 10, &speed); + if (error) + return error; + + if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) + return -EINVAL; + + mutex_lock(&data->update_lock); + data->fan_duty_cycle[nr] = speed; + ym2651y_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t show_linear(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + + u16 value = 0; + int exponent, mantissa; + int multiplier = 1000; + + switch (attr->index) { + case PSU_V_OUT: + value = data->v_out; + break; + case PSU_I_OUT: + value = data->i_out; + break; + case PSU_P_OUT_UV: + multiplier = 1000000; /*For lm-sensors, unit is micro-Volt.*/ + /*Passing through*/ + case PSU_P_OUT: + value = data->p_out; + break; + case PSU_TEMP1_INPUT: + value = data->temp; + break; + case PSU_FAN1_SPEED: + value = data->fan_speed; + multiplier = 1; + break; + case PSU_FAN1_DUTY_CYCLE: + value = data->fan_duty_cycle[0]; + multiplier = 1; + break; + case PSU_MFR_VIN_MIN: + value = data->mfr_vin_min; + break; + case PSU_MFR_VIN_MAX: + value = data->mfr_vin_max; + break; + case PSU_MFR_VOUT_MIN: + value = data->mfr_vout_min; + break; + case PSU_MFR_VOUT_MAX: + value = data->mfr_vout_max; + break; + case PSU_MFR_PIN_MAX: + value = data->mfr_pin_max; + break; + case PSU_MFR_POUT_MAX: + value = data->mfr_pout_max; + break; + case PSU_MFR_IOUT_MAX: + value = data->mfr_iout_max; + break; + case PSU_MFR_IIN_MAX: + value = data->mfr_iin_max; + break; + } + + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + + u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; + + return sprintf(buf, "%d\n", data->fan_fault >> shift); +} + +static ssize_t show_over_temp(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct ym2651y_data *data = ym2651y_update_device(dev); + + return sprintf(buf, "%d\n", data->over_temp >> 7); +} + +static ssize_t show_ascii(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + u8 *ptr = NULL; + + switch (attr->index) { + case PSU_FAN_DIRECTION: /* psu_fan_dir */ + ptr = data->fan_dir; + break; + case PSU_MFR_ID: /* psu_mfr_id */ + ptr = data->mfr_id; + break; + case PSU_MFR_MODEL: /* psu_mfr_model */ + ptr = data->mfr_model; + break; + case PSU_MFR_REVISION: /* psu_mfr_revision */ + ptr = data->mfr_revsion; + break; + default: + return 0; + } + + return sprintf(buf, "%s\n", ptr); +} + +static const struct attribute_group ym2651y_group = { + .attrs = ym2651y_attributes, +}; + +static int ym2651y_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct ym2651y_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct ym2651y_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &ym2651y_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &ym2651y_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int ym2651y_remove(struct i2c_client *client) +{ + struct ym2651y_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &ym2651y_group); + kfree(data); + + return 0; +} + +static const struct i2c_device_id ym2651y_id[] = { + { "ym2651", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, ym2651y_id); + +static struct i2c_driver ym2651y_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "ym2651", + }, + .probe = ym2651y_probe, + .remove = ym2651y_remove, + .id_table = ym2651y_id, + .address_list = normal_i2c, +}; + +static int ym2651y_read_byte(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int ym2651y_read_word(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_word_data(client, reg); +} + +static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value) +{ + return i2c_smbus_write_word_data(client, reg, value); +} + +static int ym2651y_read_block(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ + int result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + + if (unlikely(result < 0)) + goto abort; + if (unlikely(result != data_len)) { + result = -EIO; + goto abort; + } + + result = 0; + +abort: + return result; +} + +struct reg_data_byte { + u8 reg; + u8 *value; +}; + +struct reg_data_word { + u8 reg; + u16 *value; +}; + +static struct ym2651y_data *ym2651y_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct ym2651y_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int i, status; + u8 command; + u8 fan_dir[5] = {0}; + struct reg_data_byte regs_byte[] = { {0x19, &data->capability}, + {0x7d, &data->over_temp}, + {0x81, &data->fan_fault}, + {0x98, &data->pmbus_revision}}; + struct reg_data_word regs_word[] = { {0x79, &data->status_word}, + {0x8b, &data->v_out}, + {0x8c, &data->i_out}, + {0x96, &data->p_out}, + {0x8d, &data->temp}, + {0x3b, &(data->fan_duty_cycle[0])}, + {0x3c, &(data->fan_duty_cycle[1])}, + {0x90, &data->fan_speed}, + {0xa0, &data->mfr_vin_min}, + {0xa1, &data->mfr_vin_max}, + {0xa2, &data->mfr_iin_max}, + {0xa3, &data->mfr_pin_max}, + {0xa4, &data->mfr_vout_min}, + {0xa5, &data->mfr_vout_max}, + {0xa6, &data->mfr_iout_max}, + {0xa7, &data->mfr_pout_max}}; + + dev_dbg(&client->dev, "Starting ym2651 update\n"); + + /* Read byte data */ + for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { + status = ym2651y_read_byte(client, regs_byte[i].reg); + + if (status < 0) + { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_byte[i].reg, status); + } + else { + *(regs_byte[i].value) = status; + } + } + + /* Read word data */ + for (i = 0; i < ARRAY_SIZE(regs_word); i++) { + status = ym2651y_read_word(client, regs_word[i].reg); + + if (status < 0) + { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_word[i].reg, status); + } + else { + *(regs_word[i].value) = status; + } + } + + /* Read fan_direction */ + command = 0xC3; + status = ym2651y_read_block(client, command, fan_dir, ARRAY_SIZE(fan_dir)-1); + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + } + + strncpy(data->fan_dir, fan_dir+1, ARRAY_SIZE(data->fan_dir)-1); + data->fan_dir[ARRAY_SIZE(data->fan_dir)-1] = '\0'; + + /* Read mfr_id */ + command = 0x99; + status = ym2651y_read_block(client, command, data->mfr_id, + ARRAY_SIZE(data->mfr_id)-1); + data->mfr_id[ARRAY_SIZE(data->mfr_id)-1] = '\0'; + + if (status < 0) + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + + /* Read mfr_model */ + command = 0x9a; + status = ym2651y_read_block(client, command, data->mfr_model, + ARRAY_SIZE(data->mfr_model)-1); + data->mfr_model[ARRAY_SIZE(data->mfr_model)-1] = '\0'; + + if (status < 0) + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + + /* Read mfr_revsion */ + command = 0x9b; + status = ym2651y_read_block(client, command, data->mfr_revsion, + ARRAY_SIZE(data->mfr_revsion)-1); + data->mfr_revsion[ARRAY_SIZE(data->mfr_revsion)-1] = '\0'; + + if (status < 0) + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +module_i2c_driver(ym2651y_driver); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("3Y Power YM-2651Y driver"); +MODULE_LICENSE("GPL"); + + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/service/as7716-platform-monitor.service b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/service/as7716-platform-monitor.service new file mode 100755 index 000000000000..b1428d7844f8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/service/as7716-platform-monitor.service @@ -0,0 +1,17 @@ +[Unit] +Description=Accton AS7716-32X Platform Monitoring service +Before=pmon.service +After=sysinit.target +DefaultDependencies=no + +[Service] +ExecStartPre=/usr/local/bin/accton_as7716_util.py install +ExecStart=/usr/local/bin/accton_as7716_monitor.py +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/setup.py b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/setup.py new file mode 100755 index 000000000000..7a3d784d326e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/setup.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python + +import os +import sys +from setuptools import setup +os.listdir + +setup( + name='as7716_32x', + version='1.0', + description='Module to initialize Accton AS7716-32X platforms', + + packages=['as7716_32x'], + package_dir={'as7716_32x': 'as7716-32x/classes'}, +) + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/README b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/README new file mode 100755 index 000000000000..44e03cab5f52 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/README @@ -0,0 +1,117 @@ +Copyright (C) 2016 Accton Networks, 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 3 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, see . + +Contents of this package: + patch - files under patch/ is for kernel and ONIE installer + for the kernel: + config-accton-as5712_54x.patch + for kernel configuration. + driver-i2c-muxes-pca954x-always-deselect.patch + for i2c_mux deselects after transaction. + driver-patches-for-accton-as5712-fan-psu-cpld.patch + for as5712's fan/psu/cpld/led/sfp drivers. + for ONIE: + onie_installer-accton-AS5712-54X.patch + for console port setting and copy util script o rootfs. + module - Contains source code of as5712 kernel driver modules. + +The late Sonic building scripts, pushed @Dec 5 2016, will automatically +create a docker container and run building process under it. +User is not necessary to handle docker environment creation. + +1. Download sonic-buildimage environment. + - Run "git clone https://github.com/Azure/sonic-buildimage". + - cd to sonic-buildimage and run "git submodule update --init --recursive". +2. Build kernel + - cd ./src/sonic-linux-kernel + - Copy patches and series from patch/kernel of this release to + sonic-linux-kernel/patch. + - Build kernel by "make". + - The built kernel package, linux-image-3.16.0-5-amd64_3.16.51-3+deb8u1_amd64.deb + , is generated. +3. Build installer + - Change directory back to sonic-buildimage/. + - Get onie_installer-accton-AS5712-54X.patch" from patch/installer. + - Change setting for AS5712-54X by patching build_image.sh. + "patch -p1 < onie_installer-accton-AS5712-54X.patch" + !!NOTICE, patching onie_installer-accton-AS5712-54X.patch comments out the + "git status" checking at build_image.sh. + - The account and password of installed OS can be given at rules/config. + The default user and password are "admin" & "YourPaSsWoRd" respectively. + - Run "make configure PLATFORM=broadcom" + - Copy the built kernel debian package to target/debs/. + The file is linux-image-3.16.0-5-amd64_*_amd64.deb under directory + src/sonic-linux-kernel/. + - Run "make target/sonic-generic.bin" + - Get the installer, target/sonic-generic.bin, to target machine and install. + +All Linux kernel code is licensed under the GPLv1. All other code is +licensed under the GPLv3. Please see the LICENSE file for copies of +both licenses. + +The code for integacting with Accton AS5712-54X has 2 parts, +kernel drivers and operational script. +The kernel drivers of peripherals are under module/ directory. +1. These drivers are patched into kernel by + driver-patches-for-accton-as5712-fan-psu-cpld.patch + Or you can build the driver under module/ by setting environment variable, + KERNEL_SRC, to proper linux built directory and run make. + It may be sonic-linux-kernel/linux-3.*/debian/build/build_amd64_none_amd64/. +2. A operational script, accton_as5712_util.py, for device initializatian and + peripheral accessing should be installed at /usr/bin. + This script is generated by onie_installer-accton-AS5712-54X.patch. + It's done by patching onie_installer-accton-AS5712-54X.patch at build-image. + Run "accton_as5712_util.py install" to install drivers. + +To initialize the system, run "accton_as5712_util.py install". +To clean up the drivers & devices, run "accton_as5712_util.py clean". +To dump information of sensors, run "accton_as5712_util.py show". +To dump SFP EEPROM, run "accton_as5712_util.py sff". +To set fan speed, run "accton_as5712_util.py set fan". +To enable/disable SFP emission, run "accton_as5712_util.py set sfp". +To set system LEDs' color, run "accton_as5712_util.py set led" +For more information, run "accton_as5712_util.py --help". + +==================================================================== +Besides applying accton_as5712_util.py to access peripherals, you can +access peripherals by sysfs nodes directly after the installation is run. + +System LED: + There are 5 system LEDs at the lower-left corner of front panel. + They are loc, diag, fan, ps1, and ps2. + The sysfs interface color mappings are as follows: + Brightness: + 0 => off + 1 => green + 2 => amber + 3 => red + 4 => blue + But not all colors are available for each LED. + +Fan Control: + There are 10 fans inside 5 fan modules. + All fans share 1 duty setting, ranged from 0~100. + +Thermal sensers: + 3 temperature sensors are controlled by the lm75 kernel modules. + +PSUs: + There 2 power supplies slot at the left/right side of the back. + Once if a PSU is not plugged, the status of it is shown failed. + +There are 48 SFP+ and 6 QSFP modules are equipped. +Before operating on PSU and QSFP+, please make sure it is well plugged. +Otherwise, operation is going to fail. + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/accton_as7716_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/accton_as7716_monitor.py new file mode 100755 index 000000000000..63f26d5d2ef6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/accton_as7716_monitor.py @@ -0,0 +1,207 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 Accton Technology Corporation +# +# 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 3 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, see . + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 11/13/2017: Polly Hsu, Create +# 1/10/2018: Jostar modify for as7716_32 +# ------------------------------------------------------------------ + +try: + import os + import sys, getopt + import subprocess + import click + import imp + import logging + import logging.config + import types + import time # this is only being used as part of the example + import traceback + from tabulate import tabulate + from as7716_32x.fanutil import FanUtil + from as7716_32x.thermalutil import ThermalUtil +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + +# Deafults +VERSION = '1.0' +FUNCTION_NAME = 'accton_as7716_monitor' + +global log_file +global log_level + + # For AC power Front to Back : + # If any fan fail, please fan speed register to 15 + # The max value of Fan speed register is 9 + # [LM75(48) + LM75(49) + LM75(4A)] > 174 => set Fan speed value from 4 to 5 + # [LM75(48) + LM75(49) + LM75(4A)] > 182 => set Fan speed value from 5 to 7 + # [LM75(48) + LM75(49) + LM75(4A)] > 190 => set Fan speed value from 7 to 9 + # + # [LM75(48) + LM75(49) + LM75(4A)] < 170 => set Fan speed value from 5 to 4 + # [LM75(48) + LM75(49) + LM75(4A)] < 178 => set Fan speed value from 7 to 5 + # [LM75(48) + LM75(49) + LM75(4A)] < 186 => set Fan speed value from 9 to 7 + # + # + # For AC power Back to Front : + # If any fan fail, please fan speed register to 15 + # The max value of Fan speed register is 10 + # [LM75(48) + LM75(49) + LM75(4A)] > 140 => set Fan speed value from 4 to 5 + # [LM75(48) + LM75(49) + LM75(4A)] > 150 => set Fan speed value from 5 to 7 + # [LM75(48) + LM75(49) + LM75(4A)] > 160 => set Fan speed value from 7 to 10 + # + # [LM75(48) + LM75(49) + LM75(4A)] < 135 => set Fan speed value from 5 to 4 + # [LM75(48) + LM75(49) + LM75(4A)] < 145 => set Fan speed value from 7 to 5 + # [LM75(48) + LM75(49) + LM75(4A)] < 155 => set Fan speed value from 10 to 7 + # + + + # 2.If no matched fan speed is found from the policy, + # use FAN_DUTY_CYCLE_MIN as default speed + # Get current temperature + # 4.Decision 3: Decide new fan speed depend on fan direction/current fan speed/temperature + + + + +# Make a class we can use to capture stdout and sterr in the log +class accton_as7716_monitor(object): + # static temp var + _ori_temp = 0 + _new_perc = 0 + _ori_perc = 0 + + def __init__(self, log_file, log_level): + """Needs a logger and a logger level.""" + # set up logging to file + logging.basicConfig( + filename=log_file, + filemode='w', + level=log_level, + format= '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s', + datefmt='%H:%M:%S' + ) + + # set up logging to console + if log_level == logging.DEBUG: + console = logging.StreamHandler() + console.setLevel(log_level) + formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') + console.setFormatter(formatter) + logging.getLogger('').addHandler(console) + + logging.debug('SET. logfile:%s / loglevel:%d', log_file, log_level) + + def manage_fans(self): + + fan_policy_f2b = { + 0: [32, 0, 174000], + 1: [38, 170000, 182000], + 2: [50, 178000, 190000], + 3: [63, 186000, 0], + } + fan_policy_b2f = { + 0: [32, 0, 140000], + 1: [38, 135000, 150000], + 2: [50, 145000, 160000], + 3: [69, 15500, 0], + } + + thermal = ThermalUtil() + fan = FanUtil() + get_temp = thermal.get_thermal_temp() + + cur_duty_cycle = fan.get_fan_duty_cycle() + + for x in range(fan.get_idx_fan_start(), fan.get_num_fans()+1): + fan_status = fan.get_fan_status(x) + if fan_status is None: + logging.debug('INFO. SET new_perc to %d (FAN stauts is None. fan_num:%d)', 100, x) + return False + if fan_status is False: + logging.debug('INFO. SET new_perc to %d (FAN fault. fan_num:%d)', 100, x) + fan.set_fan_duty_cycle(45) + return True + logging.debug('INFO. fan_status is True (fan_num:%d)', x) + + if fan_status is not None and fan_status is not False: + fan_dir=fan.get_fan_dir(1) + for x in range(0, 4): + if cur_duty_cycle == fan_policy_f2b[x][0]: + break + + if fan_dir == 1: + if x == 4 : + fan.set_fan_duty_cycle(fan_policy_f2b[0][0]) + new_duty_cycle=cur_duty_cycle + # if temp > up_levle, else if temp < down_level + if get_temp > fan_policy_f2b[x][2] and x != 3 : + new_duty_cycle= fan_policy_f2b[x+1][0] + logging.debug('INFO. THERMAL temp UP, temp %d > %d , new_duty_cycle=%d', get_temp, fan_policy_f2b[x][2], new_duty_cycle) + elif get_temp < fan_policy_f2b[x][1] : + new_duty_cycle= fan_policy_f2b[x-1][0] + logging.debug('INFO. THERMAL temp down, temp %d < %d , new_duty_cycle=%d', get_temp, fan_policy_f2b[x][1], new_duty_cycle) + if new_duty_cycle == cur_duty_cycle : + return True + else: + if x == 4 : + fan.set_fan_duty_cycle(fan_policy_b2f[0][0]) + new_duty_cycle=cur_duty_cycle + # if temp > up_levle, else if temp < down_level + if get_temp > fan_policy_b2f[x][1] and x != 3 : + new_duty_cycle= fan_policy_b2f[x+1][0] + logging.debug('INFO. THERMAL temp UP, temp %d > %d , new_duty_cycle=%d', get_temp, fan_policy_b2f[x][2], new_duty_cycle) + elif get_temp < fan_policy_b2f[x][0] and x != 0 : + new_duty_cycle= fan_policy_b2f[x-1][0] + logging.debug('INFO. THERMAL temp down, temp %d < %d , new_duty_cycle=%d', get_temp, fan_policy_b2f[x][1], new_duty_cycle) + if new_duty_cycle == cur_duty_cycle : + return True + + fan.set_fan_duty_cycle(new_duty_cycle) + + return True + + + +def main(argv): + log_file = '%s.log' % FUNCTION_NAME + log_level = logging.INFO + if len(sys.argv) != 1: + try: + opts, args = getopt.getopt(argv,'hdl:',['lfile=']) + except getopt.GetoptError: + print 'Usage: %s [-d] [-l ]' % sys.argv[0] + return 0 + for opt, arg in opts: + if opt == '-h': + print 'Usage: %s [-d] [-l ]' % sys.argv[0] + return 0 + elif opt in ('-d', '--debug'): + log_level = logging.DEBUG + elif opt in ('-l', '--lfile'): + log_file = arg + + monitor = accton_as7716_monitor(log_file, log_level) + + # Loop forever, doing something useful hopefully: + while True: + monitor.manage_fans() + time.sleep(1) + +if __name__ == '__main__': + main(sys.argv[1:]) diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/accton_as7716_util.py b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/accton_as7716_util.py new file mode 100755 index 000000000000..cd35b50d200e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/accton_as7716_util.py @@ -0,0 +1,595 @@ +#!/usr/bin/env python +# +# Copyright (C) 2016 Accton Networks, 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 3 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, see . + +""" +Usage: %(scriptName)s [options] command object + +options: + -h | --help : this help message + -d | --debug : run with debug mode + -f | --force : ignore error during installation or clean +command: + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes + show : show all systen status + sff : dump SFP eeprom + set : change board setting with fan|led|sfp +""" + +import os +import commands +import sys, getopt +import logging +import re +import time +from collections import namedtuple + +PROJECT_NAME = 'as7716_32x' +version = '0.0.1' +verbose = False +DEBUG = False +args = [] +ALL_DEVICE = {} +DEVICE_NO = {'led':5, 'fan1':1, 'fan2':1,'fan3':1,'fan4':1,'fan5':1,'thermal':3, 'psu':2, 'sfp':54} + + +led_prefix ='/sys/devices/platform/as7716_32x_led/leds/accton_'+PROJECT_NAME+'_led::' +fan_prefix ='/sys/devices/platform/as7716_32x_' +hwmon_types = {'led': ['diag','fan','loc','psu1','psu2'], + 'fan1': ['fan'], + 'fan2': ['fan'], + 'fan3': ['fan'], + 'fan4': ['fan'], + 'fan5': ['fan'], + 'fan5': ['fan'], + } +hwmon_nodes = {'led': ['brightness'] , + 'fan1': ['fan_duty_cycle_percentage', 'fan1_fault', 'fan1_speed_rpm', 'fan1_direction', 'fanr1_fault', 'fanr1_speed_rpm'], + 'fan2': ['fan_duty_cycle_percentage','fan2_fault', 'fan2_speed_rpm', 'fan2_direction', 'fanr2_fault', 'fanr2_speed_rpm'], + 'fan3': ['fan_duty_cycle_percentage','fan3_fault', 'fan3_speed_rpm', 'fan3_direction', 'fanr3_fault', 'fanr3_speed_rpm'], + 'fan4': ['fan4_duty_cycle_percentage','fan4_fault', 'fan4_speed_rpm', 'fan4_direction', 'fanr4_fault', 'fanr4_speed_rpm'], + 'fan5': ['fan_duty_cycle_percentage','fan5_fault', 'fan5_speed_rpm', 'fan5_direction', 'fanr5_fault', 'fanr5_speed_rpm'], + } +hwmon_prefix ={'led': led_prefix, + 'fan1': fan_prefix, + 'fan2': fan_prefix, + 'fan3': fan_prefix, + 'fan4': fan_prefix, + 'fan5': fan_prefix, + } + +i2c_prefix = '/sys/bus/i2c/devices/' +i2c_bus = {'thermal': ['10-0048','10-0049', '10-004a'] , + 'psu': ['17-0050','18-0053'], + 'sfp': ['-0050']} +i2c_nodes = { + 'thermal': ['hwmon/hwmon*/temp1_input'] , + 'psu': ['psu_present ', 'psu_power_good'] , + 'sfp': ['sfp_is_present ', 'sfp_tx_disable']} + +sfp_map = [29, 30, 31, 32, 34, 33, 36, 35, + 25, 26, 27, 28, 37, 38, 39, 40, + 41, 42, 43, 44, 53, 54, 55, 56, + 45, 46, 47, 48, 49, 50, 51, 52] + +mknod =[ +'echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo as7716_32x_fan 0x66 > /sys/bus/i2c/devices/i2c-9/new_device', + +'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-10/new_device', +'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-10/new_device', +'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-10/new_device', + +'echo as7716_32x_cpld1 0x60 > /sys/bus/i2c/devices/i2c-11/new_device', +'echo accton_i2c_cpld 0x62 > /sys/bus/i2c/devices/i2c-12/new_device', +'echo accton_i2c_cpld 0x64 > /sys/bus/i2c/devices/i2c-13/new_device', + +'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-2/new_device', +'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-2/new_device', +'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-2/new_device', +'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-2/new_device', +'echo pca9548 0x75 > /sys/bus/i2c/devices/i2c-2/new_device', + +# PSU-1 +'echo as7716_32x_psu1 0x53 > /sys/bus/i2c/devices/i2c-18/new_device', +'echo ym2651 0x5b > /sys/bus/i2c/devices/i2c-18/new_device', + +# PSU-2 +'echo as7716_32x_psu2 0x50> /sys/bus/i2c/devices/i2c-17/new_device', +'echo ym2651 0x58 > /sys/bus/i2c/devices/i2c-17/new_device', + + + +#EERPOM +'echo 24c02 0x56 > /sys/bus/i2c/devices/i2c-1/new_device', +] + +mknod2 =[ +'echo as7716_32x_cpld1 0x60 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo accton_i2c_cpld 0x61 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo accton_i2c_cpld 0x62 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-0/new_device', + +# PSU-1 +'echo as7716_32x_psu1 0x38 > /sys/bus/i2c/devices/i2c-57/new_device', +'echo cpr_4011_4mxx 0x3c > /sys/bus/i2c/devices/i2c-57/new_device', +'echo as7716_32x_psu1 0x50 > /sys/bus/i2c/devices/i2c-57/new_device', +'echo ym2401 0x58 > /sys/bus/i2c/devices/i2c-57/new_device', + +# PSU-2 +'echo as7716_32x_psu2 0x3b > /sys/bus/i2c/devices/i2c-58/new_device', +'echo cpr_4011_4mxx 0x3f > /sys/bus/i2c/devices/i2c-58/new_device', +'echo as7716_32x_psu2 0x53 > /sys/bus/i2c/devices/i2c-58/new_device', +'echo ym2401 0x5b > /sys/bus/i2c/devices/i2c-58/new_device', + +'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-61/new_device', +'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-62/new_device', +'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-63/new_device', + +#EERPOM +'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-1/new_device', +] + +FORCE = 0 +logging.basicConfig(filename= PROJECT_NAME+'.log', filemode='w',level=logging.DEBUG) +logging.basicConfig(level=logging.INFO) + + +if DEBUG == True: + print sys.argv[0] + print 'ARGV :', sys.argv[1:] + + +def main(): + global DEBUG + global args + global FORCE + + if len(sys.argv)<2: + show_help() + + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', + 'debug', + 'force', + ]) + if DEBUG == True: + print options + print args + print len(sys.argv) + + for opt, arg in options: + if opt in ('-h', '--help'): + show_help() + elif opt in ('-d', '--debug'): + DEBUG = True + logging.basicConfig(level=logging.INFO) + elif opt in ('-f', '--force'): + FORCE = 1 + else: + logging.info('no option') + for arg in args: + if arg == 'install': + do_install() + elif arg == 'clean': + do_uninstall() + elif arg == 'show': + device_traversal() + elif arg == 'sff': + if len(args)!=2: + show_eeprom_help() + elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']: + show_eeprom_help() + else: + show_eeprom(args[1]) + return + elif arg == 'set': + if len(args)<3: + show_set_help() + else: + set_device(args[1:]) + return + else: + show_help() + + + return 0 + +def show_help(): + print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + sys.exit(0) + +def show_set_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print cmd +" [led|sfp|fan]" + print " use \""+ cmd + " led 0-4 \" to set led color" + print " use \""+ cmd + " fan 0-100\" to set fan duty percetage" + print " use \""+ cmd + " sfp 1-32 {0|1}\" to set sfp# tx_disable" + sys.exit(0) + +def show_eeprom_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print " use \""+ cmd + " 1-32 \" to dump sfp# eeprom" + sys.exit(0) + +def my_log(txt): + if DEBUG == True: + print "[ACCTON DBG]: "+txt + return + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status = 1 + output = "" + status, output = commands.getstatusoutput(cmd) + my_log (cmd +"with result:" + str(status)) + my_log ("cmd:" + cmd) + my_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + +def driver_inserted(): + ret, lsmod = log_os_system("lsmod| grep accton", 0) + logging.info('mods:'+lsmod) + if len(lsmod) ==0: + return False + +#'modprobe cpr_4011_4mxx', + +kos = [ +'depmod -ae', +'modprobe i2c_dev', +'modprobe i2c_mux_pca954x', +'modprobe accton_i2c_cpld', +'modprobe cpr_4011_4mxx', +'modprobe ym2651y', +'modprobe accton_as7716_32x_cpld1', +'modprobe accton_as7716_32x_fan', +'modprobe accton_as7716_32x_leds', +'modprobe accton_as7716_32x_psu'] + +def driver_install(): + global FORCE + for i in range(0,len(kos)): + status, output = log_os_system(kos[i], 1) + if status: + if FORCE == 0: + return status + return 0 + +def driver_uninstall(): + global FORCE + for i in range(0,len(kos)): + rm = kos[-(i+1)].replace("modprobe", "modprobe -rq") + rm = rm.replace("insmod", "rmmod") + status, output = log_os_system(rm, 1) + if status: + if FORCE == 0: + return status + return 0 + + + +def i2c_order_check(): + # i2c bus 0 and 1 might be installed in different order. + # Here check if 0x76 is exist @ i2c-0 + tmp = "echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-1/new_device" + status, output = log_os_system(tmp, 0) + if not device_exist(): + order = 1 + else: + order = 0 + tmp = "echo 0x70 > /sys/bus/i2c/devices/i2c-1/delete_device" + status, output = log_os_system(tmp, 0) + return order + +def device_install(): + global FORCE + + for i in range(0,len(mknod)): + #for pca932x need times to built new i2c buses + if mknod[i].find('pca954') != -1: + time.sleep(2) + + status, output = log_os_system(mknod[i], 1) + if status: + print output + if FORCE == 0: + return status + + for i in range(0,len(sfp_map)): + status, output =log_os_system("echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + status, output =log_os_system("echo port"+str(i)+" > /sys/bus/i2c/devices/"+str(sfp_map[i])+"-0050/port_name", 1) + if status: + print output + if FORCE == 0: + return status + return + +def device_uninstall(): + global FORCE + + status, output =log_os_system("ls /sys/bus/i2c/devices/0-0070", 0) + if status==0: + I2C_ORDER=1 + else: + I2C_ORDER=0 + + for i in range(0,len(sfp_map)): + target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device" + status, output =log_os_system("echo 0x50 > "+ target, 1) + if status: + print output + if FORCE == 0: + return status + + if I2C_ORDER==0: + nodelist = mknod + else: + nodelist = mknod2 + + for i in range(len(nodelist)): + target = nodelist[-(i+1)] + temp = target.split() + del temp[1] + temp[-1] = temp[-1].replace('new_device', 'delete_device') + status, output = log_os_system(" ".join(temp), 1) + if status: + print output + if FORCE == 0: + return status + + return + +def system_ready(): + if driver_inserted() == False: + return False + if not device_exist(): + print "not device_exist()" + return False + return True + +def do_install(): + if driver_inserted() == False: + status = driver_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" drivers detected...." + if not device_exist(): + status = device_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" devices detected...." + return + +def do_uninstall(): + if not device_exist(): + print PROJECT_NAME.upper() +" has no device installed...." + else: + print "Removing device...." + status = device_uninstall() + if status: + if FORCE == 0: + return status + + if driver_inserted()== False : + print PROJECT_NAME.upper() +" has no driver installed...." + else: + print "Removing installed driver...." + status = driver_uninstall() + if status: + if FORCE == 0: + return status + + return + +def devices_info(): + global DEVICE_NO + global ALL_DEVICE + global i2c_bus, hwmon_types + for key in DEVICE_NO: + ALL_DEVICE[key]= {} + for i in range(0,DEVICE_NO[key]): + ALL_DEVICE[key][key+str(i+1)] = [] + + for key in i2c_bus: + buses = i2c_bus[key] + nodes = i2c_nodes[key] + for i in range(0,len(buses)): + for j in range(0,len(nodes)): + if 'fan' == key: + for k in range(0,DEVICE_NO[key]): + node = key+str(k+1) + path = i2c_prefix+ buses[i]+"/fan"+str(k+1)+"_"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + elif 'sfp' == key: + for k in range(0,DEVICE_NO[key]): + node = key+str(k+1) + path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + else: + node = key+str(i+1) + path = i2c_prefix+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + + for key in hwmon_types: + itypes = hwmon_types[key] + nodes = hwmon_nodes[key] + for i in range(0,len(itypes)): + for j in range(0,len(nodes)): + node = key+"_"+itypes[i] + path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][ key+str(i+1)].append(path) + + #show dict all in the order + if DEBUG == True: + for i in sorted(ALL_DEVICE.keys()): + print(i+": ") + for j in sorted(ALL_DEVICE[i].keys()): + print(" "+j) + for k in (ALL_DEVICE[i][j]): + print(" "+" "+k) + return + +def show_eeprom(index): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0] + node = node.replace(node.split("/")[-1], 'sfp_eeprom') + # check if got hexdump command in current environment + ret, log = log_os_system("which hexdump", 0) + ret, log2 = log_os_system("which busybox hexdump", 0) + if len(log): + hex_cmd = 'hexdump' + elif len(log2): + hex_cmd = ' busybox hexdump' + else: + log = 'Failed : no hexdump cmd!!' + logging.info(log) + print log + return 1 + + print node + ":" + ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1) + if ret==0: + print log + else: + print "**********device no found**********" + return + +def set_device(args): + global DEVICE_NO + global ALL_DEVICE + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + + if args[0]=='led': + if int(args[1])>4: + show_set_help() + return + #print ALL_DEVICE['led'] + for i in range(0,len(ALL_DEVICE['led'])): + for k in (ALL_DEVICE['led']['led'+str(i+1)]): + ret, log = log_os_system("echo "+args[1]+" >"+k, 1) + if ret: + return ret + elif args[0]=='fan': + if int(args[1])>100: + show_set_help() + return + #print ALL_DEVICE['fan'] + #fan1~6 is all fine, all fan share same setting + node = ALL_DEVICE['fan1'] ['fan11'][0] + node = node.replace(node.split("/")[-1], 'fan1_duty_cycle_percentage') + ret, log = log_os_system("cat "+ node, 1) + if ret==0: + print ("Previous fan duty: " + log.strip() +"%") + ret, log = log_os_system("echo "+args[1]+" >"+node, 1) + if ret==0: + print ("Current fan duty: " + args[1] +"%") + return ret + elif args[0]=='sfp': + if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0: + show_set_help() + return + if len(args)<2: + show_set_help() + return + + if int(args[2])>1: + show_set_help() + return + + #print ALL_DEVICE[args[0]] + for i in range(0,len(ALL_DEVICE[args[0]])): + for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]: + if j.find('tx_disable')!= -1: + ret, log = log_os_system("echo "+args[2]+" >"+ j, 1) + if ret: + return ret + + return + +#get digits inside a string. +#Ex: 31 for "sfp31" +def get_value(input): + digit = re.findall('\d+', input) + return int(digit[0]) + +def device_traversal(): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + for i in sorted(ALL_DEVICE.keys()): + print("============================================") + print(i.upper()+": ") + print("============================================") + + for j in sorted(ALL_DEVICE[i].keys(), key=get_value): + print " "+j+":", + for k in (ALL_DEVICE[i][j]): + ret, log = log_os_system("cat "+k, 0) + func = k.split("/")[-1].strip() + func = re.sub(j+'_','',func,1) + func = re.sub(i.lower()+'_','',func,1) + if ret==0: + print func+"="+log+" ", + else: + print func+"="+"X"+" ", + print + print("----------------------------------------------------------------") + + + print + return + +def device_exist(): + ret1, log = log_os_system("ls "+i2c_prefix+"*0077", 0) + ret2, log = log_os_system("ls "+i2c_prefix+"i2c-2", 0) + return not(ret1 or ret2) + +if __name__ == "__main__": + main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/classes/__init__.py b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/classes/__init__.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/classes/fanutil.py b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/classes/fanutil.py new file mode 100755 index 000000000000..e001e94092c7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/classes/fanutil.py @@ -0,0 +1,263 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 Accton Technology Corporation +# +# 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 3 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, see . + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 11/13/2017: Polly Hsu, Create +# 1/10/2018: Jostar modify for as7716_32 +# ------------------------------------------------------------------ + +try: + import time + import logging + from collections import namedtuple +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + + +class FanUtil(object): + """Platform-specific FanUtil class""" + + FAN_NUM_ON_MAIN_BROAD = 6 + FAN_NUM_1_IDX = 1 + FAN_NUM_2_IDX = 2 + FAN_NUM_3_IDX = 3 + FAN_NUM_4_IDX = 4 + FAN_NUM_5_IDX = 5 + FAN_NUM_6_IDX = 6 + + FAN_NODE_NUM_OF_MAP = 2 + FAN_NODE_FAULT_IDX_OF_MAP = 1 + #FAN_NODE_SPEED_IDX_OF_MAP = 2 + FAN_NODE_DIR_IDX_OF_MAP = 2 + #FAN_NODE_DUTY_IDX_OF_MAP = 4 + #FANR_NODE_FAULT_IDX_OF_MAP = 5 + + #BASE_VAL_PATH = '/sys/devices/platform/as5712_54x_fan/{0}' + BASE_VAL_PATH = '/sys/bus/i2c/devices/9-0066/{0}' + FAN_DUTY_PATH = '/sys/bus/i2c/devices/9-0066/fan_duty_cycle_percentage' + + #logfile = '' + #loglevel = logging.INFO + + """ Dictionary where + key1 = fan id index (integer) starting from 1 + key2 = fan node index (interger) starting from 1 + value = path to fan device file (string) """ + _fan_to_device_path_mapping = {} + +#fan1_direction +#fan1_fault +#fan1_present + + #(FAN_NUM_2_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan2_duty_cycle_percentage', + _fan_to_device_node_mapping = { + (FAN_NUM_1_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan1_fault', + (FAN_NUM_1_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan1_direction', + + (FAN_NUM_2_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan2_fault', + (FAN_NUM_2_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan2_direction', + + (FAN_NUM_3_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan3_fault', + (FAN_NUM_3_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan3_direction', + + (FAN_NUM_4_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan4_fault', + (FAN_NUM_4_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan4_direction', + + (FAN_NUM_5_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan5_fault', + (FAN_NUM_5_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan5_direction', + + (FAN_NUM_6_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan6_fault', + (FAN_NUM_6_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan6_direction', + } + + def _get_fan_to_device_node(self, fan_num, node_num): + return self._fan_to_device_node_mapping[(fan_num, node_num)] + + def _get_fan_node_val(self, fan_num, node_num): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. fan_num:%d', fan_num) + return None + + if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP: + logging.debug('GET. Parameter error. node_num:%d', node_num) + return None + + device_path = self.get_fan_to_device_path(fan_num, node_num) + + try: + val_file = open(device_path, 'r') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None + + content = val_file.readline().rstrip() + #print "fan_num=%d" %fan_num + #print "node_num=%d" %node_num + #print "device_path=%s" %device_path + #print "content=%s" %content + + if content == '': + logging.debug('GET. content is NULL. device_path:%s', device_path) + return None + + try: + val_file.close() + except: + logging.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return int(content) + + def _set_fan_node_val(self, fan_num, node_num, val): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. fan_num:%d', fan_num) + return None + + if node_num < self.FAN_NODE_FAULT_IDX_OF_MAP or node_num > self.FAN_NODE_NUM_OF_MAP: + logging.debug('GET. Parameter error. node_num:%d', node_num) + return None + + content = str(val) + if content == '': + logging.debug('GET. content is NULL. device_path:%s', device_path) + return None + + device_path = self.get_fan_to_device_path(fan_num, node_num) + try: + val_file = open(device_path, 'w') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None + + val_file.write(content) + + try: + val_file.close() + except: + logging.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return True + + def __init__(self): + fan_path = self.BASE_VAL_PATH + + for fan_num in range(self.FAN_NUM_1_IDX, self.FAN_NUM_ON_MAIN_BROAD+1): + for node_num in range(self.FAN_NODE_FAULT_IDX_OF_MAP, self.FAN_NODE_NUM_OF_MAP+1): + self._fan_to_device_path_mapping[(fan_num, node_num)] = fan_path.format( + self._fan_to_device_node_mapping[(fan_num, node_num)]) + #self._fan_to_device_path_mapping[(fan_num, node_num)] = fan_path + self._fan_to_device_node_mapping[(fan_num, node_num)]) + #print "fan_num=%d" %fan_num + #print "node_num=%d" %node_num + #print "self._fan_to_device_path_mapping[(fan_num, node_num)]=%s" %self._fan_to_device_path_mapping[(fan_num, node_num)] + + def get_num_fans(self): + return self.FAN_NUM_ON_MAIN_BROAD + + def get_idx_fan_start(self): + return self.FAN_NUM_1_IDX + + def get_num_nodes(self): + return self.FAN_NODE_NUM_OF_MAP + + def get_idx_node_start(self): + return self.FAN_NODE_FAULT_IDX_OF_MAP + + def get_size_node_map(self): + return len(self._fan_to_device_node_mapping) + + def get_size_path_map(self): + return len(self._fan_to_device_path_mapping) + + def get_fan_to_device_path(self, fan_num, node_num): + return self._fan_to_device_path_mapping[(fan_num, node_num)] + + def get_fan_fault(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_FAULT_IDX_OF_MAP) + + #def get_fan_speed(self, fan_num): + # return self._get_fan_node_val(fan_num, self.FAN_NODE_SPEED_IDX_OF_MAP) + + def get_fan_dir(self, fan_num): + return self._get_fan_node_val(fan_num, self.FAN_NODE_DIR_IDX_OF_MAP) + + def get_fan_duty_cycle(self): + #duty_path = self.FAN_DUTY_PATH + try: + val_file = open(self.FAN_DUTY_PATH) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = val_file.readline().rstrip() + val_file.close() + + return int(content) + #self._get_fan_node_val(fan_num, self.FAN_NODE_DUTY_IDX_OF_MAP) +#static u32 reg_val_to_duty_cycle(u8 reg_val) +#{ +# reg_val &= FAN_DUTY_CYCLE_REG_MASK; +# return ((u32)(reg_val+1) * 625 + 75)/ 100; +#} +# + def set_fan_duty_cycle(self, val): + + try: + fan_file = open(self.FAN_DUTY_PATH, 'r+') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + #val = ((val + 1 ) * 625 +75 ) / 100 + fan_file.write(str(val)) + fan_file.close() + return True + + #def get_fanr_fault(self, fan_num): + # return self._get_fan_node_val(fan_num, self.FANR_NODE_FAULT_IDX_OF_MAP) + + def get_fanr_speed(self, fan_num): + return self._get_fan_node_val(fan_num, self.FANR_NODE_SPEED_IDX_OF_MAP) + + def get_fan_status(self, fan_num): + if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. fan_num, %d', fan_num) + print "fan %d return none" %fan_num + return None + + if self.get_fan_fault(fan_num) is not None and self.get_fan_fault(fan_num) > 0: + logging.debug('GET. FAN fault. fan_num, %d', fan_num) + return False + + #if self.get_fanr_fault(fan_num) is not None and self.get_fanr_fault(fan_num) > 0: + # logging.debug('GET. FANR fault. fan_num, %d', fan_num) + # return False + + return True + +#def main(): +# fan = FanUtil() +# +# print 'get_size_node_map : %d' % fan.get_size_node_map() +# print 'get_size_path_map : %d' % fan.get_size_path_map() +# for x in range(fan.get_idx_fan_start(), fan.get_num_fans()+1): +# for y in range(fan.get_idx_node_start(), fan.get_num_nodes()+1): +# print fan.get_fan_to_device_path(x, y) +# +#if __name__ == '__main__': +# main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/classes/thermalutil.py b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/classes/thermalutil.py new file mode 100755 index 000000000000..d3feda8faad9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/classes/thermalutil.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 Accton Technology Corporation +# +# 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 3 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, see . + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 11/13/2017: Polly Hsu, Create +# 1/10/2018:Jostar modify for as7716_32x +# ------------------------------------------------------------------ + +try: + import time + import logging + import glob + from collections import namedtuple +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + + +class ThermalUtil(object): + """Platform-specific ThermalUtil class""" + + THERMAL_NUM_ON_MAIN_BROAD = 3 + THERMAL_NUM_1_IDX = 1 # 1_ON_MAIN_BROAD + THERMAL_NUM_2_IDX = 2 # 2_ON_MAIN_BROAD + THERMAL_NUM_3_IDX = 3 # 3_ON_MAIN_BROAD + + BASE_VAL_PATH = '/sys/bus/i2c/devices/{0}-00{1}/hwmon/hwmon*/temp1_input' + + """ Dictionary where + key1 = thermal id index (integer) starting from 1 + value = path to fan device file (string) """ + _thermal_to_device_path_mapping = {} + + _thermal_to_device_node_mapping = { + THERMAL_NUM_1_IDX: ['10', '48'], + THERMAL_NUM_2_IDX: ['10', '49'], + THERMAL_NUM_3_IDX: ['10', '4a'], + } + + def __init__(self): + thermal_path = self.BASE_VAL_PATH + + for x in range(self.THERMAL_NUM_1_IDX, self.THERMAL_NUM_ON_MAIN_BROAD+1): + self._thermal_to_device_path_mapping[x] = thermal_path.format( + self._thermal_to_device_node_mapping[x][0], + self._thermal_to_device_node_mapping[x][1]) + #print "self._thermal_to_device_path_mapping[x]=%s" %self._thermal_to_device_path_mapping[x] + + def _get_thermal_node_val(self, thermal_num): + if thermal_num < self.THERMAL_NUM_1_IDX or thermal_num > self.THERMAL_NUM_ON_MAIN_BROAD: + logging.debug('GET. Parameter error. thermal_num, %d', thermal_num) + return None + + device_path = self.get_thermal_to_device_path(thermal_num) + for filename in glob.glob(device_path): + try: + val_file = open(filename, 'r') + except IOError as e: + logging.error('GET. unable to open file: %s', str(e)) + return None + + content = val_file.readline().rstrip() + + if content == '': + logging.debug('GET. content is NULL. device_path:%s', device_path) + return None + + try: + val_file.close() + except: + logging.debug('GET. unable to close file. device_path:%s', device_path) + return None + + return int(content) + + + def get_num_thermals(self): + return self.THERMAL_NUM_ON_MAIN_BROAD + + def get_idx_thermal_start(self): + return self.THERMAL_NUM_1_IDX + + def get_size_node_map(self): + return len(self._thermal_to_device_node_mapping) + + def get_size_path_map(self): + return len(self._thermal_to_device_path_mapping) + + def get_thermal_to_device_path(self, thermal_num): + return self._thermal_to_device_path_mapping[thermal_num] + + def get_thermal_1_val(self): + return self._get_thermal_node_val(self.THERMAL_NUM_1_IDX) + + def get_thermal_2_val(self): + return self._get_thermal_node_val(self.THERMAL_NUM_2_IDX) + def get_thermal_temp(self): + return (self._get_thermal_node_val(self.THERMAL_NUM_1_IDX) + self._get_thermal_node_val(self.THERMAL_NUM_2_IDX) +self._get_thermal_node_val(self.THERMAL_NUM_3_IDX)) + +#def main(): +# thermal = ThermalUtil() +# +# print 'get_size_node_map : %d' % thermal.get_size_node_map() +# print 'get_size_path_map : %d' % thermal.get_size_path_map() +# for x in range(thermal.get_idx_thermal_start(), thermal.get_num_thermals()+1): +# print thermal.get_thermal_to_device_path(x) +# +#if __name__ == '__main__': +# main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/Makefile b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/Makefile new file mode 100755 index 000000000000..3dfb021a7aaf --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/Makefile @@ -0,0 +1,17 @@ +ifneq ($(KERNELRELEASE),) +obj-m:= accton_as7716_32xb_cpld1.o accton_as7716_32xb_fan.o \ + accton_as7716_32xb_leds.o accton_as7716_32xb_psu.o \ + accton_as7716_32xb_thermal.o accton_as7716_32xb_oom.o accton_as7716_32xb_pmbus.o\ + accton_as7716_32xb_sys.o accton_i2c_cpld.o +else +ifeq (,$(KERNEL_SRC)) +$(error KERNEL_SRC is not defined) +else +KERNELDIR:=$(KERNEL_SRC) +endif +PWD:=$(shell pwd) +default: + $(MAKE) -C $(KERNELDIR) M=$(PWD) modules +clean: + rm -rf *.o *.mod.o *.mod.o *.ko .*cmd .tmp_versions Module.markers Module.symvers modules.order +endif diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_cpld1.c b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_cpld1.c new file mode 100755 index 000000000000..d2db4fb1f484 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_cpld1.c @@ -0,0 +1,1021 @@ +/* + * A hwmon driver for the as7716_32xbb_cpld + * + * Copyright (C) 2013 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static LIST_HEAD(cpld_client_list); +static struct mutex list_lock; + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; + +#define I2C_RW_RETRY_COUNT 10 +#define I2C_RW_RETRY_INTERVAL 60 /* ms */ +#define STRING_TO_DEC_VALUE 10 + +static ssize_t show_present(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_present_all(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t access(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t show_version(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t get_mode_reset(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t set_mode_reset(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); + +static int as7716_32xb_cpld_read_internal(struct i2c_client *client, u8 reg); +static int as7716_32xb_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value); + +static ssize_t sfp_value_show(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t sfp_value_store(struct device *dev, struct device_attribute *da, + char *buf, size_t size); + + +#define PORT_NUM_MAX 32 + +struct as7716_32xb_cpld_data { + struct device *hwmon_dev; + struct mutex update_lock; + unsigned int present[PORT_NUM_MAX]; + unsigned int reset[PORT_NUM_MAX]; +}; +enum port_id { + PORT1_ID, + PORT2_ID, + PORT3_ID, + PORT4_ID, + PORT5_ID, + PORT6_ID, + PORT7_ID, + PORT8_ID, + PORT9_ID, + PORT10_ID, + PORT11_ID, + PORT12_ID, + PORT13_ID, + PORT14_ID, + PORT15_ID, + PORT16_ID, + PORT17_ID, + PORT18_ID, + PORT19_ID, + PORT20_ID, + PORT21_ID, + PORT22_ID, + PORT23_ID, + PORT24_ID, + PORT25_ID, + PORT26_ID, + PORT27_ID, + PORT28_ID, + PORT29_ID, + PORT30_ID, + PORT31_ID, + PORT32_ID +}; + +/* Addresses scanned for as7716_32xbb_cpld + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +#define TRANSCEIVER_PRESENT_ATTR_ID(index) MODULE_PRESENT_##index +#define TRANSCEIVER_RESET_ATTR_ID(index) MODULE_RESET_##index + +enum as7716_32xb_cpld_sysfs_attributes { + CPLD_VERSION, + ACCESS, + MODULE_PRESENT_ALL, + /* transceiver attributes */ + TRANSCEIVER_PRESENT_ATTR_ID(1), + TRANSCEIVER_PRESENT_ATTR_ID(2), + TRANSCEIVER_PRESENT_ATTR_ID(3), + TRANSCEIVER_PRESENT_ATTR_ID(4), + TRANSCEIVER_PRESENT_ATTR_ID(5), + TRANSCEIVER_PRESENT_ATTR_ID(6), + TRANSCEIVER_PRESENT_ATTR_ID(7), + TRANSCEIVER_PRESENT_ATTR_ID(8), + TRANSCEIVER_PRESENT_ATTR_ID(9), + TRANSCEIVER_PRESENT_ATTR_ID(10), + TRANSCEIVER_PRESENT_ATTR_ID(11), + TRANSCEIVER_PRESENT_ATTR_ID(12), + TRANSCEIVER_PRESENT_ATTR_ID(13), + TRANSCEIVER_PRESENT_ATTR_ID(14), + TRANSCEIVER_PRESENT_ATTR_ID(15), + TRANSCEIVER_PRESENT_ATTR_ID(16), + TRANSCEIVER_PRESENT_ATTR_ID(17), + TRANSCEIVER_PRESENT_ATTR_ID(18), + TRANSCEIVER_PRESENT_ATTR_ID(19), + TRANSCEIVER_PRESENT_ATTR_ID(20), + TRANSCEIVER_PRESENT_ATTR_ID(21), + TRANSCEIVER_PRESENT_ATTR_ID(22), + TRANSCEIVER_PRESENT_ATTR_ID(23), + TRANSCEIVER_PRESENT_ATTR_ID(24), + TRANSCEIVER_PRESENT_ATTR_ID(25), + TRANSCEIVER_PRESENT_ATTR_ID(26), + TRANSCEIVER_PRESENT_ATTR_ID(27), + TRANSCEIVER_PRESENT_ATTR_ID(28), + TRANSCEIVER_PRESENT_ATTR_ID(29), + TRANSCEIVER_PRESENT_ATTR_ID(30), + TRANSCEIVER_PRESENT_ATTR_ID(31), + TRANSCEIVER_PRESENT_ATTR_ID(32), + TRANSCEIVER_RESET_ATTR_ID(1), + TRANSCEIVER_RESET_ATTR_ID(2), + TRANSCEIVER_RESET_ATTR_ID(3), + TRANSCEIVER_RESET_ATTR_ID(4), + TRANSCEIVER_RESET_ATTR_ID(5), + TRANSCEIVER_RESET_ATTR_ID(6), + TRANSCEIVER_RESET_ATTR_ID(7), + TRANSCEIVER_RESET_ATTR_ID(8), + TRANSCEIVER_RESET_ATTR_ID(9), + TRANSCEIVER_RESET_ATTR_ID(10), + TRANSCEIVER_RESET_ATTR_ID(11), + TRANSCEIVER_RESET_ATTR_ID(12), + TRANSCEIVER_RESET_ATTR_ID(13), + TRANSCEIVER_RESET_ATTR_ID(14), + TRANSCEIVER_RESET_ATTR_ID(15), + TRANSCEIVER_RESET_ATTR_ID(16), + TRANSCEIVER_RESET_ATTR_ID(17), + TRANSCEIVER_RESET_ATTR_ID(18), + TRANSCEIVER_RESET_ATTR_ID(19), + TRANSCEIVER_RESET_ATTR_ID(20), + TRANSCEIVER_RESET_ATTR_ID(21), + TRANSCEIVER_RESET_ATTR_ID(22), + TRANSCEIVER_RESET_ATTR_ID(23), + TRANSCEIVER_RESET_ATTR_ID(24), + TRANSCEIVER_RESET_ATTR_ID(25), + TRANSCEIVER_RESET_ATTR_ID(26), + TRANSCEIVER_RESET_ATTR_ID(27), + TRANSCEIVER_RESET_ATTR_ID(28), + TRANSCEIVER_RESET_ATTR_ID(29), + TRANSCEIVER_RESET_ATTR_ID(30), + TRANSCEIVER_RESET_ATTR_ID(31), + TRANSCEIVER_RESET_ATTR_ID(32), +}; + +/* sysfs attributes for hwmon + */ + +/* transceiver attributes */ +/*present*/ +#define DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(index) \ + static SENSOR_DEVICE_ATTR(module_present_##index, S_IWUSR|S_IRUGO, sfp_value_show, sfp_value_store, MODULE_PRESENT_##index) +#define DECLARE_TRANSCEIVER_ATTR(index) &sensor_dev_attr_module_present_##index.dev_attr.attr + +/*reset*/ +//#define DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(index) \ +// static SENSOR_DEVICE_ATTR(module_reset_##index, S_IWUSR | S_IRUGO, get_mode_reset, set_mode_reset, MODULE_RESET_##index) +//#define DECLARE_TRANSCEIVER_RESET_ATTR(index) &sensor_dev_attr_module_reset_##index.dev_attr.attr +#define DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(index) \ + static SENSOR_DEVICE_ATTR(module_reset_##index, S_IWUSR | S_IRUGO, sfp_value_show, sfp_value_store, MODULE_RESET_##index) +#define DECLARE_TRANSCEIVER_RESET_ATTR(index) &sensor_dev_attr_module_reset_##index.dev_attr.attr + + + + +static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, CPLD_VERSION); +static SENSOR_DEVICE_ATTR(access, S_IWUSR, NULL, access, ACCESS); +/* transceiver attributes */ +static SENSOR_DEVICE_ATTR(module_present_all, S_IRUGO, show_present_all, NULL, MODULE_PRESENT_ALL); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(1); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(2); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(3); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(4); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(5); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(6); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(7); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(8); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(9); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(10); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(11); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(12); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(13); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(14); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(15); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(16); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(17); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(18); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(19); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(20); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(21); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(22); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(23); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(24); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(25); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(26); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(27); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(28); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(29); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(30); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(31); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_ATTR(32); + +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(1); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(2); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(3); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(4); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(5); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(6); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(7); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(8); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(9); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(10); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(11); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(12); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(13); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(14); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(15); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(16); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(17); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(18); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(19); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(20); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(21); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(22); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(23); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(24); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(25); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(26); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(27); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(28); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(29); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(30); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(31); +DECLARE_TRANSCEIVER_SENSOR_DEVICE_RESET_ATTR(32); + + +static struct attribute *as7716_32xb_cpld_attributes[] = { + &sensor_dev_attr_version.dev_attr.attr, + &sensor_dev_attr_access.dev_attr.attr, + /* transceiver attributes */ + &sensor_dev_attr_module_present_all.dev_attr.attr, + DECLARE_TRANSCEIVER_ATTR(1), + DECLARE_TRANSCEIVER_ATTR(2), + DECLARE_TRANSCEIVER_ATTR(3), + DECLARE_TRANSCEIVER_ATTR(4), + DECLARE_TRANSCEIVER_ATTR(5), + DECLARE_TRANSCEIVER_ATTR(6), + DECLARE_TRANSCEIVER_ATTR(7), + DECLARE_TRANSCEIVER_ATTR(8), + DECLARE_TRANSCEIVER_ATTR(9), + DECLARE_TRANSCEIVER_ATTR(10), + DECLARE_TRANSCEIVER_ATTR(11), + DECLARE_TRANSCEIVER_ATTR(12), + DECLARE_TRANSCEIVER_ATTR(13), + DECLARE_TRANSCEIVER_ATTR(14), + DECLARE_TRANSCEIVER_ATTR(15), + DECLARE_TRANSCEIVER_ATTR(16), + DECLARE_TRANSCEIVER_ATTR(17), + DECLARE_TRANSCEIVER_ATTR(18), + DECLARE_TRANSCEIVER_ATTR(19), + DECLARE_TRANSCEIVER_ATTR(20), + DECLARE_TRANSCEIVER_ATTR(21), + DECLARE_TRANSCEIVER_ATTR(22), + DECLARE_TRANSCEIVER_ATTR(23), + DECLARE_TRANSCEIVER_ATTR(24), + DECLARE_TRANSCEIVER_ATTR(25), + DECLARE_TRANSCEIVER_ATTR(26), + DECLARE_TRANSCEIVER_ATTR(27), + DECLARE_TRANSCEIVER_ATTR(28), + DECLARE_TRANSCEIVER_ATTR(29), + DECLARE_TRANSCEIVER_ATTR(30), + DECLARE_TRANSCEIVER_ATTR(31), + DECLARE_TRANSCEIVER_ATTR(32), + DECLARE_TRANSCEIVER_RESET_ATTR(1), + DECLARE_TRANSCEIVER_RESET_ATTR(2), + DECLARE_TRANSCEIVER_RESET_ATTR(3), + DECLARE_TRANSCEIVER_RESET_ATTR(4), + DECLARE_TRANSCEIVER_RESET_ATTR(5), + DECLARE_TRANSCEIVER_RESET_ATTR(6), + DECLARE_TRANSCEIVER_RESET_ATTR(7), + DECLARE_TRANSCEIVER_RESET_ATTR(8), + DECLARE_TRANSCEIVER_RESET_ATTR(9), + DECLARE_TRANSCEIVER_RESET_ATTR(10), + DECLARE_TRANSCEIVER_RESET_ATTR(11), + DECLARE_TRANSCEIVER_RESET_ATTR(12), + DECLARE_TRANSCEIVER_RESET_ATTR(13), + DECLARE_TRANSCEIVER_RESET_ATTR(14), + DECLARE_TRANSCEIVER_RESET_ATTR(15), + DECLARE_TRANSCEIVER_RESET_ATTR(16), + DECLARE_TRANSCEIVER_RESET_ATTR(17), + DECLARE_TRANSCEIVER_RESET_ATTR(18), + DECLARE_TRANSCEIVER_RESET_ATTR(19), + DECLARE_TRANSCEIVER_RESET_ATTR(20), + DECLARE_TRANSCEIVER_RESET_ATTR(21), + DECLARE_TRANSCEIVER_RESET_ATTR(22), + DECLARE_TRANSCEIVER_RESET_ATTR(23), + DECLARE_TRANSCEIVER_RESET_ATTR(24), + DECLARE_TRANSCEIVER_RESET_ATTR(25), + DECLARE_TRANSCEIVER_RESET_ATTR(26), + DECLARE_TRANSCEIVER_RESET_ATTR(27), + DECLARE_TRANSCEIVER_RESET_ATTR(28), + DECLARE_TRANSCEIVER_RESET_ATTR(29), + DECLARE_TRANSCEIVER_RESET_ATTR(30), + DECLARE_TRANSCEIVER_RESET_ATTR(31), + DECLARE_TRANSCEIVER_RESET_ATTR(32), + NULL +}; + +static const struct attribute_group as7716_32xb_cpld_group = { + .attrs = as7716_32xb_cpld_attributes, +}; + +static ssize_t show_present_all(struct device *dev, struct device_attribute *da, + char *buf) +{ + int i, status; + u8 values[4] = {0}; + u8 regs[] = {0x30, 0x31, 0x32, 0x33}; + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32xb_cpld_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + for (i = 0; i < ARRAY_SIZE(regs); i++) { + status = as7716_32xb_cpld_read_internal(client, regs[i]); + + if (status < 0) { + goto exit; + } + + values[i] = ~(u8)status; + } + + mutex_unlock(&data->update_lock); + + /* Return values 1 -> 32 in order */ + return sprintf(buf, "%.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], + values[3]); + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static int sfp_array_index_get(int attr_idx) +{ + switch(attr_idx) + { + case TRANSCEIVER_PRESENT_ATTR_ID(1): + case TRANSCEIVER_RESET_ATTR_ID(1): + return PORT1_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(2): + case TRANSCEIVER_RESET_ATTR_ID(2): + return PORT2_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(3): + case TRANSCEIVER_RESET_ATTR_ID(3): + return PORT3_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(4): + case TRANSCEIVER_RESET_ATTR_ID(4): + return PORT4_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(5): + case TRANSCEIVER_RESET_ATTR_ID(5): + return PORT5_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(6): + case TRANSCEIVER_RESET_ATTR_ID(6): + return PORT6_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(7): + case TRANSCEIVER_RESET_ATTR_ID(7): + return PORT7_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(8): + case TRANSCEIVER_RESET_ATTR_ID(8): + return PORT8_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(9): + case TRANSCEIVER_RESET_ATTR_ID(9): + return PORT9_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(10): + case TRANSCEIVER_RESET_ATTR_ID(10): + return PORT10_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(11): + case TRANSCEIVER_RESET_ATTR_ID(11): + return PORT11_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(12): + case TRANSCEIVER_RESET_ATTR_ID(12): + return PORT12_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(13): + case TRANSCEIVER_RESET_ATTR_ID(13): + return PORT13_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(14): + case TRANSCEIVER_RESET_ATTR_ID(14): + return PORT14_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(15): + case TRANSCEIVER_RESET_ATTR_ID(15): + return PORT15_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(16): + case TRANSCEIVER_RESET_ATTR_ID(16): + return PORT16_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(17): + case TRANSCEIVER_RESET_ATTR_ID(17): + return PORT17_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(18): + case TRANSCEIVER_RESET_ATTR_ID(18): + return PORT18_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(19): + case TRANSCEIVER_RESET_ATTR_ID(19): + return PORT19_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(20): + case TRANSCEIVER_RESET_ATTR_ID(20): + return PORT20_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(21): + case TRANSCEIVER_RESET_ATTR_ID(21): + return PORT21_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(22): + case TRANSCEIVER_RESET_ATTR_ID(22): + return PORT22_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(23): + case TRANSCEIVER_RESET_ATTR_ID(23): + return PORT23_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(24): + case TRANSCEIVER_RESET_ATTR_ID(24): + return PORT24_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(25): + case TRANSCEIVER_RESET_ATTR_ID(25): + return PORT25_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(26): + case TRANSCEIVER_RESET_ATTR_ID(26): + return PORT26_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(27): + case TRANSCEIVER_RESET_ATTR_ID(27): + return PORT27_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(28): + case TRANSCEIVER_RESET_ATTR_ID(28): + return PORT28_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(29): + case TRANSCEIVER_RESET_ATTR_ID(29): + return PORT29_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(30): + case TRANSCEIVER_RESET_ATTR_ID(30): + return PORT30_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(31): + case TRANSCEIVER_RESET_ATTR_ID(31): + return PORT31_ID; + case TRANSCEIVER_PRESENT_ATTR_ID(32): + case TRANSCEIVER_RESET_ATTR_ID(32): + return PORT32_ID; + default : + return -1; + } +} + + +static ssize_t sfp_value_store(struct device *dev, struct device_attribute *da, + char *buf, size_t size) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32xb_cpld_data *data = i2c_get_clientdata(client); + int status = -EINVAL; + int index; + long keyin = 0; + + //printk("sfp_value_store\n"); + //printk("attr->index=%d\n", attr->index); + mutex_lock(&data->update_lock); + switch (attr->index) + { + case MODULE_PRESENT_1 ... MODULE_PRESENT_8: + case MODULE_PRESENT_9 ... MODULE_PRESENT_16: + case MODULE_PRESENT_17 ... MODULE_PRESENT_24: + case MODULE_PRESENT_25 ... MODULE_PRESENT_32: + index=sfp_array_index_get(attr->index); + if(index < 0 || index > PORT_NUM_MAX -1) + break; + status = kstrtol(buf, STRING_TO_DEC_VALUE, &keyin); + if(keyin < 0 || keyin > 1) + break; + data->present[index]=keyin; + break; + case MODULE_RESET_1 ... MODULE_RESET_8: + case MODULE_RESET_9 ... MODULE_RESET_16: + case MODULE_RESET_17 ... MODULE_RESET_24: + case MODULE_RESET_25 ... MODULE_RESET_32: + index=sfp_array_index_get(attr->index); + if(index < 0 || index > PORT_NUM_MAX -1) + break; + status = kstrtol(buf, STRING_TO_DEC_VALUE, &keyin); + if(keyin < 0 || keyin > 1) + break; + data->reset[index]=keyin; + break; + default : + break; + } + mutex_unlock(&data->update_lock); + return size; +} +static ssize_t sfp_value_show(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32xb_cpld_data *data = i2c_get_clientdata(client); + ssize_t ret = 0; + int index; + int status = -EINVAL; + + //printk("sfp_value_show, attr->index=%d\n", attr->index); + //printk("TRANSCEIVER_PRESENT_ATTR_ID(1)=%d, TRANSCEIVER_RESET_ATTR_ID(1)=%d\n", TRANSCEIVER_PRESENT_ATTR_ID(1), TRANSCEIVER_RESET_ATTR_ID(1)); + mutex_lock(&data->update_lock); + switch (attr->index) + { + case MODULE_PRESENT_1 ... MODULE_PRESENT_8: + case MODULE_PRESENT_9 ... MODULE_PRESENT_16: + case MODULE_PRESENT_17 ... MODULE_PRESENT_24: + case MODULE_PRESENT_25 ... MODULE_PRESENT_32: + index=sfp_array_index_get(attr->index); + if(index < 0 || index > PORT_NUM_MAX -1) + break; + status = sprintf(buf, "%u\n", data->present[index]); + break; + case MODULE_RESET_1 ... MODULE_RESET_8: + case MODULE_RESET_9 ... MODULE_RESET_16: + case MODULE_RESET_17 ... MODULE_RESET_24: + case MODULE_RESET_25 ... MODULE_RESET_32: + index=sfp_array_index_get(attr->index); + //printk("rst:attr->index=%d, index=%d\n",attr->index, index); + if(index < 0 || index > PORT_NUM_MAX -1) + break; + status = sprintf(buf, "%u\n", data->reset[index]); + break; + default : + break; + } + + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t show_present(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32xb_cpld_data *data = i2c_get_clientdata(client); + int status = 0; + u8 reg = 0, mask = 0; + + switch (attr->index) { + case MODULE_PRESENT_1 ... MODULE_PRESENT_8: + reg = 0x30; + mask = 0x1 << (attr->index - MODULE_PRESENT_1); + break; + case MODULE_PRESENT_9 ... MODULE_PRESENT_16: + reg = 0x31; + mask = 0x1 << (attr->index - MODULE_PRESENT_9); + break; + case MODULE_PRESENT_17 ... MODULE_PRESENT_24: + reg = 0x32; + mask = 0x1 << (attr->index - MODULE_PRESENT_17); + break; + case MODULE_PRESENT_25 ... MODULE_PRESENT_32: + reg = 0x33; + mask = 0x1 << (attr->index - MODULE_PRESENT_25); + break; + default: + return 0; + } + + + mutex_lock(&data->update_lock); + status = as7716_32xb_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", !(status & mask)); + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t show_version(struct device *dev, struct device_attribute *da, + char *buf) +{ + u8 reg = 0, mask = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32xb_cpld_data *data = i2c_get_clientdata(client); + int status = 0; + + switch (attr->index) { + case CPLD_VERSION: + reg = 0x1; + mask = 0xFF; + break; + default: + break; + } + + mutex_lock(&data->update_lock); + status = as7716_32xb_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + return sprintf(buf, "%d\n", (status & mask)); + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t access(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int status; + u32 addr, val; + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32xb_cpld_data *data = i2c_get_clientdata(client); + + if (sscanf(buf, "0x%x 0x%x", &addr, &val) != 2) { + return -EINVAL; + } + + if (addr > 0xFF || val > 0xFF) { + return -EINVAL; + } + + mutex_lock(&data->update_lock); + status = as7716_32xb_cpld_write_internal(client, addr, val); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static int as7716_32xb_cpld_read_internal(struct i2c_client *client, u8 reg) +{ + int status = 0, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_read_byte_data(client, reg); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + return status; +} + +static int as7716_32xb_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value) +{ + int status = 0, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_write_byte_data(client, reg, value); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + return status; +} + +static void as7716_32xb_cpld_add_client(struct i2c_client *client) +{ + struct cpld_client_node *node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", client->addr); + return; + } + + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &cpld_client_list); + mutex_unlock(&list_lock); +} + +static void as7716_32xb_cpld_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client == client) { + found = 1; + break; + } + } + + if (found) { + list_del(list_node); + kfree(cpld_node); + } + + mutex_unlock(&list_lock); +} + +static int as7716_32xb_cpld_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int status; + struct as7716_32xb_cpld_data *data = NULL; + + data = kzalloc(sizeof(struct as7716_32xb_cpld_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as7716_32xb_cpld_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + as7716_32xb_cpld_add_client(client); + + dev_info(&client->dev, "%s: cpld '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as7716_32xb_cpld_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as7716_32xb_cpld_remove(struct i2c_client *client) +{ + struct as7716_32xb_cpld_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as7716_32xb_cpld_group); + kfree(data); + as7716_32xb_cpld_remove_client(client); + + return 0; +} + +int as7716_32xb_cpld_read(unsigned short cpld_addr, u8 reg) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EPERM; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = i2c_smbus_read_byte_data(cpld_node->client, reg); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(as7716_32xb_cpld_read); + +int as7716_32xb_cpld_write(unsigned short cpld_addr, u8 reg, u8 value) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EIO; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = i2c_smbus_write_byte_data(cpld_node->client, reg, value); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(as7716_32xb_cpld_write); + +static ssize_t get_mode_reset(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32xb_cpld_data *data = i2c_get_clientdata(client); + int status = 0; + u8 reg = 0, mask = 0; + + switch (attr->index) { + case MODULE_RESET_1 ... MODULE_RESET_8: + reg = 0x04; + mask = 0x1 << (attr->index - MODULE_RESET_1); + break; + case MODULE_RESET_9 ... MODULE_RESET_16: + reg = 0x05; + mask = 0x1 << (attr->index - MODULE_RESET_9); + break; + case MODULE_RESET_17 ... MODULE_RESET_24: + reg = 0x06; + mask = 0x1 << (attr->index - MODULE_RESET_17); + break; + case MODULE_RESET_25 ... MODULE_RESET_32: + reg = 0x07; + mask = 0x1 << (attr->index - MODULE_RESET_25); + break; + default: + return 0; + } + + + mutex_lock(&data->update_lock); + status = as7716_32xb_cpld_read_internal(client, reg); + + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\r\n", !(status & mask)); + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t set_mode_reset(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32xb_cpld_data *data = i2c_get_clientdata(client); + long reset; + int status=0, val, error; + u8 reg = 0, mask = 0; + + + error = kstrtol(buf, 10, &reset); + if (error) { + return error; + } + //printk("set_mode_reset:attr->index=%d\n",attr->index); + switch (attr->index) { + case MODULE_RESET_1 ... MODULE_RESET_8: + reg = 0x04; + mask = 0x1 << (attr->index - MODULE_RESET_1); + break; + case MODULE_RESET_9 ... MODULE_RESET_16: + reg = 0x05; + mask = 0x1 << (attr->index - MODULE_RESET_9); + break; + case MODULE_RESET_17 ... MODULE_RESET_24: + reg = 0x06; + mask = 0x1 << (attr->index - MODULE_RESET_17); + break; + case MODULE_RESET_25 ... MODULE_RESET_32: + reg = 0x07; + mask = 0x1 << (attr->index - MODULE_RESET_25); + break; + default: + return 0; + } + mutex_lock(&data->update_lock); + + status = as7716_32xb_cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + //printk("set_mode_reset:reset=%d, reg=0x%x, mask=0x%x, ori_val=0x%x\n", reset, reg, mask, status); + /* Update lp_mode status */ + if (reset) + { + val = status&(~mask); + //printk("1:new val=0x%x\n", val); + } + else + { + val =status | (mask); + //printk("0:new val=0x%x\n", val); + } + + status = as7716_32xb_cpld_write_internal(client, reg, val); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + + + +static const struct i2c_device_id as7716_32xb_cpld_id[] = { + { "as7716_32xb_cpld1", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, as7716_32xb_cpld_id); + +static struct i2c_driver as7716_32xb_cpld_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "as7716_32xb_cpld1", + }, + .probe = as7716_32xb_cpld_probe, + .remove = as7716_32xb_cpld_remove, + .id_table = as7716_32xb_cpld_id, + .address_list = normal_i2c, +}; + +static int __init as7716_32xb_cpld_init(void) +{ + mutex_init(&list_lock); + return i2c_add_driver(&as7716_32xb_cpld_driver); +} + +static void __exit as7716_32xb_cpld_exit(void) +{ + i2c_del_driver(&as7716_32xb_cpld_driver); +} + +module_init(as7716_32xb_cpld_init); +module_exit(as7716_32xb_cpld_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("as7716_32xb_cpld driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_fan.c b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_fan.c new file mode 100755 index 000000000000..5c1c3016c3a1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_fan.c @@ -0,0 +1,969 @@ +/* + * A hwmon driver for the Accton as7716 32x fan + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "as7716_32xb_fan" + +#define NUM_THERMAL_SENSORS (3) /* Get sum of this number of sensors.*/ +#define THERMAL_SENSORS_DRIVER "lm75" +#define STRING_TO_DEC_VALUE 10 + +#define IN +#define OUT + +static struct as7716_32xb_fan_data *as7716_32xb_fan_update_device(struct device *dev); +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t get_enable(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_enable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t get_sys_temp(struct device *dev, struct device_attribute *da, char *buf); + + +static ssize_t fan_value_show(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t fan_value_store(struct device *dev, struct device_attribute *da, + char *buf, size_t size); + +/* fan related data, the index should match sysfs_fan_attributes + */ +static const u8 fan_reg[] = { + 0x0F, /* fan 1-6 present status */ + 0x10, /* fan 1-6 direction(0:B2F 1:F2B) */ + 0x11, /* fan PWM(for all fan) */ + 0x12, /* front fan 1 speed(rpm) */ + 0x13, /* front fan 2 speed(rpm) */ + 0x14, /* front fan 3 speed(rpm) */ + 0x15, /* front fan 4 speed(rpm) */ + 0x16, /* front fan 5 speed(rpm) */ + 0x17, /* front fan 6 speed(rpm) */ + 0x22, /* rear fan 1 speed(rpm) */ + 0x23, /* rear fan 2 speed(rpm) */ + 0x24, /* rear fan 3 speed(rpm) */ + 0x25, /* rear fan 4 speed(rpm) */ + 0x26, /* rear fan 5 speed(rpm) */ + 0x27, /* rear fan 6 speed(rpm) */ +}; + +#define FAN_NUM_MAX 6 +/* Each client has this additional data */ +struct as7716_32xb_fan_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[ARRAY_SIZE(fan_reg)]; /* Register value */ + u8 enable; + u8 duty_cycle; + int system_temp; /*In unit of mini-Celsius*/ + int sensors_found; + unsigned int present[FAN_NUM_MAX]; + unsigned int front_speed_rpm[FAN_NUM_MAX]; + unsigned int rear_speed_rpm[FAN_NUM_MAX]; + unsigned int direction[FAN_NUM_MAX]; + unsigned int fault[FAN_NUM_MAX]; + unsigned int input[FAN_NUM_MAX]; +}; + +enum FAN_ID { + FAN1_ID, + FAN2_ID, + FAN3_ID, + FAN4_ID, + FAN5_ID, + FAN6_ID +}; + +enum sysfs_fan_attributes { + FAN_PRESENT_REG, + FAN_DIRECTION_REG, + FAN_DUTY_CYCLE_PERCENTAGE, /* Only one CPLD register to control duty cycle for all fans */ + FAN1_FRONT_SPEED_RPM, + FAN2_FRONT_SPEED_RPM, + FAN3_FRONT_SPEED_RPM, + FAN4_FRONT_SPEED_RPM, + FAN5_FRONT_SPEED_RPM, + FAN6_FRONT_SPEED_RPM, + FAN1_REAR_SPEED_RPM, + FAN2_REAR_SPEED_RPM, + FAN3_REAR_SPEED_RPM, + FAN4_REAR_SPEED_RPM, + FAN5_REAR_SPEED_RPM, + FAN6_REAR_SPEED_RPM, + FAN1_DIRECTION, + FAN2_DIRECTION, + FAN3_DIRECTION, + FAN4_DIRECTION, + FAN5_DIRECTION, + FAN6_DIRECTION, + FAN1_PRESENT, + FAN2_PRESENT, + FAN3_PRESENT, + FAN4_PRESENT, + FAN5_PRESENT, + FAN6_PRESENT, + FAN1_FAULT, + FAN2_FAULT, + FAN3_FAULT, + FAN4_FAULT, + FAN5_FAULT, + FAN6_FAULT +}; + +/* Define attributes + */ +#define DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(index, index2) \ + static SENSOR_DEVICE_ATTR(fan##index##_fault, S_IRUGO|S_IWUSR, fan_value_show, fan_value_store, FAN##index##_FAULT);\ + static SENSOR_DEVICE_ATTR(fan##index2##_fault, S_IRUGO|S_IWUSR, fan_value_show, fan_value_store, FAN##index##_FAULT) +#define DECLARE_FAN_FAULT_ATTR(index, index2) &sensor_dev_attr_fan##index##_fault.dev_attr.attr, \ + &sensor_dev_attr_fan##index2##_fault.dev_attr.attr + +#define DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_direction, S_IRUGO|S_IWUSR, fan_value_show, fan_value_store, FAN##index##_DIRECTION) +#define DECLARE_FAN_DIRECTION_ATTR(index) &sensor_dev_attr_fan##index##_direction.dev_attr.attr + + +#define DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan_duty_cycle_percentage, S_IWUSR | S_IRUGO, fan_value_show, fan_value_store, FAN_DUTY_CYCLE_PERCENTAGE);\ + static SENSOR_DEVICE_ATTR(pwm##index, S_IWUSR | S_IRUGO, fan_value_show, set_duty_cycle, FAN_DUTY_CYCLE_PERCENTAGE);\ + static SENSOR_DEVICE_ATTR(pwm##index##_enable, S_IWUSR | S_IRUGO, get_enable, set_enable, FAN_DUTY_CYCLE_PERCENTAGE) + +#define DECLARE_FAN_DUTY_CYCLE_ATTR(index) &sensor_dev_attr_fan_duty_cycle_percentage.dev_attr.attr, \ + &sensor_dev_attr_pwm##index.dev_attr.attr, \ + &sensor_dev_attr_pwm##index##_enable.dev_attr.attr + +#define DECLARE_FAN_SYSTEM_TEMP_SENSOR_DEV_ATTR() \ + static SENSOR_DEVICE_ATTR(sys_temp, S_IWUSR|S_IRUGO, get_sys_temp, NULL, FAN_DUTY_CYCLE_PERCENTAGE) + +#define DECLARE_FAN_SYSTEM_TEMP_ATTR() &sensor_dev_attr_sys_temp.dev_attr.attr + + + +#define DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_present, S_IWUSR|S_IRUGO, fan_value_show, fan_value_store, FAN##index##_PRESENT) +#define DECLARE_FAN_PRESENT_ATTR(index) &sensor_dev_attr_fan##index##_present.dev_attr.attr + + +#define DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(index, index2) \ + static SENSOR_DEVICE_ATTR(fan##index##_front_speed_rpm, S_IWUSR|S_IRUGO, fan_value_show, fan_value_store, FAN##index##_FRONT_SPEED_RPM);\ + static SENSOR_DEVICE_ATTR(fan##index##_rear_speed_rpm, S_IWUSR|S_IRUGO, fan_value_show, fan_value_store, FAN##index##_REAR_SPEED_RPM);\ + static SENSOR_DEVICE_ATTR(fan##index##_input, S_IWUSR|S_IRUGO, fan_value_show, fan_value_store, FAN##index##_FRONT_SPEED_RPM);\ + static SENSOR_DEVICE_ATTR(fan##index2##_input, S_IWUSR|S_IRUGO, fan_value_show, fan_value_store, FAN##index##_REAR_SPEED_RPM) +#define DECLARE_FAN_SPEED_RPM_ATTR(index, index2) &sensor_dev_attr_fan##index##_front_speed_rpm.dev_attr.attr, \ + &sensor_dev_attr_fan##index##_rear_speed_rpm.dev_attr.attr, \ + &sensor_dev_attr_fan##index##_input.dev_attr.attr, \ + &sensor_dev_attr_fan##index2##_input.dev_attr.attr + +/* 6 fan fault attributes in this platform */ +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(1,11); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(2,12); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(3,13); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(4,14); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(5,15); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(6,16); +/* 6 fan speed(rpm) attributes in this platform */ +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(1,11); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(2,12); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(3,13); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(4,14); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(5,15); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(6,16); +/* 6 fan present attributes in this platform */ +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(1); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(2); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(3); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(4); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(5); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(6); + +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(1); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(2); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(3); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(4); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(5); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(6); + +/* 1 fan duty cycle attribute in this platform */ +DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(1); +/* System temperature for fancontrol */ +DECLARE_FAN_SYSTEM_TEMP_SENSOR_DEV_ATTR(); + +static struct attribute *as7716_32xb_fan_attributes[] = { + /* fan related attributes */ + DECLARE_FAN_FAULT_ATTR(1,11), + DECLARE_FAN_FAULT_ATTR(2,12), + DECLARE_FAN_FAULT_ATTR(3,13), + DECLARE_FAN_FAULT_ATTR(4,14), + DECLARE_FAN_FAULT_ATTR(5,15), + DECLARE_FAN_FAULT_ATTR(6,16), + DECLARE_FAN_SPEED_RPM_ATTR(1,11), + DECLARE_FAN_SPEED_RPM_ATTR(2,12), + DECLARE_FAN_SPEED_RPM_ATTR(3,13), + DECLARE_FAN_SPEED_RPM_ATTR(4,14), + DECLARE_FAN_SPEED_RPM_ATTR(5,15), + DECLARE_FAN_SPEED_RPM_ATTR(6,16), + DECLARE_FAN_PRESENT_ATTR(1), + DECLARE_FAN_PRESENT_ATTR(2), + DECLARE_FAN_PRESENT_ATTR(3), + DECLARE_FAN_PRESENT_ATTR(4), + DECLARE_FAN_PRESENT_ATTR(5), + DECLARE_FAN_PRESENT_ATTR(6), + DECLARE_FAN_DIRECTION_ATTR(1), + DECLARE_FAN_DIRECTION_ATTR(2), + DECLARE_FAN_DIRECTION_ATTR(3), + DECLARE_FAN_DIRECTION_ATTR(4), + DECLARE_FAN_DIRECTION_ATTR(5), + DECLARE_FAN_DIRECTION_ATTR(6), + DECLARE_FAN_DUTY_CYCLE_ATTR(1), + DECLARE_FAN_SYSTEM_TEMP_ATTR(), + NULL +}; + +#define FAN_DUTY_CYCLE_REG_MASK 0xF +#define FAN_MAX_DUTY_CYCLE 100 +#define FAN_REG_VAL_TO_SPEED_RPM_STEP 100 + +static int as7716_32xb_fan_read_value(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int as7716_32xb_fan_write_value(struct i2c_client *client, u8 reg, u8 value) +{ + return i2c_smbus_write_byte_data(client, reg, value); +} + +/* fan utility functions + */ +static u32 reg_val_to_duty_cycle(u8 reg_val) +{ + reg_val &= FAN_DUTY_CYCLE_REG_MASK; + return ((u32)(reg_val+1) * 625 + 75)/ 100; +} + +static u8 duty_cycle_to_reg_val(u8 duty_cycle) +{ + return ((u32)duty_cycle * 100 / 625) - 1; +} + +static u32 reg_val_to_speed_rpm(u8 reg_val) +{ + return (u32)reg_val * FAN_REG_VAL_TO_SPEED_RPM_STEP; +} + +static u8 reg_val_to_direction(u8 reg_val, enum FAN_ID id) +{ + u8 mask = (1 << id); + + reg_val &= mask; + + return reg_val ? 1 : 0; +} +static u8 reg_val_to_is_present(u8 reg_val, enum FAN_ID id) +{ + u8 mask = (1 << id); + + reg_val &= mask; + + return reg_val ? 0 : 1; +} + +static u8 is_fan_fault(struct as7716_32xb_fan_data *data, enum FAN_ID id) +{ + u8 ret = 0; + + /* Check if the speed of front or rear fan is ZERO, + */ + if (!data->front_speed_rpm[id] && + !data->rear_speed_rpm[id] ) + { + ret = 1; + } + + return ret; +} + + +static ssize_t set_enable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct as7716_32xb_fan_data *data = as7716_32xb_fan_update_device(dev); + int error, value; + + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (value < 0 || value > 1) + return -EINVAL; + + data->enable = value; + if (value == 0) + { + return set_duty_cycle(dev, da, buf, FAN_MAX_DUTY_CYCLE); + } + return count; +} + + + +static ssize_t get_enable(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct as7716_32xb_fan_data *data = as7716_32xb_fan_update_device(dev); + + return sprintf(buf, "%u\n", data->enable); +} + +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int error, value; + struct i2c_client *client = to_i2c_client(dev); + + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (value < 0 || value > FAN_MAX_DUTY_CYCLE) + return -EINVAL; + + as7716_32xb_fan_write_value(client, 0x33, 0); /* Disable fan speed watch dog */ + as7716_32xb_fan_write_value(client, fan_reg[FAN_DUTY_CYCLE_PERCENTAGE], duty_cycle_to_reg_val(value)); + return count; +} + +/* Due to this struct is declared at lm75.c, it cannot be include + * under Sonic environment. I duplicate it from lm75.c. + */ +struct lm75_data { + struct i2c_client *client; + struct device *hwmon_dev; + struct thermal_zone_device *tz; + struct mutex update_lock; + u8 orig_conf; + u8 resolution; /* In bits, between 9 and 12 */ + u8 resolution_limits; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + unsigned long sample_time; /* In jiffies */ + s16 temp[3]; /* Register values, + 0 = input + 1 = max + 2 = hyst */ +}; + +/*Copied from lm75.c*/ +static inline long lm75_reg_to_mc(s16 temp, u8 resolution) +{ + return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8); +} + +/*Get hwmon_dev from i2c_client, set hwmon_dev = NULL is failed.*/ +static struct device * get_hwmon_dev( + struct i2c_client *client) +{ + struct lm75_data *data = NULL; + + data = i2c_get_clientdata(client); + if(data) + { + if( data->valid == 1 && data->hwmon_dev) + { + return data->hwmon_dev; + } + + } + return NULL; +} + +/* To find hwmon index by opening hwmon under that i2c address. + */ +static int find_hwmon_index_by_FileOpen( + int bus_nr, + unsigned short addr, + OUT int *index) +{ +#define MAX_HWMON_DEVICE (10) /* Find hwmon device in 0~10*/ + struct file *sfd; + char client_name[96]; + int i=0; + + do { + snprintf(client_name, sizeof(client_name), + "/sys/bus/i2c/devices/%d-%04x/hwmon/hwmon%d/temp1_input", + bus_nr, addr, i); + + sfd = filp_open(client_name, O_RDONLY, 0); + i++; + } while( IS_ERR(sfd) && i < MAX_HWMON_DEVICE); + + if (IS_ERR(sfd)) { + pr_err("Failed to open file(%s)#%d\r\n", client_name, __LINE__); + return -ENOENT; + } + filp_close(sfd, 0); + *index = i - 1; + return 0; + +#undef MAX_HWMON_DEVICE +} + +static int get_temp_file_path( + int bus_nr, unsigned short addr, + struct device *hwmon_dev + ,char *path, int max_len) +{ + + if(hwmon_dev && strlen(dev_name(hwmon_dev))) + { + snprintf(path, max_len, + "/sys/bus/i2c/devices/%d-%04x/hwmon/%s/temp1_input", + bus_nr, addr, dev_name(hwmon_dev)); + } + else + { + int i=0; + if(find_hwmon_index_by_FileOpen( bus_nr, addr, &i)) + { + return -EIO; + } + snprintf(path, max_len, + "/sys/bus/i2c/devices/%d-%04x/hwmon/hwmon%d/temp1_input", + bus_nr, addr, i); + } + return 0; +} + +/*File read the dev file at user space.*/ +static int read_devfile_temp1_input( + struct device *dev, + int bus_nr, + unsigned short addr, + struct device *hwmon_dev, + int *miniCelsius) +{ + struct file *sfd; + char buffer[96]; + char devfile[96]; + int rc, status; + int rdlen, value; + mm_segment_t old_fs; + + rc = 0; + get_temp_file_path(bus_nr, addr, hwmon_dev, devfile, sizeof(devfile)); + sfd = filp_open(devfile, O_RDONLY, 0); + if (IS_ERR(sfd)) { + pr_err("Failed to open file(%s)#%d\r\n", devfile, __LINE__); + return -ENOENT; + } + dev_dbg(dev, "Found device:%s\n",devfile); + + if(!(sfd->f_op) || !(sfd->f_op->read) ) { + pr_err("file %s cann't readable ?\n",devfile); + return -ENOENT; + } + + old_fs = get_fs(); + set_fs(KERNEL_DS); + rdlen = sfd->f_op->read(sfd, buffer, sizeof(buffer), &sfd->f_pos); + if (rdlen == 0) { + pr_err( "File(%s) empty!\n", devfile); + rc = -EIO; + goto exit; + } + status = sscanf(buffer, "%d", &value); + if (status != 1) { + rc = -EIO; + goto exit; + } + *miniCelsius = value; + dev_dbg(dev,"found sensors: %d @i2c %d-%04x\n", value, bus_nr, addr); + +exit: + set_fs(old_fs); + filp_close(sfd, 0); + return rc; +} + +static u8 is_lm75_data_due(struct i2c_client *client) +{ + struct lm75_data *data = NULL; + + data = i2c_get_clientdata(client); + if (time_after(jiffies, data->last_updated + data->sample_time)) + { + return 1; + } + return 0; +} +static int get_lm75_temp(struct i2c_client *client, int *miniCelsius) +{ + struct lm75_data *data = NULL; + + data = i2c_get_clientdata(client); + *miniCelsius = lm75_reg_to_mc(data->temp[0], data->resolution); + + return 0; +} + +static int _find_lm75_device(struct device *dev, void *data) +{ + struct device_driver *driver; + struct as7716_32xb_fan_data *prv = data; + char *driver_name = THERMAL_SENSORS_DRIVER; + + driver = dev->driver; + if (driver && driver->name && + strcmp(driver->name, driver_name) == 0) + { + struct i2c_client *client; + client = to_i2c_client(dev); + if (client) + { + /*cannot use "struct i2c_adapter *adap = to_i2c_adapter(dev);"*/ + struct i2c_adapter *adap = client->adapter; + int miniCelsius = 0; + + + if (!adap) { + return -ENXIO; + } + + /* If the data is not updated, read them from devfile + to drive them updateing data from chip.*/ + if (is_lm75_data_due(client)) + { + struct device *hwmon_dev; + + hwmon_dev = get_hwmon_dev(client); + if(0 == read_devfile_temp1_input(dev, adap->nr, + client->addr, hwmon_dev, &miniCelsius)) + { + prv->system_temp += miniCelsius; + prv->sensors_found++; + } + + } + else + { + get_lm75_temp(client, &miniCelsius); + prv->system_temp += miniCelsius; + prv->sensors_found++; + + } + } + } + return 0; +} + +/*Find all lm75 devices and return sum of temperatures.*/ +static ssize_t get_sys_temp(struct device *dev, struct device_attribute *da, + char *buf) +{ + ssize_t ret = 0; + struct as7716_32xb_fan_data *data = as7716_32xb_fan_update_device(dev); + + data->system_temp=0; + data->sensors_found=0; + i2c_for_each_dev(data, _find_lm75_device); + if (NUM_THERMAL_SENSORS != data->sensors_found) + { + dev_dbg(dev,"only %d of %d temps are found\n", + data->sensors_found, NUM_THERMAL_SENSORS); + data->system_temp = 0; + } + ret = sprintf(buf, "%d\n",data->system_temp); + return ret; +} + + +static int fan_array_index_get(int attr_idx) +{ + switch(attr_idx) + { + case FAN1_PRESENT: + case FAN1_FRONT_SPEED_RPM: + case FAN1_REAR_SPEED_RPM: + case FAN1_FAULT: + case FAN1_DIRECTION: + return FAN1_ID; + case FAN2_PRESENT: + case FAN2_FRONT_SPEED_RPM: + case FAN2_REAR_SPEED_RPM: + case FAN2_FAULT: + case FAN2_DIRECTION: + return FAN2_ID; + case FAN3_PRESENT: + case FAN3_FRONT_SPEED_RPM: + case FAN3_REAR_SPEED_RPM: + case FAN3_FAULT: + case FAN3_DIRECTION: + return FAN3_ID; + case FAN4_PRESENT: + case FAN4_FRONT_SPEED_RPM: + case FAN4_REAR_SPEED_RPM: + case FAN4_FAULT: + case FAN4_DIRECTION: + return FAN4_ID; + case FAN5_PRESENT: + case FAN5_FRONT_SPEED_RPM: + case FAN5_REAR_SPEED_RPM: + case FAN5_FAULT: + case FAN5_DIRECTION: + return FAN5_ID; + case FAN6_PRESENT: + case FAN6_FRONT_SPEED_RPM: + case FAN6_REAR_SPEED_RPM: + case FAN6_FAULT: + case FAN6_DIRECTION: + return FAN6_ID; + default : + return -1; + } +} + +static ssize_t fan_value_store(struct device *dev, struct device_attribute *da, + char *buf, size_t size) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32xb_fan_data *data = i2c_get_clientdata(client); + int status = -EINVAL; + int index; + long keyin = 0; + //printk("fan_value_store\n"); + //printk("attr->index=%d\n", attr->index); + mutex_lock(&data->update_lock); + switch (attr->index) + { + case FAN_DUTY_CYCLE_PERCENTAGE: + status = kstrtol(buf, STRING_TO_DEC_VALUE, &keyin); + if (status) + break; + if (keyin > 1 || keyin < 0) + break; + data->duty_cycle=keyin; + break; + case FAN1_FRONT_SPEED_RPM: + case FAN2_FRONT_SPEED_RPM: + case FAN3_FRONT_SPEED_RPM: + case FAN4_FRONT_SPEED_RPM: + case FAN5_FRONT_SPEED_RPM: + case FAN6_FRONT_SPEED_RPM: + status = kstrtol(buf, STRING_TO_DEC_VALUE, &keyin); + if (status) + break; + index=fan_array_index_get(attr->index); + if(index < 0 || index > (FAN_NUM_MAX-1)) + break; + data->front_speed_rpm[index]=keyin; + break; + case FAN1_REAR_SPEED_RPM: + case FAN2_REAR_SPEED_RPM: + case FAN3_REAR_SPEED_RPM: + case FAN4_REAR_SPEED_RPM: + case FAN5_REAR_SPEED_RPM: + case FAN6_REAR_SPEED_RPM: + status = kstrtol(buf, STRING_TO_DEC_VALUE, &keyin); + if (status) + break; + index=fan_array_index_get(attr->index); + if(index < 0 || index > (FAN_NUM_MAX-1)) + break; + data->rear_speed_rpm[index]=keyin; + case FAN1_PRESENT: + case FAN2_PRESENT: + case FAN3_PRESENT: + case FAN4_PRESENT: + case FAN5_PRESENT: + case FAN6_PRESENT: + status = kstrtol(buf, STRING_TO_DEC_VALUE, &keyin); + if (status) + break; + index=fan_array_index_get(attr->index); + if(index < 0 || index > (FAN_NUM_MAX-1)) + break; + if(keyin < 0 || keyin > 1) + break; + data->present[index]=keyin; + break; + case FAN1_FAULT: + case FAN2_FAULT: + case FAN3_FAULT: + case FAN4_FAULT: + case FAN5_FAULT: + case FAN6_FAULT: + status = kstrtol(buf, STRING_TO_DEC_VALUE, &keyin); + if (status) + break; + index=fan_array_index_get(attr->index); + if(index < 0 || index > (FAN_NUM_MAX-1)) + break; + if(keyin < 0 || keyin > 1) + break; + data->fault[index]=keyin; + break; + case FAN1_DIRECTION: + case FAN2_DIRECTION: + case FAN3_DIRECTION: + case FAN4_DIRECTION: + case FAN5_DIRECTION: + case FAN6_DIRECTION: + status = kstrtol(buf, STRING_TO_DEC_VALUE, &keyin); + if (status) + break; + index=fan_array_index_get(attr->index); + if(index < 0 || index > (FAN_NUM_MAX-1)) + break; + if(keyin < 0 || keyin > 1) + break; + data->direction[index]=keyin; + break; + default: + break; + } + mutex_unlock(&data->update_lock); + return size; +} +static ssize_t fan_value_show(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32xb_fan_data *data = i2c_get_clientdata(client); + int status = -EINVAL; + int index=0; + //printk("ffan_value_show\n"); + //printk("attr->index=%d\n", attr->index); + mutex_lock(&data->update_lock); + switch (attr->index) + { + case FAN_DUTY_CYCLE_PERCENTAGE: + status = sprintf(buf, "%u\n", data->duty_cycle); + break; + case FAN1_FRONT_SPEED_RPM: + case FAN2_FRONT_SPEED_RPM: + case FAN3_FRONT_SPEED_RPM: + case FAN4_FRONT_SPEED_RPM: + case FAN5_FRONT_SPEED_RPM: + case FAN6_FRONT_SPEED_RPM: + index=fan_array_index_get(attr->index); + if(index < 0 || index > (FAN_NUM_MAX-1)) + break; + status = sprintf(buf, "%u\n", data->front_speed_rpm[index]); + break; + case FAN1_REAR_SPEED_RPM: + case FAN2_REAR_SPEED_RPM: + case FAN3_REAR_SPEED_RPM: + case FAN4_REAR_SPEED_RPM: + case FAN5_REAR_SPEED_RPM: + case FAN6_REAR_SPEED_RPM: + index=fan_array_index_get(attr->index); + if(index < 0 || index > (FAN_NUM_MAX-1)) + break; + status = sprintf(buf, "%u\n", data->rear_speed_rpm[index]); + break; + case FAN1_PRESENT: + case FAN2_PRESENT: + case FAN3_PRESENT: + case FAN4_PRESENT: + case FAN5_PRESENT: + case FAN6_PRESENT: + index=fan_array_index_get(attr->index); + if(index < 0 || index > (FAN_NUM_MAX-1)) + break; + status = sprintf(buf, "%d\n", data->present[index]); + break; + case FAN1_FAULT: + case FAN2_FAULT: + case FAN3_FAULT: + case FAN4_FAULT: + case FAN5_FAULT: + case FAN6_FAULT: + index=fan_array_index_get(attr->index); + if(index < 0 || index > (FAN_NUM_MAX-1)) + break; + status = sprintf(buf, "%d\n", is_fan_fault(data, index)); + break; + case FAN1_DIRECTION: + case FAN2_DIRECTION: + case FAN3_DIRECTION: + case FAN4_DIRECTION: + case FAN5_DIRECTION: + case FAN6_DIRECTION: + index=fan_array_index_get(attr->index);; + if(index < 0 || index > (FAN_NUM_MAX-1)) + break; + status = sprintf(buf, "%d\n", data->direction[index]); + break; + default: + break; + } + mutex_unlock(&data->update_lock); + return status; +} + +static const struct attribute_group as7716_32xb_fan_group = { + .attrs = as7716_32xb_fan_attributes, +}; + +static struct as7716_32xb_fan_data *as7716_32xb_fan_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32xb_fan_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || + !data->valid) { + int i; + + dev_dbg(&client->dev, "Starting as7716_32xb_fan update\n"); + data->valid = 0; + + /* Update fan data + */ + for (i = 0; i < ARRAY_SIZE(data->reg_val); i++) { + int status = as7716_32xb_fan_read_value(client, fan_reg[i]); + + if (status < 0) { + data->valid = 0; + mutex_unlock(&data->update_lock); + dev_dbg(&client->dev, "reg %d, err %d\n", fan_reg[i], status); + return data; + } + else { + data->reg_val[i] = status; + } + } + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +static int as7716_32xb_fan_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct as7716_32xb_fan_data *data; + int status; + + data = kzalloc(sizeof(struct as7716_32xb_fan_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as7716_32xb_fan_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: fan '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as7716_32xb_fan_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as7716_32xb_fan_remove(struct i2c_client *client) +{ + struct as7716_32xb_fan_data *data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as7716_32xb_fan_group); + + return 0; +} + +/* Addresses to scan */ +static const unsigned short normal_i2c[] = { 0x66, I2C_CLIENT_END }; + +static const struct i2c_device_id as7716_32xb_fan_id[] = { + { "as7716_32xb_fan", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, as7716_32xb_fan_id); + +static struct i2c_driver as7716_32xb_fan_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = DRVNAME, + }, + .probe = as7716_32xb_fan_probe, + .remove = as7716_32xb_fan_remove, + .id_table = as7716_32xb_fan_id, + .address_list = normal_i2c, +}; + +static int __init as7716_32xb_fan_init(void) +{ + return i2c_add_driver(&as7716_32xb_fan_driver); +} + +static void __exit as7716_32xb_fan_exit(void) +{ + i2c_del_driver(&as7716_32xb_fan_driver); +} + +module_init(as7716_32xb_fan_init); +module_exit(as7716_32xb_fan_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("as7716_32xb_fan driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_leds.c b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_leds.c new file mode 100755 index 000000000000..2fa3fd722cb1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_leds.c @@ -0,0 +1,443 @@ +/* + * A LED driver for the as7716_32xb_led + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*#define DEBUG*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +extern void led_classdev_unregister(struct led_classdev *led_cdev); +extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); +extern void led_classdev_resume(struct led_classdev *led_cdev); +extern void led_classdev_suspend(struct led_classdev *led_cdev); + +#define DRVNAME "as7716_32x_led" + +struct as7716_32x_led_data { + struct platform_device *pdev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[1]; /* only 1 register*/ +}; + +static struct as7716_32x_led_data *ledctl = NULL; + +/* LED related data + */ + +#define LED_CNTRLER_I2C_ADDRESS (0x60) + +#define LED_TYPE_DIAG_REG_MASK (0x3) +#define LED_MODE_DIAG_GREEN_VALUE (0x02) +#define LED_MODE_DIAG_RED_VALUE (0x01) +#define LED_MODE_DIAG_AMBER_VALUE (0x00) /*It's yellow actually. Green+Red=Yellow*/ +#define LED_MODE_DIAG_OFF_VALUE (0x03) + + +#define LED_TYPE_LOC_REG_MASK (0x80) +#define LED_MODE_LOC_ON_VALUE (0) +#define LED_MODE_LOC_OFF_VALUE (0x80) + +enum led_type { + LED_TYPE_DIAG, + LED_TYPE_LOC, + LED_TYPE_FAN, + LED_TYPE_PSU1, + LED_TYPE_PSU2 +}; + +struct led_reg { + u32 types; + u8 reg_addr; +}; + +static const struct led_reg led_reg_map[] = { + {(1<update_lock); + + if (time_after(jiffies, ledctl->last_updated + HZ + HZ / 2) + || !ledctl->valid) { + int i; + + dev_dbg(&ledctl->pdev->dev, "Starting as7716_32x_led update\n"); + + /* Update LED data + */ + for (i = 0; i < ARRAY_SIZE(ledctl->reg_val); i++) { + int status = as7716_32x_led_read_value(led_reg_map[i].reg_addr); + + if (status < 0) { + ledctl->valid = 0; + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", led_reg_map[i].reg_addr, status); + goto exit; + } + else + { + ledctl->reg_val[i] = status; + } + } + + ledctl->last_updated = jiffies; + ledctl->valid = 1; + } + +exit: + mutex_unlock(&ledctl->update_lock); +} + +static void as7716_32x_led_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode, + enum led_type type) +{ + int reg_val; + u8 reg ; + mutex_lock(&ledctl->update_lock); + + if( !getLedReg(type, ®)) + { + dev_dbg(&ledctl->pdev->dev, "Not match item for %d.\n", type); + } + + reg_val = as7716_32x_led_read_value(reg); + + if (reg_val < 0) { + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", reg, reg_val); + goto exit; + } + reg_val = led_light_mode_to_reg_val(type, led_light_mode, reg_val); + as7716_32x_led_write_value(reg, reg_val); + + /* to prevent the slow-update issue */ + ledctl->valid = 0; + +exit: + mutex_unlock(&ledctl->update_lock); +} + + +static void as7716_32x_led_diag_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + as7716_32x_led_set(led_cdev, led_light_mode, LED_TYPE_DIAG); +} + +static enum led_brightness as7716_32x_led_diag_get(struct led_classdev *cdev) +{ + as7716_32x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_DIAG, ledctl->reg_val[0]); +} + +static void as7716_32x_led_loc_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + as7716_32x_led_set(led_cdev, led_light_mode, LED_TYPE_LOC); +} + +static enum led_brightness as7716_32x_led_loc_get(struct led_classdev *cdev) +{ + as7716_32x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_LOC, ledctl->reg_val[0]); +} + +static void as7716_32x_led_auto_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ +} + +static enum led_brightness as7716_32x_led_auto_get(struct led_classdev *cdev) +{ + return LED_MODE_AUTO; +} + +static struct led_classdev as7716_32x_leds[] = { + [LED_TYPE_DIAG] = { + .name = "as7716_32x_led::diag", + .default_trigger = "unused", + .brightness_set = as7716_32x_led_diag_set, + .brightness_get = as7716_32x_led_diag_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_RED, + }, + [LED_TYPE_LOC] = { + .name = "as7716_32x_led::loc", + .default_trigger = "unused", + .brightness_set = as7716_32x_led_loc_set, + .brightness_get = as7716_32x_led_loc_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_BLUE, + }, + [LED_TYPE_FAN] = { + .name = "as7716_32x_led::fan", + .default_trigger = "unused", + .brightness_set = as7716_32x_led_auto_set, + .brightness_get = as7716_32x_led_auto_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_PSU1] = { + .name = "as7716_32x_led::psu1", + .default_trigger = "unused", + .brightness_set = as7716_32x_led_auto_set, + .brightness_get = as7716_32x_led_auto_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_PSU2] = { + .name = "as7716_32x_led::psu2", + .default_trigger = "unused", + .brightness_set = as7716_32x_led_auto_set, + .brightness_get = as7716_32x_led_auto_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, +}; + +static int as7716_32x_led_suspend(struct platform_device *dev, + pm_message_t state) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(as7716_32x_leds); i++) { + led_classdev_suspend(&as7716_32x_leds[i]); + } + + return 0; +} + +static int as7716_32x_led_resume(struct platform_device *dev) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(as7716_32x_leds); i++) { + led_classdev_resume(&as7716_32x_leds[i]); + } + + return 0; +} + +static int as7716_32x_led_probe(struct platform_device *pdev) +{ + int ret, i; + + printk("as7716_32x_led_probe 1\n"); + for (i = 0; i < ARRAY_SIZE(as7716_32x_leds); i++) { + ret = led_classdev_register(&pdev->dev, &as7716_32x_leds[i]); + + if (ret < 0) + { + printk("ret < 0, i=%d\n", i); + break; + } + } + printk("as7716_32x_led_probe 2\n"); + /* Check if all LEDs were successfully registered */ + if (i != ARRAY_SIZE(as7716_32x_leds)){ + int j; + + /* only unregister the LEDs that were successfully registered */ + for (j = 0; j < i; j++) { + led_classdev_unregister(&as7716_32x_leds[i]); + } + } + + printk("as7716_32x_led_probe 3\n"); + return 0; +} + +static int as7716_32x_led_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(as7716_32x_leds); i++) { + led_classdev_unregister(&as7716_32x_leds[i]); + } + + return 0; +} + +static struct platform_driver as7716_32x_led_driver = { + .probe = as7716_32x_led_probe, + .remove = as7716_32x_led_remove, + .suspend = as7716_32x_led_suspend, + .resume = as7716_32x_led_resume, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +static int __init as7716_32x_led_init(void) +{ + int ret; + + printk("leds:1\n"); + ret = platform_driver_register(&as7716_32x_led_driver); + if (ret < 0) { + printk("leds:fail platform_driver_register\n"); + goto exit; + } + printk("leds:2\n"); + ledctl = kzalloc(sizeof(struct as7716_32x_led_data), GFP_KERNEL); + if (!ledctl) { + ret = -ENOMEM; + platform_driver_unregister(&as7716_32x_led_driver); + goto exit; + } + + mutex_init(&ledctl->update_lock); + printk("leds:3\n"); + ledctl->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(ledctl->pdev)) { + printk("leds:fail platform_device_register_simple\n"); + ret = PTR_ERR(ledctl->pdev); + platform_driver_unregister(&as7716_32x_led_driver); + kfree(ledctl); + goto exit; + } + +exit: + return 0; +} + +static void __exit as7716_32x_led_exit(void) +{ + platform_device_unregister(ledctl->pdev); + platform_driver_unregister(&as7716_32x_led_driver); + kfree(ledctl); +} + +module_init(as7716_32x_led_init); +module_exit(as7716_32x_led_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("as7716_32x_led driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_oom.c b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_oom.c new file mode 100755 index 000000000000..5e88d9efad5d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_oom.c @@ -0,0 +1,267 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define STRING_TO_DEC_VALUE 10 +#define EEPROM_DATA_SIZE 512 + + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; +#define MAX_PORT_NAME_LEN 20 +/* Each client has this additional data + */ +struct as7716_32xb_oom_data { + struct device *hwmon_dev; + struct mutex lock; + u8 index; + unsigned char eeprom[EEPROM_DATA_SIZE]; + char port_name[MAX_PORT_NAME_LEN]; + +}; + + + +enum as7716_32xb_oom_sysfs_attributes { + TEMP1_INPUT, + TEMP1_MAX_HYST, + TEMP1_MAX +}; + +/* sysfs attributes for hwmon + */ + +static ssize_t oom_info_store(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t oom_info_show(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_port_name(struct device *dev, + struct device_attribute *dattr, char *buf); +static ssize_t set_port_name(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count); +static SENSOR_DEVICE_ATTR(eeprom, S_IWUSR|S_IRUGO, oom_info_show, oom_info_store, 0); +static SENSOR_DEVICE_ATTR(port_name, S_IRUGO | S_IWUSR, show_port_name, set_port_name, 1); + + +static struct attribute *as7716_32xb_oom_attributes[] = { + &sensor_dev_attr_eeprom.dev_attr.attr, + &sensor_dev_attr_port_name.dev_attr.attr, + NULL +}; + + +static ssize_t oom_info_show(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32xb_oom_data *data = i2c_get_clientdata(client); + int i; + + mutex_lock(&data->lock); + memcpy(buf, data->eeprom, EEPROM_DATA_SIZE); + //for(i=0; i < EEPROM_DATA_SIZE ; i++) + //{ + // buf[i]=data->eeprom[i]; + // printk("buf[%d]=0x%x ",i, buf[i]); + //} + //status = EEPROM_DATA_SIZE+1; + + + memcpy(buf, data->eeprom, 256); + mutex_unlock(&data->lock); + + return 256; +} + +static ssize_t oom_info_store(struct device *dev, struct device_attribute *da, + const char *buf, size_t size) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32xb_oom_data *data = i2c_get_clientdata(client); + int i=0, j=0, k=0; + unsigned char str[3]; + unsigned int val; + + // printk("strlen(buf)=%d\n",strlen(buf)); + k=0; + mutex_lock(&data->lock); + memset(data->eeprom, 0xFF, EEPROM_DATA_SIZE); + memset(str, 0x0, 3); + if(strlen(buf) >= 256 ) + { + for(i=0; i < strlen(buf) ; i++) + { + // printk("i=%d ", i); + for(j=0;j<2; j++) + { + str[j]=buf[i+j]; + } + sscanf(str, "%x", &val); + //printk("str=%s val=0x%x ", str, val); + i=j+i-1; + if(k>=EEPROM_DATA_SIZE) + { + break; + } + data->eeprom[k]=(unsigned char)val; + //printk("data->eeprom[%d]=0x%x\n",k, data->eeprom[k]); + k++; + } + } + //printk("buf=\n"); + //for(i=0; i < strlen(buf) ; i++) + //{ + // printk("%c%c ", buf[i], buf[i+1]); + // if((i % 31)==0) + // printk("\n"); + //} + //printk("\n"); + + + mutex_unlock(&data->lock); + return size; + +} + +static ssize_t show_port_name(struct device *dev, + struct device_attribute *dattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32xb_oom_data *data = i2c_get_clientdata(client); + ssize_t count; + + mutex_lock(&data->lock); + count = sprintf(buf, "%s\n", data->port_name); + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t set_port_name(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32xb_oom_data *data = i2c_get_clientdata(client); + char port_name[MAX_PORT_NAME_LEN]; + + /* no checking, this value is not used except by show_port_name */ + + if (sscanf(buf, "%19s", port_name) != 1) + return -EINVAL; + + mutex_lock(&data->lock); + strcpy(data->port_name, port_name); + mutex_unlock(&data->lock); + + return count; +} + + +static const struct attribute_group as7716_32xb_oom_group = { + .attrs = as7716_32xb_oom_attributes, +}; + +static int as7716_32xb_oom_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct as7716_32xb_oom_data *data; + int status; + + data = kzalloc(sizeof(struct as7716_32xb_oom_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + i2c_set_clientdata(client, data); + data->index = dev_id->driver_data; + mutex_init(&data->lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as7716_32xb_oom_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: oom '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as7716_32xb_oom_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as7716_32xb_oom_remove(struct i2c_client *client) +{ + struct as7716_32xb_oom_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as7716_32xb_oom_group); + kfree(data); + + return 0; +} + + +static const struct i2c_device_id as7716_32xb_oom_id[] = { + { "as7716_32xb_oom", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, as7716_32xb_oom_id); + +static struct i2c_driver as7716_32xb_oom_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "as7716_32xb_oom", + }, + .probe = as7716_32xb_oom_probe, + .remove = as7716_32xb_oom_remove, + .id_table = as7716_32xb_oom_id, + .address_list = normal_i2c, +}; + + + + + + +static int __init as7716_32xb_oom_init(void) +{ + return i2c_add_driver(&as7716_32xb_oom_driver); +} + +static void __exit as7716_32xb_oom_exit(void) +{ + i2c_del_driver(&as7716_32xb_oom_driver); +} + +module_init(as7716_32xb_oom_init); +module_exit(as7716_32xb_oom_exit); + +MODULE_AUTHOR("Jostar yang "); +MODULE_DESCRIPTION("as7716_32xb_oom driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_pmbus.c b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_pmbus.c new file mode 100755 index 000000000000..3f4dba90d1aa --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_pmbus.c @@ -0,0 +1,444 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define STRING_TO_DEC_VALUE 10 + + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +/* Each client has this additional data + */ +struct as7716_32xb_pmbus_data { + struct device *hwmon_dev; + struct mutex update_lock; + u8 index; + u8 capability; + u16 status_word; + u8 fan_fault; + u8 over_temp; + u16 v_out; + u16 i_out; + u16 p_out; + u16 temp; + u16 fan_speed; + u16 fan_duty_cycle; + u8 fan_dir[4]; + u8 pmbus_revision; + u8 mfr_id[10]; + u8 mfr_model[10]; + u8 mfr_revision[3]; + u16 mfr_vin_min; + u16 mfr_vin_max; + u16 mfr_iin_max; + u16 mfr_iout_max; + u16 mfr_pin_max; + u16 mfr_pout_max; + u16 mfr_vout_min; + u16 mfr_vout_max; + u16 power_on; + u16 temp_fault; + u16 power_good; +}; + + + +enum as7716_32xb_pmbus_sysfs_attributes { + PSU_POWER_ON = 0, + PSU_TEMP_FAULT, + PSU_POWER_GOOD, + PSU_FAN1_FAULT, + PSU_FAN_DIRECTION, + PSU_OVER_TEMP, + PSU_V_OUT, + PSU_I_OUT, + PSU_P_OUT, + PSU_P_OUT_UV, /*In Unit of microVolt, instead of mini.*/ + PSU_TEMP1_INPUT, + PSU_FAN1_SPEED, + PSU_FAN1_DUTY_CYCLE, + PSU_PMBUS_REVISION, + PSU_MFR_ID, + PSU_MFR_MODEL, + PSU_MFR_REVISION, + PSU_MFR_VIN_MIN, + PSU_MFR_VIN_MAX, + PSU_MFR_VOUT_MIN, + PSU_MFR_VOUT_MAX, + PSU_MFR_IIN_MAX, + PSU_MFR_IOUT_MAX, + PSU_MFR_PIN_MAX, + PSU_MFR_POUT_MAX +}; + +/* sysfs attributes for hwmon + */ +static ssize_t pmbus_info_show(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t pmbus_info_store(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static SENSOR_DEVICE_ATTR(psu_power_on, S_IWUSR| S_IRUGO, pmbus_info_show, pmbus_info_store, PSU_POWER_ON); +static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IWUSR| S_IRUGO, pmbus_info_show, pmbus_info_store, PSU_TEMP_FAULT); +static SENSOR_DEVICE_ATTR(psu_power_good, S_IWUSR| S_IRUGO, pmbus_info_show, pmbus_info_store, PSU_POWER_GOOD); +static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IWUSR| S_IRUGO, pmbus_info_show, pmbus_info_store, PSU_FAN1_FAULT); +static SENSOR_DEVICE_ATTR(psu_over_temp, S_IWUSR| S_IRUGO, pmbus_info_show, pmbus_info_store, PSU_OVER_TEMP); +static SENSOR_DEVICE_ATTR(psu_v_out, S_IWUSR| S_IRUGO, pmbus_info_show, pmbus_info_store, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(psu_i_out, S_IWUSR| S_IRUGO, pmbus_info_show, pmbus_info_store, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(psu_p_out, S_IWUSR| S_IRUGO, pmbus_info_show, pmbus_info_store, PSU_P_OUT); +static SENSOR_DEVICE_ATTR(psu_temp1_input,S_IWUSR| S_IRUGO, pmbus_info_show, pmbus_info_store, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm,S_IWUSR| S_IRUGO, pmbus_info_show, pmbus_info_store, PSU_FAN1_SPEED); +static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, pmbus_info_show, pmbus_info_store, PSU_FAN1_DUTY_CYCLE); +static SENSOR_DEVICE_ATTR(psu_fan_dir, S_IWUSR| S_IRUGO, pmbus_info_show, pmbus_info_store, PSU_FAN_DIRECTION); +static SENSOR_DEVICE_ATTR(psu_pmbus_revision,S_IWUSR| S_IRUGO, pmbus_info_show, pmbus_info_store, PSU_PMBUS_REVISION); +static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IWUSR| S_IRUGO, pmbus_info_show, pmbus_info_store, PSU_MFR_ID); +static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IWUSR| S_IRUGO, pmbus_info_show, pmbus_info_store, PSU_MFR_MODEL); +static SENSOR_DEVICE_ATTR(psu_mfr_revision, S_IWUSR| S_IRUGO, pmbus_info_show,pmbus_info_store, PSU_MFR_REVISION); +static SENSOR_DEVICE_ATTR(psu_mfr_vin_min, S_IWUSR| S_IRUGO, pmbus_info_show, pmbus_info_store, PSU_MFR_VIN_MIN); +static SENSOR_DEVICE_ATTR(psu_mfr_vin_max, S_IWUSR| S_IRUGO, pmbus_info_show, pmbus_info_store, PSU_MFR_VIN_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_vout_min, S_IWUSR| S_IRUGO, pmbus_info_show, pmbus_info_store, PSU_MFR_VOUT_MIN); +static SENSOR_DEVICE_ATTR(psu_mfr_vout_max, S_IWUSR| S_IRUGO, pmbus_info_show, pmbus_info_store, PSU_MFR_VOUT_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_iin_max, S_IWUSR| S_IRUGO, pmbus_info_show, pmbus_info_store, PSU_MFR_IIN_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_iout_max, S_IWUSR| S_IRUGO, pmbus_info_show, pmbus_info_store, PSU_MFR_IOUT_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_pin_max, S_IWUSR|S_IRUGO, pmbus_info_show, pmbus_info_store, PSU_MFR_PIN_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_pout_max, S_IWUSR| S_IRUGO, pmbus_info_show, pmbus_info_store, PSU_MFR_POUT_MAX); + +/*Duplicate nodes for lm-sensors.*/ +static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, pmbus_info_show, pmbus_info_store, PSU_P_OUT_UV); +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, pmbus_info_show, pmbus_info_store, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, pmbus_info_show, pmbus_info_store, PSU_FAN1_SPEED); +static SENSOR_DEVICE_ATTR(temp1_fault, S_IRUGO, pmbus_info_show, pmbus_info_store, PSU_TEMP_FAULT); + + +static struct attribute *as7716_32xb_pmbus_attributes[] = { + &sensor_dev_attr_psu_power_on.dev_attr.attr, + &sensor_dev_attr_psu_temp_fault.dev_attr.attr, + &sensor_dev_attr_psu_power_good.dev_attr.attr, + &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, + &sensor_dev_attr_psu_over_temp.dev_attr.attr, + &sensor_dev_attr_psu_v_out.dev_attr.attr, + &sensor_dev_attr_psu_i_out.dev_attr.attr, + &sensor_dev_attr_psu_p_out.dev_attr.attr, + &sensor_dev_attr_psu_temp1_input.dev_attr.attr, + &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, + &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, + &sensor_dev_attr_psu_fan_dir.dev_attr.attr, + &sensor_dev_attr_psu_pmbus_revision.dev_attr.attr, + &sensor_dev_attr_psu_mfr_id.dev_attr.attr, + &sensor_dev_attr_psu_mfr_model.dev_attr.attr, + &sensor_dev_attr_psu_mfr_revision.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vin_min.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vin_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_pout_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_iin_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_pin_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vout_min.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vout_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_iout_max.dev_attr.attr, + /*Duplicate nodes for lm-sensors.*/ + &sensor_dev_attr_power1_input.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_temp1_fault.dev_attr.attr, + NULL +}; + + +static ssize_t pmbus_info_show(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32xb_pmbus_data *data = i2c_get_clientdata(client); + int status = -EINVAL; + //printk("pmbus_info_show\n"); + printk("attr->index=%d\n", attr->index); + mutex_lock(&data->update_lock); + switch (attr->index) + { + case PSU_POWER_ON: + status=snprintf(buf, PAGE_SIZE-1, "%d\r\n", data->power_on); + break; + case PSU_TEMP_FAULT: + status=snprintf(buf, PAGE_SIZE-1, "%d\r\n", data->temp_fault); + break; + case PSU_POWER_GOOD: + status=snprintf(buf, PAGE_SIZE-1, "%d\r\n", data->power_good); + break; + case PSU_FAN1_FAULT: + status=snprintf(buf, PAGE_SIZE-1, "%d\r\n", data->fan_fault); + break; + case PSU_FAN_DIRECTION: + status=snprintf(buf, PAGE_SIZE-1, "%s\r\n", data->fan_dir); + break; + case PSU_OVER_TEMP: + status=snprintf(buf, PAGE_SIZE-1, "%d\r\n", data->over_temp); + break; + case PSU_V_OUT: + status=snprintf(buf, PAGE_SIZE-1, "%d\r\n", data->v_out); + break; + case PSU_I_OUT: + status=snprintf(buf, PAGE_SIZE-1, "%d\r\n", data->i_out); + break; + case PSU_P_OUT: + printk("read PSU_P_OUT\n"); + status=snprintf(buf, PAGE_SIZE-1, "%d\r\n", data->p_out); + break; + case PSU_P_OUT_UV: + printk("read PSU_P_OUT_UV\n"); + status=snprintf(buf, PAGE_SIZE-1, "%ld\r\n", data->p_out * 1000000); + break; + case PSU_TEMP1_INPUT: + status=snprintf(buf, PAGE_SIZE-1, "%d\r\n", data->temp); + break; + case PSU_FAN1_SPEED: + status=snprintf(buf, PAGE_SIZE-1, "%d\r\n", data->fan_speed); + break; + case PSU_FAN1_DUTY_CYCLE: + status=snprintf(buf, PAGE_SIZE-1, "%d\r\n", data->fan_duty_cycle); + break; + case PSU_PMBUS_REVISION: + break; + case PSU_MFR_ID: + status=snprintf(buf, PAGE_SIZE-1, "%s\r\n", data->mfr_id); + break; + case PSU_MFR_MODEL: + status=snprintf(buf, PAGE_SIZE-1, "%s\r\n", data->mfr_model); + break; + case PSU_MFR_REVISION: + status=snprintf(buf, PAGE_SIZE-1, "%s\r\n", data->mfr_revision); + break; + case PSU_MFR_VIN_MIN: + status=snprintf(buf, PAGE_SIZE-1, "%d\r\n", data->mfr_vin_min); + break; + case PSU_MFR_VIN_MAX: + status=snprintf(buf, PAGE_SIZE-1, "%d\r\n", data->mfr_vin_max); + break; + case PSU_MFR_VOUT_MIN: + status=snprintf(buf, PAGE_SIZE-1, "%d\r\n", data->mfr_vin_max); + break; + case PSU_MFR_VOUT_MAX: + status=snprintf(buf, PAGE_SIZE-1, "%d\r\n", data->mfr_vout_max); + break; + case PSU_MFR_IIN_MAX: + status=snprintf(buf, PAGE_SIZE-1, "%d\r\n", data->mfr_iin_max); + break; + case PSU_MFR_IOUT_MAX: + status=snprintf(buf, PAGE_SIZE-1, "%d\r\n", data->mfr_iout_max); + break; + case PSU_MFR_PIN_MAX: + status=snprintf(buf, PAGE_SIZE-1, "%d\r\n", data->mfr_pin_max); + break; + case PSU_MFR_POUT_MAX: + status=snprintf(buf, PAGE_SIZE-1, "%d\r\n", data->mfr_pout_max); + break; + default : + break; + } + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t pmbus_info_store(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32xb_pmbus_data *data = i2c_get_clientdata(client); + long keyin = 0; + int status = -EINVAL; + //printk("pmbus_info_store\n"); + //printk("attr->index=%d\n", attr->index); + mutex_lock(&data->update_lock); + status = kstrtol(buf, STRING_TO_DEC_VALUE, &keyin); + switch (attr->index) + { + case PSU_POWER_ON: + data->power_on=keyin; + break; + case PSU_TEMP_FAULT: + data->temp_fault=keyin; + break; + case PSU_POWER_GOOD: + data->power_good=keyin; + break; + case PSU_FAN1_FAULT: + break; + case PSU_FAN_DIRECTION: + memcpy(data->fan_dir, buf, sizeof(data->fan_dir)); + break; + case PSU_OVER_TEMP: + data->over_temp=keyin; + break; + case PSU_V_OUT: + data->v_out=keyin; + break; + case PSU_I_OUT: + data->i_out=keyin; + break; + case PSU_P_OUT: + printk("data->p_out=%d\n", data->p_out); + data->p_out=keyin; + break; + case PSU_P_OUT_UV: + //multiplier = 1000000; /*For lm-sensors, unit is micro-Volt.*/ + + break; + case PSU_TEMP1_INPUT: + data->temp=keyin; + break; + case PSU_FAN1_SPEED: + data->fan_speed=keyin; + break; + case PSU_FAN1_DUTY_CYCLE: + break; + case PSU_PMBUS_REVISION: + data->pmbus_revision=keyin; + break; + case PSU_MFR_ID: + memcpy(data->mfr_id, buf, sizeof(data->mfr_id)); + break; + case PSU_MFR_MODEL: + memcpy(data->mfr_model, buf, sizeof(data->mfr_model)); + break; + case PSU_MFR_REVISION: + memcpy(data->mfr_revision, buf, sizeof(data->mfr_revision)); + break; + case PSU_MFR_VIN_MIN: + data->mfr_vin_min=keyin; + break; + case PSU_MFR_VIN_MAX: + data->mfr_vin_max=keyin; + break; + case PSU_MFR_VOUT_MIN: + data->mfr_vout_min=keyin; + break; + case PSU_MFR_VOUT_MAX: + data->mfr_vout_max=keyin; + break; + case PSU_MFR_IIN_MAX: + data->mfr_iin_max=keyin; + break; + case PSU_MFR_IOUT_MAX: + data->mfr_iout_max=keyin; + break; + case PSU_MFR_PIN_MAX: + data->mfr_pin_max=keyin; + break; + case PSU_MFR_POUT_MAX: + data->mfr_pout_max=keyin; + break; + default : + break; + } + mutex_unlock(&data->update_lock); + return count; +} + + +static const struct attribute_group as7716_32xb_pmbus_group = { + .attrs = as7716_32xb_pmbus_attributes, +}; + +static int as7716_32xb_pmbus_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct as7716_32xb_pmbus_data *data; + int status; + + data = kzalloc(sizeof(struct as7716_32xb_pmbus_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + i2c_set_clientdata(client, data); + data->index = dev_id->driver_data; + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as7716_32xb_pmbus_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: pmbus '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as7716_32xb_pmbus_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as7716_32xb_pmbus_remove(struct i2c_client *client) +{ + struct as7716_32xb_pmbus_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as7716_32xb_pmbus_group); + kfree(data); + + return 0; +} + + +static const struct i2c_device_id as7716_32xb_pmbus_id[] = { + { "as7716_32xb_pmbus", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, as7716_32xb_pmbus_id); + +static struct i2c_driver as7716_32xb_pmbus_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "as7716_32xb_pmbus", + }, + .probe = as7716_32xb_pmbus_probe, + .remove = as7716_32xb_pmbus_remove, + .id_table = as7716_32xb_pmbus_id, + .address_list = normal_i2c, +}; + + + + + + +static int __init as7716_32xb_pmbus_init(void) +{ + return i2c_add_driver(&as7716_32xb_pmbus_driver); +} + +static void __exit as7716_32xb_pmbus_exit(void) +{ + i2c_del_driver(&as7716_32xb_pmbus_driver); +} + +module_init(as7716_32xb_pmbus_init); +module_exit(as7716_32xb_pmbus_exit); + +MODULE_AUTHOR("Jostar yang "); +MODULE_DESCRIPTION("as7716_32xb_pmbus driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_psu.c b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_psu.c new file mode 100755 index 000000000000..01756e8596eb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_psu.c @@ -0,0 +1,355 @@ +/* + * An hwmon driver for accton as7716_32xbb Power Module + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_MODEL_NAME 16 +#define DC12V_FAN_DIR_OFFSET 0x34 +#define DC12V_FAN_DIR_LEN 3 +#define STRING_TO_DEC_VALUE 10 + +//static ssize_t show_string(struct device *dev, struct device_attribute *da, char *buf); +static int as7716_32xb_psu_read_block(struct i2c_client *client, u8 command, u8 *data,int data_len); +extern int as7716_32xb_cpld_read (unsigned short cpld_addr, u8 reg); + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +/* Each client has this additional data + */ +struct as7716_32xb_psu_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 index; /* PSU index */ + u8 status; /* Status(present/power_good) register read from CPLD */ + u8 present; + u8 power_good; + char model_name[MAX_MODEL_NAME+1]; /* Model name, read from eeprom */ + char fan_dir[DC12V_FAN_DIR_LEN+1]; /* DC12V fan direction */ +}; + +enum as7716_32xb_psu_sysfs_attributes { + PSU_PRESENT, + PSU_MODEL_NAME, + PSU_POWER_GOOD, + PSU_FAN_DIR /* For DC12V only */ +}; + +/* sysfs attributes for hwmon + */ +static ssize_t psu_info_store(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t psu_info_show(struct device *dev, struct device_attribute *da, + char *buf); +static SENSOR_DEVICE_ATTR(psu_present, S_IWUSR|S_IRUGO, psu_info_show, psu_info_store, PSU_PRESENT); +static SENSOR_DEVICE_ATTR(psu_model_name, S_IWUSR|S_IRUGO, psu_info_show, psu_info_store, PSU_MODEL_NAME); +static SENSOR_DEVICE_ATTR(psu_power_good, S_IWUSR|S_IRUGO, psu_info_show, psu_info_store, PSU_POWER_GOOD); +static SENSOR_DEVICE_ATTR(psu_fan_dir, S_IWUSR|S_IRUGO, psu_info_show, psu_info_store, PSU_FAN_DIR); + + +static struct attribute *as7716_32xb_psu_attributes[] = { + &sensor_dev_attr_psu_present.dev_attr.attr, + &sensor_dev_attr_psu_model_name.dev_attr.attr, + &sensor_dev_attr_psu_power_good.dev_attr.attr, + &sensor_dev_attr_psu_fan_dir.dev_attr.attr, + NULL +}; + +static ssize_t psu_info_show(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32xb_psu_data *data = i2c_get_clientdata(client); + int status = -EINVAL; + //printk("psu_info_show\n"); + // printk("attr->index=%d\n", attr->index); + mutex_lock(&data->update_lock); + switch (attr->index) + { + case PSU_PRESENT: + //printk("data->present=%d\n",data->present); + status = snprintf(buf, PAGE_SIZE - 1, "%d\r\n", data->present); + break; + case PSU_MODEL_NAME: + //printk("data->model_name=%s\n",data->model_name); + status = snprintf(buf, PAGE_SIZE - 1, "%s\r\n", data->model_name); + break; + case PSU_POWER_GOOD: + // printk("data->present=%d\n",data->power_good); + status = snprintf(buf, PAGE_SIZE - 1, "%d\r\n", data->power_good); + break; + case PSU_FAN_DIR: + //printk("data->fan_dir=%s\n",data->fan_dir); + status = snprintf(buf, PAGE_SIZE - 1, "%s\r\n", data->fan_dir); + break; + default : + break; + } + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t psu_info_store(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32xb_psu_data *data = i2c_get_clientdata(client); + long keyin = 0; + int status = -EINVAL; + //printk("psu_info_store\n"); + //printk("attr->index=%d\n", attr->index); + mutex_lock(&data->update_lock); + switch (attr->index) + { + case PSU_PRESENT: + status = kstrtol(buf, STRING_TO_DEC_VALUE, &keyin); + if (status) + goto fail_exit; + if (keyin > 1 || keyin < 0) + goto fail_exit; + data->present=keyin; + break; + case PSU_MODEL_NAME: + memcpy(data->model_name, buf, MAX_MODEL_NAME); + break; + case PSU_POWER_GOOD: + status = kstrtol(buf, STRING_TO_DEC_VALUE, &keyin); + if (status) + goto fail_exit; + if (keyin > 1 || keyin < 0) + goto fail_exit; + data->power_good=keyin; + break; + case PSU_FAN_DIR: + memcpy(data->fan_dir, buf, DC12V_FAN_DIR_LEN); + break; + default : + goto fail_exit; + } + mutex_unlock(&data->update_lock); + return count; + +fail_exit: + mutex_unlock(&data->update_lock); + return -EINVAL; +} + +static const struct attribute_group as7716_32xb_psu_group = { + .attrs = as7716_32xb_psu_attributes, +}; + +static int as7716_32xb_psu_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct as7716_32xb_psu_data *data; + int status; + + data = kzalloc(sizeof(struct as7716_32xb_psu_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + data->index = dev_id->driver_data; + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as7716_32xb_psu_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as7716_32xb_psu_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as7716_32xb_psu_remove(struct i2c_client *client) +{ + struct as7716_32xb_psu_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as7716_32xb_psu_group); + kfree(data); + + return 0; +} + +enum psu_index +{ + as7716_32xb_psu1, + as7716_32xb_psu2 +}; + +static const struct i2c_device_id as7716_32xb_psu_id[] = { + { "as7716_32xb_psu1", as7716_32xb_psu1 }, + { "as7716_32xb_psu2", as7716_32xb_psu2 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, as7716_32xb_psu_id); + +static struct i2c_driver as7716_32xb_psu_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "as7716_32xb_psu", + }, + .probe = as7716_32xb_psu_probe, + .remove = as7716_32xb_psu_remove, + .id_table = as7716_32xb_psu_id, + .address_list = normal_i2c, +}; + +static int as7716_32xb_psu_read_block(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ + int result = 0; + int retry_count = 5; + + while (retry_count) { + retry_count--; + + result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + + if (unlikely(result < 0)) { + msleep(10); + continue; + } + + if (unlikely(result != data_len)) { + result = -EIO; + msleep(10); + continue; + } + + result = 0; + break; + } + + return result; +} + +enum psu_type { + PSU_TYPE_AC_110V, + PSU_TYPE_DC_48V, + PSU_TYPE_DC_12V +}; + +struct model_name_info { + enum psu_type type; + u8 offset; + u8 length; + char* model_name; +}; + +struct model_name_info models[] = { +{PSU_TYPE_AC_110V, 0x20, 8, "YM-2651Y"}, +{PSU_TYPE_DC_48V, 0x20, 8, "YM-2651V"}, +{PSU_TYPE_DC_12V, 0x00, 11, "PSU-12V-750"}, +}; + +static int as7716_32xb_psu_model_name_get(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32xb_psu_data *data = i2c_get_clientdata(client); + int i, status; + + for (i = 0; i < ARRAY_SIZE(models); i++) { + memset(data->model_name, 0, sizeof(data->model_name)); + + status = as7716_32xb_psu_read_block(client, models[i].offset, + data->model_name, models[i].length); + if (status < 0) { + data->model_name[0] = '\0'; + dev_dbg(&client->dev, "unable to read model name from (0x%x) offset(0x%x)\n", + client->addr, models[i].offset); + return status; + } + else { + data->model_name[models[i].length] = '\0'; + } + + /* Determine if the model name is known, if not, read next index + */ + if (strncmp(data->model_name, models[i].model_name, models[i].length) == 0) { + return 0; + } + else { + data->model_name[0] = '\0'; + } + } + + return -ENODATA; +} + +static int __init as7716_32xb_psu_init(void) +{ + return i2c_add_driver(&as7716_32xb_psu_driver); +} + +static void __exit as7716_32xb_psu_exit(void) +{ + i2c_del_driver(&as7716_32xb_psu_driver); +} + +module_init(as7716_32xb_psu_init); +module_exit(as7716_32xb_psu_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("as7716_32xb_psu driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_sfp.c b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_sfp.c new file mode 100755 index 000000000000..9c7a05632154 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_sfp.c @@ -0,0 +1,365 @@ +/* + * An hwmon driver for accton as7716_32x sfp + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BIT_INDEX(i) (1UL << (i)) +#define I2C_ADDR_CPLD1 0x60 +#define I2C_ADDR_CPLD2 0x62 +#define I2C_ADDR_CPLD3 0x64 +#define CPLD1_OFFSET_QSFP_PRESET1 0x30 +#define CPLD1_OFFSET_QSFP_PRESET2 0x31 +#define CPLD1_OFFSET_QSFP_PRESET3 0x32 +#define CPLD1_OFFSET_QSFP_PRESET4 0x33 + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { 0x50, I2C_CLIENT_END }; + +/* Each client has this additional data + */ +struct as7716_32x_sfp_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + int port; /* Front port index */ + char eeprom[256]; /* eeprom data */ + u32 is_present; /* present status */ +}; + +static struct as7716_32x_sfp_data *as7716_32x_sfp_update_device(struct device *dev); +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_present(struct device *dev, struct device_attribute *da,char *buf); +static ssize_t show_eeprom(struct device *dev, struct device_attribute *da, char *buf); +extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +enum as7716_32x_sfp_sysfs_attributes { + SFP_PORT_NUMBER, + SFP_IS_PRESENT, + SFP_IS_PRESENT_ALL, + SFP_EEPROM +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(sfp_port_number, S_IRUGO, show_port_number, NULL, SFP_PORT_NUMBER); +static SENSOR_DEVICE_ATTR(sfp_is_present, S_IRUGO, show_present, NULL, SFP_IS_PRESENT); +static SENSOR_DEVICE_ATTR(sfp_is_present_all, S_IRUGO, show_present, NULL, SFP_IS_PRESENT_ALL); +static SENSOR_DEVICE_ATTR(sfp_eeprom, S_IRUGO, show_eeprom, NULL, SFP_EEPROM); + +static struct attribute *as7716_32x_sfp_attributes[] = { + &sensor_dev_attr_sfp_port_number.dev_attr.attr, + &sensor_dev_attr_sfp_is_present.dev_attr.attr, + &sensor_dev_attr_sfp_is_present_all.dev_attr.attr, + &sensor_dev_attr_sfp_eeprom.dev_attr.attr, + NULL +}; + +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32x_sfp_data *data = i2c_get_clientdata(client); + + return sprintf(buf, "%d\n", data->port+1); +} + +/* Error-check the CPLD read results. */ +#define VALIDATED_READ(_buf, _rv, _read_expr, _invert) \ +do { \ + _rv = (_read_expr); \ + if(_rv < 0) { \ + return sprintf(_buf, "READ ERROR\n"); \ + } \ + if(_invert) { \ + _rv = ~_rv; \ + } \ + _rv &= 0xFF; \ +} while(0) + +static ssize_t show_present(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + if(attr->index == SFP_IS_PRESENT_ALL) { + int values[4]; + /* + * Report the SFP_PRESENCE status for all ports. + */ + + /* QSFP_PRESENT Ports 1-8 */ + //VALIDATED_READ(buf, values[0], accton_i2c_cpld_read(0x62, 0x9), 1); + VALIDATED_READ(buf, values[0], accton_i2c_cpld_read(I2C_ADDR_CPLD1, CPLD1_OFFSET_QSFP_PRESET1), 1); + /* QSFP_PRESENT Ports 9-16 */ + VALIDATED_READ(buf, values[1], accton_i2c_cpld_read(I2C_ADDR_CPLD1, CPLD1_OFFSET_QSFP_PRESET2), 1); + /* QSFP_PRESENT Ports 17-24 */ + VALIDATED_READ(buf, values[2], accton_i2c_cpld_read(I2C_ADDR_CPLD1, CPLD1_OFFSET_QSFP_PRESET3), 1); + /* QSFP_PRESENT Ports 25-32 */ + VALIDATED_READ(buf, values[3], accton_i2c_cpld_read(I2C_ADDR_CPLD1, CPLD1_OFFSET_QSFP_PRESET4), 1); + + /* Return values 1 -> 32 in order */ + return sprintf(buf, "%.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], values[3]); + } + else { /* SFP_IS_PRESENT */ + struct as7716_32x_sfp_data *data = as7716_32x_sfp_update_device(dev); + + if (!data->valid) { + printk("return -EIO\n"); + return -EIO; + } + + return sprintf(buf, "%d\n", data->is_present); + } +} + +static ssize_t show_eeprom(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct as7716_32x_sfp_data *data = as7716_32x_sfp_update_device(dev); + + if (!data->valid) { + return 0; + } + + if (!data->is_present) { + return 0; + } + + memcpy(buf, data->eeprom, sizeof(data->eeprom)); + + return sizeof(data->eeprom); +} + +static const struct attribute_group as7716_32x_sfp_group = { + .attrs = as7716_32x_sfp_attributes, +}; + +static int as7716_32x_sfp_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct as7716_32x_sfp_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct as7716_32x_sfp_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + mutex_init(&data->update_lock); + data->port = dev_id->driver_data; + i2c_set_clientdata(client, data); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as7716_32x_sfp_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: sfp '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as7716_32x_sfp_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as7716_32x_sfp_remove(struct i2c_client *client) +{ + struct as7716_32x_sfp_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as7716_32x_sfp_group); + kfree(data); + + return 0; +} + +enum port_numbers { +as7716_32x_sfp1, as7716_32x_sfp2, as7716_32x_sfp3, as7716_32x_sfp4, +as7716_32x_sfp5, as7716_32x_sfp6, as7716_32x_sfp7, as7716_32x_sfp8, +as7716_32x_sfp9, as7716_32x_sfp10,as7716_32x_sfp11,as7716_32x_sfp12, +as7716_32x_sfp13,as7716_32x_sfp14,as7716_32x_sfp15,as7716_32x_sfp16, +as7716_32x_sfp17,as7716_32x_sfp18,as7716_32x_sfp19,as7716_32x_sfp20, +as7716_32x_sfp21,as7716_32x_sfp22,as7716_32x_sfp23,as7716_32x_sfp24, +as7716_32x_sfp25,as7716_32x_sfp26,as7716_32x_sfp27,as7716_32x_sfp28, +as7716_32x_sfp29,as7716_32x_sfp30,as7716_32x_sfp31,as7716_32x_sfp32 +}; + +static const struct i2c_device_id as7716_32x_sfp_id[] = { +{ "as7716_32x_sfp1", as7716_32x_sfp1 }, { "as7716_32x_sfp2", as7716_32x_sfp2 }, +{ "as7716_32x_sfp3", as7716_32x_sfp3 }, { "as7716_32x_sfp4", as7716_32x_sfp4 }, +{ "as7716_32x_sfp5", as7716_32x_sfp5 }, { "as7716_32x_sfp6", as7716_32x_sfp6 }, +{ "as7716_32x_sfp7", as7716_32x_sfp7 }, { "as7716_32x_sfp8", as7716_32x_sfp8 }, +{ "as7716_32x_sfp9", as7716_32x_sfp9 }, { "as7716_32x_sfp10", as7716_32x_sfp10 }, +{ "as7716_32x_sfp11", as7716_32x_sfp11 }, { "as7716_32x_sfp12", as7716_32x_sfp12 }, +{ "as7716_32x_sfp13", as7716_32x_sfp13 }, { "as7716_32x_sfp14", as7716_32x_sfp14 }, +{ "as7716_32x_sfp15", as7716_32x_sfp15 }, { "as7716_32x_sfp16", as7716_32x_sfp16 }, +{ "as7716_32x_sfp17", as7716_32x_sfp17 }, { "as7716_32x_sfp18", as7716_32x_sfp18 }, +{ "as7716_32x_sfp19", as7716_32x_sfp19 }, { "as7716_32x_sfp20", as7716_32x_sfp20 }, +{ "as7716_32x_sfp21", as7716_32x_sfp21 }, { "as7716_32x_sfp22", as7716_32x_sfp22 }, +{ "as7716_32x_sfp23", as7716_32x_sfp23 }, { "as7716_32x_sfp24", as7716_32x_sfp24 }, +{ "as7716_32x_sfp25", as7716_32x_sfp25 }, { "as7716_32x_sfp26", as7716_32x_sfp26 }, +{ "as7716_32x_sfp27", as7716_32x_sfp27 }, { "as7716_32x_sfp28", as7716_32x_sfp28 }, +{ "as7716_32x_sfp29", as7716_32x_sfp29 }, { "as7716_32x_sfp30", as7716_32x_sfp30 }, +{ "as7716_32x_sfp31", as7716_32x_sfp31 }, { "as7716_32x_sfp32", as7716_32x_sfp32 }, +{} +}; +MODULE_DEVICE_TABLE(i2c, as7716_32x_sfp_id); + +static struct i2c_driver as7716_32x_sfp_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "as7716_32x_sfp", + }, + .probe = as7716_32x_sfp_probe, + .remove = as7716_32x_sfp_remove, + .id_table = as7716_32x_sfp_id, + .address_list = normal_i2c, +}; + +static int as7716_32x_sfp_read_block(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ + int result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + + if (unlikely(result < 0)) + goto abort; + if (unlikely(result != data_len)) { + result = -EIO; + goto abort; + } + + result = 0; + +abort: + return result; +} + +static struct as7716_32x_sfp_data *as7716_32x_sfp_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32x_sfp_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int status = -1; + int i = 0; + u8 cpld_reg = 0x30 + (data->port/8); + + data->valid = 0; + + /* Read present status of the specified port number */ + data->is_present = 0; + status = accton_i2c_cpld_read(I2C_ADDR_CPLD1, cpld_reg); + + if (status < 0) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", I2C_ADDR_CPLD1, cpld_reg, status); + goto exit; + } + + data->is_present = (status & (1 << (data->port % 8))) ? 0 : 1; + printk("data->is_present=%d, data->port=%d, status=0x%x\n",data->is_present, data->port, status); + /* Read eeprom data based on port number */ + memset(data->eeprom, 0, sizeof(data->eeprom)); + + /* Check if the port is present */ + if (data->is_present) { + /* read eeprom */ + for (i = 0; i < sizeof(data->eeprom)/I2C_SMBUS_BLOCK_MAX; i++) { + status = as7716_32x_sfp_read_block(client, i*I2C_SMBUS_BLOCK_MAX, + data->eeprom+(i*I2C_SMBUS_BLOCK_MAX), + I2C_SMBUS_BLOCK_MAX); + if (status < 0) { + printk("unable to read eeprom from port(%d)\n", data->port); + dev_dbg(&client->dev, "unable to read eeprom from port(%d)\n", data->port); + goto exit; + } + } + } + + data->last_updated = jiffies; + data->valid = 1; + } + +exit: + mutex_unlock(&data->update_lock); + + return data; +} + +static int __init as7716_32x_sfp_init(void) +{ + //extern int platform_accton_as7716_32x(void); + //if (!platform_accton_as7716_32x()) { +// return -ENODEV; + //} + + return i2c_add_driver(&as7716_32x_sfp_driver); +} + +static void __exit as7716_32x_sfp_exit(void) +{ + i2c_del_driver(&as7716_32x_sfp_driver); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton as7716_32x_sfp driver"); +MODULE_LICENSE("GPL"); + +module_init(as7716_32x_sfp_init); +module_exit(as7716_32x_sfp_exit); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_sys.c b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_sys.c new file mode 100755 index 000000000000..f0a8125139cc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_sys.c @@ -0,0 +1,243 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define STRING_TO_DEC_VALUE 10 +#define EEPROM_DATA_SIZE 256 + + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; +#define MAX_PORT_NAME_LEN 20 +/* Each client has this additional data + */ +struct as7716_32xb_sys_data { + struct device *hwmon_dev; + struct mutex lock; + u8 index; + unsigned char eeprom[EEPROM_DATA_SIZE]; +}; + + +/* sysfs attributes for hwmon + */ + +static ssize_t sys_info_store(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t sys_info_show(struct device *dev, struct device_attribute *da, + char *buf); + +static SENSOR_DEVICE_ATTR(eeprom, S_IWUSR|S_IRUGO, sys_info_show, sys_info_store, 0); + + + +static struct attribute *as7716_32xb_sys_attributes[] = { + &sensor_dev_attr_eeprom.dev_attr.attr, + NULL +}; + + +static ssize_t sys_info_show(struct device *dev, struct device_attribute *da, + char *buf) +{ + //struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32xb_sys_data *data = i2c_get_clientdata(client); +// int status = -EINVAL; + int i; + + //printk("sys_info_show\n"); + // printk("attr->index=%d\n", attr->index); + mutex_lock(&data->lock); + //for(i=0; i<8; i++) + // printk("data->eeprom[%d]=0x%x ",i, data->eeprom[i]); + //printk("\n"); + memcpy(buf, data->eeprom, EEPROM_DATA_SIZE); + //for(i=0; i < EEPROM_DATA_SIZE ; i++) + //{ + // buf[i]=data->eeprom[i]; + // printk("buf[%d]=0x%x ",i, buf[i]); + //} + //status = EEPROM_DATA_SIZE+1; + + //printk("\n"); + //status = sprintf(buf, "%x", 0xA); + //data->eeprom[0]=0x0d; + //data->eeprom[1]=0x0; + //data->eeprom[2]=0x06; + // buf[3]=0xFF; + + // for(i=0; i< 16; i++) + // printk("buf[%d]=0x%x ",i, buf[i]); + //printk("\n"); + + memcpy(buf, data->eeprom, 256); + + + mutex_unlock(&data->lock); + + return 256; +} + +static ssize_t sys_info_store(struct device *dev, struct device_attribute *da, + const char *buf, size_t size) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32xb_sys_data *data = i2c_get_clientdata(client); + int i=0, j=0, k=0; + unsigned char str[3]; + unsigned int val; + + //printk("sys_info_store\n"); + //printk("attr->index=%d\n", attr->index); + //printk("buf[0]=0x%x, buf[1]=0x%x, buf[2]=0x%x, buf[3]=0x%x\n", buf[0], buf[1], buf[2], buf[3]); + + // printk("strlen(buf)=%d\n",strlen(buf)); + k=0; + mutex_lock(&data->lock); + memset(data->eeprom, 0xFF, EEPROM_DATA_SIZE); + memset(str, 0x0, 3); + if(strlen(buf) >= 256 ) + { + for(i=0; i < strlen(buf) ; i++) + { + // printk("i=%d ", i); + for(j=0;j<2; j++) + { + str[j]=buf[i+j]; + } + sscanf(str, "%x", &val); + // printk("str=%s val=0x%x ", str, val); + i=j+i-1; + if(k>=EEPROM_DATA_SIZE) + { + break; + } + data->eeprom[k]=(unsigned char)val; + // printk("data->eeprom[%d]=0x%x\n",k, data->eeprom[k]); + k++; + } + } + //printk("buf=\n"); + //for(i=0; i < strlen(buf) ; i++) + //{ + // printk("%c%c ", buf[i], buf[i+1]); + // if((i % 31)==0) + // printk("\n"); + //} + //printk("\n"); + + //printk("eeprom[0]=0x%x, eeprom[1]=0x%x, eeprom[2]=0x%x, eeprom[3]=0x%x\n", + // data->eeprom[0], data->eeprom[1], data->eeprom[2], data->eeprom[3]); + + mutex_unlock(&data->lock); + return size; + +} + +static const struct attribute_group as7716_32xb_sys_group = { + .attrs = as7716_32xb_sys_attributes, +}; + +static int as7716_32xb_sys_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct as7716_32xb_sys_data *data; + int status; + + data = kzalloc(sizeof(struct as7716_32xb_sys_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + i2c_set_clientdata(client, data); + data->index = dev_id->driver_data; + mutex_init(&data->lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as7716_32xb_sys_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: sys '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as7716_32xb_sys_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as7716_32xb_sys_remove(struct i2c_client *client) +{ + struct as7716_32xb_sys_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as7716_32xb_sys_group); + kfree(data); + + return 0; +} + + +static const struct i2c_device_id as7716_32xb_sys_id[] = { + { "as7716_32xb_sys", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, as7716_32xb_sys_id); + +static struct i2c_driver as7716_32xb_sys_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "as7716_32xb_sys", + }, + .probe = as7716_32xb_sys_probe, + .remove = as7716_32xb_sys_remove, + .id_table = as7716_32xb_sys_id, + .address_list = normal_i2c, +}; + + + + + + +static int __init as7716_32xb_sys_init(void) +{ + return i2c_add_driver(&as7716_32xb_sys_driver); +} + +static void __exit as7716_32xb_sys_exit(void) +{ + i2c_del_driver(&as7716_32xb_sys_driver); +} + +module_init(as7716_32xb_sys_init); +module_exit(as7716_32xb_sys_exit); + +MODULE_AUTHOR("Jostar yang "); +MODULE_DESCRIPTION("as7716_32xb_sys driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_thermal.c b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_thermal.c new file mode 100755 index 000000000000..d42341bb181a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_as7716_32xb_thermal.c @@ -0,0 +1,214 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define STRING_TO_DEC_VALUE 10 +#define STRING_TO_HEX_VALUE 16 + +#define TEMP1_MAX_HYST_DEFAULT 75000 +#define TEMP1_MAX_DEFAULT 80000 +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +/* Each client has this additional data + */ +struct as7716_32xb_thermal_data { + struct device *hwmon_dev; + struct mutex update_lock; + u8 index; + unsigned int temp1_input; + unsigned int temp1_max_hyst; + unsigned int temp1_max; +}; + + + +enum as7716_32xb_thermal_sysfs_attributes { + TEMP1_INPUT, + TEMP1_MAX_HYST, + TEMP1_MAX +}; + +/* sysfs attributes for hwmon + */ + +static ssize_t temp_info_store(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t temp_info_show(struct device *dev, struct device_attribute *da, + char *buf); +static SENSOR_DEVICE_ATTR(temp1_input, S_IWUSR|S_IRUGO, temp_info_show, temp_info_store, TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR|S_IRUGO, temp_info_show, temp_info_store, TEMP1_MAX_HYST); +static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR|S_IRUGO, temp_info_show, temp_info_store, TEMP1_MAX); + + +static struct attribute *as7716_32xb_thermal_attributes[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + NULL +}; + + +static ssize_t temp_info_show(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32xb_thermal_data *data = i2c_get_clientdata(client); + int status = -EINVAL; + + mutex_lock(&data->update_lock); + switch (attr->index) + { + case TEMP1_INPUT: + status = snprintf(buf, PAGE_SIZE - 1, "%d\r\n", data->temp1_input); + break; + case TEMP1_MAX_HYST: + status = snprintf(buf, PAGE_SIZE - 1, "%d\r\n", TEMP1_MAX_HYST_DEFAULT); + break; + case TEMP1_MAX: + status = snprintf(buf, PAGE_SIZE - 1, "%d\r\n", TEMP1_MAX_DEFAULT); + break; + default : + break; + } + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t temp_info_store(struct device *dev, struct device_attribute *da, + const char *buf, size_t size) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct as7716_32xb_thermal_data *data = i2c_get_clientdata(client); + long keyin = 0; + int status = -EINVAL; + + mutex_lock(&data->update_lock); + status = kstrtol(buf, STRING_TO_DEC_VALUE, &keyin); + switch (attr->index) + { + case TEMP1_INPUT: + data->temp1_input=keyin; + break; + case TEMP1_MAX_HYST: + data->temp1_max_hyst=keyin; + break; + case TEMP1_MAX: + data->temp1_max=keyin; + break; + default : + break; + } + mutex_unlock(&data->update_lock); + return size; + +} + +static const struct attribute_group as7716_32xb_thermal_group = { + .attrs = as7716_32xb_thermal_attributes, +}; + +static int as7716_32xb_thermal_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct as7716_32xb_thermal_data *data; + int status; + + data = kzalloc(sizeof(struct as7716_32xb_thermal_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + i2c_set_clientdata(client, data); + data->index = dev_id->driver_data; + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as7716_32xb_thermal_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: thermal '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as7716_32xb_thermal_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as7716_32xb_thermal_remove(struct i2c_client *client) +{ + struct as7716_32xb_thermal_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as7716_32xb_thermal_group); + kfree(data); + + return 0; +} + + +static const struct i2c_device_id as7716_32xb_thermal_id[] = { + { "as7716_32xb_thermal", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, as7716_32xb_thermal_id); + +static struct i2c_driver as7716_32xb_thermal_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "as7716_32xb_thermal", + }, + .probe = as7716_32xb_thermal_probe, + .remove = as7716_32xb_thermal_remove, + .id_table = as7716_32xb_thermal_id, + .address_list = normal_i2c, +}; + + + + + + +static int __init as7716_32xb_thermal_init(void) +{ + return i2c_add_driver(&as7716_32xb_thermal_driver); +} + +static void __exit as7716_32xb_thermal_exit(void) +{ + i2c_del_driver(&as7716_32xb_thermal_driver); +} + +module_init(as7716_32xb_thermal_init); +module_exit(as7716_32xb_thermal_exit); + +MODULE_AUTHOR("Jostar yang "); +MODULE_DESCRIPTION("as7716_32xb_thermal driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_i2c_cpld.c b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_i2c_cpld.c new file mode 100755 index 000000000000..46d1e2773287 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/modules/accton_i2c_cpld.c @@ -0,0 +1,259 @@ +/* + * A hwmon driver for the accton_i2c_cpld + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CPLD_VERSION_REG 0x1 + +enum as5712_54x_cpld_sysfs_attributes { + CPLD_READ_VERSION, + CPLD_BYTE_ACCESS, + CPLD_DUMP_ALL, +}; + +static ssize_t read_cpld_version(struct device *dev, struct device_attribute *da, + char *buf); +int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg); + + +static LIST_HEAD(cpld_client_list); +static struct mutex list_lock; + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; + +/* Addresses scanned for accton_i2c_cpld + */ +static const unsigned short normal_i2c[] = { 0x31, 0x35, 0x60, 0x61, 0x62, I2C_CLIENT_END }; + +static SENSOR_DEVICE_ATTR(cpld_get_version, S_IRUGO, read_cpld_version, NULL, CPLD_READ_VERSION); + +static struct attribute *as5712_54x_cpld_attributes[] = { + &sensor_dev_attr_cpld_get_version.dev_attr.attr, + NULL +}; + +static const struct attribute_group as5712_54x_cpld_group = { + .attrs = as5712_54x_cpld_attributes, +}; + +static ssize_t read_cpld_version(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + unsigned short cpld_reg = CPLD_VERSION_REG; + u8 reg; + + if(attr->index == CPLD_READ_VERSION) { + reg = accton_i2c_cpld_read(client->addr, cpld_reg); + return sprintf(buf, "%02x\n",reg); + } + return -1 ; +} + + +static void accton_i2c_cpld_add_client(struct i2c_client *client) +{ + struct cpld_client_node *node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", client->addr); + return; + } + + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &cpld_client_list); + mutex_unlock(&list_lock); +} + +static void accton_i2c_cpld_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client == client) { + found = 1; + break; + } + } + + if (found) { + list_del(list_node); + kfree(cpld_node); + } + + mutex_unlock(&list_lock); +} + +static int accton_i2c_cpld_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_dbg(&client->dev, "i2c_check_functionality failed (0x%x)\n", client->addr); + status = -EIO; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as5712_54x_cpld_group); + if (status) { + goto exit; + } + + dev_info(&client->dev, "chip found\n"); + accton_i2c_cpld_add_client(client); + + return 0; +exit: + return status; +} + +static int accton_i2c_cpld_remove(struct i2c_client *client) +{ + sysfs_remove_group(&client->dev.kobj, &as5712_54x_cpld_group); + + accton_i2c_cpld_remove_client(client); + return 0; +} + +static const struct i2c_device_id accton_i2c_cpld_id[] = { + { "accton_i2c_cpld", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, accton_i2c_cpld_id); + +static struct i2c_driver accton_i2c_cpld_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "accton_i2c_cpld", + }, + .probe = accton_i2c_cpld_probe, + .remove = accton_i2c_cpld_remove, + .id_table = accton_i2c_cpld_id, + .address_list = normal_i2c, +}; + +int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EPERM; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = i2c_smbus_read_byte_data(cpld_node->client, reg); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(accton_i2c_cpld_read); + +int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EIO; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = i2c_smbus_write_byte_data(cpld_node->client, reg, value); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(accton_i2c_cpld_write); + +static int __init accton_i2c_cpld_init(void) +{ + mutex_init(&list_lock); + return i2c_add_driver(&accton_i2c_cpld_driver); +} + +static void __exit accton_i2c_cpld_exit(void) +{ + i2c_del_driver(&accton_i2c_cpld_driver); +} +/* +static struct dmi_system_id as7712_dmi_table[] = { + { + .ident = "Accton AS7712", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Accton"), + DMI_MATCH(DMI_PRODUCT_NAME, "AS7712"), + }, + } +}; + +int platform_accton_as7712_32x(void) +{ + return dmi_check_system(as7712_dmi_table); +} +EXPORT_SYMBOL(platform_accton_as7712_32x); +*/ +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton_i2c_cpld driver"); +MODULE_LICENSE("GPL"); + +module_init(accton_i2c_cpld_init); +module_exit(accton_i2c_cpld_exit); diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/service/as7716_32xb-platform-monitor.service b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/service/as7716_32xb-platform-monitor.service new file mode 100755 index 000000000000..05a5d93c48b9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/service/as7716_32xb-platform-monitor.service @@ -0,0 +1,17 @@ +[Unit] +Description=Accton AS7716-32XB Platform Monitoring service +Before=pmon.service +After=sysinit.target +DefaultDependencies=no + +[Service] +ExecStartPre=/usr/local/bin/accton_as7716_32xb_util.py install +ExecStart=/usr/local/bin/accton_as7716_32xb_drv_handler.py +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/setup.py b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/setup.py new file mode 100755 index 000000000000..3edfc29b3817 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/setup.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python + +import os +import sys +from setuptools import setup +os.listdir + +setup( + name='as7716_32xb', + version='1.0', + description='Module to initialize Accton AS7716-32XB platforms', + + packages=['as7716_32xb'], + package_dir={'as7716_32xb': 'as7716-32xb/classes'}, +) + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/README b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/README new file mode 100755 index 000000000000..c602d753301e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/README @@ -0,0 +1,117 @@ +Copyright (C) 2016 Accton Networks, 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 3 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, see . + +Contents of this package: + patch - files under patch/ is for kernel and ONIE installer + for the kernel: + config-accton-as5712_54x.patch + for kernel configuration. + driver-i2c-muxes-pca954x-always-deselect.patch + for i2c_mux deselects after transaction. + driver-patches-for-accton-as5712-fan-psu-cpld.patch + for as5712's fan/psu/cpld/led/sfp drivers. + for ONIE: + onie_installer-accton-AS5712-54X.patch + for console port setting and copy util script o rootfs. + module - Contains source code of as5712 kernel driver modules. + +The late Sonic building scripts, pushed @Dec 5 2016, will automatically +create a docker container and run building process under it. +User is not necessary to handle docker environment creation. + +1. Download sonic-buildimage environment. + - Run "git clone https://github.com/Azure/sonic-buildimage". + - cd to sonic-buildimage and run "git submodule update --init --recursive". +2. Build kernel + - cd ./src/sonic-linux-kernel + - Copy patches and series from patch/kernel of this release to + sonic-linux-kernel/patch. + - Build kernel by "make". + - The built kernel package, linux-image-3.16.0-4-amd64_3.16.36-1+deb8u2_amd64.deb + , is generated. +3. Build installer + - Change directory back to sonic-buildimage/. + - Get onie_installer-accton-AS5712-54X.patch" from patch/installer. + - Change setting for AS5712-54X by patching build_image.sh. + "patch -p1 < onie_installer-accton-AS5712-54X.patch" + !!NOTICE, patching onie_installer-accton-AS5712-54X.patch comments out the + "git status" checking at build_image.sh. + - The account and password of installed OS can be given at rules/config. + The default user and password are "admin" & "YourPaSsWoRd" respectively. + - Run "make configure PLATFORM=broadcom" + - Copy the built kernel debian package to target/debs/. + The file is linux-image-3.16.0-4-amd64_*_amd64.deb under directory + src/sonic-linux-kernel/. + - Run "make target/sonic-generic.bin" + - Get the installer, target/sonic-generic.bin, to target machine and install. + +All Linux kernel code is licensed under the GPLv1. All other code is +licensed under the GPLv3. Please see the LICENSE file for copies of +both licenses. + +The code for integacting with Accton AS5712-54X has 2 parts, +kernel drivers and operational script. +The kernel drivers of peripherals are under module/ directory. +1. These drivers are patched into kernel by + driver-patches-for-accton-as5712-fan-psu-cpld.patch + Or you can build the driver under module/ by setting environment variable, + KERNEL_SRC, to proper linux built directory and run make. + It may be sonic-linux-kernel/linux-3.*/debian/build/build_amd64_none_amd64/. +2. A operational script, accton_as5712_util.py, for device initializatian and + peripheral accessing should be installed at /usr/bin. + This script is generated by onie_installer-accton-AS5712-54X.patch. + It's done by patching onie_installer-accton-AS5712-54X.patch at build-image. + Run "accton_as5712_util.py install" to install drivers. + +To initialize the system, run "accton_as5712_util.py install". +To clean up the drivers & devices, run "accton_as5712_util.py clean". +To dump information of sensors, run "accton_as5712_util.py show". +To dump SFP EEPROM, run "accton_as5712_util.py sff". +To set fan speed, run "accton_as5712_util.py set fan". +To enable/disable SFP emission, run "accton_as5712_util.py set sfp". +To set system LEDs' color, run "accton_as5712_util.py set led" +For more information, run "accton_as5712_util.py --help". + +==================================================================== +Besides applying accton_as5712_util.py to access peripherals, you can +access peripherals by sysfs nodes directly after the installation is run. + +System LED: + There are 5 system LEDs at the lower-left corner of front panel. + They are loc, diag, fan, ps1, and ps2. + The sysfs interface color mappings are as follows: + Brightness: + 0 => off + 1 => green + 2 => amber + 3 => red + 4 => blue + But not all colors are available for each LED. + +Fan Control: + There are 10 fans inside 5 fan modules. + All fans share 1 duty setting, ranged from 0~100. + +Thermal sensers: + 3 temperature sensors are controlled by the lm75 kernel modules. + +PSUs: + There 2 power supplies slot at the left/right side of the back. + Once if a PSU is not plugged, the status of it is shown failed. + +There are 48 SFP+ and 6 QSFP modules are equipped. +Before operating on PSU and QSFP+, please make sure it is well plugged. +Otherwise, operation is going to fail. + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_drv_handler.py b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_drv_handler.py new file mode 100755 index 000000000000..c08a82c7dc45 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_drv_handler.py @@ -0,0 +1,443 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 Accton Technology Corporation +# +# 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 3 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, see . + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 1/18/2018: Jostar create for as7716_32xb +# ------------------------------------------------------------------ + +try: + import os + import sys, getopt + import subprocess + import click + import imp + import logging + import logging.config + import types + import time # this is only being used as part of the example + import traceback + import commands + from tabulate import tabulate +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + +# Deafults +VERSION = '1.0' +FUNCTION_NAME = 'as7716_32xb_drv_handler' +DEBUG = False + +global log_file +global log_level + +def my_log(txt): + if DEBUG == True: + print "[ACCTON DBG]: "+txt + return + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status = 1 + output = "" + status, output = commands.getstatusoutput(cmd) + if DEBUG == True: + my_log (cmd +" , result:" + str(status)) + else: + if show: + print "ACC: " + str(cmd) + " , result:"+ str(status) + #my_log ("cmd:" + cmd) + #my_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + + +# Make a class we can use to capture stdout and sterr in the log +class accton_as7716xb_drv_handler(object): + + QSFP_PORT_START = 1 + QSFP_PORT_END = 32 + BASE_PATH = "/usr/local/bin/" + BASE_I2C_PATH="/sys/bus/i2c/devices/" + QSFP_PRESENT_PATH = "/sys/bus/i2c/devices/0-0060/module_present_" + QSFP_RESET_PATH = "/sys/bus/i2c/devices/0-0060/module_reset_" + QSFP_PRESENT_FILE = "/tmp/ipmi_qsfp_pres" + QSFP_EEPROM_FILE = "/tmp/ipmi_qsfp_ee_" + THERMAL_FILE = "/tmp/ipmi_thermal" + IPMI_CMD_QSFP = "ipmitool raw 0x34 0x10 " + IPMI_CMD_THERMAL = "ipmitool raw 0x34 0x12 " + IPMI_CMD_FAN = "ipmitool raw 0x34 0x14 " + IPMI_CMD_PSU ="ipmitool raw 0x34 0x16 " + IPMI_CMD_SYS_EEPROM_1 ="ipmitool raw 0x34 0x18 0x0 0x80" + IPMI_CMD_SYS_EEPROM_2 ="ipmitool raw 0x34 0x18 0x80 0x80" + FAN_ID_START = 1 + FAN_ID_END = 6 + FAN_FILE = "/tmp/ipmi_fan" + FAN_PATH = "/sys/bus/i2c/devices/0-0066/fan" + PSU_ID_START = 1 + PSU_ID_END = 2 + PSU1_PATH = "/sys/bus/i2c/devices/0-0053/" + PSU2_PATH = "/sys/bus/i2c/devices/0-0050/" + PSU1_PMBUS_PATH = "/sys/bus/i2c/devices/0-005b/" + PSU2_PMBUS_PATH = "/sys/bus/i2c/devices/0-0058/" + PSU_FILE = "/tmp/ipmi_psu_" + SYS_EEPROM_FILE_1 = "/tmp/ipmi_sys_eeprom_1" + SYS_EEPROM_FILE_2 = "/tmp/ipmi_sys_eeprom_2" + SYS_EEPROM_PATH = "/sys/bus/i2c/devices/0-0056/eeprom" + + + def __init__(self, log_file, log_level): + """Needs a logger and a logger level.""" + # set up logging to file + logging.basicConfig( + filename=log_file, + filemode='w', + level=log_level, + format= '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s', + datefmt='%H:%M:%S' + ) + + # set up logging to console + if log_level == logging.DEBUG: + console = logging.StreamHandler() + console.setLevel(log_level) + formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') + console.setFormatter(formatter) + logging.getLogger('').addHandler(console) + + logging.debug('SET. logfile:%s / loglevel:%d', log_file, log_level) + + def manage_ipmi_qsfp(self): + logging.debug ("drv hanlder-manage_ipmi_qsfp") + print "drv hanlder" + #Handle QSFP case + ipmi_cmd = self.IPMI_CMD_QSFP + " 0x10 > " +self.QSFP_PRESENT_FILE + log_os_system(ipmi_cmd, 0) + file_path = self.QSFP_PRESENT_FILE + check_file = open(file_path) + try: + check_file = open(file_path) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + line = check_file.readline() + pres_line= line.rstrip().replace(" ","") + while line: + line = check_file.readline() + pres_line+=line.rstrip().replace(" ","") + check_file.close() + + + for i in range(self.QSFP_PORT_START, self.QSFP_PORT_END+1, 1): + if i>1: + k=(i-1)*2 +1 + else: + k=1; + if pres_line[k] == '1': + #Set QSFP present + #print "port-%d present" %i + set_drv_cmd = "echo 1 > " + self.QSFP_PRESENT_PATH + str(i) + log_os_system(set_drv_cmd, 0) + #Read QSFP EEPROM + ipmi_cmd = self.IPMI_CMD_QSFP +str(i)+ " 0x00 > " +self.QSFP_EEPROM_FILE + str(i) + "_1" + log_os_system(ipmi_cmd, 0) + ipmi_cmd = self.IPMI_CMD_QSFP +str(i)+ " 0x01 > " +self.QSFP_EEPROM_FILE + str(i) + "_2" + log_os_system(ipmi_cmd, 0) + file_path = self.QSFP_EEPROM_FILE + str(i) + "_1" + check_file = open(file_path) + try: + check_file = open(file_path) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + line = check_file.readline() + str_line= line.rstrip().replace(" ","") + while line: + line = check_file.readline() + str_line+=line.rstrip().replace(" ","") + check_file.close() + file_path = self.QSFP_EEPROM_FILE + str(i) + "_2" + check_file = open(file_path) + try: + check_file = open(file_path) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + line = check_file.readline() + str_line+= line.rstrip().replace(" ","") + + while line: + line = check_file.readline() + str_line+=line.rstrip().replace(" ","") + check_file.close() + #Set QSFP EEPROM + if(i < 10): + set_drv_cmd = "echo " + str_line+ " > " + self.BASE_I2C_PATH + "0-000"+str(i) +"/eeprom" + else: + set_drv_cmd = "echo " + str_line+ " > " + self.BASE_I2C_PATH + "0-00"+str(i) +"/eeprom" + #print(set_drv_cmd) + log_os_system(set_drv_cmd, 0) + else: + ipmi_cmd = "echo 0 > " + self.QSFP_PRESENT_PATH + str(i) + log_os_system(ipmi_cmd, 0) + if(i < 10): + set_drv_cmd = "echo 0 > " + self.BASE_I2C_PATH + "0-000"+str(i) +"/eeprom" + else: + set_drv_cmd = "echo 0 > " + self.BASE_I2C_PATH + "0-00"+str(i) +"/eeprom" + #print(set_drv_cmd) + log_os_system(set_drv_cmd, 0) + + time.sleep(0.01) + return True + + def manage_ipmi_thermal(self): + logging.debug ("drv hanlder-manage_ipmi_thermal") + #Handle thermal case + #ipmitool raw 0x34 0x12 + ipmi_cmd = self.IPMI_CMD_THERMAL + " > " +self.THERMAL_FILE + log_os_system(ipmi_cmd, 0) + file_path = self.THERMAL_FILE + check_file = open(file_path) + try: + check_file = open(file_path) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + line = check_file.readline() + str_line= line.rstrip().replace(" ","") + while line: + line = check_file.readline() + str_line+=line.rstrip().replace(" ","") + check_file.close() + val_str= "0x" + str(str_line[4])+str(str_line[5]) + val_int=int(val_str, 16)*1000 + check_file.close() + set_drv_cmd = "echo "+str(val_int) + " > " + self.BASE_I2C_PATH + "0-0048/temp1_input" + log_os_system(set_drv_cmd,0) + val_str= "0x" + str(str_line[10])+str(str_line[11]) + val_int=int(val_str, 16) * 1000 + set_drv_cmd = "echo "+str(val_int) + " > " + self.BASE_I2C_PATH + "0-0049/temp1_input" + log_os_system(set_drv_cmd,0) + val_str= "0x" + str(str_line[16])+str(str_line[17]) + val_int=int(val_str, 16) * 1000 + set_drv_cmd = "echo "+str(val_int) + " > " + self.BASE_I2C_PATH + "0-004a/temp1_input" + log_os_system(set_drv_cmd, 0) + + return True + + def manage_ipmi_fan(self): + logging.debug ("drv hanlder-manage_ipmi_fan") + #Handle fan case + #ipmitool raw 0x34 0x14 + ipmi_cmd = self.IPMI_CMD_FAN + " > " +self.FAN_FILE + log_os_system(ipmi_cmd, 0) + file_path = self.FAN_FILE + #print(file_path) + check_file = open(file_path) + try: + check_file = open(file_path) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + line = check_file.readline() + str_line= line.rstrip().replace(" ","") + while line: + line = check_file.readline() + str_line+=line.rstrip().replace(" ","") + check_file.close() + #print (str_line) + k=0 + for i in range(self.FAN_ID_START, self.FAN_ID_END+1, 1): + #print "k=%d"%k + if str_line[k+1]=='0': + set_drv_cmd = "echo 1 > " + self.FAN_PATH + str(i) + "_present" + else: + set_drv_cmd = "echo 0 > " + self.FAN_PATH + str(i) + "_present" + log_os_system(set_drv_cmd, 0) + + val_str= "0x" + str(str_line[k+6])+str(str_line[k+7]) + str(str_line[k+4])+str(str_line[k+5]) + val_int=int(val_str, 16) + set_drv_cmd = "echo " + str(val_int) + " > " + self.FAN_PATH + str(i) + "_front_speed_rpm" + log_os_system(set_drv_cmd, 0) + val_str= "0x" + str(str_line[k+54])+str(str_line[k+55]) + str(str_line[k+52])+str(str_line[k+53]) + val_int=int(val_str, 16) + set_drv_cmd = "echo " + str(val_int) + " > " + self.FAN_PATH + str(i) + "_rear_speed_rpm" + log_os_system(set_drv_cmd, 0) + k+=8; + return True + + + def manage_ipmi_psu(self): + logging.debug ("drv hanlder-manage_ipmi_psu") + #Handle psu case + #present: ipmitool raw 0x34 0x16 '0x1' . Param-1 is psu id(id_1:0x1, id_2:0x2) + + #cpld access psu + for i in range(self.PSU_ID_START, self.PSU_ID_END+1, 1): + #present case + ipmi_cmd = self.IPMI_CMD_PSU + str(i) + " > " +self.PSU_FILE + str(i) + log_os_system(ipmi_cmd, 0) + if i==1: + psu_sysfs_path = self.PSU1_PATH + else: + psu_sysfs_path = self.PSU2_PATH + file_path = self.PSU_FILE + str(i) + #print(file_path) + check_file = open(file_path) + try: + check_file = open(file_path) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + line = check_file.readline() + str_line= line.rstrip().replace(" ","") + while line: + line = check_file.readline() + str_line+=line.rstrip().replace(" ","") + check_file.close() + #print (line) + if str_line[1]=='0': + int_val=1 #psu insert + #print "psu_%d present"%i + set_drv_cmd = "echo " +str(int_val) + " > " + psu_sysfs_path + "psu_present" + log_os_system(set_drv_cmd, 0) + set_drv_cmd = "echo " + str(str_line[5]) + " > " + psu_sysfs_path + "psu_power_good" + log_os_system(set_drv_cmd, 0) + else: + int_val=0 + set_drv_cmd = "echo " +str(int_val) + " > " + psu_sysfs_path + "psu_present" + log_os_system(set_drv_cmd, 0) + set_drv_cmd = "echo " + str(int_val) + " > " + psu_sysfs_path + "psu_power_good" + log_os_system(set_drv_cmd, 0) + + #pmbus + if i==1: + psu_sysfs_path = self.PSU1_PMBUS_PATH + else: + psu_sysfs_path = self.PSU2_PMBUS_PATH + + if str_line[5]=='1': #power_on + val_str= "0x" + str(str_line[28])+str(str_line[29]) + str(str_line[26])+str(str_line[27]) + val_int=int(val_str, 16) * 1000 + set_drv_cmd = "echo " + str(val_int) + " > " + psu_sysfs_path + "psu_temp1_input" + log_os_system(set_drv_cmd, 0) + #print "val_int=%d"%val_int + val_str= "0x" + str(str_line[32])+str(str_line[33]) + str(str_line[30])+str(str_line[31]) + val_int=int(val_str, 16) + #print "fan:val_int=%d"%val_int + set_drv_cmd = "echo " + str(val_int) + " > " + psu_sysfs_path + "psu_fan1_speed_rpm" + log_os_system(set_drv_cmd, 0) + val_str= "0x" + str(str_line[36])+str(str_line[37]) + str(str_line[34])+str(str_line[35]) + val_int=int(val_str, 16) + #print "pout val_int=%d"%val_int + set_drv_cmd = "echo " + str(val_int) + " > " + psu_sysfs_path + "psu_p_out" + log_os_system(set_drv_cmd, 0) + else: #power_off + val_int=0 + set_drv_cmd = "echo " + str(val_int) + " > " + psu_sysfs_path + "psu_temp1_input" + log_os_system(set_drv_cmd, 0) + set_drv_cmd = "echo " + str(val_int) + " > " + psu_sysfs_path + "psu_fan1_speed_rpm" + log_os_system(set_drv_cmd, 0) + set_drv_cmd = "echo " + str(val_int) + " > " + psu_sysfs_path + "psu_p_out" + log_os_system(set_drv_cmd, 0) + + time.sleep(2) + return True + + def manage_ipmi_sys(self): + logging.debug ("drv hanlder-manage_ipmi_sys") + #Handle sys case + #ipmitool -raw 0x34 0x18 0x00 0x80 + #ipmitool -raw 0x34 0x18 0x80 0x80 + + ipmi_cmd = self.IPMI_CMD_SYS_EEPROM_1 + " > " + self.SYS_EEPROM_FILE_1 + log_os_system(ipmi_cmd, 0) + ipmi_cmd = self.IPMI_CMD_SYS_EEPROM_2 + " > " + self.SYS_EEPROM_FILE_2 + log_os_system(ipmi_cmd, 0) + + #Read SYS EEPROM + file_path = self.SYS_EEPROM_FILE_1 + check_file = open(file_path) + try: + check_file = open(file_path) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + line = check_file.readline() + str_line= line.rstrip().replace(" ","") + while line: + line = check_file.readline() + str_line+=line.rstrip().replace(" ","") + check_file.close() + + file_path = self.SYS_EEPROM_FILE_2 + check_file = open(file_path) + try: + check_file = open(file_path) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + line = check_file.readline() + str_line+= line.rstrip().replace(" ","") + while line: + line = check_file.readline() + str_line+=line.rstrip().replace(" ","") + check_file.close() + #print(len(str_line)) + #print(str_line) + set_drv_cmd = "echo " + str_line+ " > " + self.SYS_EEPROM_PATH + #print(set_drv_cmd) + log_os_system(set_drv_cmd, 0) + + return True + +def main(argv): + log_file = '%s.log' % FUNCTION_NAME + log_level = logging.WARNING + if len(sys.argv) != 1: + try: + opts, args = getopt.getopt(argv,'hdl:',['lfile=']) + except getopt.GetoptError: + print 'Usage: %s [-d] [-l ]' % sys.argv[0] + return 0 + for opt, arg in opts: + if opt == '-h': + print 'Usage: %s [-d] [-l ]' % sys.argv[0] + return 0 + elif opt in ('-d', '--debug'): + log_level = logging.DEBUG + elif opt in ('-l', '--lfile'): + log_file = arg + + set_drv_cmd = "echo 100 > /sys/module/ipmi_si/parameters/kipmid_max_busy_us" + log_os_system(set_drv_cmd, 0) + monitor = accton_as7716xb_drv_handler(log_file, log_level) + + set_sys_eeprom=0 + thermal_chk_time=0 + psu_chk_time=0 + # Loop forever, doing something useful hopefully: + while True: + logging.debug ("monitor.manage_ipmi") + if set_sys_eeprom==0: + monitor.manage_ipmi_sys() + set_sys_eeprom=1 + monitor.manage_ipmi_qsfp() + time.sleep(0.1) + monitor.manage_ipmi_thermal() + monitor.manage_ipmi_psu() + time.sleep(0.1) + monitor.manage_ipmi_fan() + time.sleep(0.05) + +if __name__ == '__main__': + main(sys.argv[1:]) diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_monitor.py new file mode 100755 index 000000000000..2568312b0955 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_monitor.py @@ -0,0 +1,227 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 Accton Technology Corporation +# +# 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 3 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, see . + +# ------------------------------------------------------------------ +# HISTORY: +# mm/dd/yyyy (A.D.) +# 11/13/2017: Polly Hsu, Create +# 1/10/2018: Jostar modify for as7716_32 +# ------------------------------------------------------------------ + +try: + import os + import sys, getopt + import subprocess + import click + import imp + import logging + import logging.config + import types + import time # this is only being used as part of the example + import traceback + from tabulate import tabulate + from as7716_32x.fanutil import FanUtil + from as7716_32x.thermalutil import ThermalUtil +except ImportError as e: + raise ImportError('%s - required module not found' % str(e)) + +# Deafults +VERSION = '1.0' +FUNCTION_NAME = 'accton_as7716_monitor' + +global log_file +global log_level + + # For AC power Front to Back : + # If any fan fail, please fan speed register to 15 + # The max value of Fan speed register is 9 + # [LM75(48) + LM75(49) + LM75(4A)] > 174 => set Fan speed value from 4 to 5 + # [LM75(48) + LM75(49) + LM75(4A)] > 182 => set Fan speed value from 5 to 7 + # [LM75(48) + LM75(49) + LM75(4A)] > 190 => set Fan speed value from 7 to 9 + # + # [LM75(48) + LM75(49) + LM75(4A)] < 170 => set Fan speed value from 5 to 4 + # [LM75(48) + LM75(49) + LM75(4A)] < 178 => set Fan speed value from 7 to 5 + # [LM75(48) + LM75(49) + LM75(4A)] < 186 => set Fan speed value from 9 to 7 + # + # + # For AC power Back to Front : + # If any fan fail, please fan speed register to 15 + # The max value of Fan speed register is 10 + # [LM75(48) + LM75(49) + LM75(4A)] > 140 => set Fan speed value from 4 to 5 + # [LM75(48) + LM75(49) + LM75(4A)] > 150 => set Fan speed value from 5 to 7 + # [LM75(48) + LM75(49) + LM75(4A)] > 160 => set Fan speed value from 7 to 10 + # + # [LM75(48) + LM75(49) + LM75(4A)] < 135 => set Fan speed value from 5 to 4 + # [LM75(48) + LM75(49) + LM75(4A)] < 145 => set Fan speed value from 7 to 5 + # [LM75(48) + LM75(49) + LM75(4A)] < 155 => set Fan speed value from 10 to 7 + # + + + # 2.If no matched fan speed is found from the policy, + # use FAN_DUTY_CYCLE_MIN as default speed + # Get current temperature + # 4.Decision 3: Decide new fan speed depend on fan direction/current fan speed/temperature + + + + +# Make a class we can use to capture stdout and sterr in the log +class accton_as7716_monitor(object): + # static temp var + _ori_temp = 0 + _new_perc = 0 + _ori_perc = 0 + + def __init__(self, log_file, log_level): + """Needs a logger and a logger level.""" + # set up logging to file + logging.basicConfig( + filename=log_file, + filemode='w', + level=log_level, + format= '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s', + datefmt='%H:%M:%S' + ) + + # set up logging to console + if log_level == logging.DEBUG: + console = logging.StreamHandler() + console.setLevel(log_level) + formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') + console.setFormatter(formatter) + logging.getLogger('').addHandler(console) + + logging.debug('SET. logfile:%s / loglevel:%d', log_file, log_level) + + def manage_fans(self): + + fan_policy_f2b = { + 0: [32, 0, 174000], + 1: [38, 170000, 182000], + 2: [50, 178000, 190000], + 3: [63, 186000, 0], + } + fan_policy_b2f = { + 0: [32, 0, 140000], + 1: [38, 135000, 150000], + 2: [50, 145000, 160000], + 3: [69, 15500, 0], + } + + thermal = ThermalUtil() + fan = FanUtil() + get_temp = thermal.get_thermal_temp() + # 1. Get each fan status, one not presented, set speed to full + # Get fan direction (Only get the first one since all fan direction are the same) + # Get current fan duty cycle + cur_duty_cycle = fan.get_fan_duty_cycle() + #print "cur_duty_cycle=%d" %cur_duty_cycle + #print "get_temp=%d" %get_temp + + for x in range(fan.get_idx_fan_start(), fan.get_num_fans()+1): + fan_status = fan.get_fan_status(x) + if fan_status is None: + #print "fan_status is None" + logging.debug('INFO. SET new_perc to %d (FAN stauts is None. fan_num:%d)', 100, x) + return False + if fan_status is False: + #self._new_perc = FAN_LEV1_SPEED_PERC + #print "fan_%d status=false, set 45 duty_cycle" %x + logging.debug('INFO. SET new_perc to %d (FAN fault. fan_num:%d)', 100, x) + fan.set_fan_duty_cycle(45) + return True + logging.debug('INFO. fan_status is True (fan_num:%d)', x) + + if fan_status is not None and fan_status is not False: + fan_dir=fan.get_fan_dir(1) + for x in range(0, 4): + if cur_duty_cycle == fan_policy_f2b[x][0]: + break + #print "x=%d" %x + #print "fan_dir=%d" %fan_dir + #print "fan_policy_f2b[x][0]=%d" %fan_policy_f2b[x][0] + #print "cur_duty_cycle=%d" %cur_duty_cycle + + if fan_dir == 1: + if x == 4 : + fan.set_fan_duty_cycle(fan_policy_f2b[0][0]) + new_duty_cycle=cur_duty_cycle + # if temp > up_levle, else if temp < down_level + if get_temp > fan_policy_f2b[x][2] and x != 3 : + new_duty_cycle= fan_policy_f2b[x+1][0] + #print "new_duty_cycle= fan_policy_f2b[x+1][0]=%d" %new_duty_cycle + #print "Becasue get_temp > fan_policy_f2b[x][2]=%d" %fan_policy_f2b[x][2] + logging.debug('INFO. THERMAL temp UP, temp %d > %d , new_duty_cycle=%d', get_temp, fan_policy_f2b[x][2], new_duty_cycle) + #else get_temp < fan_policy_f2b[x][1] and x != 0 : + elif get_temp < fan_policy_f2b[x][1] : + new_duty_cycle= fan_policy_f2b[x-1][0] + #print "new_duty_cycle= fan_policy_f2b[x-1][0]=%d" %new_duty_cycle + #print "Becasue get_temp < fan_policy_f2b[x][1]=%d" %fan_policy_f2b[x][1] + logging.debug('INFO. THERMAL temp down, temp %d < %d , new_duty_cycle=%d', get_temp, fan_policy_f2b[x][1], new_duty_cycle) + if new_duty_cycle == cur_duty_cycle : + #print "new_duty_cycle == cur_duty_cycle case, so return True" + return True + else: + if x == 4 : + fan.set_fan_duty_cycle(fan_policy_b2f[0][0]) + new_duty_cycle=cur_duty_cycle + # if temp > up_levle, else if temp < down_level + if get_temp > fan_policy_b2f[x][1] and x != 3 : + new_duty_cycle= fan_policy_b2f[x+1][0] + logging.debug('INFO. THERMAL temp UP, temp %d > %d , new_duty_cycle=%d', get_temp, fan_policy_b2f[x][2], new_duty_cycle) + elif get_temp < fan_policy_b2f[x][0] and x != 0 : + #elif get_temp < fan_policy_b2f[x][0] + new_duty_cycle= fan_policy_b2f[x-1][0] + logging.debug('INFO. THERMAL temp down, temp %d < %d , new_duty_cycle=%d', get_temp, fan_policy_b2f[x][1], new_duty_cycle) + if new_duty_cycle == cur_duty_cycle : + return True + + fan.set_fan_duty_cycle(new_duty_cycle) + #print "set new_duty_cycle=%d" %new_duty_cycle + #print "old_duty_cycle=%d" %cur_duty_cycle + + return True + + + +def main(argv): + log_file = '%s.log' % FUNCTION_NAME + log_level = logging.INFO + if len(sys.argv) != 1: + try: + opts, args = getopt.getopt(argv,'hdl:',['lfile=']) + except getopt.GetoptError: + print 'Usage: %s [-d] [-l ]' % sys.argv[0] + return 0 + for opt, arg in opts: + if opt == '-h': + print 'Usage: %s [-d] [-l ]' % sys.argv[0] + return 0 + elif opt in ('-d', '--debug'): + log_level = logging.DEBUG + elif opt in ('-l', '--lfile'): + log_file = arg + + monitor = accton_as7716_monitor(log_file, log_level) + + # Loop forever, doing something useful hopefully: + while True: + monitor.manage_fans() + time.sleep(1) + +if __name__ == '__main__': + main(sys.argv[1:]) diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_util.py b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_util.py new file mode 100755 index 000000000000..ffddfb338506 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32xb/utils/accton_as7716_32xb_util.py @@ -0,0 +1,616 @@ +#!/usr/bin/env python +# +# Copyright (C) 2016 Accton Networks, 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 3 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, see . + +""" +Usage: %(scriptName)s [options] command object + +options: + -h | --help : this help message + -d | --debug : run with debug mode + -f | --force : ignore error during installation or clean +command: + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes + show : show all systen status + sff : dump SFP eeprom + set : change board setting with fan|led|sfp +""" + +import os +import commands +import sys, getopt +import logging +import re +import time +from collections import namedtuple + +PROJECT_NAME = 'as7716_32xb' +version = '0.0.1' +verbose = False +DEBUG = False +args = [] +ALL_DEVICE = {} +DEVICE_NO = {'led':5, 'fan1':1, 'fan2':1,'fan3':1,'fan4':1,'fan5':1,'thermal':3, 'psu':2, 'sfp':54} + + +led_prefix ='/sys/devices/platform/as7716_32xb_led/leds/accton_'+PROJECT_NAME+'_led::' +fan_prefix ='/sys/devices/platform/as7716_32xb_' +hwmon_types = {'led': ['diag','fan','loc','psu1','psu2'], + 'fan1': ['fan'], + 'fan2': ['fan'], + 'fan3': ['fan'], + 'fan4': ['fan'], + 'fan5': ['fan'], + 'fan5': ['fan'], + } +hwmon_nodes = {'led': ['brightness'] , + 'fan1': ['fan_duty_cycle_percentage', 'fan1_fault', 'fan1_speed_rpm', 'fan1_direction', 'fanr1_fault', 'fanr1_speed_rpm'], + 'fan2': ['fan_duty_cycle_percentage','fan2_fault', 'fan2_speed_rpm', 'fan2_direction', 'fanr2_fault', 'fanr2_speed_rpm'], + 'fan3': ['fan_duty_cycle_percentage','fan3_fault', 'fan3_speed_rpm', 'fan3_direction', 'fanr3_fault', 'fanr3_speed_rpm'], + 'fan4': ['fan4_duty_cycle_percentage','fan4_fault', 'fan4_speed_rpm', 'fan4_direction', 'fanr4_fault', 'fanr4_speed_rpm'], + 'fan5': ['fan_duty_cycle_percentage','fan5_fault', 'fan5_speed_rpm', 'fan5_direction', 'fanr5_fault', 'fanr5_speed_rpm'], + } +hwmon_prefix ={'led': led_prefix, + 'fan1': fan_prefix, + 'fan2': fan_prefix, + 'fan3': fan_prefix, + 'fan4': fan_prefix, + 'fan5': fan_prefix, + } + +i2c_prefix = '/sys/bus/i2c/devices/' +i2c_drv_prefix = '/sys/bus/i2c/devices/' +i2c_bus = {'thermal': ['10-0048','10-0049', '10-004a'] , + 'psu': ['17-0050','18-0053'], + 'sfp': ['-0050']} +i2c_nodes = { + 'thermal': ['hwmon/hwmon*/temp1_input'] , + 'psu': ['psu_present ', 'psu_power_good'] , + 'sfp': ['sfp_is_present ', 'sfp_tx_disable']} + +sfp_map = [1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32] + +mknod =[ +'echo as7716_32xb_cpld1 0x60 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo accton_i2c_cpld 0x62 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo accton_i2c_cpld 0x64 > /sys/bus/i2c/devices/i2c-0/new_device', + +] + +mknod_xb =[ +'echo as7716_32xb_cpld1 0x60 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo accton_i2c_cpld 0x62 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo accton_i2c_cpld 0x64 > /sys/bus/i2c/devices/i2c-0/new_device', +#Thermal +'echo as7716_32xb_thermal 0x48 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo as7716_32xb_thermal 0x49 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo as7716_32xb_thermal 0x4a > /sys/bus/i2c/devices/i2c-0/new_device', +#Fan +'echo as7716_32xb_fan 0x66 > /sys/bus/i2c/devices/i2c-0/new_device', +# PSU-1 +'echo as7716_32xb_psu1 0x53 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo as7716_32xb_psu2 0x50> /sys/bus/i2c/devices/i2c-0/new_device', +# PSU-2 +'echo as7716_32xb_pmbus 0x5b > /sys/bus/i2c/devices/i2c-0/new_device', +'echo as7716_32xb_pmbus 0x58 > /sys/bus/i2c/devices/i2c-0/new_device', +#EERPOM +'echo as7716_32xb_sys 0x56 > /sys/bus/i2c/devices/i2c-0/new_device', +] + + + +mknod2 =[ +'echo as7716_32xb_cpld1 0x60 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo accton_i2c_cpld 0x61 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo accton_i2c_cpld 0x62 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-0/new_device', + +# PSU-1 +'echo as7716_32xb_psu1 0x38 > /sys/bus/i2c/devices/i2c-57/new_device', +'echo cpr_4011_4mxx 0x3c > /sys/bus/i2c/devices/i2c-57/new_device', +'echo as7716_32xb_psu1 0x50 > /sys/bus/i2c/devices/i2c-57/new_device', +'echo ym2401 0x58 > /sys/bus/i2c/devices/i2c-57/new_device', + +# PSU-2 +'echo as7716_32xb_psu2 0x3b > /sys/bus/i2c/devices/i2c-58/new_device', +'echo cpr_4011_4mxx 0x3f > /sys/bus/i2c/devices/i2c-58/new_device', +'echo as7716_32xb_psu2 0x53 > /sys/bus/i2c/devices/i2c-58/new_device', +'echo ym2401 0x5b > /sys/bus/i2c/devices/i2c-58/new_device', + +'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-61/new_device', +'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-62/new_device', +'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-63/new_device', + +#EERPOM +#'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-1/new_device', +] + +FORCE = 0 +logging.basicConfig(filename= PROJECT_NAME+'.log', filemode='w',level=logging.DEBUG) +logging.basicConfig(level=logging.INFO) + + +if DEBUG == True: + print sys.argv[0] + print 'ARGV :', sys.argv[1:] + + +def main(): + global DEBUG + global args + global FORCE + + if len(sys.argv)<2: + show_help() + + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', + 'debug', + 'force', + ]) + if DEBUG == True: + print options + print args + print len(sys.argv) + + for opt, arg in options: + if opt in ('-h', '--help'): + show_help() + elif opt in ('-d', '--debug'): + DEBUG = True + logging.basicConfig(level=logging.INFO) + elif opt in ('-f', '--force'): + FORCE = 1 + else: + logging.info('no option') + for arg in args: + if arg == 'install': + do_install() + elif arg == 'clean': + do_uninstall() + elif arg == 'show': + device_traversal() + elif arg == 'sff': + if len(args)!=2: + show_eeprom_help() + elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']: + show_eeprom_help() + else: + show_eeprom(args[1]) + return + elif arg == 'set': + if len(args)<3: + show_set_help() + else: + set_device(args[1:]) + return + else: + show_help() + + + return 0 + +def show_help(): + print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + sys.exit(0) + +def show_set_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print cmd +" [led|sfp|fan]" + print " use \""+ cmd + " led 0-4 \" to set led color" + print " use \""+ cmd + " fan 0-100\" to set fan duty percetage" + print " use \""+ cmd + " sfp 1-32 {0|1}\" to set sfp# tx_disable" + sys.exit(0) + +def show_eeprom_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print " use \""+ cmd + " 1-32 \" to dump sfp# eeprom" + sys.exit(0) + +def my_log(txt): + if DEBUG == True: + print "[ACCTON DBG]: "+txt + return + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status = 1 + output = "" + status, output = commands.getstatusoutput(cmd) + my_log (cmd +"with result:" + str(status)) + my_log ("cmd:" + cmd) + my_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + +def driver_inserted(): + ret, lsmod = log_os_system("lsmod| grep accton", 0) + logging.info('mods:'+lsmod) + if len(lsmod) ==0: + return False + + +kos = [ +'depmod -ae', +'modprobe ipmi_msghandler', +'modprobe ipmi_si', +'modprobe ipmi_devintf', +'modprobe i2c_dev', +'modprobe accton_i2c_cpld', +'modprobe accton_as7716_32xb_cpld1', +'modprobe accton_as7716_32xb_fan', +'modprobe accton_as7716_32xb_leds', +'modprobe accton_as7716_32xb_psu', +'modprobe accton_as7716_32xb_oom', +'modprobe accton_as7716_32xb_thermal', +'modprobe accton_as7716_32xb_pmbus', +'modprobe accton_as7716_32xb_sys'] + +def driver_install(): + global FORCE + for i in range(0,len(kos)): + status, output = log_os_system(kos[i], 1) + if status: + if FORCE == 0: + return status + return 0 + +def driver_uninstall(): + global FORCE + for i in range(0,len(kos)): + rm = kos[-(i+1)].replace("modprobe", "modprobe -rq") + rm = rm.replace("insmod", "rmmod") + status, output = log_os_system(rm, 1) + if status: + if FORCE == 0: + return status + return 0 + + + +def i2c_order_check(): + # i2c bus 0 and 1 might be installed in different order. + # Here check if 0x76 is exist @ i2c-0 + tmp = "echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-1/new_device" + status, output = log_os_system(tmp, 0) + if not device_exist(): + order = 1 + else: + order = 0 + tmp = "echo 0x70 > /sys/bus/i2c/devices/i2c-1/delete_device" + status, output = log_os_system(tmp, 0) + return order + +def device_install(): + global FORCE + + #order = i2c_order_check() + # if 0x76 is not exist @i2c-0, use reversed bus order + #if order: + # for i in range(0,len(mknod2)): + # #for pca932x need times to built new i2c buses + # if mknod2[i].find('pca954') != -1: + # time.sleep(2) + + # status, output = log_os_system(mknod2[i], 1) + # if status: + # print output + # if FORCE == 0: + # return status + #else: + print "Prepar to create instance.............." + for i in range(0,len(mknod_xb)): + print "Beginn to create instance.............." + status, output = log_os_system(mknod_xb[i], 1) + print "status=%s" %status + print "output=%s" %output + if status: + print output + if FORCE == 0: + return status + #time.sleep (50.0 / 1000.0) + print "Create sfp instance.............." + for i in range(0,len(sfp_map)): + status, output =log_os_system("echo as7716_32xb_oom 0x"+str(sfp_map[i])+ " > /sys/bus/i2c/devices/i2c-0/new_device", 1) + if status: + print output + if FORCE == 0: + return status + #status, output =log_os_system("echo port"+str(i)+" > /sys/bus/i2c/devices/0-000"+str(sfp_map[i])+"/port_name", 1) + #if status: + # print output + # if FORCE == 0: + # return status + return + +def device_uninstall(): + global FORCE + + for i in range(0,len(sfp_map)): + target = "echo 0x"+str(sfp_map[i])+ " > /sys/bus/i2c/devices/i2c-0/delete_device" + print(target) + status, output =log_os_system(target, 1) + if status: + print output + if FORCE == 0: + return status + + nodelist = mknod_xb + + for i in range(len(nodelist)): + target = nodelist[-(i+1)] + temp = target.split() + del temp[1] + temp[-1] = temp[-1].replace('new_device', 'delete_device') + status, output = log_os_system(" ".join(temp), 1) + if status: + print output + if FORCE == 0: + return status + + return + +def system_ready(): + if driver_inserted() == False: + print "driver_inserted() == False" + return False + if not device_exist(): + print "not device_exist()" + return False + return True + +def do_install(): + print "Checking system...." + if driver_inserted() == False: + print "No driver, installing.1..." + status = driver_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" drivers detected...." + if not device_exist(): + print "No device, installing..2.." + status = device_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" devices detected...." + return + +def do_uninstall(): + print "Checking systemm...." + if not device_exist(): + print PROJECT_NAME.upper() +" has no device installed...." + else: + print "Removing device...." + status = device_uninstall() + if status: + if FORCE == 0: + return status + + if driver_inserted()== False : + print PROJECT_NAME.upper() +" has no driver installed...." + else: + print "Removing installed driver...." + status = driver_uninstall() + if status: + if FORCE == 0: + return status + + return + +def devices_info(): + global DEVICE_NO + global ALL_DEVICE + global i2c_bus, hwmon_types + for key in DEVICE_NO: + ALL_DEVICE[key]= {} + for i in range(0,DEVICE_NO[key]): + ALL_DEVICE[key][key+str(i+1)] = [] + + for key in i2c_bus: + buses = i2c_bus[key] + nodes = i2c_nodes[key] + for i in range(0,len(buses)): + for j in range(0,len(nodes)): + if 'fan' == key: + for k in range(0,DEVICE_NO[key]): + node = key+str(k+1) + path = i2c_prefix+ buses[i]+"/fan"+str(k+1)+"_"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + elif 'sfp' == key: + for k in range(0,DEVICE_NO[key]): + node = key+str(k+1) + path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j] + print "path= %s" %path + print "i=%d" %i + print "k=%d" %k + print "j= %d" %j + print "sfp_map[k]=%s" %sfp_map[k] + print " buses[i]=%s" %buses[i] + print "nodes[j]=%s" %nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + else: + node = key+str(i+1) + path = i2c_prefix+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + + for key in hwmon_types: + itypes = hwmon_types[key] + nodes = hwmon_nodes[key] + for i in range(0,len(itypes)): + for j in range(0,len(nodes)): + node = key+"_"+itypes[i] + path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][ key+str(i+1)].append(path) + + #show dict all in the order + if DEBUG == True: + for i in sorted(ALL_DEVICE.keys()): + print(i+": ") + for j in sorted(ALL_DEVICE[i].keys()): + print(" "+j) + for k in (ALL_DEVICE[i][j]): + print(" "+" "+k) + return + +def show_eeprom(index): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0] + node = node.replace(node.split("/")[-1], 'sfp_eeprom') + # check if got hexdump command in current environment + ret, log = log_os_system("which hexdump", 0) + ret, log2 = log_os_system("which busybox hexdump", 0) + if len(log): + hex_cmd = 'hexdump' + elif len(log2): + hex_cmd = ' busybox hexdump' + else: + log = 'Failed : no hexdump cmd!!' + logging.info(log) + print log + return 1 + + print node + ":" + ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1) + if ret==0: + print log + else: + print "**********device no found**********" + return + +def set_device(args): + global DEVICE_NO + global ALL_DEVICE + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + + if args[0]=='led': + if int(args[1])>4: + show_set_help() + return + #print ALL_DEVICE['led'] + for i in range(0,len(ALL_DEVICE['led'])): + for k in (ALL_DEVICE['led']['led'+str(i+1)]): + ret, log = log_os_system("echo "+args[1]+" >"+k, 1) + if ret: + return ret + elif args[0]=='fan': + if int(args[1])>100: + show_set_help() + return + #print ALL_DEVICE['fan'] + #fan1~6 is all fine, all fan share same setting + node = ALL_DEVICE['fan1'] ['fan11'][0] + node = node.replace(node.split("/")[-1], 'fan1_duty_cycle_percentage') + ret, log = log_os_system("cat "+ node, 1) + if ret==0: + print ("Previous fan duty: " + log.strip() +"%") + ret, log = log_os_system("echo "+args[1]+" >"+node, 1) + if ret==0: + print ("Current fan duty: " + args[1] +"%") + return ret + elif args[0]=='sfp': + if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0: + show_set_help() + return + if len(args)<2: + show_set_help() + return + + if int(args[2])>1: + show_set_help() + return + + #print ALL_DEVICE[args[0]] + for i in range(0,len(ALL_DEVICE[args[0]])): + for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]: + if j.find('tx_disable')!= -1: + ret, log = log_os_system("echo "+args[2]+" >"+ j, 1) + if ret: + return ret + + return + +#get digits inside a string. +#Ex: 31 for "sfp31" +def get_value(input): + digit = re.findall('\d+', input) + return int(digit[0]) + +def device_traversal(): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + for i in sorted(ALL_DEVICE.keys()): + print("============================================") + print(i.upper()+": ") + print("============================================") + + for j in sorted(ALL_DEVICE[i].keys(), key=get_value): + print " "+j+":", + for k in (ALL_DEVICE[i][j]): + ret, log = log_os_system("cat "+k, 0) + func = k.split("/")[-1].strip() + func = re.sub(j+'_','',func,1) + func = re.sub(i.lower()+'_','',func,1) + if ret==0: + print func+"="+log+" ", + else: + print func+"="+"X"+" ", + print + print("----------------------------------------------------------------") + + + print + return + +def device_exist(): + ret1, log = log_os_system("ls "+i2c_prefix+"*0060", 0) + ret2, log = log_os_system("ls "+i2c_prefix+"i2c-0", 0) + print(ret1) + print(ret2) + return not(ret1 or ret2) + +if __name__ == "__main__": + main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/classes/__init__.py b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/classes/__init__.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/classes/fanutil.py b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/classes/fanutil.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/classes/thermalutil.py b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/classes/thermalutil.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/Makefile b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/Makefile new file mode 100644 index 000000000000..1b3477b0b771 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/Makefile @@ -0,0 +1,2 @@ +obj-m:=x86-64-accton-as7816-64x-fan.o x86-64-accton-as7816-64x-sfp.o x86-64-accton-as7816-64x-leds.o \ + x86-64-accton-as7816-64x-psu.o accton_i2c_cpld.o ym2651y.o diff --git a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/accton_i2c_cpld.c b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/accton_i2c_cpld.c new file mode 120000 index 000000000000..39c0826d16fd --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/accton_i2c_cpld.c @@ -0,0 +1 @@ +../../common/modules/accton_i2c_cpld.c \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/x86-64-accton-as7816-64x-fan.c b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/x86-64-accton-as7816-64x-fan.c new file mode 100644 index 000000000000..3de2c200e1e1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/x86-64-accton-as7816-64x-fan.c @@ -0,0 +1,466 @@ +/* + * A hwmon driver for the Accton as7816-64x fan + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "as7816_64x_fan" + +static struct as7816_64x_fan_data *as7816_64x_fan_update_device(struct device *dev); +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); + +/* fan related data, the index should match sysfs_fan_attributes + */ +static const u8 fan_reg[] = { + 0x80, /* fan 1-4 present status */ + 0x81, /* fan 1-4 direction(0:F2B 1:B2F) */ + 0x87, /* fan PWM(for all fan) */ + 0x90, /* front fan 1 speed(rpm) */ + 0x91, /* front fan 2 speed(rpm) */ + 0x92, /* front fan 3 speed(rpm) */ + 0x93, /* front fan 4 speed(rpm) */ + 0x98, /* rear fan 1 speed(rpm) */ + 0x99, /* rear fan 2 speed(rpm) */ + 0x9A, /* rear fan 3 speed(rpm) */ + 0x9B, /* rear fan 4 speed(rpm) */ +}; + +/* Each client has this additional data */ +struct as7816_64x_fan_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[ARRAY_SIZE(fan_reg)]; /* Register value */ +}; + +enum fan_id { + FAN1_ID, + FAN2_ID, + FAN3_ID, + FAN4_ID +}; + +enum sysfs_fan_attributes { + FAN_PRESENT_REG, + FAN_DIRECTION_REG, + FAN_DUTY_CYCLE_PERCENTAGE, /* Only one CPLD register to control duty cycle for all fans */ + FAN1_FRONT_SPEED_RPM, + FAN2_FRONT_SPEED_RPM, + FAN3_FRONT_SPEED_RPM, + FAN4_FRONT_SPEED_RPM, + FAN1_REAR_SPEED_RPM, + FAN2_REAR_SPEED_RPM, + FAN3_REAR_SPEED_RPM, + FAN4_REAR_SPEED_RPM, + FAN1_DIRECTION, + FAN2_DIRECTION, + FAN3_DIRECTION, + FAN4_DIRECTION, + FAN1_PRESENT, + FAN2_PRESENT, + FAN3_PRESENT, + FAN4_PRESENT, + FAN1_FAULT, + FAN2_FAULT, + FAN3_FAULT, + FAN4_FAULT +}; + +/* Define attributes + */ +#define DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(index, index2) \ + static SENSOR_DEVICE_ATTR(fan##index##_fault, S_IRUGO, fan_show_value, NULL, FAN##index##_FAULT);\ + static SENSOR_DEVICE_ATTR(fan##index2##_fault, S_IRUGO, fan_show_value, NULL, FAN##index##_FAULT) +#define DECLARE_FAN_FAULT_ATTR(index, index2) &sensor_dev_attr_fan##index##_fault.dev_attr.attr, \ + &sensor_dev_attr_fan##index2##_fault.dev_attr.attr + +#define DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_direction, S_IRUGO, fan_show_value, NULL, FAN##index##_DIRECTION) +#define DECLARE_FAN_DIRECTION_ATTR(index) &sensor_dev_attr_fan##index##_direction.dev_attr.attr + +#define DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan_duty_cycle_percentage, S_IWUSR | S_IRUGO, fan_show_value, set_duty_cycle, FAN_DUTY_CYCLE_PERCENTAGE);\ + static SENSOR_DEVICE_ATTR(pwm##index, S_IWUSR | S_IRUGO, fan_show_value, set_duty_cycle, FAN_DUTY_CYCLE_PERCENTAGE) + +#define DECLARE_FAN_DUTY_CYCLE_ATTR(index) &sensor_dev_attr_fan_duty_cycle_percentage.dev_attr.attr, \ + &sensor_dev_attr_pwm##index.dev_attr.attr + + +#define DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_present, S_IRUGO, fan_show_value, NULL, FAN##index##_PRESENT) +#define DECLARE_FAN_PRESENT_ATTR(index) &sensor_dev_attr_fan##index##_present.dev_attr.attr + +#define DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(index, index2) \ + static SENSOR_DEVICE_ATTR(fan##index##_front_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_FRONT_SPEED_RPM);\ + static SENSOR_DEVICE_ATTR(fan##index##_rear_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_REAR_SPEED_RPM);\ + static SENSOR_DEVICE_ATTR(fan##index##_input, S_IRUGO, fan_show_value, NULL, FAN##index##_FRONT_SPEED_RPM);\ + static SENSOR_DEVICE_ATTR(fan##index2##_input, S_IRUGO, fan_show_value, NULL, FAN##index##_REAR_SPEED_RPM) +#define DECLARE_FAN_SPEED_RPM_ATTR(index, index2) &sensor_dev_attr_fan##index##_front_speed_rpm.dev_attr.attr, \ + &sensor_dev_attr_fan##index##_rear_speed_rpm.dev_attr.attr, \ + &sensor_dev_attr_fan##index##_input.dev_attr.attr, \ + &sensor_dev_attr_fan##index2##_input.dev_attr.attr + +/* 6 fan fault attributes in this platform */ +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(1,11); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(2,12); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(3,13); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(4,14); +/* 6 fan speed(rpm) attributes in this platform */ +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(1,11); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(2,12); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(3,13); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(4,14); +/* 6 fan present attributes in this platform */ +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(1); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(2); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(3); +DECLARE_FAN_PRESENT_SENSOR_DEV_ATTR(4); +/* 6 fan direction attribute in this platform */ +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(1); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(2); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(3); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(4); +/* 1 fan duty cycle attribute in this platform */ +DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(1); + +static struct attribute *as7816_64x_fan_attributes[] = { + /* fan related attributes */ + DECLARE_FAN_FAULT_ATTR(1,11), + DECLARE_FAN_FAULT_ATTR(2,12), + DECLARE_FAN_FAULT_ATTR(3,13), + DECLARE_FAN_FAULT_ATTR(4,14), + DECLARE_FAN_SPEED_RPM_ATTR(1,11), + DECLARE_FAN_SPEED_RPM_ATTR(2,12), + DECLARE_FAN_SPEED_RPM_ATTR(3,13), + DECLARE_FAN_SPEED_RPM_ATTR(4,14), + DECLARE_FAN_PRESENT_ATTR(1), + DECLARE_FAN_PRESENT_ATTR(2), + DECLARE_FAN_PRESENT_ATTR(3), + DECLARE_FAN_PRESENT_ATTR(4), + DECLARE_FAN_DIRECTION_ATTR(1), + DECLARE_FAN_DIRECTION_ATTR(2), + DECLARE_FAN_DIRECTION_ATTR(3), + DECLARE_FAN_DIRECTION_ATTR(4), + DECLARE_FAN_DUTY_CYCLE_ATTR(1), + NULL +}; + +#define FAN_DUTY_CYCLE_REG_MASK 0xF +#define FAN_MAX_DUTY_CYCLE 100 +#define FAN_REG_VAL_TO_SPEED_RPM_STEP 100 + +static int as7816_64x_fan_read_value(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int as7816_64x_fan_write_value(struct i2c_client *client, u8 reg, u8 value) +{ + return i2c_smbus_write_byte_data(client, reg, value); +} + +/* fan utility functions + */ +static u32 reg_val_to_duty_cycle(u8 reg_val) +{ + reg_val &= FAN_DUTY_CYCLE_REG_MASK; + + if (!reg_val) { + return 0; + } + + if (reg_val == 0xF) { + return FAN_MAX_DUTY_CYCLE; + } + + return (reg_val * 6) + 10; +} + +static u8 duty_cycle_to_reg_val(u8 duty_cycle) +{ + if (duty_cycle < 16) { + return 0; + } + + if (duty_cycle >= 100) { + return 0xF; + } + + return (duty_cycle - 10) / 6; +} + +static u32 reg_val_to_speed_rpm(u8 reg_val) +{ + return (u32)reg_val * FAN_REG_VAL_TO_SPEED_RPM_STEP; +} + +static u8 reg_val_to_direction(u8 reg_val, enum fan_id id) +{ + u8 mask = (1 << id); + return !!(reg_val & mask); +} + +static u8 reg_val_to_is_present(u8 reg_val, enum fan_id id) +{ + u8 mask = (1 << id); + return !(reg_val & mask); +} + +static u8 is_fan_fault(struct as7816_64x_fan_data *data, enum fan_id id) +{ + u8 ret = 1; + int front_fan_index = FAN1_FRONT_SPEED_RPM + id; + int rear_fan_index = FAN1_REAR_SPEED_RPM + id; + + /* Check if the speed of front or rear fan is ZERO, + */ + if (reg_val_to_speed_rpm(data->reg_val[front_fan_index]) && + reg_val_to_speed_rpm(data->reg_val[rear_fan_index])) { + ret = 0; + } + + return ret; +} + +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int error, value; + struct i2c_client *client = to_i2c_client(dev); + + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (value < 0 || value > FAN_MAX_DUTY_CYCLE) + return -EINVAL; + + as7816_64x_fan_write_value(client, 0x28, 0); /* Disable fan speed watch dog */ + as7816_64x_fan_write_value(client, fan_reg[FAN_DUTY_CYCLE_PERCENTAGE], duty_cycle_to_reg_val(value)); + return count; +} + +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct as7816_64x_fan_data *data = as7816_64x_fan_update_device(dev); + ssize_t ret = 0; + + if (data->valid) { + switch (attr->index) { + case FAN_DUTY_CYCLE_PERCENTAGE: + { + u32 duty_cycle = reg_val_to_duty_cycle(data->reg_val[FAN_DUTY_CYCLE_PERCENTAGE]); + ret = sprintf(buf, "%u\n", duty_cycle); + break; + } + case FAN1_FRONT_SPEED_RPM: + case FAN2_FRONT_SPEED_RPM: + case FAN3_FRONT_SPEED_RPM: + case FAN4_FRONT_SPEED_RPM: + case FAN1_REAR_SPEED_RPM: + case FAN2_REAR_SPEED_RPM: + case FAN3_REAR_SPEED_RPM: + case FAN4_REAR_SPEED_RPM: + { + ret = sprintf(buf, "%u\n", reg_val_to_speed_rpm(data->reg_val[attr->index])); + break; + } + case FAN1_PRESENT: + case FAN2_PRESENT: + case FAN3_PRESENT: + case FAN4_PRESENT: + ret = sprintf(buf, "%d\n", + reg_val_to_is_present(data->reg_val[FAN_PRESENT_REG], + attr->index - FAN1_PRESENT)); + break; + case FAN1_FAULT: + case FAN2_FAULT: + case FAN3_FAULT: + case FAN4_FAULT: + ret = sprintf(buf, "%d\n", is_fan_fault(data, attr->index - FAN1_FAULT)); + break; + case FAN1_DIRECTION: + case FAN2_DIRECTION: + case FAN3_DIRECTION: + case FAN4_DIRECTION: + ret = sprintf(buf, "%d\n", + reg_val_to_direction(data->reg_val[FAN_DIRECTION_REG], + attr->index - FAN1_DIRECTION)); + break; + default: + break; + } + } + + return ret; +} + +static const struct attribute_group as7816_64x_fan_group = { + .attrs = as7816_64x_fan_attributes, +}; + +static struct as7816_64x_fan_data *as7816_64x_fan_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as7816_64x_fan_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || + !data->valid) { + int i; + + dev_dbg(&client->dev, "Starting as7816_64x_fan update\n"); + data->valid = 0; + + /* Update fan data + */ + for (i = 0; i < ARRAY_SIZE(data->reg_val); i++) { + int status = as7816_64x_fan_read_value(client, fan_reg[i]); + + if (status < 0) { + data->valid = 0; + mutex_unlock(&data->update_lock); + dev_dbg(&client->dev, "reg %d, err %d\n", fan_reg[i], status); + return data; + } + else { + data->reg_val[i] = status; + } + } + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +static int as7816_64x_fan_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct as7816_64x_fan_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct as7816_64x_fan_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as7816_64x_fan_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: fan '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as7816_64x_fan_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as7816_64x_fan_remove(struct i2c_client *client) +{ + struct as7816_64x_fan_data *data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as7816_64x_fan_group); + + return 0; +} + +/* Addresses to scan */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +static const struct i2c_device_id as7816_64x_fan_id[] = { + { "as7816_64x_fan", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, as7816_64x_fan_id); + +static struct i2c_driver as7816_64x_fan_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = DRVNAME, + }, + .probe = as7816_64x_fan_probe, + .remove = as7816_64x_fan_remove, + .id_table = as7816_64x_fan_id, + .address_list = normal_i2c, +}; + +static int __init as7816_64x_fan_init(void) +{ + return i2c_add_driver(&as7816_64x_fan_driver); +} + +static void __exit as7816_64x_fan_exit(void) +{ + i2c_del_driver(&as7816_64x_fan_driver); +} + +module_init(as7816_64x_fan_init); +module_exit(as7816_64x_fan_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("as7816_64x_fan driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/x86-64-accton-as7816-64x-leds.c b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/x86-64-accton-as7816-64x-leds.c new file mode 100644 index 000000000000..025f87d692a3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/x86-64-accton-as7816-64x-leds.c @@ -0,0 +1,460 @@ +/* + * A LED driver for the as7816_64x_led + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*#define DEBUG*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +extern int accton_i2c_cpld_read (u8 cpld_addr, u8 reg); +extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +extern void led_classdev_unregister(struct led_classdev *led_cdev); +extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); +extern void led_classdev_resume(struct led_classdev *led_cdev); +extern void led_classdev_suspend(struct led_classdev *led_cdev); + +#define DRVNAME "as7816_64x_led" + +struct as7816_64x_led_data { + struct platform_device *pdev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[1]; /* only 1 register*/ +}; + +static struct as7816_64x_led_data *ledctl = NULL; + +/* LED related data + */ + +#define LED_CNTRLER_I2C_ADDRESS (0x60) + +#define LED_TYPE_DIAG_REG_MASK (0x03) +#define LED_MODE_DIAG_YELLOW_VALUE (0x00) +#define LED_MODE_DIAG_RED_VALUE (0x01) +#define LED_MODE_DIAG_GREEN_VALUE (0x02) +#define LED_MODE_DIAG_OFF_VALUE (0x03) + +#define LED_TYPE_LOC_REG_MASK (0x10) +#define LED_MODE_LOC_ORANGE_VALUE (0x00) +#define LED_MODE_LOC_OFF_VALUE (0x10) + +#define LED_TYPE_FAN_REG_MASK (0x0C) +#define LED_MODE_FAN_ORANGE_VALUE (0x04) +#define LED_MODE_FAN_GREEN_VALUE_1 (0x00) +#define LED_MODE_FAN_GREEN_VALUE_2 (0x08) +#define LED_MODE_FAN_OFF_VALUE (0x0C) + +enum led_type { + LED_TYPE_DIAG, + LED_TYPE_LOC, + LED_TYPE_FAN, + LED_TYPE_PSU1, + LED_TYPE_PSU2 +}; + +struct led_reg { + u32 types; + u8 reg_addr; +}; + +static const struct led_reg led_reg_map[] = { + {(1 << LED_TYPE_LOC) | (1 << LED_TYPE_DIAG) | (1 << LED_TYPE_FAN), 0x30}, +}; + +enum led_light_mode { + LED_MODE_OFF, + LED_MODE_RED = 10, + LED_MODE_RED_BLINKING = 11, + LED_MODE_ORANGE = 12, + LED_MODE_ORANGE_BLINKING = 13, + LED_MODE_YELLOW = 14, + LED_MODE_YELLOW_BLINKING = 15, + LED_MODE_GREEN = 16, + LED_MODE_GREEN_BLINKING = 17, + LED_MODE_BLUE = 18, + LED_MODE_BLUE_BLINKING = 19, + LED_MODE_PURPLE = 20, + LED_MODE_PURPLE_BLINKING = 21, + LED_MODE_AUTO = 22, + LED_MODE_AUTO_BLINKING = 23, + LED_MODE_WHITE = 24, + LED_MODE_WHITE_BLINKING = 25, + LED_MODE_CYAN = 26, + LED_MODE_CYAN_BLINKING = 27, + LED_MODE_UNKNOWN = 99 +}; + +struct led_type_mode { + enum led_type type; + enum led_light_mode mode; + int reg_bit_mask; + int mode_value; +}; + +static struct led_type_mode led_type_mode_data[] = { +{LED_TYPE_LOC, LED_MODE_OFF, LED_TYPE_LOC_REG_MASK, LED_MODE_LOC_OFF_VALUE}, +{LED_TYPE_LOC, LED_MODE_ORANGE,LED_TYPE_LOC_REG_MASK, LED_MODE_LOC_ORANGE_VALUE}, +{LED_TYPE_DIAG, LED_MODE_OFF, LED_TYPE_DIAG_REG_MASK, LED_MODE_DIAG_OFF_VALUE}, +{LED_TYPE_DIAG, LED_MODE_GREEN, LED_TYPE_DIAG_REG_MASK, LED_MODE_DIAG_GREEN_VALUE}, +{LED_TYPE_DIAG, LED_MODE_RED, LED_TYPE_DIAG_REG_MASK, LED_MODE_DIAG_RED_VALUE}, +{LED_TYPE_DIAG, LED_MODE_YELLOW,LED_TYPE_DIAG_REG_MASK, LED_MODE_DIAG_YELLOW_VALUE}, +{LED_TYPE_FAN, LED_MODE_OFF, LED_TYPE_FAN_REG_MASK, LED_MODE_FAN_OFF_VALUE}, +{LED_TYPE_FAN, LED_MODE_GREEN, LED_TYPE_FAN_REG_MASK, LED_MODE_FAN_GREEN_VALUE_1}, +{LED_TYPE_FAN, LED_MODE_GREEN, LED_TYPE_FAN_REG_MASK, LED_MODE_FAN_GREEN_VALUE_2}, +{LED_TYPE_FAN, LED_MODE_ORANGE,LED_TYPE_FAN_REG_MASK, LED_MODE_FAN_ORANGE_VALUE} +}; + +static int get_led_reg(enum led_type type, u8 *reg) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(led_reg_map); i++) { + if(led_reg_map[i].types & (1 << type)) { + *reg = led_reg_map[i].reg_addr; + return 0; + } + } + + return 1; +} + +static int led_reg_val_to_light_mode(enum led_type type, u8 reg_val) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) { + + if (type != led_type_mode_data[i].type) + continue; + + if ((led_type_mode_data[i].reg_bit_mask & reg_val) == + led_type_mode_data[i].mode_value) + { + return led_type_mode_data[i].mode; + } + } + + return 0; +} + +static u8 led_light_mode_to_reg_val(enum led_type type, + enum led_light_mode mode, u8 reg_val) { + int i; + + for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) { + if (type != led_type_mode_data[i].type) + continue; + + if (mode != led_type_mode_data[i].mode) + continue; + + reg_val = led_type_mode_data[i].mode_value | + (reg_val & (~led_type_mode_data[i].reg_bit_mask)); + break; + } + + return reg_val; +} + +static int as7816_64x_led_read_value(u8 reg) +{ + return accton_i2c_cpld_read(LED_CNTRLER_I2C_ADDRESS, reg); +} + +static int as7816_64x_led_write_value(u8 reg, u8 value) +{ + return accton_i2c_cpld_write(LED_CNTRLER_I2C_ADDRESS, reg, value); +} + +static void as7816_64x_led_update(void) +{ + mutex_lock(&ledctl->update_lock); + + if (time_after(jiffies, ledctl->last_updated + HZ + HZ / 2) + || !ledctl->valid) { + int i; + + dev_dbg(&ledctl->pdev->dev, "Starting as7816_64x_led update\n"); + + /* Update LED data + */ + for (i = 0; i < ARRAY_SIZE(ledctl->reg_val); i++) { + int status = as7816_64x_led_read_value(led_reg_map[i].reg_addr); + + if (status < 0) { + ledctl->valid = 0; + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", led_reg_map[i].reg_addr, status); + goto exit; + } + else + { + ledctl->reg_val[i] = status; + } + } + + ledctl->last_updated = jiffies; + ledctl->valid = 1; + } + +exit: + mutex_unlock(&ledctl->update_lock); +} + +static void as7816_64x_led_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode, + enum led_type type) +{ + int reg_val; + u8 reg ; + mutex_lock(&ledctl->update_lock); + + if( !get_led_reg(type, ®)) { + dev_dbg(&ledctl->pdev->dev, "Not match register for %d.\n", type); + } + + reg_val = as7816_64x_led_read_value(reg); + if (reg_val < 0) { + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", reg, reg_val); + goto exit; + } + + reg_val = led_light_mode_to_reg_val(type, led_light_mode, reg_val); + as7816_64x_led_write_value(reg, reg_val); + + /* to prevent the slow-update issue */ + ledctl->valid = 0; + +exit: + mutex_unlock(&ledctl->update_lock); +} + + +static void as7816_64x_led_diag_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + as7816_64x_led_set(led_cdev, led_light_mode, LED_TYPE_DIAG); +} + +static enum led_brightness as7816_64x_led_diag_get(struct led_classdev *cdev) +{ + as7816_64x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_DIAG, ledctl->reg_val[0]); +} + +static void as7816_64x_led_loc_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + as7816_64x_led_set(led_cdev, led_light_mode, LED_TYPE_LOC); +} + +static enum led_brightness as7816_64x_led_loc_get(struct led_classdev *cdev) +{ + as7816_64x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_LOC, ledctl->reg_val[0]); +} + +static void as7816_64x_led_fan_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + as7816_64x_led_set(led_cdev, led_light_mode, LED_TYPE_FAN); +} + +static enum led_brightness as7816_64x_led_fan_get(struct led_classdev *cdev) +{ + as7816_64x_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_FAN, ledctl->reg_val[0]); +} + +static void as7816_64x_led_auto_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ +} + +static enum led_brightness as7816_64x_led_auto_get(struct led_classdev *cdev) +{ + return LED_MODE_AUTO; +} + +static struct led_classdev as7816_64x_leds[] = { + [LED_TYPE_DIAG] = { + .name = "as7816_64x_led::diag", + .default_trigger = "unused", + .brightness_set = as7816_64x_led_diag_set, + .brightness_get = as7816_64x_led_diag_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_GREEN, + }, + [LED_TYPE_LOC] = { + .name = "as7816_64x_led::loc", + .default_trigger = "unused", + .brightness_set = as7816_64x_led_loc_set, + .brightness_get = as7816_64x_led_loc_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_ORANGE, + }, + [LED_TYPE_FAN] = { + .name = "as7816_64x_led::fan", + .default_trigger = "unused", + .brightness_set = as7816_64x_led_fan_set, + .brightness_get = as7816_64x_led_fan_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_GREEN, + }, + [LED_TYPE_PSU1] = { + .name = "as7816_64x_led::psu1", + .default_trigger = "unused", + .brightness_set = as7816_64x_led_auto_set, + .brightness_get = as7816_64x_led_auto_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_PSU2] = { + .name = "as7816_64x_led::psu2", + .default_trigger = "unused", + .brightness_set = as7816_64x_led_auto_set, + .brightness_get = as7816_64x_led_auto_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, +}; + +static int as7816_64x_led_suspend(struct platform_device *dev, + pm_message_t state) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(as7816_64x_leds); i++) { + led_classdev_suspend(&as7816_64x_leds[i]); + } + + return 0; +} + +static int as7816_64x_led_resume(struct platform_device *dev) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(as7816_64x_leds); i++) { + led_classdev_resume(&as7816_64x_leds[i]); + } + + return 0; +} + +static int as7816_64x_led_probe(struct platform_device *pdev) +{ + int ret, i; + + for (i = 0; i < ARRAY_SIZE(as7816_64x_leds); i++) { + ret = led_classdev_register(&pdev->dev, &as7816_64x_leds[i]); + + if (ret < 0) + break; + } + + /* Check if all LEDs were successfully registered */ + if (i != ARRAY_SIZE(as7816_64x_leds)){ + int j; + + /* only unregister the LEDs that were successfully registered */ + for (j = 0; j < i; j++) { + led_classdev_unregister(&as7816_64x_leds[i]); + } + } + + return ret; +} + +static int as7816_64x_led_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(as7816_64x_leds); i++) { + led_classdev_unregister(&as7816_64x_leds[i]); + } + + return 0; +} + +static struct platform_driver as7816_64x_led_driver = { + .probe = as7816_64x_led_probe, + .remove = as7816_64x_led_remove, + .suspend = as7816_64x_led_suspend, + .resume = as7816_64x_led_resume, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +static int __init as7816_64x_led_init(void) +{ + int ret; + + ret = platform_driver_register(&as7816_64x_led_driver); + if (ret < 0) { + goto exit; + } + + ledctl = kzalloc(sizeof(struct as7816_64x_led_data), GFP_KERNEL); + if (!ledctl) { + ret = -ENOMEM; + platform_driver_unregister(&as7816_64x_led_driver); + goto exit; + } + + mutex_init(&ledctl->update_lock); + + ledctl->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(ledctl->pdev)) { + ret = PTR_ERR(ledctl->pdev); + platform_driver_unregister(&as7816_64x_led_driver); + kfree(ledctl); + goto exit; + } + +exit: + return ret; +} + +static void __exit as7816_64x_led_exit(void) +{ + platform_device_unregister(ledctl->pdev); + platform_driver_unregister(&as7816_64x_led_driver); + kfree(ledctl); +} + +module_init(as7816_64x_led_init); +module_exit(as7816_64x_led_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("as7816_64x_led driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/x86-64-accton-as7816-64x-psu.c b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/x86-64-accton-as7816-64x-psu.c new file mode 100644 index 000000000000..cdc535347dc0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/x86-64-accton-as7816-64x-psu.c @@ -0,0 +1,239 @@ +/* + * An hwmon driver for accton as7816_64x Power Module + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PSU_STATUS_I2C_ADDR 0x60 +#define PSU_STATUS_I2C_REG_OFFSET 0x03 + +#define IS_POWER_GOOD(id, value) (!!(value & BIT(2+id))) +#define IS_PRESENT(id, value) (!(value & BIT(id))) + +static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); +static struct as7816_64x_psu_data *as7816_64x_psu_update_device(struct device *dev); +extern int accton_i2c_cpld_read (u8 cpld_addr, u8 reg); + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +/* Each client has this additional data + */ +struct as7816_64x_psu_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 index; /* PSU index */ + u8 status; /* Status(present/power_good) register read from CPLD */ +}; + +enum as7816_64x_psu_sysfs_attributes { + PSU_PRESENT, + PSU_POWER_GOOD +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, show_status, NULL, PSU_PRESENT); +static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_status, NULL, PSU_POWER_GOOD); + +static struct attribute *as7816_64x_psu_attributes[] = { + &sensor_dev_attr_psu_present.dev_attr.attr, + &sensor_dev_attr_psu_power_good.dev_attr.attr, + NULL +}; + +static ssize_t show_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct as7816_64x_psu_data *data = as7816_64x_psu_update_device(dev); + u8 status = 0; + + if (!data->valid) { + return -EIO; + } + + if (attr->index == PSU_PRESENT) { + status = IS_PRESENT(data->index, data->status); + } + else { /* PSU_POWER_GOOD */ + status = IS_POWER_GOOD(data->index, data->status); + } + + return sprintf(buf, "%d\n", status); +} + +static const struct attribute_group as7816_64x_psu_group = { + .attrs = as7816_64x_psu_attributes, +}; + +static int as7816_64x_psu_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct as7816_64x_psu_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct as7816_64x_psu_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + data->index = dev_id->driver_data; + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as7816_64x_psu_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as7816_64x_psu_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as7816_64x_psu_remove(struct i2c_client *client) +{ + struct as7816_64x_psu_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as7816_64x_psu_group); + kfree(data); + + return 0; +} + +enum psu_index +{ + as7816_64x_psu1, + as7816_64x_psu2 +}; + +static const struct i2c_device_id as7816_64x_psu_id[] = { + { "as7816_64x_psu1", as7816_64x_psu1 }, + { "as7816_64x_psu2", as7816_64x_psu2 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, as7816_64x_psu_id); + +static struct i2c_driver as7816_64x_psu_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "as7816_64x_psu", + }, + .probe = as7816_64x_psu_probe, + .remove = as7816_64x_psu_remove, + .id_table = as7816_64x_psu_id, + .address_list = normal_i2c, +}; + +static struct as7816_64x_psu_data *as7816_64x_psu_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as7816_64x_psu_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int status; + + data->valid = 0; + dev_dbg(&client->dev, "Starting as7816_64x update\n"); + + /* Read psu status */ + status = accton_i2c_cpld_read(PSU_STATUS_I2C_ADDR, PSU_STATUS_I2C_REG_OFFSET); + + if (status < 0) { + dev_dbg(&client->dev, "cpld reg (0x%x) err %d\n", PSU_STATUS_I2C_ADDR, status); + goto exit; + } + else { + data->status = status; + } + + data->last_updated = jiffies; + data->valid = 1; + } + +exit: + mutex_unlock(&data->update_lock); + + return data; +} + +static int __init as7816_64x_psu_init(void) +{ + return i2c_add_driver(&as7816_64x_psu_driver); +} + +static void __exit as7816_64x_psu_exit(void) +{ + i2c_del_driver(&as7816_64x_psu_driver); +} + +module_init(as7816_64x_psu_init); +module_exit(as7816_64x_psu_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("as7816_64x_psu driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/x86-64-accton-as7816-64x-sfp.c b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/x86-64-accton-as7816-64x-sfp.c new file mode 100644 index 000000000000..76444ebbafcb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/x86-64-accton-as7816-64x-sfp.c @@ -0,0 +1,1576 @@ +/* + * SFP driver for accton as7816_64x sfp + * + * Copyright (C) Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "as7816_64x_sfp" /* Platform dependent */ + +#define DEBUG_MODE 0 + +#if (DEBUG_MODE == 1) + #define DEBUG_PRINT(fmt, args...) \ + printk (KERN_INFO "%s:%s[%d]: " fmt "\r\n", __FILE__, __FUNCTION__, __LINE__, ##args) +#else + #define DEBUG_PRINT(fmt, args...) +#endif + +#define NUM_OF_SFP_PORT 24 +#define EEPROM_NAME "sfp_eeprom" +#define EEPROM_SIZE 256 /* 256 byte eeprom */ +#define BIT_INDEX(i) (1ULL << (i)) +#define USE_I2C_BLOCK_READ 1 /* Platform dependent */ +#define I2C_RW_RETRY_COUNT 10 +#define I2C_RW_RETRY_INTERVAL 60 /* ms */ + +#define SFP_EEPROM_A0_I2C_ADDR (0xA0 >> 1) + +#define SFF8024_PHYSICAL_DEVICE_ID_ADDR 0x0 +#define SFF8024_DEVICE_ID_SFP 0x3 +#define SFF8024_DEVICE_ID_QSFP 0xC +#define SFF8024_DEVICE_ID_QSFP_PLUS 0xD +#define SFF8024_DEVICE_ID_QSFP28 0x11 + +#define SFF8436_RX_LOS_ADDR 3 +#define SFF8436_TX_FAULT_ADDR 4 +#define SFF8436_TX_DISABLE_ADDR 86 + +#define MULTIPAGE_SUPPORT 1 + +#if (MULTIPAGE_SUPPORT == 1) +/* fundamental unit of addressing for SFF_8472/SFF_8436 */ +#define SFF_8436_PAGE_SIZE 128 +/* + * The current 8436 (QSFP) spec provides for only 4 supported + * pages (pages 0-3). + * This driver is prepared to support more, but needs a register in the + * EEPROM to indicate how many pages are supported before it is safe + * to implement more pages in the driver. + */ +#define SFF_8436_SPECED_PAGES 4 +#define SFF_8436_EEPROM_SIZE ((1 + SFF_8436_SPECED_PAGES) * SFF_8436_PAGE_SIZE) +#define SFF_8436_EEPROM_UNPAGED_SIZE (2 * SFF_8436_PAGE_SIZE) +/* + * The current 8472 (SFP) spec provides for only 3 supported + * pages (pages 0-2). + * This driver is prepared to support more, but needs a register in the + * EEPROM to indicate how many pages are supported before it is safe + * to implement more pages in the driver. + */ +#define SFF_8472_SPECED_PAGES 3 +#define SFF_8472_EEPROM_SIZE ((3 + SFF_8472_SPECED_PAGES) * SFF_8436_PAGE_SIZE) +#define SFF_8472_EEPROM_UNPAGED_SIZE (4 * SFF_8436_PAGE_SIZE) + +/* a few constants to find our way around the EEPROM */ +#define SFF_8436_PAGE_SELECT_REG 0x7F +#define SFF_8436_PAGEABLE_REG 0x02 +#define SFF_8436_NOT_PAGEABLE (1<<2) +#define SFF_8472_PAGEABLE_REG 0x40 +#define SFF_8472_PAGEABLE (1<<4) + +/* + * This parameter is to help this driver avoid blocking other drivers out + * of I2C for potentially troublesome amounts of time. With a 100 kHz I2C + * clock, one 256 byte read takes about 1/43 second which is excessive; + * but the 1/170 second it takes at 400 kHz may be quite reasonable; and + * at 1 MHz (Fm+) a 1/430 second delay could easily be invisible. + * + * This value is forced to be a power of two so that writes align on pages. + */ +static unsigned io_limit = SFF_8436_PAGE_SIZE; + +/* + * specs often allow 5 msec for a page write, sometimes 20 msec; + * it's important to recover from write timeouts. + */ +static unsigned write_timeout = 25; + +typedef enum qsfp_opcode { + QSFP_READ_OP = 0, + QSFP_WRITE_OP = 1 +} qsfp_opcode_e; +#endif + +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_present(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute *da, const char *buf, size_t count);; +static ssize_t sfp_eeprom_read(struct i2c_client *, u8, u8 *,int); +static ssize_t sfp_eeprom_write(struct i2c_client *, u8 , const char *,int); +extern int accton_i2c_cpld_read (u8 cpld_addr, u8 reg); + +enum sfp_sysfs_attributes { + PRESENT, + PRESENT_ALL, + PORT_NUMBER, + PORT_TYPE, + DDM_IMPLEMENTED, + TX_FAULT, + TX_FAULT1, + TX_FAULT2, + TX_FAULT3, + TX_FAULT4, + TX_DISABLE, + TX_DISABLE1, + TX_DISABLE2, + TX_DISABLE3, + TX_DISABLE4, + RX_LOS, + RX_LOS1, + RX_LOS2, + RX_LOS3, + RX_LOS4, + RX_LOS_ALL +}; + +/* SFP/QSFP common attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_port_number, S_IRUGO, show_port_number, NULL, PORT_NUMBER); +static SENSOR_DEVICE_ATTR(sfp_is_present, S_IRUGO, show_present, NULL, PRESENT); +static SENSOR_DEVICE_ATTR(sfp_is_present_all, S_IRUGO, show_present, NULL, PRESENT_ALL); +static SENSOR_DEVICE_ATTR(sfp_tx_disable, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE); +static SENSOR_DEVICE_ATTR(sfp_tx_fault, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT); + +/* QSFP attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_rx_los, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS); +static SENSOR_DEVICE_ATTR(sfp_rx_los1, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS1); +static SENSOR_DEVICE_ATTR(sfp_rx_los2, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS2); +static SENSOR_DEVICE_ATTR(sfp_rx_los3, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS3); +static SENSOR_DEVICE_ATTR(sfp_rx_los4, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS4); +static SENSOR_DEVICE_ATTR(sfp_tx_disable1, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE1); +static SENSOR_DEVICE_ATTR(sfp_tx_disable2, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE2); +static SENSOR_DEVICE_ATTR(sfp_tx_disable3, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE3); +static SENSOR_DEVICE_ATTR(sfp_tx_disable4, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE4); +static SENSOR_DEVICE_ATTR(sfp_tx_fault1, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT1); +static SENSOR_DEVICE_ATTR(sfp_tx_fault2, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT2); +static SENSOR_DEVICE_ATTR(sfp_tx_fault3, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT3); +static SENSOR_DEVICE_ATTR(sfp_tx_fault4, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT4); +static struct attribute *qsfp_attributes[] = { + &sensor_dev_attr_sfp_port_number.dev_attr.attr, + &sensor_dev_attr_sfp_is_present.dev_attr.attr, + &sensor_dev_attr_sfp_is_present_all.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los1.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los2.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los3.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los4.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable1.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable2.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable3.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable4.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault1.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault2.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault3.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault4.dev_attr.attr, + NULL +}; + +/* Platform dependent +++ */ +#define CPLD_PORT_TO_FRONT_PORT(port) (port+1) + +enum port_numbers { +as7816_64x_port1, as7816_64x_port2, as7816_64x_port3, as7816_64x_port4, +as7816_64x_port5, as7816_64x_port6, as7816_64x_port7, as7816_64x_port8, +as7816_64x_port9, as7816_64x_port10, as7816_64x_port11, as7816_64x_port12, +as7816_64x_port13, as7816_64x_port14, as7816_64x_port15, as7816_64x_port16, +as7816_64x_port17, as7816_64x_port18, as7816_64x_port19, as7816_64x_port20, +as7816_64x_port21, as7816_64x_port22, as7816_64x_port23, as7816_64x_port24, +as7816_64x_port25, as7816_64x_port26, as7816_64x_port27, as7816_64x_port28, +as7816_64x_port29, as7816_64x_port30, as7816_64x_port31, as7816_64x_port32, +as7816_64x_port33, as7816_64x_port34, as7816_64x_port35, as7816_64x_port36, +as7816_64x_port37, as7816_64x_port38, as7816_64x_port39, as7816_64x_port40, +as7816_64x_port41, as7816_64x_port42, as7816_64x_port43, as7816_64x_port44, +as7816_64x_port45, as7816_64x_port46, as7816_64x_port47, as7816_64x_port48, +as7816_64x_port49, as7816_64x_port50, as7816_64x_port51, as7816_64x_port52, +as7816_64x_port53, as7816_64x_port54, as7816_64x_port55, as7816_64x_port56, +as7816_64x_port57, as7816_64x_port58, as7816_64x_port59, as7816_64x_port60, +as7816_64x_port61, as7816_64x_port62, as7816_64x_port63, as7816_64x_port64 +}; + +#define I2C_DEV_ID(x) { #x, x} + +static const struct i2c_device_id sfp_device_id[] = { +I2C_DEV_ID(as7816_64x_port1), +I2C_DEV_ID(as7816_64x_port2), +I2C_DEV_ID(as7816_64x_port3), +I2C_DEV_ID(as7816_64x_port4), +I2C_DEV_ID(as7816_64x_port5), +I2C_DEV_ID(as7816_64x_port6), +I2C_DEV_ID(as7816_64x_port7), +I2C_DEV_ID(as7816_64x_port8), +I2C_DEV_ID(as7816_64x_port9), +I2C_DEV_ID(as7816_64x_port10), +I2C_DEV_ID(as7816_64x_port11), +I2C_DEV_ID(as7816_64x_port12), +I2C_DEV_ID(as7816_64x_port13), +I2C_DEV_ID(as7816_64x_port14), +I2C_DEV_ID(as7816_64x_port15), +I2C_DEV_ID(as7816_64x_port16), +I2C_DEV_ID(as7816_64x_port17), +I2C_DEV_ID(as7816_64x_port18), +I2C_DEV_ID(as7816_64x_port19), +I2C_DEV_ID(as7816_64x_port20), +I2C_DEV_ID(as7816_64x_port21), +I2C_DEV_ID(as7816_64x_port22), +I2C_DEV_ID(as7816_64x_port23), +I2C_DEV_ID(as7816_64x_port24), +I2C_DEV_ID(as7816_64x_port25), +I2C_DEV_ID(as7816_64x_port26), +I2C_DEV_ID(as7816_64x_port27), +I2C_DEV_ID(as7816_64x_port28), +I2C_DEV_ID(as7816_64x_port29), +I2C_DEV_ID(as7816_64x_port30), +I2C_DEV_ID(as7816_64x_port31), +I2C_DEV_ID(as7816_64x_port32), +I2C_DEV_ID(as7816_64x_port33), +I2C_DEV_ID(as7816_64x_port34), +I2C_DEV_ID(as7816_64x_port35), +I2C_DEV_ID(as7816_64x_port36), +I2C_DEV_ID(as7816_64x_port37), +I2C_DEV_ID(as7816_64x_port38), +I2C_DEV_ID(as7816_64x_port39), +I2C_DEV_ID(as7816_64x_port40), +I2C_DEV_ID(as7816_64x_port41), +I2C_DEV_ID(as7816_64x_port42), +I2C_DEV_ID(as7816_64x_port43), +I2C_DEV_ID(as7816_64x_port44), +I2C_DEV_ID(as7816_64x_port45), +I2C_DEV_ID(as7816_64x_port46), +I2C_DEV_ID(as7816_64x_port47), +I2C_DEV_ID(as7816_64x_port48), +I2C_DEV_ID(as7816_64x_port49), +I2C_DEV_ID(as7816_64x_port50), +I2C_DEV_ID(as7816_64x_port51), +I2C_DEV_ID(as7816_64x_port52), +I2C_DEV_ID(as7816_64x_port53), +I2C_DEV_ID(as7816_64x_port54), +I2C_DEV_ID(as7816_64x_port55), +I2C_DEV_ID(as7816_64x_port56), +I2C_DEV_ID(as7816_64x_port57), +I2C_DEV_ID(as7816_64x_port58), +I2C_DEV_ID(as7816_64x_port59), +I2C_DEV_ID(as7816_64x_port60), +I2C_DEV_ID(as7816_64x_port61), +I2C_DEV_ID(as7816_64x_port62), +I2C_DEV_ID(as7816_64x_port63), +I2C_DEV_ID(as7816_64x_port64), +{ /* LIST END */ } +}; +MODULE_DEVICE_TABLE(i2c, sfp_device_id); +/* Platform dependent --- */ + +enum driver_type_e { + DRIVER_TYPE_SFP_MSA, + DRIVER_TYPE_SFP_DDM, + DRIVER_TYPE_QSFP, + DRIVER_TYPE_XFP +}; + +/* Each client has this additional data + */ +struct eeprom_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + struct bin_attribute bin; /* eeprom data */ +}; + +struct qsfp_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 status[3]; /* bit0:port0, bit1:port1 and so on */ + /* index 0 => tx_fail + 1 => tx_disable + 2 => rx_loss */ + u8 device_id; + struct eeprom_data eeprom; +}; + +struct sfp_port_data { + struct mutex update_lock; + enum driver_type_e driver_type; + int port; /* CPLD port index */ + u64 present; /* present status, bit0:port0, bit1:port1 and so on */ + + struct qsfp_data *qsfp; + + struct i2c_client *client; +#if (MULTIPAGE_SUPPORT == 1) + int use_smbus; + u8 *writebuf; + unsigned write_max; +#endif +}; + +#if (MULTIPAGE_SUPPORT == 1) +static ssize_t sfp_port_read_write(struct sfp_port_data *port_data, + char *buf, loff_t off, size_t len, qsfp_opcode_e opcode); +#endif +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + return sprintf(buf, "%d\n", CPLD_PORT_TO_FRONT_PORT(data->port)); +} + +/* Platform dependent +++ */ +static struct sfp_port_data *sfp_update_present(struct i2c_client *client) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + int i = 0; + int status = -1; + u8 regs[] = {0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77}; + + DEBUG_PRINT("Starting sfp present status update"); + mutex_lock(&data->update_lock); + + /* Read present status of port 1~64 */ + data->present = 0; + + for (i = 0; i < ARRAY_SIZE(regs); i++) { + status = accton_i2c_cpld_read(0x60, regs[i]); + + if (status < 0) { + DEBUG_PRINT("cpld(0x60) reg(0x%x) err %d", regs[i], status); + goto exit; + } + + DEBUG_PRINT("Present status = 0x%lx", data->present); + data->present |= (u64)status << (i*8); + } + + DEBUG_PRINT("Present status = 0x%lx", data->present); +exit: + mutex_unlock(&data->update_lock); + return (status < 0) ? ERR_PTR(status) : data; +} + +/* Platform dependent --- */ + +static int sfp_is_port_present(struct i2c_client *client, int port) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + + data = sfp_update_present(client); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + return (data->present & BIT_INDEX(data->port)) ? 0 : 1; /* Platform dependent */ +} + +/* Platform dependent +++ */ +static ssize_t show_present(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + + if (PRESENT_ALL == attr->index) { + int i; + u8 values[8] = {0}; + struct sfp_port_data *data = sfp_update_present(client); + + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + for (i = 0; i < ARRAY_SIZE(values); i++) { + values[i] = ~(u8)(data->present >> (i * 8)); + } + + /* Return values 1 -> 64 in order */ + return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], values[3], + values[4], values[5], values[6], values[7]); + } + else { + struct sfp_port_data *data = i2c_get_clientdata(client); + int present = sfp_is_port_present(client, data->port); + + if (IS_ERR_VALUE(present)) { + return present; + } + + /* PRESENT */ + return sprintf(buf, "%d\n", present); + } +} +/* Platform dependent --- */ + +static struct sfp_port_data *qsfp_update_tx_rx_status(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int i, status = -1; + u8 buf = 0; + u8 reg[] = {SFF8436_TX_FAULT_ADDR, SFF8436_TX_DISABLE_ADDR, SFF8436_RX_LOS_ADDR}; + + if (time_before(jiffies, data->qsfp->last_updated + HZ + HZ / 2) && data->qsfp->valid) { + return data; + } + + DEBUG_PRINT("Starting sfp tx rx status update"); + mutex_lock(&data->update_lock); + data->qsfp->valid = 0; + memset(data->qsfp->status, 0, sizeof(data->qsfp->status)); + + /* Notify device to update tx fault/ tx disable/ rx los status */ + for (i = 0; i < ARRAY_SIZE(reg); i++) { + status = sfp_eeprom_read(client, reg[i], &buf, sizeof(buf)); + if (unlikely(status < 0)) { + goto exit; + } + } + msleep(200); + + /* Read actual tx fault/ tx disable/ rx los status */ + for (i = 0; i < ARRAY_SIZE(reg); i++) { + status = sfp_eeprom_read(client, reg[i], &buf, sizeof(buf)); + if (unlikely(status < 0)) { + goto exit; + } + + DEBUG_PRINT("qsfp reg(0x%x) status = (0x%x)", reg[i], data->qsfp->status[i]); + data->qsfp->status[i] = (buf & 0xF); + } + + data->qsfp->valid = 1; + data->qsfp->last_updated = jiffies; + +exit: + mutex_unlock(&data->update_lock); + return (status < 0) ? ERR_PTR(status) : data; +} + +static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + int present; + u8 val = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENXIO; + } + + data = qsfp_update_tx_rx_status(dev); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + switch (attr->index) { + case TX_FAULT: + val = !!(data->qsfp->status[2] & 0xF); + break; + case TX_FAULT1: + case TX_FAULT2: + case TX_FAULT3: + case TX_FAULT4: + val = !!(data->qsfp->status[2] & BIT_INDEX(attr->index - TX_FAULT1)); + break; + case TX_DISABLE: + val = data->qsfp->status[1] & 0xF; + break; + case TX_DISABLE1: + case TX_DISABLE2: + case TX_DISABLE3: + case TX_DISABLE4: + val = !!(data->qsfp->status[1] & BIT_INDEX(attr->index - TX_DISABLE1)); + break; + case RX_LOS: + val = !!(data->qsfp->status[0] & 0xF); + break; + case RX_LOS1: + case RX_LOS2: + case RX_LOS3: + case RX_LOS4: + val = !!(data->qsfp->status[0] & BIT_INDEX(attr->index - RX_LOS1)); + break; + default: + break; + } + + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + long disable; + int status; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + status = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(status)) { + return status; + } + + if (!status) { + /* port is not present */ + return -ENXIO; + } + + status = kstrtol(buf, 10, &disable); + if (status) { + return status; + } + + data = qsfp_update_tx_rx_status(dev); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + mutex_lock(&data->update_lock); + + if (attr->index == TX_DISABLE) { + if (disable) { + data->qsfp->status[1] |= 0xF; + } + else { + data->qsfp->status[1] &= ~0xF; + } + } + else {/* TX_DISABLE1 ~ TX_DISABLE4*/ + if (disable) { + data->qsfp->status[1] |= (1 << (attr->index - TX_DISABLE1)); + } + else { + data->qsfp->status[1] &= ~(1 << (attr->index - TX_DISABLE1)); + } + } + + DEBUG_PRINT("index = (%d), status = (0x%x)", attr->index, data->qsfp->status[1]); + status = sfp_eeprom_write(data->client, SFF8436_TX_DISABLE_ADDR, &data->qsfp->status[1], sizeof(data->qsfp->status[1])); + if (unlikely(status < 0)) { + count = status; + } + + mutex_unlock(&data->update_lock); + return count; +} + +static ssize_t sfp_eeprom_write(struct i2c_client *client, u8 command, const char *data, + int data_len) +{ +#if USE_I2C_BLOCK_READ + int status, retry = I2C_RW_RETRY_COUNT; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_write_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + return status; + } + + return data_len; +#else + int status, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_write_byte_data(client, command, *data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + return status; + } + + return 1; +#endif + + +} + +#if (MULTIPAGE_SUPPORT == 0) +static ssize_t sfp_port_write(struct sfp_port_data *data, + const char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + return count; + } + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&data->update_lock); + + while (count) { + ssize_t status; + + status = sfp_eeprom_write(data->client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&data->update_lock); + return retval; +} +#endif + +static ssize_t sfp_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct sfp_port_data *data; + DEBUG_PRINT("%s(%d) offset = (%d), count = (%d)", off, count); + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + + present = sfp_is_port_present(data->client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + +#if (MULTIPAGE_SUPPORT == 1) + return sfp_port_read_write(data, buf, off, count, QSFP_WRITE_OP); +#else + return sfp_port_write(data, buf, off, count); +#endif +} + +static ssize_t sfp_eeprom_read(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ +#if USE_I2C_BLOCK_READ + int status, retry = I2C_RW_RETRY_COUNT; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + goto abort; + } + if (unlikely(status != data_len)) { + status = -EIO; + goto abort; + } + + //result = data_len; + +abort: + return status; +#else + int status, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_read_byte_data(client, command); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "sfp read byte data failed, command(0x%2x), data(0x%2x)\r\n", command, status); + goto abort; + } + + *data = (u8)status; + status = 1; + +abort: + return status; +#endif +} + +#if (MULTIPAGE_SUPPORT == 1) +/*-------------------------------------------------------------------------*/ +/* + * This routine computes the addressing information to be used for + * a given r/w request. + * + * Task is to calculate the client (0 = i2c addr 50, 1 = i2c addr 51), + * the page, and the offset. + * + * Handles both SFP and QSFP. + * For SFP, offset 0-255 are on client[0], >255 is on client[1] + * Offset 256-383 are on the lower half of client[1] + * Pages are accessible on the upper half of client[1]. + * Offset >383 are in 128 byte pages mapped into the upper half + * + * For QSFP, all offsets are on client[0] + * offset 0-127 are on the lower half of client[0] (no paging) + * Pages are accessible on the upper half of client[1]. + * Offset >127 are in 128 byte pages mapped into the upper half + * + * Callers must not read/write beyond the end of a client or a page + * without recomputing the client/page. Hence offset (within page) + * plus length must be less than or equal to 128. (Note that this + * routine does not have access to the length of the call, hence + * cannot do the validity check.) + * + * Offset within Lower Page 00h and Upper Page 00h are not recomputed + */ +static uint8_t sff_8436_translate_offset(struct sfp_port_data *port_data, + loff_t *offset, struct i2c_client **client) +{ + unsigned page = 0; + + *client = port_data->client; + + /* + * if offset is in the range 0-128... + * page doesn't matter (using lower half), return 0. + * offset is already correct (don't add 128 to get to paged area) + */ + if (*offset < SFF_8436_PAGE_SIZE) + return page; + + /* note, page will always be positive since *offset >= 128 */ + page = (*offset >> 7)-1; + /* 0x80 places the offset in the top half, offset is last 7 bits */ + *offset = SFF_8436_PAGE_SIZE + (*offset & 0x7f); + + return page; /* note also returning client and offset */ +} + +static ssize_t sff_8436_eeprom_read(struct sfp_port_data *port_data, + struct i2c_client *client, + char *buf, unsigned offset, size_t count) +{ + struct i2c_msg msg[2]; + u8 msgbuf[2]; + unsigned long timeout, read_time; + int status, i; + + memset(msg, 0, sizeof(msg)); + + switch (port_data->use_smbus) { + case I2C_SMBUS_I2C_BLOCK_DATA: + /*smaller eeproms can work given some SMBus extension calls */ + if (count > I2C_SMBUS_BLOCK_MAX) + count = I2C_SMBUS_BLOCK_MAX; + break; + case I2C_SMBUS_WORD_DATA: + /* Check for odd length transaction */ + count = (count == 1) ? 1 : 2; + break; + case I2C_SMBUS_BYTE_DATA: + count = 1; + break; + default: + /* + * When we have a better choice than SMBus calls, use a + * combined I2C message. Write address; then read up to + * io_limit data bytes. msgbuf is u8 and will cast to our + * needs. + */ + i = 0; + msgbuf[i++] = offset; + + msg[0].addr = client->addr; + msg[0].buf = msgbuf; + msg[0].len = i; + + msg[1].addr = client->addr; + msg[1].flags = I2C_M_RD; + msg[1].buf = buf; + msg[1].len = count; + } + + /* + * Reads fail if the previous write didn't complete yet. We may + * loop a few times until this one succeeds, waiting at least + * long enough for one entire page write to work. + */ + timeout = jiffies + msecs_to_jiffies(write_timeout); + do { + read_time = jiffies; + + switch (port_data->use_smbus) { + case I2C_SMBUS_I2C_BLOCK_DATA: + status = i2c_smbus_read_i2c_block_data(client, offset, + count, buf); + break; + case I2C_SMBUS_WORD_DATA: + status = i2c_smbus_read_word_data(client, offset); + if (status >= 0) { + buf[0] = status & 0xff; + if (count == 2) + buf[1] = status >> 8; + status = count; + } + break; + case I2C_SMBUS_BYTE_DATA: + status = i2c_smbus_read_byte_data(client, offset); + if (status >= 0) { + buf[0] = status; + status = count; + } + break; + default: + status = i2c_transfer(client->adapter, msg, 2); + if (status == 2) + status = count; + } + + dev_dbg(&client->dev, "eeprom read %zu@%d --> %d (%ld)\n", + count, offset, status, jiffies); + + if (status == count) /* happy path */ + return count; + + if (status == -ENXIO) /* no module present */ + return status; + + /* REVISIT: at HZ=100, this is sloooow */ + msleep(1); + } while (time_before(read_time, timeout)); + + return -ETIMEDOUT; +} + +static ssize_t sff_8436_eeprom_write(struct sfp_port_data *port_data, + struct i2c_client *client, + const char *buf, + unsigned offset, size_t count) +{ + struct i2c_msg msg; + ssize_t status; + unsigned long timeout, write_time; + unsigned next_page_start; + int i = 0; + + /* write max is at most a page + * (In this driver, write_max is actually one byte!) + */ + if (count > port_data->write_max) + count = port_data->write_max; + + /* shorten count if necessary to avoid crossing page boundary */ + next_page_start = roundup(offset + 1, SFF_8436_PAGE_SIZE); + if (offset + count > next_page_start) + count = next_page_start - offset; + + switch (port_data->use_smbus) { + case I2C_SMBUS_I2C_BLOCK_DATA: + /*smaller eeproms can work given some SMBus extension calls */ + if (count > I2C_SMBUS_BLOCK_MAX) + count = I2C_SMBUS_BLOCK_MAX; + break; + case I2C_SMBUS_WORD_DATA: + /* Check for odd length transaction */ + count = (count == 1) ? 1 : 2; + break; + case I2C_SMBUS_BYTE_DATA: + count = 1; + break; + default: + /* If we'll use I2C calls for I/O, set up the message */ + msg.addr = client->addr; + msg.flags = 0; + + /* msg.buf is u8 and casts will mask the values */ + msg.buf = port_data->writebuf; + + msg.buf[i++] = offset; + memcpy(&msg.buf[i], buf, count); + msg.len = i + count; + break; + } + + /* + * Reads fail if the previous write didn't complete yet. We may + * loop a few times until this one succeeds, waiting at least + * long enough for one entire page write to work. + */ + timeout = jiffies + msecs_to_jiffies(write_timeout); + do { + write_time = jiffies; + + switch (port_data->use_smbus) { + case I2C_SMBUS_I2C_BLOCK_DATA: + status = i2c_smbus_write_i2c_block_data(client, + offset, count, buf); + if (status == 0) + status = count; + break; + case I2C_SMBUS_WORD_DATA: + if (count == 2) { + status = i2c_smbus_write_word_data(client, + offset, (u16)((buf[0])|(buf[1] << 8))); + } else { + /* count = 1 */ + status = i2c_smbus_write_byte_data(client, + offset, buf[0]); + } + if (status == 0) + status = count; + break; + case I2C_SMBUS_BYTE_DATA: + status = i2c_smbus_write_byte_data(client, offset, + buf[0]); + if (status == 0) + status = count; + break; + default: + status = i2c_transfer(client->adapter, &msg, 1); + if (status == 1) + status = count; + break; + } + + dev_dbg(&client->dev, "eeprom write %zu@%d --> %ld (%lu)\n", + count, offset, (long int) status, jiffies); + + if (status == count) + return count; + + /* REVISIT: at HZ=100, this is sloooow */ + msleep(1); + } while (time_before(write_time, timeout)); + + return -ETIMEDOUT; +} + + +static ssize_t sff_8436_eeprom_update_client(struct sfp_port_data *port_data, + char *buf, loff_t off, + size_t count, qsfp_opcode_e opcode) +{ + struct i2c_client *client; + ssize_t retval = 0; + u8 page = 0; + loff_t phy_offset = off; + int ret = 0; + + page = sff_8436_translate_offset(port_data, &phy_offset, &client); + + dev_dbg(&client->dev, + "sff_8436_eeprom_update_client off %lld page:%d phy_offset:%lld, count:%ld, opcode:%d\n", + off, page, phy_offset, (long int) count, opcode); + if (page > 0) { + ret = sff_8436_eeprom_write(port_data, client, &page, + SFF_8436_PAGE_SELECT_REG, 1); + if (ret < 0) { + dev_dbg(&client->dev, + "Write page register for page %d failed ret:%d!\n", + page, ret); + return ret; + } + } + + while (count) { + ssize_t status; + + if (opcode == QSFP_READ_OP) { + status = sff_8436_eeprom_read(port_data, client, + buf, phy_offset, count); + } else { + status = sff_8436_eeprom_write(port_data, client, + buf, phy_offset, count); + } + if (status <= 0) { + if (retval == 0) + retval = status; + break; + } + buf += status; + phy_offset += status; + count -= status; + retval += status; + } + + + if (page > 0) { + /* return the page register to page 0 (why?) */ + page = 0; + ret = sff_8436_eeprom_write(port_data, client, &page, + SFF_8436_PAGE_SELECT_REG, 1); + if (ret < 0) { + dev_err(&client->dev, + "Restore page register to page %d failed ret:%d!\n", + page, ret); + return ret; + } + } + return retval; +} + + +/* + * Figure out if this access is within the range of supported pages. + * Note this is called on every access because we don't know if the + * module has been replaced since the last call. + * If/when modules support more pages, this is the routine to update + * to validate and allow access to additional pages. + * + * Returns updated len for this access: + * - entire access is legal, original len is returned. + * - access begins legal but is too long, len is truncated to fit. + * - initial offset exceeds supported pages, return -EINVAL + */ +static ssize_t sff_8436_page_legal(struct sfp_port_data *port_data, + loff_t off, size_t len) +{ + struct i2c_client *client = port_data->client; + u8 regval; + int status; + size_t maxlen; + + if (off < 0) return -EINVAL; + if (port_data->driver_type == DRIVER_TYPE_SFP_MSA) { + /* SFP case */ + /* if no pages needed, we're good */ + if ((off + len) <= SFF_8472_EEPROM_UNPAGED_SIZE) return len; + /* if offset exceeds possible pages, we're not good */ + if (off >= SFF_8472_EEPROM_SIZE) return -EINVAL; + /* in between, are pages supported? */ + status = sff_8436_eeprom_read(port_data, client, ®val, + SFF_8472_PAGEABLE_REG, 1); + if (status < 0) return status; /* error out (no module?) */ + if (regval & SFF_8472_PAGEABLE) { + /* Pages supported, trim len to the end of pages */ + maxlen = SFF_8472_EEPROM_SIZE - off; + } else { + /* pages not supported, trim len to unpaged size */ + maxlen = SFF_8472_EEPROM_UNPAGED_SIZE - off; + } + len = (len > maxlen) ? maxlen : len; + dev_dbg(&client->dev, + "page_legal, SFP, off %lld len %ld\n", + off, (long int) len); + } + else if (port_data->driver_type == DRIVER_TYPE_QSFP || + port_data->driver_type == DRIVER_TYPE_XFP) { + /* QSFP case */ + /* if no pages needed, we're good */ + if ((off + len) <= SFF_8436_EEPROM_UNPAGED_SIZE) return len; + /* if offset exceeds possible pages, we're not good */ + if (off >= SFF_8436_EEPROM_SIZE) return -EINVAL; + /* in between, are pages supported? */ + status = sff_8436_eeprom_read(port_data, client, ®val, + SFF_8436_PAGEABLE_REG, 1); + if (status < 0) return status; /* error out (no module?) */ + if (regval & SFF_8436_NOT_PAGEABLE) { + /* pages not supported, trim len to unpaged size */ + maxlen = SFF_8436_EEPROM_UNPAGED_SIZE - off; + } else { + /* Pages supported, trim len to the end of pages */ + maxlen = SFF_8436_EEPROM_SIZE - off; + } + len = (len > maxlen) ? maxlen : len; + dev_dbg(&client->dev, + "page_legal, QSFP, off %lld len %ld\n", + off, (long int) len); + } + else { + return -EINVAL; + } + return len; +} + + +static ssize_t sfp_port_read_write(struct sfp_port_data *port_data, + char *buf, loff_t off, size_t len, qsfp_opcode_e opcode) +{ + struct i2c_client *client = port_data->client; + int chunk; + int status = 0; + ssize_t retval; + size_t pending_len = 0, chunk_len = 0; + loff_t chunk_offset = 0, chunk_start_offset = 0; + + if (unlikely(!len)) + return len; + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&port_data->update_lock); + + /* + * Confirm this access fits within the device suppored addr range + */ + len = sff_8436_page_legal(port_data, off, len); + if (len < 0) { + status = len; + goto err; + } + + /* + * For each (128 byte) chunk involved in this request, issue a + * separate call to sff_eeprom_update_client(), to + * ensure that each access recalculates the client/page + * and writes the page register as needed. + * Note that chunk to page mapping is confusing, is different for + * QSFP and SFP, and never needs to be done. Don't try! + */ + pending_len = len; /* amount remaining to transfer */ + retval = 0; /* amount transferred */ + for (chunk = off >> 7; chunk <= (off + len - 1) >> 7; chunk++) { + + /* + * Compute the offset and number of bytes to be read/write + * + * 1. start at offset 0 (within the chunk), and read/write + * the entire chunk + * 2. start at offset 0 (within the chunk) and read/write less + * than entire chunk + * 3. start at an offset not equal to 0 and read/write the rest + * of the chunk + * 4. start at an offset not equal to 0 and read/write less than + * (end of chunk - offset) + */ + chunk_start_offset = chunk * SFF_8436_PAGE_SIZE; + + if (chunk_start_offset < off) { + chunk_offset = off; + if ((off + pending_len) < (chunk_start_offset + + SFF_8436_PAGE_SIZE)) + chunk_len = pending_len; + else + chunk_len = (chunk+1)*SFF_8436_PAGE_SIZE - off;/*SFF_8436_PAGE_SIZE - off;*/ + } else { + chunk_offset = chunk_start_offset; + if (pending_len > SFF_8436_PAGE_SIZE) + chunk_len = SFF_8436_PAGE_SIZE; + else + chunk_len = pending_len; + } + + dev_dbg(&client->dev, + "sff_r/w: off %lld, len %ld, chunk_start_offset %lld, chunk_offset %lld, chunk_len %ld, pending_len %ld\n", + off, (long int) len, chunk_start_offset, chunk_offset, + (long int) chunk_len, (long int) pending_len); + + /* + * note: chunk_offset is from the start of the EEPROM, + * not the start of the chunk + */ + status = sff_8436_eeprom_update_client(port_data, buf, + chunk_offset, chunk_len, opcode); + if (status != chunk_len) { + /* This is another 'no device present' path */ + dev_dbg(&client->dev, + "sff_8436_update_client for chunk %d chunk_offset %lld chunk_len %ld failed %d!\n", + chunk, chunk_offset, (long int) chunk_len, status); + goto err; + } + buf += status; + pending_len -= status; + retval += status; + } + mutex_unlock(&port_data->update_lock); + + return retval; + +err: + mutex_unlock(&port_data->update_lock); + + return status; +} + +#else +static ssize_t sfp_port_read(struct sfp_port_data *data, + char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + DEBUG_PRINT("Count = 0, return"); + return count; + } + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&data->update_lock); + + while (count) { + ssize_t status; + + status = sfp_eeprom_read(data->client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&data->update_lock); + return retval; + +} +#endif + +static ssize_t sfp_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct sfp_port_data *data; + DEBUG_PRINT("offset = (%d), count = (%d)", off, count); + + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + present = sfp_is_port_present(data->client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + +#if (MULTIPAGE_SUPPORT == 1) + return sfp_port_read_write(data, buf, off, count, QSFP_READ_OP); +#else + return sfp_port_read(data, buf, off, count); +#endif +} + +#if (MULTIPAGE_SUPPORT == 1) +static int sfp_sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom, size_t size) +#else +static int sfp_sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom) +#endif +{ + int err; + + sysfs_bin_attr_init(eeprom); + eeprom->attr.name = EEPROM_NAME; + eeprom->attr.mode = S_IWUSR | S_IRUGO; + eeprom->read = sfp_bin_read; + eeprom->write = sfp_bin_write; +#if (MULTIPAGE_SUPPORT == 1) + eeprom->size = size; +#else + eeprom->size = EEPROM_SIZE; +#endif + + /* Create eeprom file */ + err = sysfs_create_bin_file(kobj, eeprom); + if (err) { + return err; + } + + return 0; +} + +static int sfp_sysfs_eeprom_cleanup(struct kobject *kobj, struct bin_attribute *eeprom) +{ + sysfs_remove_bin_file(kobj, eeprom); + return 0; +} + + +#if (MULTIPAGE_SUPPORT == 0) +static int sfp_i2c_check_functionality(struct i2c_client *client) +{ +#if USE_I2C_BLOCK_READ + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK); +#else + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA); +#endif +} +#endif + + +static const struct attribute_group qsfp_group = { + .attrs = qsfp_attributes, +}; + +static int qsfp_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct qsfp_data **data) +{ + int status; + struct qsfp_data *qsfp; + +#if (MULTIPAGE_SUPPORT == 0) + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } +#endif + + qsfp = kzalloc(sizeof(struct qsfp_data), GFP_KERNEL); + if (!qsfp) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &qsfp_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ +#if (MULTIPAGE_SUPPORT == 1) + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &qsfp->eeprom.bin, SFF_8436_EEPROM_SIZE); +#else + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &qsfp->eeprom.bin); +#endif + if (status) { + goto exit_remove; + } + + *data = qsfp; + dev_info(&client->dev, "qsfp '%s'\n", client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &qsfp_group); +exit_free: + kfree(qsfp); +exit: + + return status; +} + +/* Platform dependent +++ */ +static int sfp_device_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int ret = 0; + struct sfp_port_data *data = NULL; + + if (client->addr != SFP_EEPROM_A0_I2C_ADDR) { + return -ENODEV; + } + + if (dev_id->driver_data < as7816_64x_port1 || dev_id->driver_data > as7816_64x_port64) { + return -ENXIO; + } + + data = kzalloc(sizeof(struct sfp_port_data), GFP_KERNEL); + if (!data) { + return -ENOMEM; + } + +#if (MULTIPAGE_SUPPORT == 1) + data->use_smbus = 0; + + /* Use I2C operations unless we're stuck with SMBus extensions. */ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { + data->use_smbus = I2C_SMBUS_I2C_BLOCK_DATA; + } else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_WORD_DATA)) { + data->use_smbus = I2C_SMBUS_WORD_DATA; + } else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_BYTE_DATA)) { + data->use_smbus = I2C_SMBUS_BYTE_DATA; + } else { + ret = -EPFNOSUPPORT; + goto exit_kfree; + } + } + + if (!data->use_smbus || + (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) || + i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_WORD_DATA) || + i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { + /* + * NOTE: AN-2079 + * Finisar recommends that the host implement 1 byte writes + * only since this module only supports 32 byte page boundaries. + * 2 byte writes are acceptable for PE and Vout changes per + * Application Note AN-2071. + */ + unsigned write_max = 1; + + if (write_max > io_limit) + write_max = io_limit; + if (data->use_smbus && write_max > I2C_SMBUS_BLOCK_MAX) + write_max = I2C_SMBUS_BLOCK_MAX; + data->write_max = write_max; + + /* buffer (data + address at the beginning) */ + data->writebuf = kmalloc(write_max + 2, GFP_KERNEL); + if (!data->writebuf) { + ret = -ENOMEM; + goto exit_kfree; + } + } else { + dev_warn(&client->dev, + "cannot write due to controller restrictions."); + } + + if (data->use_smbus == I2C_SMBUS_WORD_DATA || + data->use_smbus == I2C_SMBUS_BYTE_DATA) { + dev_notice(&client->dev, "Falling back to %s reads, " + "performance will suffer\n", data->use_smbus == + I2C_SMBUS_WORD_DATA ? "word" : "byte"); + } +#endif + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->port = dev_id->driver_data; + data->client = client; + data->driver_type = DRIVER_TYPE_QSFP; + + ret = qsfp_probe(client, dev_id, &data->qsfp); + if (ret < 0) { + goto exit_kfree_buf; + } + + return ret; + +exit_kfree_buf: +#if (MULTIPAGE_SUPPORT == 1) + if (data->writebuf) kfree(data->writebuf); +#endif + +exit_kfree: + kfree(data); + return ret; +} +/* Platform dependent --- */ + +static int qsfp_remove(struct i2c_client *client, struct qsfp_data *data) +{ + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + sysfs_remove_group(&client->dev.kobj, &qsfp_group); + kfree(data); + return 0; +} + +static int sfp_device_remove(struct i2c_client *client) +{ + int ret = 0; + struct sfp_port_data *data = i2c_get_clientdata(client); + + if (data->driver_type == DRIVER_TYPE_QSFP) { + ret = qsfp_remove(client, data->qsfp); + } + + kfree(data); + return ret; +} + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +static struct i2c_driver sfp_driver = { + .driver = { + .name = DRIVER_NAME, + }, + .probe = sfp_device_probe, + .remove = sfp_device_remove, + .id_table = sfp_device_id, + .address_list = normal_i2c, +}; + +static int __init sfp_init(void) +{ + return i2c_add_driver(&sfp_driver); +} + +static void __exit sfp_exit(void) +{ + i2c_del_driver(&sfp_driver); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton as7816_64x_sfp driver"); +MODULE_LICENSE("GPL"); + +module_init(sfp_init); +module_exit(sfp_exit); + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/ym2651y.c b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/ym2651y.c new file mode 120000 index 000000000000..f4d67640ccc3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/modules/ym2651y.c @@ -0,0 +1 @@ +../../common/modules/ym2651y.c \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/service/as7816-platform-init.service b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/service/as7816-platform-init.service new file mode 100755 index 000000000000..c1ba30092f1d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/service/as7816-platform-init.service @@ -0,0 +1,13 @@ +[Unit] +Description=Accton AS7816-64X Platform initialization service +Before=pmon.service +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/accton_as7816_util.py install +ExecStop=/usr/local/bin/accton_as7816_util.py clean +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/setup.py b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/setup.py new file mode 100755 index 000000000000..6633b9438b86 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/setup.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python + +import os +import sys +from setuptools import setup +os.listdir + +setup( + name='as7816_64x', + version='1.0', + description='Module to initialize Accton AS7816-64X platforms', + + packages=['as7816_64x'], + package_dir={'as7816_64x': 'as7816-64x/classes'}, +) + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/README b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/README new file mode 100755 index 000000000000..0b9fc1633999 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/README @@ -0,0 +1,60 @@ +Copyright (C) 2016 Accton Networks, 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 3 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, see . + +To initialize the system, run "accton_as7712_util.py install". +To clean up the drivers & devices, run "accton_as7712_util.py clean". +To dump information of sensors, run "accton_as7712_util.py show". +To dump SFP EEPROM, run "accton_as7712_util.py sff". +To set fan speed, run "accton_as7712_util.py set fan". +To enable/disable SFP emission, run "accton_as7712_util.py set sfp". +To set system LEDs' color, run "accton_as7712_util.py set led" +For more information, run "accton_as7712_util.py --help". + +==================================================================== +Besides applying accton_as7712_util.py to access peripherals, you can +access peripherals by sysfs nodes directly after the installation is run. + +LED controls can be found under /sys/class/leds. The sysfs interface +color mappings are as follows: +Brightness: + 0 => off + 1 => green + 2 => amber + 3 => red + 4 => blue + +There are 5 system LEDs, loc, diag, fan, ps1, and ps2. +They are lit automatically by CPLD, but the loc and diag. +The loc led has only 1 color, blue. +The diag one has 3 colors: red, amber, and green. + +Fan controls can be found in /sys/bus/i2c/devices/2-0066. +There are 12 fans inside 6 fan modules. +All fans share 1 duty setting, ranged from 0~100. + +Three temperature sensors are controlled by the lm75 kernel modules. +They should already be visible under /sys/bus/i2c/drivers/lm75/. + +Two power supplies are controlled by the CPLD. +Here provide their status under +/sys/bus/i2c/devices/10-0050 and /sys/bus/i2c/devices/11-0053. + +There are 32 QSFP+ modules are equipped. +Apply "accton_as7712_util.py show" to get their status. +Apply "accton_as7712_util.py set sfp" to turn on/off light transmission. +Apply "accton_as7712_util.py sff" to dump EEPROM information. +Before operating on that QSFP+, please make sure it is well plugged. +Otherwise, operation is going to fail. + diff --git a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/accton_as7816_util.py b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/accton_as7816_util.py new file mode 100755 index 000000000000..44c4486a2d59 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/accton_as7816_util.py @@ -0,0 +1,523 @@ +#!/usr/bin/env python +# +# Copyright (C) 2016 Accton Networks, 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 3 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, see . + +""" +Usage: %(scriptName)s [options] command object + +options: + -h | --help : this help message + -d | --debug : run with debug mode + -f | --force : ignore error during installation or clean +command: + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes + show : show all systen status + sff : dump SFP eeprom + set : change board setting with fan|led|sfp +""" + +import os +import commands +import sys, getopt +import logging +import re +import time +from collections import namedtuple + + + + +PROJECT_NAME = 'as7816_64x' +version = '0.1.0' +verbose = False +DEBUG = False +args = [] +ALL_DEVICE = {} +DEVICE_NO = {'led':5, 'fan':4,'thermal':6, 'psu':2, 'sfp':64} +FORCE = 0 +#logging.basicConfig(filename= PROJECT_NAME+'.log', filemode='w',level=logging.DEBUG) +#logging.basicConfig(level=logging.INFO) + + +if DEBUG == True: + print sys.argv[0] + print 'ARGV :', sys.argv[1:] + + +def main(): + global DEBUG + global args + global FORCE + + if len(sys.argv)<2: + show_help() + + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', + 'debug', + 'force', + ]) + if DEBUG == True: + print options + print args + print len(sys.argv) + + for opt, arg in options: + if opt in ('-h', '--help'): + show_help() + elif opt in ('-d', '--debug'): + DEBUG = True + logging.basicConfig(level=logging.INFO) + elif opt in ('-f', '--force'): + FORCE = 1 + else: + logging.info('no option') + for arg in args: + if arg == 'install': + do_install() + elif arg == 'clean': + do_uninstall() + elif arg == 'show': + device_traversal() + elif arg == 'sff': + if len(args)!=2: + show_eeprom_help() + elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']: + show_eeprom_help() + else: + show_eeprom(args[1]) + return + elif arg == 'set': + if len(args)<3: + show_set_help() + else: + set_device(args[1:]) + return + else: + show_help() + + + return 0 + +def show_help(): + print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + sys.exit(0) + +def show_set_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print cmd +" [led|sfp|fan]" + print " use \""+ cmd + " led 0-4 \" to set led color" + print " use \""+ cmd + " fan 0-100\" to set fan duty percetage" + print " use \""+ cmd + " sfp 1-32 {0|1}\" to set sfp# tx_disable" + sys.exit(0) + +def show_eeprom_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print " use \""+ cmd + " 1-32 \" to dump sfp# eeprom" + sys.exit(0) + +def my_log(txt): + if DEBUG == True: + print "[ROY]"+txt + return + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) + my_log (cmd +"with result:" + str(status)) + my_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + +def driver_check(): + ret, lsmod = log_os_system("lsmod| grep accton", 0) + logging.info('mods:'+lsmod) + if len(lsmod) ==0: + return False + return True + + + +kos = [ +'modprobe i2c_dev', +'modprobe i2c_mux_pca954x', +'modprobe accton_i2c_cpld' , +'modprobe ym2651y' , +'modprobe x86-64-accton-as7816-64x-fan' , +'modprobe x86-64-accton-as7816-64x-sfp' , +'modprobe x86-64-accton-as7816-64x-leds' , +'modprobe x86-64-accton-as7816-64x-psu' ] + +def driver_install(): + global FORCE + status, output = log_os_system("depmod", 1) + for i in range(0,len(kos)): + status, output = log_os_system(kos[i], 1) + if status: + if FORCE == 0: + return status + return 0 + +def driver_uninstall(): + global FORCE + for i in range(0,len(kos)): + rm = kos[-(i+1)].replace("modprobe", "modprobe -rq") + rm = rm.replace("insmod", "rmmod") + status, output = log_os_system(rm, 1) + if status: + if FORCE == 0: + return status + return 0 + +led_prefix ='/sys/class/leds/'+PROJECT_NAME+'_led::' +hwmon_types = {'led': ['diag','fan','loc','psu1','psu2']} +hwmon_nodes = {'led': ['brightness'] } +hwmon_prefix ={'led': led_prefix} + +i2c_prefix = '/sys/bus/i2c/devices/' +i2c_bus = {'fan': ['17-0068'] , + 'thermal': ['18-0048','18-0049', '18-004a' , '18-004b', '17-004d', '17-004e'] , + 'psu': ['10-0053','9-0050'], + 'sfp': ['-0050']} +i2c_nodes = {'fan': ['present', 'front_speed_rpm', 'rear_speed_rpm'] , + 'thermal': ['hwmon/hwmon*/temp1_input'] , + 'psu': ['psu_present ', 'psu_power_good'] , + 'sfp': ['sfp_is_present ', 'sfp_tx_disable']} + +sfp_map = [37,38,39,40,42,41,44,43,33,34,35,36,45,46,47,48,49,50,51,52, + 61,62,63,64,53,54,55,56,57,58,59,60,69,70,71,72,77,78,79,80,65, + 66,67,68,73,74,75,76,85,86,87,88,31,32,29,30,81,82,83,84,25,26, + 27,28] + +mknod =[ +'echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-2/new_device', +'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-2/new_device', +'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-2/new_device', +'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-2/new_device', +'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-2/new_device', +'echo pca9548 0x75 > /sys/bus/i2c/devices/i2c-2/new_device', +'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-2/new_device', +'echo 24c02 0x56 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo as7816_64x_psu1 0x53 > /sys/bus/i2c/devices/i2c-10/new_device', +'echo ym2851 0x5b > /sys/bus/i2c/devices/i2c-10/new_device', +'echo as7816_64x_psu2 0x50 > /sys/bus/i2c/devices/i2c-9/new_device', +'echo ym2851 0x58 > /sys/bus/i2c/devices/i2c-9/new_device', +'echo as7816_64x_fan 0x68 > /sys/bus/i2c/devices/i2c-17/new_device', +'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-18/new_device', +'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-18/new_device', +'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-18/new_device', +'echo lm75 0x4b > /sys/bus/i2c/devices/i2c-18/new_device', +'echo lm75 0x4d > /sys/bus/i2c/devices/i2c-17/new_device', +'echo lm75 0x4e > /sys/bus/i2c/devices/i2c-17/new_device', +'echo cpld_as7816 0x60 > /sys/bus/i2c/devices/i2c-19/new_device', +'echo cpld_plain 0x62 > /sys/bus/i2c/devices/i2c-20/new_device', +'echo cpld_plain 0x64 > /sys/bus/i2c/devices/i2c-21/new_device', +'echo cpld_plain 0x66 > /sys/bus/i2c/devices/i2c-22/new_device'] + +def i2c_order_check(): + return 0 + +def device_install(): + global FORCE + + for i in range(0,len(mknod)): + #for pca954x need times to built new i2c buses + if mknod[i].find('pca954') != -1: + time.sleep(1) + + status, output = log_os_system(mknod[i], 1) + if status: + print output + if FORCE == 0: + return status + + for i in range(0,len(sfp_map)): + status, output =log_os_system("echo as7816_64x_port"+str(i+1)+" 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + return + +def device_uninstall(): + global FORCE + + status, output =log_os_system("ls /sys/bus/i2c/devices/1-0076", 0) + + for i in range(0,len(sfp_map)): + target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device" + status, output =log_os_system("echo 0x50 > "+ target, 1) + if status: + print output + if FORCE == 0: + return status + + nodelist = mknod + + for i in range(len(nodelist)): + target = nodelist[-(i+1)] + temp = target.split() + del temp[1] + temp[-1] = temp[-1].replace('new_device', 'delete_device') + status, output = log_os_system(" ".join(temp), 1) + if status: + print output + if FORCE == 0: + return status + + return + +def system_ready(): + if driver_check() == False: + return False + if not device_exist(): + return False + return True + +def do_install(): + print "Checking system...." + if driver_check() == False: + print "No driver, installing...." + status = driver_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" drivers detected...." + if not device_exist(): + print "No device, installing...." + status = device_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" devices detected...." + return + +def do_uninstall(): + print "Checking system...." + if not device_exist(): + print PROJECT_NAME.upper() +" has no device installed...." + else: + print "Removing device...." + status = device_uninstall() + if status: + if FORCE == 0: + return status + + if driver_check()== False : + print PROJECT_NAME.upper() +" has no driver installed...." + else: + print "Removing installed driver...." + status = driver_uninstall() + if status: + if FORCE == 0: + return status + + return + +def devices_info(): + global DEVICE_NO + global ALL_DEVICE + global i2c_bus, hwmon_types + for key in DEVICE_NO: + ALL_DEVICE[key]= {} + for i in range(0,DEVICE_NO[key]): + ALL_DEVICE[key][key+str(i+1)] = [] + + for key in i2c_bus: + buses = i2c_bus[key] + nodes = i2c_nodes[key] + for i in range(0,len(buses)): + for j in range(0,len(nodes)): + if 'fan' == key: + for k in range(0,DEVICE_NO[key]): + node = key+str(k+1) + path = i2c_prefix+ buses[i]+"/fan"+str(k+1)+"_"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + elif 'sfp' == key: + for k in range(0,DEVICE_NO[key]): + node = key+str(k+1) + path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + else: + node = key+str(i+1) + path = i2c_prefix+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + + for key in hwmon_types: + itypes = hwmon_types[key] + nodes = hwmon_nodes[key] + for i in range(0,len(itypes)): + for j in range(0,len(nodes)): + node = key+"_"+itypes[i] + path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][ key+str(i+1)].append(path) + + #show dict all in the order + if DEBUG == True: + for i in sorted(ALL_DEVICE.keys()): + print(i+": ") + for j in sorted(ALL_DEVICE[i].keys()): + print(" "+j) + for k in (ALL_DEVICE[i][j]): + print(" "+" "+k) + return + +def show_eeprom(index): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0] + node = node.replace(node.split("/")[-1], 'sfp_eeprom') + # check if got hexdump command in current environment + ret, log = log_os_system("which hexdump", 0) + ret, log2 = log_os_system("which busybox hexdump", 0) + if len(log): + hex_cmd = 'hexdump' + elif len(log2): + hex_cmd = ' busybox hexdump' + else: + log = 'Failed : no hexdump cmd!!' + logging.info(log) + print log + return 1 + + print node + ":" + ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1) + if ret==0: + print log + else: + print "**********device no found**********" + return + +def set_device(args): + global DEVICE_NO + global ALL_DEVICE + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + + if args[0]=='led': + if int(args[1])>4: + show_set_help() + return + #print ALL_DEVICE['led'] + for i in range(0,len(ALL_DEVICE['led'])): + for k in (ALL_DEVICE['led']['led'+str(i+1)]): + ret, log = log_os_system("echo "+args[1]+" >"+k, 1) + if ret: + return ret + elif args[0]=='fan': + if int(args[1])>100: + show_set_help() + return + #print ALL_DEVICE['fan'] + #fan1~6 is all fine, all fan share same setting + node = ALL_DEVICE['fan'] ['fan1'][0] + node = node.replace(node.split("/")[-1], 'fan_duty_cycle_percentage') + ret, log = log_os_system("cat "+ node, 1) + if ret==0: + print ("Previous fan duty: " + log.strip() +"%") + ret, log = log_os_system("echo "+args[1]+" >"+node, 1) + if ret==0: + print ("Current fan duty: " + args[1] +"%") + return ret + elif args[0]=='sfp': + if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0: + show_set_help() + return + if len(args)<2: + show_set_help() + return + + if int(args[2])>1: + show_set_help() + return + + #print ALL_DEVICE[args[0]] + for i in range(0,len(ALL_DEVICE[args[0]])): + for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]: + if j.find('tx_disable')!= -1: + ret, log = log_os_system("echo "+args[2]+" >"+ j, 1) + if ret: + return ret + + return + +#get digits inside a string. +#Ex: 31 for "sfp31" +def get_value(input): + digit = re.findall('\d+', input) + return int(digit[0]) + +def device_traversal(): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + for i in sorted(ALL_DEVICE.keys()): + print("============================================") + print(i.upper()+": ") + print("============================================") + + for j in sorted(ALL_DEVICE[i].keys(), key=get_value): + print " "+j+":", + for k in (ALL_DEVICE[i][j]): + ret, log = log_os_system("cat "+k, 0) + func = k.split("/")[-1].strip() + func = re.sub(j+'_','',func,1) + func = re.sub(i.lower()+'_','',func,1) + if ret==0: + print func+"="+log+" ", + else: + print func+"="+"X"+" ", + print + print("----------------------------------------------------------------") + + + print + return + +def device_exist(): + ret1, log = log_os_system("ls "+i2c_prefix+"*0076", 0) + ret2, log = log_os_system("ls "+i2c_prefix+"i2c-2", 0) + return not(ret1 or ret2) + +if __name__ == "__main__": + main() diff --git a/platform/broadcom/sonic-platform-modules-accton/common/modules/accton_i2c_cpld.c b/platform/broadcom/sonic-platform-modules-accton/common/modules/accton_i2c_cpld.c new file mode 100644 index 000000000000..aae4e5538b63 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/common/modules/accton_i2c_cpld.c @@ -0,0 +1,887 @@ +/* + * A hwmon driver for the accton_i2c_cpld + * + * Copyright (C) 2013 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define MAX_PORT_NUM 64 +#define I2C_RW_RETRY_COUNT 10 +#define I2C_RW_RETRY_INTERVAL 60 /* ms */ + +#define I2C_ADDR_CPLD1 0x60 +#define I2C_ADDR_CPLD2 0x62 +#define I2C_ADDR_CPLD3 0x64 +#define CPLD_ADDRS {I2C_ADDR_CPLD1, I2C_ADDR_CPLD2, I2C_ADDR_CPLD3} + + +/* + * Number of additional attribute pointers to allocate + * with each call to krealloc + */ +#define ATTR_ALLOC_SIZE 1 /*For last attribute which is NUll.*/ + +#define NAME_SIZE 24 +#define MAX_RESP_LENGTH 48 + +typedef ssize_t (*show_func)( struct device *dev, + struct device_attribute *attr, + char *buf); +typedef ssize_t (*store_func)(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count); + +enum models { + AS7712_32X, + AS7716_32X, + AS7816_64X, + AS7312_54X, + PLAIN_CPLD, /*No attribute but add i2c addr to the list.*/ + NUM_MODEL +}; + +enum sfp_func { + HAS_SFP = 1<<0 , + HAS_QSFP = 1<<1 , +}; + +enum common_attrs { + CMN_VERSION, + CMN_ACCESS, + CMN_PRESENT_ALL, + NUM_COMMON_ATTR +}; + +enum sfp_attrs { + SFP_PRESENT, + SFP_RESET, + SFP_LP_MODE, + NUM_SFP_ATTR +}; + +struct cpld_sensor { + struct cpld_sensor *next; + char name[NAME_SIZE+1]; /* sysfs sensor name */ + struct device_attribute attribute; + bool update; /* runtime sensor update needed */ + int data; /* Sensor data. Negative if there was a read error */ + + u8 reg; /* register */ + u8 mask; /* bit mask */ + bool invert; /* inverted value*/ + +}; + +#define to_cpld_sensor(_attr) \ + container_of(_attr, struct cpld_sensor, attribute) + +struct cpld_data { + struct device *dev; + struct device *hwmon_dev; + + int num_attributes; + struct attribute_group group; + + enum models model; + struct cpld_sensor *sensors; + struct mutex update_lock; + bool valid; + unsigned long last_updated; /* in jiffies */ + + int attr_index; + u16 sfp_num; + u8 sfp_types; + struct model_attrs *cmn_attr; +}; + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; + + +struct base_attrs { + const char *name; + umode_t mode; + show_func get; + store_func set; +}; + +struct attrs { + int reg; + bool invert; + struct base_attrs *base; +}; + +struct model_attrs { + struct attrs **cmn; + struct attrs **portly; +}; + + +static ssize_t show_bit(struct device *dev, + struct device_attribute *devattr, char *buf); +static ssize_t show_presnet_all(struct device *dev, + struct device_attribute *devattr, char *buf); +static ssize_t set_1bit(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t set_byte(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t access(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); + +int accton_i2c_cpld_read(u8 cpld_addr, u8 reg); +int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + + +struct base_attrs common_attrs[NUM_COMMON_ATTR] = +{ + [CMN_VERSION] = {"version", S_IRUGO, show_bit, NULL}, + [CMN_ACCESS] = {"access", S_IWUSR, NULL, set_byte}, + [CMN_PRESENT_ALL] = {"module_present_all", S_IRUGO, show_presnet_all, NULL}, +}; + +struct attrs as7712_common[] = { + [CMN_VERSION] = {0x01, false, &common_attrs[CMN_VERSION]}, + [CMN_ACCESS] = {0x00, false, &common_attrs[CMN_ACCESS]}, + [CMN_PRESENT_ALL] = {0x30, false, &common_attrs[CMN_PRESENT_ALL]}, +}; +struct attrs as7816_common[] = { + [CMN_VERSION] = {0x01, false, &common_attrs[CMN_VERSION]}, + [CMN_ACCESS] = {0x00, false, &common_attrs[CMN_ACCESS]}, + [CMN_PRESENT_ALL] = {0x30, false, &common_attrs[CMN_PRESENT_ALL]}, +}; +struct attrs as7312_common[] = { + [CMN_VERSION] = {0x01, false, &common_attrs[CMN_VERSION]}, + [CMN_ACCESS] = {0x00, false, &common_attrs[CMN_ACCESS]}, + [CMN_PRESENT_ALL] = {-1, false, &common_attrs[CMN_PRESENT_ALL]}, +}; +struct attrs plain_common[] = { + [CMN_VERSION] = {0x01, false, &common_attrs[CMN_VERSION]}, +}; + +struct base_attrs portly_attrs[] = +{ + [SFP_PRESENT] = {"module_present", S_IRUGO, show_bit, NULL}, + [SFP_RESET] = {"module_reset", S_IRUGO|S_IWUGO, show_bit, set_1bit}, +}; + +struct attrs as7712_port[] = { + {0x30, true, &portly_attrs[SFP_PRESENT]}, + {0x04, true, &portly_attrs[SFP_RESET]}, +}; + +struct attrs as7816_port[] = { + {0x70, true, &portly_attrs[SFP_PRESENT]}, + {0x40, true, &portly_attrs[SFP_RESET]}, +}; + +struct attrs *as7712_cmn_list[] = { + &as7712_common[CMN_VERSION], + &as7712_common[CMN_ACCESS], + &as7712_common[CMN_PRESENT_ALL], + NULL +}; + +struct attrs *as7816_cmn_list[] = { + &as7816_common[CMN_VERSION], + &as7816_common[CMN_ACCESS], + &as7816_common[CMN_PRESENT_ALL], + NULL +}; + +struct attrs *as7312_cmn_list[] = { + &as7312_common[CMN_VERSION], + &as7312_common[CMN_ACCESS], + &as7312_common[CMN_PRESENT_ALL], + NULL +}; + +struct attrs *plain_cmn_list[] = { + &plain_common[CMN_VERSION], + NULL +}; + +struct attrs *as7712_port_list[] = { + &as7712_port[SFP_PRESENT], + &as7712_port[SFP_RESET], + NULL +}; +struct attrs *as7816_port_list[] = { + &as7816_port[SFP_PRESENT], + &as7816_port[SFP_RESET], + NULL +}; + +struct model_attrs models_attr[NUM_MODEL] = { + {.cmn = as7712_cmn_list, .portly=as7712_port_list}, + {.cmn = as7712_cmn_list, .portly=as7712_port_list}, /*7716's as 7712*/ + {.cmn = as7816_cmn_list, .portly=as7816_port_list}, + {.cmn = as7312_cmn_list, .portly=as7816_port_list}, + {.cmn = plain_cmn_list, .portly=NULL}, +}; + +static LIST_HEAD(cpld_client_list); +static struct mutex list_lock; +/* Addresses scanned for accton_i2c_cpld + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +static int get_sfp_spec(int model, u16 *num, u8 *types) +{ + switch (model) { + case AS7712_32X: + case AS7716_32X: + *num = 32; + *types = HAS_QSFP; + break; + case AS7816_64X: + *num = 64; + *types = HAS_QSFP; + break; + case AS7312_54X: + *num = 54; + *types = HAS_QSFP|HAS_SFP; + default: + *types = 0; + *num = 0; + break; + } + + return 0; +} + +static int get_present_reg(int model, u8 port, u8 *cpld_addr, u8 *reg, u8 *num) +{ + u8 cpld_address[] = CPLD_ADDRS; + + switch (model) { + case AS7312_54X: + if (port < 48) { + *cpld_addr = cpld_address[1 + port/24]; + *reg = 0x09 + (port%24)/8; + *num = 8; + } + else + { + *reg = 0x18; + *num = 4; + *cpld_addr = ( port < 52)? cpld_address[1]: cpld_address[2]; + } + break; + default: + return -EINVAL; + } +} + + +/*Assume the bits for ports are listed in-a-row.*/ +static int get_reg_bit(u8 reg_start, int port, + u8 *reg ,u8 *mask) +{ + *reg = reg_start + ((port)/8); + *mask = 1 << ((port)%8); + + return 0; +} + +static int cpld_write_internal( + struct i2c_client *client, u8 reg, u8 value) +{ + int status = 0, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_write_byte_data(client, reg, value); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + return status; +} + +static int cpld_read_internal(struct i2c_client *client, u8 reg) +{ + int status = 0, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_read_byte_data(client, reg); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + return status; +} + + +/*Turn a numberic array into string with " " between each element. + * e.g., {0x11, 0x33, 0xff, 0xf1} => "11 33 ff f1" + */ +static ssize_t array_stringify(char *buf, u8 *input, size_t size) { + + int i; + char t[MAX_RESP_LENGTH+1]; + + buf[0] = '\0'; + for (i = 0; i < size; i++) { + snprintf(t, MAX_RESP_LENGTH, "%x ", input[i]); + strncat(buf, t, MAX_RESP_LENGTH); + } + + if (strlen(buf) > 0) + buf[strlen(buf)-1] = '\0'; /*Remove tailing blank*/ + + return snprintf(buf, MAX_RESP_LENGTH, "%s\n", buf); +} + +static ssize_t show_presnet_all_distinct(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 i, value, reg; + u8 cpld_addr, num; + u8 _value[8]; + u64 *values = (u64 *)_value; + + values = 0; + mutex_lock(&data->update_lock); + while(i < data->sfp_num) + { + get_present_reg(data->model, i, &cpld_addr, ®, &num); + if(cpld_addr == client->addr) + value = cpld_read_internal(client, reg); + else + value = accton_i2c_cpld_read(cpld_addr, reg); + + if (unlikely(value < 0)) { + goto exit; + } + + *values |= (value&((1<<(num))-1)) << i; + i += num; + } + mutex_unlock(&data->update_lock); + + *values = cpu_to_le64(*values); + return array_stringify(buf, _value, i); +exit: + mutex_unlock(&data->update_lock); + return value; +} + +static ssize_t show_presnet_all(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + struct cpld_sensor *sensor = to_cpld_sensor(devattr); + u8 i, values[MAX_RESP_LENGTH/8]; + + if (sensor->reg < 0) { + return show_presnet_all_distinct(dev, devattr, buf); + } + + mutex_lock(&data->update_lock); + for (i = 0; i < ((data->sfp_num+7)/8); i++) { + values[i] = cpld_read_internal(client, sensor->reg + i); + if (unlikely(values[i] < 0)) { + goto exit; + } + } + mutex_unlock(&data->update_lock); + return array_stringify(buf, values, i); + +exit: + mutex_unlock(&data->update_lock); + return values[i]; +} + +static ssize_t show_bit(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int value; + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + struct cpld_sensor *sensor = to_cpld_sensor(devattr); + + mutex_lock(&data->update_lock); + value = cpld_read_internal(client, sensor->reg); + value = value & sensor->mask; + if (sensor->invert) + value = !value; + mutex_unlock(&data->update_lock); + + return snprintf(buf, PAGE_SIZE, "%x\n", value); +} + +static ssize_t set_1bit(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + long is_reset; + int value, status; + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + struct cpld_sensor *sensor = to_cpld_sensor(devattr); + u8 cpld_bit, reg; + + status = kstrtol(buf, 10, &is_reset); + if (status) { + return status; + } + reg = sensor->reg; + cpld_bit = sensor->mask; + mutex_lock(&data->update_lock); + value = cpld_read_internal(client, reg); + if (unlikely(status < 0)) { + goto exit; + } + + if (sensor->invert) + is_reset = !is_reset; + + if (is_reset) { + value |= cpld_bit; + } + else { + value &= ~cpld_bit; + } + + status = cpld_write_internal(client, reg, value); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static ssize_t set_byte(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + return access(dev, da, buf, count); +} + +static ssize_t access(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int status; + u32 addr, val; + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + + if (sscanf(buf, "0x%x 0x%x", &addr, &val) != 2) { + return -EINVAL; + } + + if (addr > 0xFF || val > 0xFF) { + return -EINVAL; + } + + mutex_lock(&data->update_lock); + status = cpld_write_internal(client, addr, val); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + return count; + +exit: + mutex_unlock(&data->update_lock); + return status; +} + +static void accton_i2c_cpld_add_client(struct i2c_client *client) +{ + struct cpld_client_node *node = + kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", + client->addr); + return; + } + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &cpld_client_list); + mutex_unlock(&list_lock); +} + +static void accton_i2c_cpld_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client == client) { + found = 1; + break; + } + } + + if (found) { + list_del(list_node); + kfree(cpld_node); + } + + mutex_unlock(&list_lock); +} + +static int cpld_add_attribute(struct cpld_data *data, struct attribute *attr) +{ + int new_max_attrs = ++data->num_attributes + ATTR_ALLOC_SIZE; + void *new_attrs = krealloc(data->group.attrs, + new_max_attrs * sizeof(void *), + GFP_KERNEL); + if (!new_attrs) + return -ENOMEM; + data->group.attrs = new_attrs; + + + data->group.attrs[data->num_attributes-1] = attr; + data->group.attrs[data->num_attributes] = NULL; + + return 0; +} + +static void cpld_dev_attr_init(struct device_attribute *dev_attr, + const char *name, umode_t mode, + show_func show, store_func store) +{ + sysfs_attr_init(&dev_attr->attr); + dev_attr->attr.name = name; + dev_attr->attr.mode = mode; + dev_attr->show = show; + dev_attr->store = store; +} + +static struct cpld_sensor * add_sensor(struct cpld_data *data, + const char *name, + u8 reg, u8 mask, bool invert, + bool update, umode_t mode, + show_func get, store_func set) +{ + struct cpld_sensor *sensor; + struct device_attribute *a; + + sensor = devm_kzalloc(data->dev, sizeof(*sensor), GFP_KERNEL); + if (!sensor) + return NULL; + a = &sensor->attribute; + + snprintf(sensor->name, sizeof(sensor->name), name); + sensor->reg = reg; + sensor->mask = mask; + sensor->update = update; + sensor->invert = invert; + cpld_dev_attr_init(a, sensor->name, + mode, + get, set); + + if (cpld_add_attribute(data, &a->attr)) + return NULL; + + sensor->next = data->sensors; + data->sensors = sensor; + + return sensor; +} + +static int add_attributes_cmn(struct cpld_data *data, struct attrs **cmn) +{ + u8 reg, i ; + bool invert; + struct attrs *a; + struct base_attrs *b; + + if (NULL == cmn) + return -1; + + for (i = 0; cmn[i]; i++) + { + a = cmn[i]; + + reg = a->reg; + invert = a->invert; + + b = a->base; + if (NULL == b) + break; + + if (add_sensor(data, b->name, + reg, 0xff, invert, + true, b->mode, + b->get, b->set) == NULL) + { + return -ENOMEM; + } + } + return 0; +} + +static int add_attributes_portly(struct cpld_data *data, struct attrs **pa) +{ + char name[NAME_SIZE+1]; + int i, j; + u8 reg, mask, invert; + struct attrs *a; + struct base_attrs *b; + + if (NULL == pa) + return -1; + + + for (i = 0; pa[i]; i++) { + a = pa[i]; + + invert = a->invert; + b = a->base; + if (b == NULL) + break; + + for (j = 0; j < data->sfp_num; j++) + { + snprintf(name, NAME_SIZE, "%s_%d", b->name, j+1); + get_reg_bit(a->reg, j, ®, &mask); + + if (add_sensor(data, name, reg, mask, invert, + true, b->mode, b->get, b->set) == NULL) + { + return -ENOMEM; + } + } + } + return 0; +} + +static int add_attributes(struct i2c_client *client, + struct cpld_data *data) +{ + struct model_attrs *m = data->cmn_attr; + + if (m == NULL) + return -EINVAL; + + /* Common attributes.*/ + add_attributes_cmn(data, m->cmn); + + /* Port-wise attributes.*/ + add_attributes_portly(data, m->portly); + + return 0; +} + +static int accton_i2c_cpld_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int status; + struct cpld_data *data = NULL; + struct device *dev = &client->dev; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_dbg(dev, "i2c_check_functionality failed (0x%x)\n", client->addr); + return -EIO; + } + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) { + return -ENOMEM; + } + + data->model = dev_id->driver_data; + data->cmn_attr = &models_attr[data->model]; + get_sfp_spec(data->model, &data->sfp_num, &data->sfp_types); + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->dev = dev; + dev_info(dev, "chip found\n"); + + status = add_attributes(client, data); + if (status) + goto out_kfree; + + /* + * If there are no attributes, something is wrong. + * Bail out instead of trying to register nothing. + */ + if (!data->num_attributes) { + dev_err(dev, "No attributes found\n"); + status = -ENODEV; + goto out_kfree; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &data->group); + if (status) { + goto out_kfree; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + accton_i2c_cpld_add_client(client); + dev_info(dev, "%s: cpld '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; +exit_remove: + sysfs_remove_group(&client->dev.kobj, &data->group); +out_kfree: + kfree(data->group.attrs); + return status; + +} + +static int accton_i2c_cpld_remove(struct i2c_client *client) +{ + struct cpld_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &data->group); + kfree(data->group.attrs); + accton_i2c_cpld_remove_client(client); + return 0; +} + +int accton_i2c_cpld_read(u8 cpld_addr, u8 reg) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EPERM; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = i2c_smbus_read_byte_data(cpld_node->client, reg); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(accton_i2c_cpld_read); + +int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EIO; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = i2c_smbus_write_byte_data(cpld_node->client, reg, value); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(accton_i2c_cpld_write); + + +static const struct i2c_device_id accton_i2c_cpld_id[] = { + { "cpld_as7712", AS7712_32X}, + { "cpld_as7716", AS7716_32X}, + { "cpld_as7816", AS7816_64X}, + { "cpld_as7312", AS7312_54X}, + { "cpld_plain", PLAIN_CPLD}, + { }, +}; +MODULE_DEVICE_TABLE(i2c, accton_i2c_cpld_id); + +static struct i2c_driver accton_i2c_cpld_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "accton_i2c_cpld", + }, + .probe = accton_i2c_cpld_probe, + .remove = accton_i2c_cpld_remove, + .id_table = accton_i2c_cpld_id, + .address_list = normal_i2c, +}; + + +static int __init accton_i2c_cpld_init(void) +{ + mutex_init(&list_lock); + return i2c_add_driver(&accton_i2c_cpld_driver); +} + +static void __exit accton_i2c_cpld_exit(void) +{ + i2c_del_driver(&accton_i2c_cpld_driver); +} + +module_init(accton_i2c_cpld_init); +module_exit(accton_i2c_cpld_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton_i2c_cpld driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-accton/common/modules/accton_pmbus_3y.c b/platform/broadcom/sonic-platform-modules-accton/common/modules/accton_pmbus_3y.c new file mode 100644 index 000000000000..ed176189cdcd --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/common/modules/accton_pmbus_3y.c @@ -0,0 +1,1978 @@ +/* + * Hardware monitoring driver for 3Y power devices. + * + * Copyright (C) 2018 Accton Technology Corporation. + * Roy Lee + * + * Based on pmbus.c, pmbus.h and pmbus_core.c. + * Copyright 2012 Guenter Roeck/Ericsson AB. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pmbus.h" + + +enum chips { + YM2651, + YM2401, + YM2851, + LIMITED_CHIPS, +}; + + +/* + * Number of additional attribute pointers to allocate + * with each call to krealloc + */ +#define PMBUS_ATTR_ALLOC_SIZE 32 + +/* + * Index into status register array, per status register group + */ +#define PB_STATUS_BASE 0 +#define PB_STATUS_VOUT_BASE (PB_STATUS_BASE + PMBUS_PAGES) +#define PB_STATUS_IOUT_BASE (PB_STATUS_VOUT_BASE + PMBUS_PAGES) +#define PB_STATUS_FAN_BASE (PB_STATUS_IOUT_BASE + PMBUS_PAGES) +#define PB_STATUS_FAN34_BASE (PB_STATUS_FAN_BASE + PMBUS_PAGES) +#define PB_STATUS_TEMP_BASE (PB_STATUS_FAN34_BASE + PMBUS_PAGES) +#define PB_STATUS_INPUT_BASE (PB_STATUS_TEMP_BASE + PMBUS_PAGES) +#define PB_STATUS_VMON_BASE (PB_STATUS_INPUT_BASE + 1) + +#define PB_NUM_STATUS_REG (PB_STATUS_VMON_BASE + 1) + +#define PMBUS_NAME_SIZE 24 + +struct pmbus_sensor { + struct pmbus_sensor *next; + char name[PMBUS_NAME_SIZE]; /* sysfs sensor name */ + struct device_attribute attribute; + u8 page; /* page number */ + u16 reg; /* register */ + enum pmbus_sensor_classes class; /* sensor class */ + bool update; /* runtime sensor update needed */ + int data; /* Sensor data. + Negative if there was a read error */ +}; +#define to_pmbus_sensor(_attr) \ + container_of(_attr, struct pmbus_sensor, attribute) + +struct pmbus_boolean { + char name[PMBUS_NAME_SIZE]; /* sysfs boolean name */ + struct sensor_device_attribute attribute; + struct pmbus_sensor *s1; + struct pmbus_sensor *s2; +}; +#define to_pmbus_boolean(_attr) \ + container_of(_attr, struct pmbus_boolean, attribute) + +struct pmbus_label { + char name[PMBUS_NAME_SIZE]; /* sysfs label name */ + struct device_attribute attribute; + char label[PMBUS_NAME_SIZE]; /* label */ +}; +#define to_pmbus_label(_attr) \ + container_of(_attr, struct pmbus_label, attribute) + +struct pmbus_data { + struct device *dev; + struct device *hwmon_dev; + + u32 flags; /* from platform data */ + + int exponent[PMBUS_PAGES]; + /* linear mode: exponent for output voltages */ + + const struct pmbus_driver_info *info; + + int max_attributes; + int num_attributes; + struct attribute_group group; + const struct attribute_group *groups[2]; + + struct pmbus_sensor *sensors; + + struct mutex update_lock; + bool valid; + unsigned long last_updated; /* in jiffies */ + + /* + * A single status register covers multiple attributes, + * so we keep them all together. + */ + u8 status[PB_NUM_STATUS_REG]; + u8 status_register; + + u8 currpage; + bool linear_16; +}; + + +static int limited_models(const struct i2c_device_id *id); + +int _pmbus_set_page(struct i2c_client *client, u8 page) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + int rv = 0; + int newpage; + + if (page != data->currpage) { + rv = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page); + newpage = i2c_smbus_read_byte_data(client, PMBUS_PAGE); + if (newpage != page) + rv = -EIO; + else + data->currpage = page; + } + return 0; +} + +/* + * _pmbus_write_byte() is similar to pmbus_write_byte(), but checks if + * a device specific mapping function exists and calls it if necessary. + */ +static int _pmbus_write_byte(struct i2c_client *client, int page, u8 value) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + const struct pmbus_driver_info *info = data->info; + int status; + + if (info->write_byte) { + status = info->write_byte(client, page, value); + if (status != -ENODATA) + return status; + } + /*Ignore page*/ + return i2c_smbus_write_byte(client, value);; +} + +/* + * _pmbus_write_word_data() is similar to pmbus_write_word_data(), but checks if + * a device specific mapping function exists and calls it if necessary. + */ +static int _pmbus_write_word_data(struct i2c_client *client, int page, int reg, + u16 word) +{ + if (reg >= PMBUS_VIRT_BASE) + return -ENXIO; + /*Ignore page*/ + return i2c_smbus_write_word_data(client, reg, word); +} + +/* + * _pmbus_read_word_data() is similar to pmbus_read_word_data(), but checks if + * a device specific mapping function exists and calls it if necessary. + */ +static int _pmbus_read_word_data(struct i2c_client *client, int page, int reg) +{ + /*Ignore page*/ + return i2c_smbus_read_word_data(client, reg);; +} + +/* + * _pmbus_read_byte_data() is similar to pmbus_read_byte_data(), but checks if + * a device specific mapping function exists and calls it if necessary. + */ +static int _pmbus_read_byte_data(struct i2c_client *client, int page, int reg) +{ + if (reg >= PMBUS_VIRT_BASE) + return -ENXIO; + + /*Ignore page*/ + return i2c_smbus_read_byte_data(client, reg); +} + +static void pmbus_clear_fault_page(struct i2c_client *client, int page) +{ + _pmbus_write_byte(client, page, PMBUS_CLEAR_FAULTS); +} + + +static int pmbus_check_status_cml(struct i2c_client *client) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + int status, status2; + + status = _pmbus_read_byte_data(client, -1, data->status_register); + if (status < 0 || (status & PB_STATUS_CML)) { + status2 = _pmbus_read_byte_data(client, -1, PMBUS_STATUS_CML); + if (status2 < 0 || (status2 & PB_CML_FAULT_INVALID_COMMAND)) + return -EIO; + } + return 0; +} + +static bool pmbus_check_register(struct i2c_client *client, + int (*func)(struct i2c_client *client, + int page, int reg), + int page, int reg) +{ + int rv; + struct pmbus_data *data = i2c_get_clientdata(client); + + if((data->flags & PMBUS_SKIP_STATUS_CHECK)) + return 1; + + rv = func(client, page, reg); + if (rv >= 0) + rv = pmbus_check_status_cml(client); + pmbus_clear_fault_page(client, -1); + return rv >= 0; +} + +static struct _pmbus_status { + u32 func; + u16 base; + u16 reg; +} pmbus_status[] = { + { PMBUS_HAVE_STATUS_VOUT, PB_STATUS_VOUT_BASE, PMBUS_STATUS_VOUT }, + { PMBUS_HAVE_STATUS_IOUT, PB_STATUS_IOUT_BASE, PMBUS_STATUS_IOUT }, + { PMBUS_HAVE_STATUS_TEMP, PB_STATUS_TEMP_BASE, + PMBUS_STATUS_TEMPERATURE + }, + { PMBUS_HAVE_STATUS_FAN12, PB_STATUS_FAN_BASE, PMBUS_STATUS_FAN_12 }, + { PMBUS_HAVE_STATUS_FAN34, PB_STATUS_FAN34_BASE, PMBUS_STATUS_FAN_34 }, +}; + +void _pmbus_clear_faults(struct i2c_client *client) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + int i; + + for (i = 0; i < data->info->pages; i++) + pmbus_clear_fault_page(client, i); +} +static struct pmbus_data *pmbus_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev->parent); + struct pmbus_data *data = i2c_get_clientdata(client); + const struct pmbus_driver_info *info = data->info; + struct pmbus_sensor *sensor; + + mutex_lock(&data->update_lock); + if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { + int i, j; + + for (i = 0; i < info->pages; i++) { + data->status[PB_STATUS_BASE + i] + = _pmbus_read_byte_data(client, i, + data->status_register); + for (j = 0; j < ARRAY_SIZE(pmbus_status); j++) { + struct _pmbus_status *s = &pmbus_status[j]; + + if (!(info->func[i] & s->func)) + continue; + data->status[s->base + i] + = _pmbus_read_byte_data(client, i, + s->reg); + } + } + + if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) + data->status[PB_STATUS_INPUT_BASE] + = _pmbus_read_byte_data(client, 0, + PMBUS_STATUS_INPUT); + + if (info->func[0] & PMBUS_HAVE_STATUS_VMON) + data->status[PB_STATUS_VMON_BASE] + = _pmbus_read_byte_data(client, 0, + PMBUS_VIRT_STATUS_VMON); + + for (sensor = data->sensors; sensor; sensor = sensor->next) { + if (!data->valid || sensor->update) + sensor->data + = _pmbus_read_word_data(client, + sensor->page, + sensor->reg); + } + _pmbus_clear_faults(client); + data->last_updated = jiffies; + data->valid = 1; + } + mutex_unlock(&data->update_lock); + return data; +} + +/* + * Convert linear sensor values to milli- or micro-units + * depending on sensor type. + */ +static long pmbus_reg2data_linear(struct pmbus_data *data, + struct pmbus_sensor *sensor) +{ + s16 exponent; + s32 mantissa; + long val; + + /* LINEAR16 */ + if ( data->linear_16 && + sensor->class == PSC_VOLTAGE_OUT) { + exponent = data->exponent[sensor->page]; + mantissa = (u16) sensor->data; + } else + { /* LINEAR11 */ + exponent = ((s16)sensor->data) >> 11; + mantissa = ((s16)((sensor->data & 0x7ff) << 5)) >> 5; + } + + val = mantissa; + + /* scale result to milli-units for all sensors except fans */ + if (sensor->class != PSC_FAN) + val = val * 1000L; + + /* scale result to micro-units for power sensors */ + if (sensor->class == PSC_POWER) + val = val * 1000L; + + if (exponent >= 0) + val <<= exponent; + else + val >>= -exponent; + + return val; +} + +/* + * Convert direct sensor values to milli- or micro-units + * depending on sensor type. + */ +static long pmbus_reg2data_direct(struct pmbus_data *data, + struct pmbus_sensor *sensor) +{ + long val = (s16) sensor->data; + long m, b, R; + + m = data->info->m[sensor->class]; + b = data->info->b[sensor->class]; + R = data->info->R[sensor->class]; + + if (m == 0) + return 0; + + /* X = 1/m * (Y * 10^-R - b) */ + R = -R; + /* scale result to milli-units for everything but fans */ + if (sensor->class != PSC_FAN) { + R += 3; + b *= 1000; + } + + /* scale result to micro-units for power sensors */ + if (sensor->class == PSC_POWER) { + R += 3; + b *= 1000; + } + + while (R > 0) { + val *= 10; + R--; + } + while (R < 0) { + val = DIV_ROUND_CLOSEST(val, 10); + R++; + } + + return (val - b) / m; +} + +/* + * Convert VID sensor values to milli- or micro-units + * depending on sensor type. + * We currently only support VR11. + */ +static long pmbus_reg2data_vid(struct pmbus_data *data, + struct pmbus_sensor *sensor) +{ + long val = sensor->data; + + if (val < 0x02 || val > 0xb2) + return 0; + return DIV_ROUND_CLOSEST(160000 - (val - 2) * 625, 100); +} + +static long pmbus_reg2data(struct pmbus_data *data, struct pmbus_sensor *sensor) +{ + long val; + + switch (data->info->format[sensor->class]) { + case direct: + val = pmbus_reg2data_direct(data, sensor); + break; + case vid: + val = pmbus_reg2data_vid(data, sensor); + break; + case linear: + default: + val = pmbus_reg2data_linear(data, sensor); + break; + } + return val; +} + +#define MAX_MANTISSA (1023 * 1000) +#define MIN_MANTISSA (511 * 1000) + +static u16 pmbus_data2reg_linear(struct pmbus_data *data, + struct pmbus_sensor *sensor, long val) +{ + s16 exponent = 0, mantissa; + bool negative = false; + + /* simple case */ + if (val == 0) + return 0; + + if (data->linear_16 && + sensor->class == PSC_VOLTAGE_OUT) { + /* LINEAR16 does not support negative voltages */ + if (val < 0) + return 0; + + /* + * For a static exponents, we don't have a choice + * but to adjust the value to it. + */ + if (data->exponent[sensor->page] < 0) + val <<= -data->exponent[sensor->page]; + else + val >>= data->exponent[sensor->page]; + val = DIV_ROUND_CLOSEST(val, 1000); + return val & 0xffff; + } + + if (val < 0) { + negative = true; + val = -val; + } + + /* Power is in uW. Convert to mW before converting. */ + if (sensor->class == PSC_POWER) + val = DIV_ROUND_CLOSEST(val, 1000L); + + /* + * For simplicity, convert fan data to milli-units + * before calculating the exponent. + */ + if (sensor->class == PSC_FAN) + val = val * 1000; + + /* Reduce large mantissa until it fits into 10 bit */ + while (val >= MAX_MANTISSA && exponent < 15) { + exponent++; + val >>= 1; + } + /* Increase small mantissa to improve precision */ + while (val < MIN_MANTISSA && exponent > -15) { + exponent--; + val <<= 1; + } + + /* Convert mantissa from milli-units to units */ + mantissa = DIV_ROUND_CLOSEST(val, 1000); + + /* Ensure that resulting number is within range */ + if (mantissa > 0x3ff) + mantissa = 0x3ff; + + /* restore sign */ + if (negative) + mantissa = -mantissa; + + /* Convert to 5 bit exponent, 11 bit mantissa */ + return (mantissa & 0x7ff) | ((exponent << 11) & 0xf800); +} + +static u16 pmbus_data2reg_direct(struct pmbus_data *data, + struct pmbus_sensor *sensor, long val) +{ + long m, b, R; + + m = data->info->m[sensor->class]; + b = data->info->b[sensor->class]; + R = data->info->R[sensor->class]; + + /* Power is in uW. Adjust R and b. */ + if (sensor->class == PSC_POWER) { + R -= 3; + b *= 1000; + } + + /* Calculate Y = (m * X + b) * 10^R */ + if (sensor->class != PSC_FAN) { + R -= 3; /* Adjust R and b for data in milli-units */ + b *= 1000; + } + val = val * m + b; + + while (R > 0) { + val *= 10; + R--; + } + while (R < 0) { + val = DIV_ROUND_CLOSEST(val, 10); + R++; + } + + return val; +} + +static u16 pmbus_data2reg_vid(struct pmbus_data *data, + struct pmbus_sensor *sensor, long val) +{ + val = clamp_val(val, 500, 1600); + + return 2 + DIV_ROUND_CLOSEST((1600 - val) * 100, 625); +} + +static u16 pmbus_data2reg(struct pmbus_data *data, + struct pmbus_sensor *sensor, long val) +{ + u16 regval; + + switch (data->info->format[sensor->class]) { + case direct: + regval = pmbus_data2reg_direct(data, sensor, val); + break; + case vid: + regval = pmbus_data2reg_vid(data, sensor, val); + break; + case linear: + default: + regval = pmbus_data2reg_linear(data, sensor, val); + break; + } + return regval; +} + +/* + * Return boolean calculated from converted data. + * defines a status register index and mask. + * The mask is in the lower 8 bits, the register index is in bits 8..23. + * + * The associated pmbus_boolean structure contains optional pointers to two + * sensor attributes. If specified, those attributes are compared against each + * other to determine if a limit has been exceeded. + * + * If the sensor attribute pointers are NULL, the function returns true if + * (status[reg] & mask) is true. + * + * If sensor attribute pointers are provided, a comparison against a specified + * limit has to be performed to determine the boolean result. + * In this case, the function returns true if v1 >= v2 (where v1 and v2 are + * sensor values referenced by sensor attribute pointers s1 and s2). + * + * To determine if an object exceeds upper limits, specify = . + * To determine if an object exceeds lower limits, specify = . + * + * If a negative value is stored in any of the referenced registers, this value + * reflects an error code which will be returned. + */ +static int pmbus_get_boolean(struct pmbus_data *data, struct pmbus_boolean *b, + int index) +{ + struct pmbus_sensor *s1 = b->s1; + struct pmbus_sensor *s2 = b->s2; + u16 reg = (index >> 8) & 0xffff; + u8 mask = index & 0xff; + int ret, status; + u8 regval; + + status = data->status[reg]; + if (status < 0) + return status; + + regval = status & mask; + if (!s1 && !s2) { + ret = !!regval; + } else if (!s1 || !s2) { + WARN(1, "Bad boolean descriptor %p: s1=%p, s2=%p\n", b, s1, s2); + return 0; + } else { + long v1, v2; + + if (s1->data < 0) + return s1->data; + if (s2->data < 0) + return s2->data; + + v1 = pmbus_reg2data(data, s1); + v2 = pmbus_reg2data(data, s2); + ret = !!(regval && v1 >= v2); + } + return ret; +} + +static ssize_t pmbus_show_boolean(struct device *dev, + struct device_attribute *da, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct pmbus_boolean *boolean = to_pmbus_boolean(attr); + struct pmbus_data *data = pmbus_update_device(dev); + int val; + + val = pmbus_get_boolean(data, boolean, attr->index); + if (val < 0) { + return snprintf(buf, PAGE_SIZE, "%d\n", 1); + } + return snprintf(buf, PAGE_SIZE, "%d\n", val); +} + +static ssize_t pmbus_show_sensor(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct pmbus_data *data = pmbus_update_device(dev); + struct pmbus_sensor *sensor = to_pmbus_sensor(devattr); + + + if (sensor->data < 0) { + return snprintf(buf, PAGE_SIZE, "%d\n", 0); + } + + + return snprintf(buf, PAGE_SIZE, "%ld\n", pmbus_reg2data(data, sensor)); +} + +static ssize_t pmbus_set_sensor(struct device *dev, + struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev->parent); + struct pmbus_data *data = i2c_get_clientdata(client); + struct pmbus_sensor *sensor = to_pmbus_sensor(devattr); + ssize_t rv = count; + long val = 0; + int ret; + u16 regval; + + if (kstrtol(buf, 10, &val) < 0) + return -EINVAL; + + mutex_lock(&data->update_lock); + regval = pmbus_data2reg(data, sensor, val); + ret = _pmbus_write_word_data(client, sensor->page, sensor->reg, regval); + if (ret < 0) + rv = ret; + else + sensor->data = regval; + mutex_unlock(&data->update_lock); + return rv; +} + +static ssize_t pmbus_show_label(struct device *dev, + struct device_attribute *da, char *buf) +{ + struct pmbus_label *label = to_pmbus_label(da); + + return snprintf(buf, PAGE_SIZE, "%s\n", label->label); +} + +static int pmbus_add_attribute(struct pmbus_data *data, struct attribute *attr) +{ + if (data->num_attributes >= data->max_attributes - 1) { + int new_max_attrs = data->max_attributes + PMBUS_ATTR_ALLOC_SIZE; + void *new_attrs = krealloc(data->group.attrs, + new_max_attrs * sizeof(void *), + GFP_KERNEL); + if (!new_attrs) + return -ENOMEM; + data->group.attrs = new_attrs; + data->max_attributes = new_max_attrs; + } + + + + data->group.attrs[data->num_attributes++] = attr; + data->group.attrs[data->num_attributes] = NULL; + return 0; +} + +static void pmbus_dev_attr_init(struct device_attribute *dev_attr, + const char *name, + umode_t mode, + ssize_t (*show)(struct device *dev, + struct device_attribute *attr, + char *buf), + ssize_t (*store)(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count)) +{ + sysfs_attr_init(&dev_attr->attr); + dev_attr->attr.name = name; + dev_attr->attr.mode = mode; + dev_attr->show = show; + dev_attr->store = store; +} + +static void pmbus_attr_init(struct sensor_device_attribute *a, + const char *name, + umode_t mode, + ssize_t (*show)(struct device *dev, + struct device_attribute *attr, + char *buf), + ssize_t (*store)(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count), + int idx) +{ + pmbus_dev_attr_init(&a->dev_attr, name, mode, show, store); + a->index = idx; +} + +static int pmbus_add_boolean(struct pmbus_data *data, + const char *name, const char *type, int seq, + struct pmbus_sensor *s1, + struct pmbus_sensor *s2, + u16 reg, u8 mask) +{ + struct pmbus_boolean *boolean; + struct sensor_device_attribute *a; + + boolean = devm_kzalloc(data->dev, sizeof(*boolean), GFP_KERNEL); + if (!boolean) + return -ENOMEM; + + a = &boolean->attribute; + + snprintf(boolean->name, sizeof(boolean->name), "%s%d_%s", + name, seq, type); + boolean->s1 = s1; + boolean->s2 = s2; + pmbus_attr_init(a, boolean->name, S_IRUGO, pmbus_show_boolean, NULL, + (reg << 8) | mask); + + return pmbus_add_attribute(data, &a->dev_attr.attr); +} + +static struct pmbus_sensor *pmbus_add_sensor(struct pmbus_data *data, + const char *name, const char *type, + int seq, int page, int reg, + enum pmbus_sensor_classes class, + bool update, bool readonly) +{ + struct pmbus_sensor *sensor; + struct device_attribute *a; + + sensor = devm_kzalloc(data->dev, sizeof(*sensor), GFP_KERNEL); + if (!sensor) + return NULL; + a = &sensor->attribute; + + snprintf(sensor->name, sizeof(sensor->name), "%s%d_%s", + name, seq, type); + sensor->page = page; + sensor->reg = reg; + sensor->class = class; + sensor->update = update; + pmbus_dev_attr_init(a, sensor->name, + readonly ? S_IRUGO : S_IRUGO | S_IWUSR, + pmbus_show_sensor, pmbus_set_sensor); + + if (pmbus_add_attribute(data, &a->attr)) + return NULL; + + sensor->next = data->sensors; + data->sensors = sensor; + + return sensor; +} + +static int pmbus_add_label(struct pmbus_data *data, + const char *name, int seq, + const char *lstring, int index) +{ + struct pmbus_label *label; + struct device_attribute *a; + + label = devm_kzalloc(data->dev, sizeof(*label), GFP_KERNEL); + if (!label) + return -ENOMEM; + + a = &label->attribute; + + snprintf(label->name, sizeof(label->name), "%s%d_label", name, seq); + if (!index) + strncpy(label->label, lstring, sizeof(label->label) - 1); + else + snprintf(label->label, sizeof(label->label), "%s%d", lstring, + index); + + pmbus_dev_attr_init(a, label->name, S_IRUGO, pmbus_show_label, NULL); + return pmbus_add_attribute(data, &a->attr); +} + +/* + * Search for attributes. Allocate sensors, booleans, and labels as needed. + */ + +/* + * The pmbus_limit_attr structure describes a single limit attribute + * and its associated alarm attribute. + */ +struct pmbus_limit_attr { + u16 reg; /* Limit register */ + u16 sbit; /* Alarm attribute status bit */ + bool update; /* True if register needs updates */ + bool low; /* True if low limit; for limits with compare + functions only */ + const char *attr; /* Attribute name */ + const char *alarm; /* Alarm attribute name */ +}; + +/* + * The pmbus_sensor_attr structure describes one sensor attribute. This + * description includes a reference to the associated limit attributes. + */ +struct pmbus_sensor_attr { + u16 reg; /* sensor register */ + u8 gbit; /* generic status bit */ + u8 nlimit; /* # of limit registers */ + enum pmbus_sensor_classes class;/* sensor class */ + const char *label; /* sensor label */ + bool paged; /* true if paged sensor */ + bool update; /* true if update needed */ + bool compare; /* true if compare function needed */ + u32 func; /* sensor mask */ + u32 sfunc; /* sensor status mask */ + int sbase; /* status base register */ + const struct pmbus_limit_attr *limit;/* limit registers */ +}; + +/* + * Add a set of limit attributes and, if supported, the associated + * alarm attributes. + * returns 0 if no alarm register found, 1 if an alarm register was found, + * < 0 on errors. + */ +static int pmbus_add_limit_attrs(struct i2c_client *client, + struct pmbus_data *data, + const struct pmbus_driver_info *info, + const char *name, int index, int page, + struct pmbus_sensor *base, + const struct pmbus_sensor_attr *attr) +{ + const struct pmbus_limit_attr *l = attr->limit; + int nlimit = attr->nlimit; + int have_alarm = 0; + int i, ret; + struct pmbus_sensor *curr; + + for (i = 0; i < nlimit; i++) { + if (_pmbus_check_word_register(client, page, l->reg)) + { + curr = pmbus_add_sensor(data, name, l->attr, index, + page, l->reg, attr->class, + attr->update || l->update, + false); + if (!curr) + return -ENOMEM; + if (l->sbit && (info->func[page] & attr->sfunc)) { + ret = pmbus_add_boolean(data, name, + l->alarm, index, + attr->compare ? l->low ? curr : base + : NULL, + attr->compare ? l->low ? base : curr + : NULL, + attr->sbase + page, l->sbit); + if (ret) + return ret; + have_alarm = 1; + } + } + l++; + } + return have_alarm; +} + +bool _pmbus_check_byte_register(struct i2c_client *client, int page, int reg) +{ + return pmbus_check_register(client, _pmbus_read_byte_data, page, reg); +} + + +bool _pmbus_check_word_register(struct i2c_client *client, int page, int reg) +{ + return pmbus_check_register(client, _pmbus_read_word_data, page, reg); +} + +static int pmbus_add_sensor_attrs_one(struct i2c_client *client, + struct pmbus_data *data, + const struct pmbus_driver_info *info, + const char *name, + int index, int page, + const struct pmbus_sensor_attr *attr) +{ + struct pmbus_sensor *base; + int ret; + + if (attr->label) { + ret = pmbus_add_label(data, name, index, attr->label, + attr->paged ? page + 1 : 0); + if (ret) + return ret; + } + base = pmbus_add_sensor(data, name, "input", index, page, attr->reg, + attr->class, true, true); + + + if (!base) + return -ENOMEM; + + if (attr->sfunc) { + ret = pmbus_add_limit_attrs(client, data, info, name, + index, page, base, attr); + if (ret < 0) + return ret; + /* + * Add generic alarm attribute only if there are no individual + * alarm attributes, if there is a global alarm bit, and if + * the generic status register for this page is accessible. + */ + if (!ret && attr->gbit && + _pmbus_check_byte_register(client, page, + data->status_register)) { + ret = pmbus_add_boolean(data, name, "alarm", index, + NULL, NULL, + PB_STATUS_BASE + page, + attr->gbit); + if (ret) + return ret; + } + } + return 0; +} + +static int pmbus_add_sensor_attrs(struct i2c_client *client, + struct pmbus_data *data, + const char *name, + const struct pmbus_sensor_attr *attrs, + int nattrs) +{ + const struct pmbus_driver_info *info = data->info; + int index, i; + int ret; + + index = 1; + for (i = 0; i < nattrs; i++) { + int page, pages; + + pages = attrs->paged ? info->pages : 1; + for (page = 0; page < pages; page++) { + if (!(info->func[page] & attrs->func)) + continue; + ret = pmbus_add_sensor_attrs_one(client, data, info, + name, index, page, + attrs); + if (ret) + return ret; + index++; + } + attrs++; + } + return 0; +} + +static const struct pmbus_limit_attr vin_limit_attrs[] = { + { + .reg = PMBUS_VIN_UV_WARN_LIMIT, + .attr = "min", + .alarm = "min_alarm", + .sbit = PB_VOLTAGE_UV_WARNING, + }, { + .reg = PMBUS_VIN_UV_FAULT_LIMIT, + .attr = "lcrit", + .alarm = "lcrit_alarm", + .sbit = PB_VOLTAGE_UV_FAULT, + }, { + .reg = PMBUS_VIN_OV_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_VOLTAGE_OV_WARNING, + }, { + .reg = PMBUS_VIN_OV_FAULT_LIMIT, + .attr = "crit", + .alarm = "crit_alarm", + .sbit = PB_VOLTAGE_OV_FAULT, + }, { + .reg = PMBUS_VIRT_READ_VIN_AVG, + .update = true, + .attr = "average", + }, { + .reg = PMBUS_VIRT_READ_VIN_MIN, + .update = true, + .attr = "lowest", + }, { + .reg = PMBUS_VIRT_READ_VIN_MAX, + .update = true, + .attr = "highest", + }, { + .reg = PMBUS_VIRT_RESET_VIN_HISTORY, + .attr = "reset_history", + }, +}; + +static const struct pmbus_limit_attr vmon_limit_attrs[] = { + { + .reg = PMBUS_VIRT_VMON_UV_WARN_LIMIT, + .attr = "min", + .alarm = "min_alarm", + .sbit = PB_VOLTAGE_UV_WARNING, + }, { + .reg = PMBUS_VIRT_VMON_UV_FAULT_LIMIT, + .attr = "lcrit", + .alarm = "lcrit_alarm", + .sbit = PB_VOLTAGE_UV_FAULT, + }, { + .reg = PMBUS_VIRT_VMON_OV_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_VOLTAGE_OV_WARNING, + }, { + .reg = PMBUS_VIRT_VMON_OV_FAULT_LIMIT, + .attr = "crit", + .alarm = "crit_alarm", + .sbit = PB_VOLTAGE_OV_FAULT, + } +}; + +static const struct pmbus_limit_attr vout_limit_attrs[] = { + { + .reg = PMBUS_VOUT_UV_WARN_LIMIT, + .attr = "min", + .alarm = "min_alarm", + .sbit = PB_VOLTAGE_UV_WARNING, + }, { + .reg = PMBUS_VOUT_UV_FAULT_LIMIT, + .attr = "lcrit", + .alarm = "lcrit_alarm", + .sbit = PB_VOLTAGE_UV_FAULT, + }, { + .reg = PMBUS_VOUT_OV_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_VOLTAGE_OV_WARNING, + }, { + .reg = PMBUS_VOUT_OV_FAULT_LIMIT, + .attr = "crit", + .alarm = "crit_alarm", + .sbit = PB_VOLTAGE_OV_FAULT, + }, { + .reg = PMBUS_VIRT_READ_VOUT_AVG, + .update = true, + .attr = "average", + }, { + .reg = PMBUS_VIRT_READ_VOUT_MIN, + .update = true, + .attr = "lowest", + }, { + .reg = PMBUS_VIRT_READ_VOUT_MAX, + .update = true, + .attr = "highest", + }, { + .reg = PMBUS_VIRT_RESET_VOUT_HISTORY, + .attr = "reset_history", + } +}; + +static const struct pmbus_sensor_attr voltage_attributes[] = { + { + .reg = PMBUS_READ_VIN, + .class = PSC_VOLTAGE_IN, + .label = "vin", + .func = PMBUS_HAVE_VIN, + .sfunc = PMBUS_HAVE_STATUS_INPUT, + .sbase = PB_STATUS_INPUT_BASE, + .gbit = PB_STATUS_VIN_UV, + .limit = vin_limit_attrs, + .nlimit = ARRAY_SIZE(vin_limit_attrs), + }, { + .reg = PMBUS_VIRT_READ_VMON, + .class = PSC_VOLTAGE_IN, + .label = "vmon", + .func = PMBUS_HAVE_VMON, + .sfunc = PMBUS_HAVE_STATUS_VMON, + .sbase = PB_STATUS_VMON_BASE, + .limit = vmon_limit_attrs, + .nlimit = ARRAY_SIZE(vmon_limit_attrs), + }, { + .reg = PMBUS_READ_VCAP, + .class = PSC_VOLTAGE_IN, + .label = "vcap", + .func = PMBUS_HAVE_VCAP, + }, { + .reg = PMBUS_READ_VOUT, + .class = PSC_VOLTAGE_OUT, + .label = "vout", + .paged = true, + .func = PMBUS_HAVE_VOUT, + .sfunc = PMBUS_HAVE_STATUS_VOUT, + .sbase = PB_STATUS_VOUT_BASE, + .gbit = PB_STATUS_VOUT_OV, + .limit = vout_limit_attrs, + .nlimit = ARRAY_SIZE(vout_limit_attrs), + } +}; + +/* Current attributes */ + +static const struct pmbus_limit_attr iin_limit_attrs[] = { + { + .reg = PMBUS_IIN_OC_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_IIN_OC_WARNING, + }, { + .reg = PMBUS_IIN_OC_FAULT_LIMIT, + .attr = "crit", + .alarm = "crit_alarm", + .sbit = PB_IIN_OC_FAULT, + }, { + .reg = PMBUS_VIRT_READ_IIN_AVG, + .update = true, + .attr = "average", + }, { + .reg = PMBUS_VIRT_READ_IIN_MIN, + .update = true, + .attr = "lowest", + }, { + .reg = PMBUS_VIRT_READ_IIN_MAX, + .update = true, + .attr = "highest", + }, { + .reg = PMBUS_VIRT_RESET_IIN_HISTORY, + .attr = "reset_history", + } +}; + +static const struct pmbus_limit_attr iout_limit_attrs[] = { + { + .reg = PMBUS_IOUT_OC_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_IOUT_OC_WARNING, + }, { + .reg = PMBUS_IOUT_UC_FAULT_LIMIT, + .attr = "lcrit", + .alarm = "lcrit_alarm", + .sbit = PB_IOUT_UC_FAULT, + }, { + .reg = PMBUS_IOUT_OC_FAULT_LIMIT, + .attr = "crit", + .alarm = "crit_alarm", + .sbit = PB_IOUT_OC_FAULT, + }, { + .reg = PMBUS_VIRT_READ_IOUT_AVG, + .update = true, + .attr = "average", + }, { + .reg = PMBUS_VIRT_READ_IOUT_MIN, + .update = true, + .attr = "lowest", + }, { + .reg = PMBUS_VIRT_READ_IOUT_MAX, + .update = true, + .attr = "highest", + }, { + .reg = PMBUS_VIRT_RESET_IOUT_HISTORY, + .attr = "reset_history", + } +}; + +static const struct pmbus_sensor_attr current_attributes[] = { + { + .reg = PMBUS_READ_IIN, + .class = PSC_CURRENT_IN, + .label = "iin", + .func = PMBUS_HAVE_IIN, + .sfunc = PMBUS_HAVE_STATUS_INPUT, + .sbase = PB_STATUS_INPUT_BASE, + .limit = iin_limit_attrs, + .nlimit = ARRAY_SIZE(iin_limit_attrs), + }, { + .reg = PMBUS_READ_IOUT, + .class = PSC_CURRENT_OUT, + .label = "iout", + .paged = true, + .func = PMBUS_HAVE_IOUT, + .sfunc = PMBUS_HAVE_STATUS_IOUT, + .sbase = PB_STATUS_IOUT_BASE, + .gbit = PB_STATUS_IOUT_OC, + .limit = iout_limit_attrs, + .nlimit = ARRAY_SIZE(iout_limit_attrs), + } +}; + +/* Power attributes */ + +static const struct pmbus_limit_attr pin_limit_attrs[] = { + { + .reg = PMBUS_PIN_OP_WARN_LIMIT, + .attr = "max", + .alarm = "alarm", + .sbit = PB_PIN_OP_WARNING, + }, { + .reg = PMBUS_VIRT_READ_PIN_AVG, + .update = true, + .attr = "average", + }, { + .reg = PMBUS_VIRT_READ_PIN_MAX, + .update = true, + .attr = "input_highest", + }, { + .reg = PMBUS_VIRT_RESET_PIN_HISTORY, + .attr = "reset_history", + } +}; + +static const struct pmbus_limit_attr pout_limit_attrs[] = { + { + .reg = PMBUS_POUT_MAX, + .attr = "cap", + .alarm = "cap_alarm", + .sbit = PB_POWER_LIMITING, + }, { + .reg = PMBUS_POUT_OP_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_POUT_OP_WARNING, + }, { + .reg = PMBUS_POUT_OP_FAULT_LIMIT, + .attr = "crit", + .alarm = "crit_alarm", + .sbit = PB_POUT_OP_FAULT, + }, { + .reg = PMBUS_VIRT_READ_POUT_AVG, + .update = true, + .attr = "average", + }, { + .reg = PMBUS_VIRT_READ_POUT_MAX, + .update = true, + .attr = "input_highest", + }, { + .reg = PMBUS_VIRT_RESET_POUT_HISTORY, + .attr = "reset_history", + } +}; + +static const struct pmbus_sensor_attr power_attributes[] = { + { + .reg = PMBUS_READ_PIN, + .class = PSC_POWER, + .label = "pin", + .func = PMBUS_HAVE_PIN, + .sfunc = PMBUS_HAVE_STATUS_INPUT, + .sbase = PB_STATUS_INPUT_BASE, + .limit = pin_limit_attrs, + .nlimit = ARRAY_SIZE(pin_limit_attrs), + }, { + .reg = PMBUS_READ_POUT, + .class = PSC_POWER, + .label = "pout", + .paged = true, + .func = PMBUS_HAVE_POUT, + .sfunc = PMBUS_HAVE_STATUS_IOUT, + .sbase = PB_STATUS_IOUT_BASE, + .limit = pout_limit_attrs, + .nlimit = ARRAY_SIZE(pout_limit_attrs), + } +}; + +/* Temperature atributes */ + +static const struct pmbus_limit_attr temp_limit_attrs[] = { + { + .reg = PMBUS_UT_WARN_LIMIT, + .low = true, + .attr = "min", + .alarm = "min_alarm", + .sbit = PB_TEMP_UT_WARNING, + }, { + .reg = PMBUS_UT_FAULT_LIMIT, + .low = true, + .attr = "lcrit", + .alarm = "lcrit_alarm", + .sbit = PB_TEMP_UT_FAULT, + }, { + .reg = PMBUS_OT_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_TEMP_OT_WARNING, + }, { + .reg = PMBUS_OT_FAULT_LIMIT, + .attr = "crit", + .alarm = "crit_alarm", + .sbit = PB_TEMP_OT_FAULT, + }, { + .reg = PMBUS_VIRT_READ_TEMP_MIN, + .attr = "lowest", + }, { + .reg = PMBUS_VIRT_READ_TEMP_AVG, + .attr = "average", + }, { + .reg = PMBUS_VIRT_READ_TEMP_MAX, + .attr = "highest", + }, { + .reg = PMBUS_VIRT_RESET_TEMP_HISTORY, + .attr = "reset_history", + } +}; + +static const struct pmbus_limit_attr temp_limit_attrs2[] = { + { + .reg = PMBUS_UT_WARN_LIMIT, + .low = true, + .attr = "min", + .alarm = "min_alarm", + .sbit = PB_TEMP_UT_WARNING, + }, { + .reg = PMBUS_UT_FAULT_LIMIT, + .low = true, + .attr = "lcrit", + .alarm = "lcrit_alarm", + .sbit = PB_TEMP_UT_FAULT, + }, { + .reg = PMBUS_OT_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_TEMP_OT_WARNING, + }, { + .reg = PMBUS_OT_FAULT_LIMIT, + .attr = "crit", + .alarm = "crit_alarm", + .sbit = PB_TEMP_OT_FAULT, + }, { + .reg = PMBUS_VIRT_READ_TEMP2_MIN, + .attr = "lowest", + }, { + .reg = PMBUS_VIRT_READ_TEMP2_AVG, + .attr = "average", + }, { + .reg = PMBUS_VIRT_READ_TEMP2_MAX, + .attr = "highest", + }, { + .reg = PMBUS_VIRT_RESET_TEMP2_HISTORY, + .attr = "reset_history", + } +}; + +static const struct pmbus_limit_attr temp_limit_attrs3[] = { + { + .reg = PMBUS_UT_WARN_LIMIT, + .low = true, + .attr = "min", + .alarm = "min_alarm", + .sbit = PB_TEMP_UT_WARNING, + }, { + .reg = PMBUS_UT_FAULT_LIMIT, + .low = true, + .attr = "lcrit", + .alarm = "lcrit_alarm", + .sbit = PB_TEMP_UT_FAULT, + }, { + .reg = PMBUS_OT_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_TEMP_OT_WARNING, + }, { + .reg = PMBUS_OT_FAULT_LIMIT, + .attr = "crit", + .alarm = "crit_alarm", + .sbit = PB_TEMP_OT_FAULT, + } +}; + +static const struct pmbus_sensor_attr temp_attributes[] = { + { + .reg = PMBUS_READ_TEMPERATURE_1, + .class = PSC_TEMPERATURE, + .paged = true, + .update = true, + .compare = true, + .func = PMBUS_HAVE_TEMP, + .sfunc = PMBUS_HAVE_STATUS_TEMP, + .sbase = PB_STATUS_TEMP_BASE, + .gbit = PB_STATUS_TEMPERATURE, + .limit = temp_limit_attrs, + .nlimit = ARRAY_SIZE(temp_limit_attrs), + }, { + .reg = PMBUS_READ_TEMPERATURE_2, + .class = PSC_TEMPERATURE, + .paged = true, + .update = true, + .compare = true, + .func = PMBUS_HAVE_TEMP2, + .sfunc = PMBUS_HAVE_STATUS_TEMP, + .sbase = PB_STATUS_TEMP_BASE, + .gbit = PB_STATUS_TEMPERATURE, + .limit = temp_limit_attrs2, + .nlimit = ARRAY_SIZE(temp_limit_attrs2), + }, { + .reg = PMBUS_READ_TEMPERATURE_3, + .class = PSC_TEMPERATURE, + .paged = true, + .update = true, + .compare = true, + .func = PMBUS_HAVE_TEMP3, + .sfunc = PMBUS_HAVE_STATUS_TEMP, + .sbase = PB_STATUS_TEMP_BASE, + .gbit = PB_STATUS_TEMPERATURE, + .limit = temp_limit_attrs3, + .nlimit = ARRAY_SIZE(temp_limit_attrs3), + } +}; + +static const int pmbus_fan_registers[] = { + PMBUS_READ_FAN_SPEED_1, + PMBUS_READ_FAN_SPEED_2, + PMBUS_READ_FAN_SPEED_3, + PMBUS_READ_FAN_SPEED_4 +}; + +static const int pmbus_fan_config_registers[] = { + PMBUS_FAN_CONFIG_12, + PMBUS_FAN_CONFIG_12, + PMBUS_FAN_CONFIG_34, + PMBUS_FAN_CONFIG_34 +}; + +static const int pmbus_fan_status_registers[] = { + PMBUS_STATUS_FAN_12, + PMBUS_STATUS_FAN_12, + PMBUS_STATUS_FAN_34, + PMBUS_STATUS_FAN_34 +}; + +static const u32 pmbus_fan_flags[] = { + PMBUS_HAVE_FAN12, + PMBUS_HAVE_FAN12, + PMBUS_HAVE_FAN34, + PMBUS_HAVE_FAN34 +}; + +static const u32 pmbus_fan_status_flags[] = { + PMBUS_HAVE_STATUS_FAN12, + PMBUS_HAVE_STATUS_FAN12, + PMBUS_HAVE_STATUS_FAN34, + PMBUS_HAVE_STATUS_FAN34 +}; + +/* Fans */ +static int pmbus_add_fan_attributes(struct i2c_client *client, + struct pmbus_data *data) +{ + const struct pmbus_driver_info *info = data->info; + int index = 1; + int page; + int ret; + + for (page = 0; page < info->pages; page++) { + int f; + + for (f = 0; f < ARRAY_SIZE(pmbus_fan_registers); f++) { + int regval; + + if (f >= info->fan_num) + break; + + if (!(info->func[page] & pmbus_fan_flags[f])) + break; + + if (!_pmbus_check_word_register(client, page, + pmbus_fan_registers[f])) + break; + + /* + * Skip fan if not installed. + * Each fan configuration register covers multiple fans, + * so we have to do some magic. + */ + regval = _pmbus_read_byte_data(client, page, + pmbus_fan_config_registers[f]); + if (regval < 0 || + (!(regval & (PB_FAN_1_INSTALLED >> ((f & 1) * 4))))) + continue; + + if (pmbus_add_sensor(data, "fan", "input", index, + page, pmbus_fan_registers[f], + PSC_FAN, true, true) == NULL) + return -ENOMEM; + + /* + * Each fan status register covers multiple fans, + * so we have to do some magic. + */ + if ((info->func[page] & pmbus_fan_status_flags[f]) && + _pmbus_check_byte_register(client, + page, pmbus_fan_status_registers[f])) { + int base; + + if (f > 1) /* fan 3, 4 */ + base = PB_STATUS_FAN34_BASE + page; + else + base = PB_STATUS_FAN_BASE + page; + ret = pmbus_add_boolean(data, "fan", + "alarm", index, NULL, NULL, base, + PB_FAN_FAN1_WARNING >> (f & 1)); + if (ret) + return ret; + ret = pmbus_add_boolean(data, "fan", + "fault", index, NULL, NULL, base, + PB_FAN_FAN1_FAULT >> (f & 1)); + if (ret) + return ret; + } + index++; + } + } + return 0; +} + +static int pmbus_find_attributes(struct i2c_client *client, + struct pmbus_data *data) +{ + int ret; + + /* Voltage sensors */ + ret = pmbus_add_sensor_attrs(client, data, "in", voltage_attributes, + ARRAY_SIZE(voltage_attributes)); + if (ret) + return ret; + + /* Current sensors */ + ret = pmbus_add_sensor_attrs(client, data, "curr", current_attributes, + ARRAY_SIZE(current_attributes)); + if (ret) + return ret; + + /* Power sensors */ + ret = pmbus_add_sensor_attrs(client, data, "power", power_attributes, + ARRAY_SIZE(power_attributes)); + if (ret) + return ret; + + /* Temperature sensors */ + ret = pmbus_add_sensor_attrs(client, data, "temp", temp_attributes, + ARRAY_SIZE(temp_attributes)); + if (ret) + return ret; + + /* Fans */ + ret = pmbus_add_fan_attributes(client, data); + return ret; +} + +/* + * Identify chip parameters. + * This function is called for all chips. + */ +static int pmbus_identify_common(struct i2c_client *client, + struct pmbus_data *data, int page) +{ + int vout_mode = -1; + + if (_pmbus_check_byte_register(client, page, PMBUS_VOUT_MODE)) + { + vout_mode = _pmbus_read_byte_data(client, page, + PMBUS_VOUT_MODE); + } + + if (vout_mode >= 0 && vout_mode != 0xff) { + /* + * Not all chips support the VOUT_MODE command, + * so a failure to read it is not an error. + */ + switch (vout_mode >> 5) { + case 0: /* linear mode */ + if (data->info->format[PSC_VOLTAGE_OUT] != linear) + return -ENODEV; + + data->exponent[page] = ((s8)(vout_mode << 3)) >> 3; + break; + case 1: /* VID mode */ + if (data->info->format[PSC_VOLTAGE_OUT] != vid) + return -ENODEV; + break; + case 2: /* direct mode */ + if (data->info->format[PSC_VOLTAGE_OUT] != direct) + return -ENODEV; + break; + default: + return -ENODEV; + } + } + + pmbus_clear_fault_page(client, page); + return 0; +} + +static int pmbus_init_common(struct i2c_client *client, struct pmbus_data *data, + struct pmbus_driver_info *info) +{ + struct device *dev = &client->dev; + int page, ret; + + /* + * Some PMBus chips don't support PMBUS_STATUS_BYTE, so try + * to use PMBUS_STATUS_WORD instead if that is the case. + * Bail out if both registers are not supported. + */ + if(0) { /*Skip this for the i2c access may fail if PSU is not powered.*/ + data->status_register = PMBUS_STATUS_BYTE; + ret = i2c_smbus_read_byte_data(client, PMBUS_STATUS_BYTE); + if (ret < 0 || ret == 0xff) { + data->status_register = PMBUS_STATUS_WORD; + ret = i2c_smbus_read_word_data(client, PMBUS_STATUS_WORD); + if (ret < 0 || ret == 0xffff) { + dev_err(dev, "PMBus status register not found\n"); + return -ENODEV; + } + } + } + _pmbus_clear_faults(client); + + if (info->identify) { + ret = (*info->identify)(client, info); + if (ret < 0) { + dev_err(dev, "Chip identification failed\n"); + return ret; + } + } + + if (info->pages <= 0 || info->pages > PMBUS_PAGES) { + dev_err(dev, "Bad number of PMBus pages: %d\n", info->pages); + return -ENODEV; + } + + for (page = 0; page < info->pages; page++) { + ret = pmbus_identify_common(client, data, page); + if (ret < 0) { + dev_err(dev, "Failed to identify chip capabilities\n"); + return ret; + } + } + return 0; +} + +int _pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, + struct pmbus_driver_info *info) +{ + struct device *dev = &client->dev; + struct pmbus_data *data; + int ret; + + if (!info) + return -ENODEV; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE + | I2C_FUNC_SMBUS_BYTE_DATA + | I2C_FUNC_SMBUS_WORD_DATA)) + return -ENODEV; + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->dev = dev; + + if (limited_models(id)) + { + data->flags |= PMBUS_SKIP_STATUS_CHECK; + info->pages = 1; + info->fan_num = 1; + data->linear_16 = 0; + } + else + { + info->pages = id->driver_data; + info->fan_num = 4; + data->linear_16 = 1; + + } + + data->info = info; + + ret = pmbus_init_common(client, data, info); + if (ret < 0) + return ret; + + ret = pmbus_find_attributes(client, data); + if (ret) + goto out_kfree; + + /* + * If there are no attributes, something is wrong. + * Bail out instead of trying to register nothing. + */ + if (!data->num_attributes) { + dev_err(dev, "No attributes found\n"); + ret = -ENODEV; + goto out_kfree; + } + + data->groups[0] = &data->group; + data->hwmon_dev = hwmon_device_register_with_groups(dev, client->name, + data, data->groups); + if (IS_ERR(data->hwmon_dev)) { + ret = PTR_ERR(data->hwmon_dev); + dev_err(dev, "Failed to register hwmon device\n"); + goto out_kfree; + } + return 0; + +out_kfree: + kfree(data->group.attrs); + return ret; +} + +/* + * Find sensor groups and status registers on each page. + */ +static void pmbus_find_sensor_groups(struct i2c_client *client, + struct pmbus_driver_info *info) +{ + int page; + + /* For i2c might not available when this driver installing, + turn on all attributes but VMON and FAN34.*/ + info->func[0] |= 0x1feff; + return ; + + + /* Sensors detected on page 0 only */ + if (_pmbus_check_word_register(client, 0, PMBUS_READ_VIN)) + info->func[0] |= PMBUS_HAVE_VIN; + if (_pmbus_check_word_register(client, 0, PMBUS_READ_VCAP)) + info->func[0] |= PMBUS_HAVE_VCAP; + if (_pmbus_check_word_register(client, 0, PMBUS_READ_IIN)) + info->func[0] |= PMBUS_HAVE_IIN; + if (_pmbus_check_word_register(client, 0, PMBUS_READ_PIN)) + info->func[0] |= PMBUS_HAVE_PIN; + if (info->func[0] + && _pmbus_check_byte_register(client, 0, PMBUS_STATUS_INPUT)) + info->func[0] |= PMBUS_HAVE_STATUS_INPUT; + if (info->fan_num > 0) + { + if (_pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_12) && + _pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_1)) { + info->func[0] |= PMBUS_HAVE_FAN12; + if (_pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_12)) + info->func[0] |= PMBUS_HAVE_STATUS_FAN12; + } + } + if (info->fan_num > 2) + { + if (_pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_34) && + _pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_3)) { + info->func[0] |= PMBUS_HAVE_FAN34; + if (_pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_34)) + info->func[0] |= PMBUS_HAVE_STATUS_FAN34; + } + } + + if (_pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_1)) + info->func[0] |= PMBUS_HAVE_TEMP; + if (_pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_2)) + info->func[0] |= PMBUS_HAVE_TEMP2; + if (_pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_3)) + info->func[0] |= PMBUS_HAVE_TEMP3; + + if (info->func[0] & (PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 + | PMBUS_HAVE_TEMP3) + && _pmbus_check_byte_register(client, 0, + PMBUS_STATUS_TEMPERATURE)) + info->func[0] |= PMBUS_HAVE_STATUS_TEMP; + + /* Sensors detected on all pages */ + for (page = 0; page < info->pages; page++) { + if (_pmbus_check_word_register(client, page, PMBUS_READ_VOUT)) { + info->func[page] |= PMBUS_HAVE_VOUT; + if (_pmbus_check_byte_register(client, page, + PMBUS_STATUS_VOUT)) + info->func[page] |= PMBUS_HAVE_STATUS_VOUT; + } + if (_pmbus_check_word_register(client, page, PMBUS_READ_IOUT)) { + info->func[page] |= PMBUS_HAVE_IOUT; + if (_pmbus_check_byte_register(client, 0, + PMBUS_STATUS_IOUT)) + info->func[page] |= PMBUS_HAVE_STATUS_IOUT; + } + if (_pmbus_check_word_register(client, page, PMBUS_READ_POUT)) + info->func[page] |= PMBUS_HAVE_POUT; + } +} + +/* + * Identify chip parameters. + */ +static int pmbus_identify(struct i2c_client *client, + struct pmbus_driver_info *info) +{ + int ret = 0; + + if (!info->pages) { + /* + * Check if the PAGE command is supported. If it is, + * keep setting the page number until it fails or until the + * maximum number of pages has been reached. Assume that + * this is the number of pages supported by the chip. + */ + if (_pmbus_check_byte_register(client, 0, PMBUS_PAGE)) { + int page; + + for (page = 1; page < PMBUS_PAGES; page++) { + if (_pmbus_set_page(client, page) < 0) + break; + } + _pmbus_set_page(client, 0); + info->pages = page; + } else { + info->pages = 1; + } + } + + if (_pmbus_check_byte_register(client, 0, PMBUS_VOUT_MODE)) { + int vout_mode; + + vout_mode = _pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE); + if (vout_mode >= 0 && vout_mode != 0xff) { + switch (vout_mode >> 5) { + case 0: + break; + case 1: + info->format[PSC_VOLTAGE_OUT] = vid; + break; + case 2: + info->format[PSC_VOLTAGE_OUT] = direct; + break; + default: + ret = -ENODEV; + goto abort; + } + } + } + + + /* + * We should check if the COEFFICIENTS register is supported. + * If it is, and the chip is configured for direct mode, we can read + * the coefficients from the chip, one set per group of sensor + * registers. + * + * To do this, we will need access to a chip which actually supports the + * COEFFICIENTS command, since the command is too complex to implement + * without testing it. Until then, abort if a chip configured for direct + * mode was detected. + */ + if (info->format[PSC_VOLTAGE_OUT] == direct) { + ret = -ENODEV; + goto abort; + } + + /* Try to find sensor groups */ + pmbus_find_sensor_groups(client, info); +abort: + return ret; +} + +/* + * Use driver_data to set the number of pages supported by the chip. + */ +static const struct i2c_device_id pmbus_id[] = { + { "accton_ym2651", YM2651 }, + { "accton_ym2401", YM2401 }, + { "accton_ym2851", YM2851 }, + {} +}; + +static int limited_models(const struct i2c_device_id *id) +{ + int j; + + if (!id->name) + return 0; + + for (j = 0; j < ARRAY_SIZE(pmbus_id); j++) { + if (!pmbus_id[j].name) + continue; + + if (!strcmp(id->name, pmbus_id[j].name)) + { + if(id->driver_data < LIMITED_CHIPS) + { + return 1; + } + else + { + return 0; + } + } + + } + + return 0; +} + +static int pmbus_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct pmbus_driver_info *info; + + info = devm_kzalloc(&client->dev, sizeof(struct pmbus_driver_info), + GFP_KERNEL); + if (!info) + return -ENOMEM; + + info->identify = pmbus_identify; + + return _pmbus_do_probe(client, id, info); +} + +int _pmbus_do_remove(struct i2c_client *client) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + kfree(data->group.attrs); + return 0; +} + +MODULE_DEVICE_TABLE(i2c, pmbus_id); + +/* This is the driver that will be inserted */ +static struct i2c_driver pmbus_driver = { + .driver = { + .name = "accton_pmbus_3y", + }, + .probe = pmbus_probe, + .remove = _pmbus_do_remove, + .id_table = pmbus_id, +}; + +module_i2c_driver(pmbus_driver); + +MODULE_AUTHOR("Roy Lee"); +MODULE_DESCRIPTION("Accton PMBus driver for 3Y Power YM-2651Y."); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-accton/common/modules/cpr_4011_4mxx.c b/platform/broadcom/sonic-platform-modules-accton/common/modules/cpr_4011_4mxx.c new file mode 100644 index 000000000000..2cea5f5e39f9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/common/modules/cpr_4011_4mxx.c @@ -0,0 +1,402 @@ +/* + * An hwmon driver for the CPR-4011-4Mxx Redundant Power Module + * + * Copyright (C) Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#if 0 +#define DEBUG +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_FAN_DUTY_CYCLE 100 + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { 0x3c, 0x3d, 0x3e, 0x3f, I2C_CLIENT_END }; + +/* Each client has this additional data + */ +struct cpr_4011_4mxx_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 vout_mode; /* Register value */ + u16 v_in; /* Register value */ + u16 v_out; /* Register value */ + u16 i_in; /* Register value */ + u16 i_out; /* Register value */ + u16 p_in; /* Register value */ + u16 p_out; /* Register value */ + u16 temp_input[2]; /* Register value */ + u8 fan_fault; /* Register value */ + u16 fan_duty_cycle[2]; /* Register value */ + u16 fan_speed[2]; /* Register value */ +}; + +static ssize_t show_linear(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_vout(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static int cpr_4011_4mxx_write_word(struct i2c_client *client, u8 reg, u16 value); +static struct cpr_4011_4mxx_data *cpr_4011_4mxx_update_device(struct device *dev); + +enum cpr_4011_4mxx_sysfs_attributes { + PSU_V_IN, + PSU_V_OUT, + PSU_I_IN, + PSU_I_OUT, + PSU_P_IN, + PSU_P_OUT, + PSU_TEMP1_INPUT, + PSU_FAN1_FAULT, + PSU_FAN1_DUTY_CYCLE, + PSU_FAN1_SPEED, +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(psu_v_in, S_IRUGO, show_linear, NULL, PSU_V_IN); +static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, show_vout, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(psu_i_in, S_IRUGO, show_linear, NULL, PSU_I_IN); +static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, show_linear, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(psu_p_in, S_IRUGO, show_linear, NULL, PSU_P_IN); +static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, show_linear, NULL, PSU_P_OUT); +static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, show_fan_fault, NULL, PSU_FAN1_FAULT); +static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, show_linear, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); +static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); + +static struct attribute *cpr_4011_4mxx_attributes[] = { + &sensor_dev_attr_psu_v_in.dev_attr.attr, + &sensor_dev_attr_psu_v_out.dev_attr.attr, + &sensor_dev_attr_psu_i_in.dev_attr.attr, + &sensor_dev_attr_psu_i_out.dev_attr.attr, + &sensor_dev_attr_psu_p_in.dev_attr.attr, + &sensor_dev_attr_psu_p_out.dev_attr.attr, + &sensor_dev_attr_psu_temp1_input.dev_attr.attr, + &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, + &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, + &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, + NULL +}; + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + bool is_negative = valid_data >> (valid_bit - 1); + + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} + +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpr_4011_4mxx_data *data = i2c_get_clientdata(client); + int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; + long speed; + int error; + + error = kstrtol(buf, 10, &speed); + if (error) + return error; + + if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) + return -EINVAL; + + mutex_lock(&data->update_lock); + data->fan_duty_cycle[nr] = speed; + cpr_4011_4mxx_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t show_linear(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct cpr_4011_4mxx_data *data = cpr_4011_4mxx_update_device(dev); + + u16 value = 0; + int exponent, mantissa; + int multiplier = 1000; + + switch (attr->index) { + case PSU_V_IN: + value = data->v_in; + break; + case PSU_I_IN: + value = data->i_in; + break; + case PSU_I_OUT: + value = data->i_out; + break; + case PSU_P_IN: + value = data->p_in; + break; + case PSU_P_OUT: + value = data->p_out; + break; + case PSU_TEMP1_INPUT: + value = data->temp_input[0]; + break; + case PSU_FAN1_DUTY_CYCLE: + multiplier = 1; + value = data->fan_duty_cycle[0]; + break; + case PSU_FAN1_SPEED: + multiplier = 1; + value = data->fan_speed[0]; + break; + default: + break; + } + + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + + return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct cpr_4011_4mxx_data *data = cpr_4011_4mxx_update_device(dev); + + u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; + + return sprintf(buf, "%d\n", data->fan_fault >> shift); +} + +static ssize_t show_vout(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct cpr_4011_4mxx_data *data = cpr_4011_4mxx_update_device(dev); + int exponent, mantissa; + int multiplier = 1000; + + exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); + mantissa = data->v_out; + + return (exponent > 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static const struct attribute_group cpr_4011_4mxx_group = { + .attrs = cpr_4011_4mxx_attributes, +}; + +static int cpr_4011_4mxx_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct cpr_4011_4mxx_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct cpr_4011_4mxx_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &cpr_4011_4mxx_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &cpr_4011_4mxx_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int cpr_4011_4mxx_remove(struct i2c_client *client) +{ + struct cpr_4011_4mxx_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &cpr_4011_4mxx_group); + kfree(data); + + return 0; +} + +static const struct i2c_device_id cpr_4011_4mxx_id[] = { + { "cpr_4011_4mxx", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, cpr_4011_4mxx_id); + +static struct i2c_driver cpr_4011_4mxx_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "cpr_4011_4mxx", + }, + .probe = cpr_4011_4mxx_probe, + .remove = cpr_4011_4mxx_remove, + .id_table = cpr_4011_4mxx_id, + .address_list = normal_i2c, +}; + +static int cpr_4011_4mxx_read_byte(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int cpr_4011_4mxx_read_word(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_word_data(client, reg); +} + +static int cpr_4011_4mxx_write_word(struct i2c_client *client, u8 reg, u16 value) +{ + return i2c_smbus_write_word_data(client, reg, value); +} + +struct reg_data_byte { + u8 reg; + u8 *value; +}; + +struct reg_data_word { + u8 reg; + u16 *value; +}; + +static struct cpr_4011_4mxx_data *cpr_4011_4mxx_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpr_4011_4mxx_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int i, status; + struct reg_data_byte regs_byte[] = { {0x20, &data->vout_mode}, + {0x81, &data->fan_fault} + }; + struct reg_data_word regs_word[] = { {0x88, &data->v_in}, + {0x8b, &data->v_out}, + {0x89, &data->i_in}, + {0x8c, &data->i_out}, + {0x96, &data->p_out}, + {0x97, &data->p_in}, + {0x8d, &(data->temp_input[0])}, + {0x8e, &(data->temp_input[1])}, + {0x3b, &(data->fan_duty_cycle[0])}, + {0x3c, &(data->fan_duty_cycle[1])}, + {0x90, &(data->fan_speed[0])}, + {0x91, &(data->fan_speed[1])} + }; + + dev_dbg(&client->dev, "Starting cpr_4011_4mxx update\n"); + + /* Read byte data */ + for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { + status = cpr_4011_4mxx_read_byte(client, regs_byte[i].reg); + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_byte[i].reg, status); + } + else { + *(regs_byte[i].value) = status; + } + } + + /* Read word data */ + for (i = 0; i < ARRAY_SIZE(regs_word); i++) { + status = cpr_4011_4mxx_read_word(client, regs_word[i].reg); + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_word[i].reg, status); + } + else { + *(regs_word[i].value) = status; + } + } + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +static int __init cpr_4011_4mxx_init(void) +{ + return i2c_add_driver(&cpr_4011_4mxx_driver); +} + +static void __exit cpr_4011_4mxx_exit(void) +{ + i2c_del_driver(&cpr_4011_4mxx_driver); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("CPR_4011_4MXX driver"); +MODULE_LICENSE("GPL"); + +module_init(cpr_4011_4mxx_init); +module_exit(cpr_4011_4mxx_exit); diff --git a/platform/broadcom/sonic-platform-modules-accton/common/modules/pmbus.h b/platform/broadcom/sonic-platform-modules-accton/common/modules/pmbus.h new file mode 100644 index 000000000000..cb6dbc34d87c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/common/modules/pmbus.h @@ -0,0 +1,389 @@ +/* + * pmbus.h - Common defines and structures for PMBus devices + * + * Copyright (c) 2010, 2011 Ericsson AB. + * Copyright (c) 2012 Guenter Roeck + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef PMBUS_H +#define PMBUS_H + +/* + * Registers + */ +#define PMBUS_PAGE 0x00 +#define PMBUS_OPERATION 0x01 +#define PMBUS_ON_OFF_CONFIG 0x02 +#define PMBUS_CLEAR_FAULTS 0x03 +#define PMBUS_PHASE 0x04 + +#define PMBUS_CAPABILITY 0x19 +#define PMBUS_QUERY 0x1A + +#define PMBUS_VOUT_MODE 0x20 +#define PMBUS_VOUT_COMMAND 0x21 +#define PMBUS_VOUT_TRIM 0x22 +#define PMBUS_VOUT_CAL_OFFSET 0x23 +#define PMBUS_VOUT_MAX 0x24 +#define PMBUS_VOUT_MARGIN_HIGH 0x25 +#define PMBUS_VOUT_MARGIN_LOW 0x26 +#define PMBUS_VOUT_TRANSITION_RATE 0x27 +#define PMBUS_VOUT_DROOP 0x28 +#define PMBUS_VOUT_SCALE_LOOP 0x29 +#define PMBUS_VOUT_SCALE_MONITOR 0x2A + +#define PMBUS_COEFFICIENTS 0x30 +#define PMBUS_POUT_MAX 0x31 + +#define PMBUS_FAN_CONFIG_12 0x3A +#define PMBUS_FAN_COMMAND_1 0x3B +#define PMBUS_FAN_COMMAND_2 0x3C +#define PMBUS_FAN_CONFIG_34 0x3D +#define PMBUS_FAN_COMMAND_3 0x3E +#define PMBUS_FAN_COMMAND_4 0x3F + +#define PMBUS_VOUT_OV_FAULT_LIMIT 0x40 +#define PMBUS_VOUT_OV_FAULT_RESPONSE 0x41 +#define PMBUS_VOUT_OV_WARN_LIMIT 0x42 +#define PMBUS_VOUT_UV_WARN_LIMIT 0x43 +#define PMBUS_VOUT_UV_FAULT_LIMIT 0x44 +#define PMBUS_VOUT_UV_FAULT_RESPONSE 0x45 +#define PMBUS_IOUT_OC_FAULT_LIMIT 0x46 +#define PMBUS_IOUT_OC_FAULT_RESPONSE 0x47 +#define PMBUS_IOUT_OC_LV_FAULT_LIMIT 0x48 +#define PMBUS_IOUT_OC_LV_FAULT_RESPONSE 0x49 +#define PMBUS_IOUT_OC_WARN_LIMIT 0x4A +#define PMBUS_IOUT_UC_FAULT_LIMIT 0x4B +#define PMBUS_IOUT_UC_FAULT_RESPONSE 0x4C + +#define PMBUS_OT_FAULT_LIMIT 0x4F +#define PMBUS_OT_FAULT_RESPONSE 0x50 +#define PMBUS_OT_WARN_LIMIT 0x51 +#define PMBUS_UT_WARN_LIMIT 0x52 +#define PMBUS_UT_FAULT_LIMIT 0x53 +#define PMBUS_UT_FAULT_RESPONSE 0x54 +#define PMBUS_VIN_OV_FAULT_LIMIT 0x55 +#define PMBUS_VIN_OV_FAULT_RESPONSE 0x56 +#define PMBUS_VIN_OV_WARN_LIMIT 0x57 +#define PMBUS_VIN_UV_WARN_LIMIT 0x58 +#define PMBUS_VIN_UV_FAULT_LIMIT 0x59 + +#define PMBUS_IIN_OC_FAULT_LIMIT 0x5B +#define PMBUS_IIN_OC_WARN_LIMIT 0x5D + +#define PMBUS_POUT_OP_FAULT_LIMIT 0x68 +#define PMBUS_POUT_OP_WARN_LIMIT 0x6A +#define PMBUS_PIN_OP_WARN_LIMIT 0x6B + +#define PMBUS_STATUS_BYTE 0x78 +#define PMBUS_STATUS_WORD 0x79 +#define PMBUS_STATUS_VOUT 0x7A +#define PMBUS_STATUS_IOUT 0x7B +#define PMBUS_STATUS_INPUT 0x7C +#define PMBUS_STATUS_TEMPERATURE 0x7D +#define PMBUS_STATUS_CML 0x7E +#define PMBUS_STATUS_OTHER 0x7F +#define PMBUS_STATUS_MFR_SPECIFIC 0x80 +#define PMBUS_STATUS_FAN_12 0x81 +#define PMBUS_STATUS_FAN_34 0x82 + +#define PMBUS_READ_VIN 0x88 +#define PMBUS_READ_IIN 0x89 +#define PMBUS_READ_VCAP 0x8A +#define PMBUS_READ_VOUT 0x8B +#define PMBUS_READ_IOUT 0x8C +#define PMBUS_READ_TEMPERATURE_1 0x8D +#define PMBUS_READ_TEMPERATURE_2 0x8E +#define PMBUS_READ_TEMPERATURE_3 0x8F +#define PMBUS_READ_FAN_SPEED_1 0x90 +#define PMBUS_READ_FAN_SPEED_2 0x91 +#define PMBUS_READ_FAN_SPEED_3 0x92 +#define PMBUS_READ_FAN_SPEED_4 0x93 +#define PMBUS_READ_DUTY_CYCLE 0x94 +#define PMBUS_READ_FREQUENCY 0x95 +#define PMBUS_READ_POUT 0x96 +#define PMBUS_READ_PIN 0x97 + +#define PMBUS_REVISION 0x98 +#define PMBUS_MFR_ID 0x99 +#define PMBUS_MFR_MODEL 0x9A +#define PMBUS_MFR_REVISION 0x9B +#define PMBUS_MFR_LOCATION 0x9C +#define PMBUS_MFR_DATE 0x9D +#define PMBUS_MFR_SERIAL 0x9E + +/* + * Virtual registers. + * Useful to support attributes which are not supported by standard PMBus + * registers but exist as manufacturer specific registers on individual chips. + * Must be mapped to real registers in device specific code. + * + * Semantics: + * Virtual registers are all word size. + * READ registers are read-only; writes are either ignored or return an error. + * RESET registers are read/write. Reading reset registers returns zero + * (used for detection), writing any value causes the associated history to be + * reset. + * Virtual registers have to be handled in device specific driver code. Chip + * driver code returns non-negative register values if a virtual register is + * supported, or a negative error code if not. The chip driver may return + * -ENODATA or any other error code in this case, though an error code other + * than -ENODATA is handled more efficiently and thus preferred. Either case, + * the calling PMBus core code will abort if the chip driver returns an error + * code when reading or writing virtual registers. + */ +#define PMBUS_VIRT_BASE 0x100 +#define PMBUS_VIRT_READ_TEMP_AVG (PMBUS_VIRT_BASE + 0) +#define PMBUS_VIRT_READ_TEMP_MIN (PMBUS_VIRT_BASE + 1) +#define PMBUS_VIRT_READ_TEMP_MAX (PMBUS_VIRT_BASE + 2) +#define PMBUS_VIRT_RESET_TEMP_HISTORY (PMBUS_VIRT_BASE + 3) +#define PMBUS_VIRT_READ_VIN_AVG (PMBUS_VIRT_BASE + 4) +#define PMBUS_VIRT_READ_VIN_MIN (PMBUS_VIRT_BASE + 5) +#define PMBUS_VIRT_READ_VIN_MAX (PMBUS_VIRT_BASE + 6) +#define PMBUS_VIRT_RESET_VIN_HISTORY (PMBUS_VIRT_BASE + 7) +#define PMBUS_VIRT_READ_IIN_AVG (PMBUS_VIRT_BASE + 8) +#define PMBUS_VIRT_READ_IIN_MIN (PMBUS_VIRT_BASE + 9) +#define PMBUS_VIRT_READ_IIN_MAX (PMBUS_VIRT_BASE + 10) +#define PMBUS_VIRT_RESET_IIN_HISTORY (PMBUS_VIRT_BASE + 11) +#define PMBUS_VIRT_READ_PIN_AVG (PMBUS_VIRT_BASE + 12) +#define PMBUS_VIRT_READ_PIN_MAX (PMBUS_VIRT_BASE + 13) +#define PMBUS_VIRT_RESET_PIN_HISTORY (PMBUS_VIRT_BASE + 14) +#define PMBUS_VIRT_READ_POUT_AVG (PMBUS_VIRT_BASE + 15) +#define PMBUS_VIRT_READ_POUT_MAX (PMBUS_VIRT_BASE + 16) +#define PMBUS_VIRT_RESET_POUT_HISTORY (PMBUS_VIRT_BASE + 17) +#define PMBUS_VIRT_READ_VOUT_AVG (PMBUS_VIRT_BASE + 18) +#define PMBUS_VIRT_READ_VOUT_MIN (PMBUS_VIRT_BASE + 19) +#define PMBUS_VIRT_READ_VOUT_MAX (PMBUS_VIRT_BASE + 20) +#define PMBUS_VIRT_RESET_VOUT_HISTORY (PMBUS_VIRT_BASE + 21) +#define PMBUS_VIRT_READ_IOUT_AVG (PMBUS_VIRT_BASE + 22) +#define PMBUS_VIRT_READ_IOUT_MIN (PMBUS_VIRT_BASE + 23) +#define PMBUS_VIRT_READ_IOUT_MAX (PMBUS_VIRT_BASE + 24) +#define PMBUS_VIRT_RESET_IOUT_HISTORY (PMBUS_VIRT_BASE + 25) +#define PMBUS_VIRT_READ_TEMP2_AVG (PMBUS_VIRT_BASE + 26) +#define PMBUS_VIRT_READ_TEMP2_MIN (PMBUS_VIRT_BASE + 27) +#define PMBUS_VIRT_READ_TEMP2_MAX (PMBUS_VIRT_BASE + 28) +#define PMBUS_VIRT_RESET_TEMP2_HISTORY (PMBUS_VIRT_BASE + 29) + +#define PMBUS_VIRT_READ_VMON (PMBUS_VIRT_BASE + 30) +#define PMBUS_VIRT_VMON_UV_WARN_LIMIT (PMBUS_VIRT_BASE + 31) +#define PMBUS_VIRT_VMON_OV_WARN_LIMIT (PMBUS_VIRT_BASE + 32) +#define PMBUS_VIRT_VMON_UV_FAULT_LIMIT (PMBUS_VIRT_BASE + 33) +#define PMBUS_VIRT_VMON_OV_FAULT_LIMIT (PMBUS_VIRT_BASE + 34) +#define PMBUS_VIRT_STATUS_VMON (PMBUS_VIRT_BASE + 35) + +/* + * CAPABILITY + */ +#define PB_CAPABILITY_SMBALERT (1<<4) +#define PB_CAPABILITY_ERROR_CHECK (1<<7) + +/* + * VOUT_MODE + */ +#define PB_VOUT_MODE_MODE_MASK 0xe0 +#define PB_VOUT_MODE_PARAM_MASK 0x1f + +#define PB_VOUT_MODE_LINEAR 0x00 +#define PB_VOUT_MODE_VID 0x20 +#define PB_VOUT_MODE_DIRECT 0x40 + +/* + * Fan configuration + */ +#define PB_FAN_2_PULSE_MASK ((1 << 0) | (1 << 1)) +#define PB_FAN_2_RPM (1 << 2) +#define PB_FAN_2_INSTALLED (1 << 3) +#define PB_FAN_1_PULSE_MASK ((1 << 4) | (1 << 5)) +#define PB_FAN_1_RPM (1 << 6) +#define PB_FAN_1_INSTALLED (1 << 7) + +/* + * STATUS_BYTE, STATUS_WORD (lower) + */ +#define PB_STATUS_NONE_ABOVE (1<<0) +#define PB_STATUS_CML (1<<1) +#define PB_STATUS_TEMPERATURE (1<<2) +#define PB_STATUS_VIN_UV (1<<3) +#define PB_STATUS_IOUT_OC (1<<4) +#define PB_STATUS_VOUT_OV (1<<5) +#define PB_STATUS_OFF (1<<6) +#define PB_STATUS_BUSY (1<<7) + +/* + * STATUS_WORD (upper) + */ +#define PB_STATUS_UNKNOWN (1<<8) +#define PB_STATUS_OTHER (1<<9) +#define PB_STATUS_FANS (1<<10) +#define PB_STATUS_POWER_GOOD_N (1<<11) +#define PB_STATUS_WORD_MFR (1<<12) +#define PB_STATUS_INPUT (1<<13) +#define PB_STATUS_IOUT_POUT (1<<14) +#define PB_STATUS_VOUT (1<<15) + +/* + * STATUS_IOUT + */ +#define PB_POUT_OP_WARNING (1<<0) +#define PB_POUT_OP_FAULT (1<<1) +#define PB_POWER_LIMITING (1<<2) +#define PB_CURRENT_SHARE_FAULT (1<<3) +#define PB_IOUT_UC_FAULT (1<<4) +#define PB_IOUT_OC_WARNING (1<<5) +#define PB_IOUT_OC_LV_FAULT (1<<6) +#define PB_IOUT_OC_FAULT (1<<7) + +/* + * STATUS_VOUT, STATUS_INPUT + */ +#define PB_VOLTAGE_UV_FAULT (1<<4) +#define PB_VOLTAGE_UV_WARNING (1<<5) +#define PB_VOLTAGE_OV_WARNING (1<<6) +#define PB_VOLTAGE_OV_FAULT (1<<7) + +/* + * STATUS_INPUT + */ +#define PB_PIN_OP_WARNING (1<<0) +#define PB_IIN_OC_WARNING (1<<1) +#define PB_IIN_OC_FAULT (1<<2) + +/* + * STATUS_TEMPERATURE + */ +#define PB_TEMP_UT_FAULT (1<<4) +#define PB_TEMP_UT_WARNING (1<<5) +#define PB_TEMP_OT_WARNING (1<<6) +#define PB_TEMP_OT_FAULT (1<<7) + +/* + * STATUS_FAN + */ +#define PB_FAN_AIRFLOW_WARNING (1<<0) +#define PB_FAN_AIRFLOW_FAULT (1<<1) +#define PB_FAN_FAN2_SPEED_OVERRIDE (1<<2) +#define PB_FAN_FAN1_SPEED_OVERRIDE (1<<3) +#define PB_FAN_FAN2_WARNING (1<<4) +#define PB_FAN_FAN1_WARNING (1<<5) +#define PB_FAN_FAN2_FAULT (1<<6) +#define PB_FAN_FAN1_FAULT (1<<7) + +/* + * CML_FAULT_STATUS + */ +#define PB_CML_FAULT_OTHER_MEM_LOGIC (1<<0) +#define PB_CML_FAULT_OTHER_COMM (1<<1) +#define PB_CML_FAULT_PROCESSOR (1<<3) +#define PB_CML_FAULT_MEMORY (1<<4) +#define PB_CML_FAULT_PACKET_ERROR (1<<5) +#define PB_CML_FAULT_INVALID_DATA (1<<6) +#define PB_CML_FAULT_INVALID_COMMAND (1<<7) + +enum pmbus_sensor_classes { + PSC_VOLTAGE_IN = 0, + PSC_VOLTAGE_OUT, + PSC_CURRENT_IN, + PSC_CURRENT_OUT, + PSC_POWER, + PSC_TEMPERATURE, + PSC_FAN, + PSC_NUM_CLASSES /* Number of power sensor classes */ +}; + +#define PMBUS_PAGES 32 /* Per PMBus specification */ + +/* Functionality bit mask */ +#define PMBUS_HAVE_VIN (1 << 0) +#define PMBUS_HAVE_VCAP (1 << 1) +#define PMBUS_HAVE_VOUT (1 << 2) +#define PMBUS_HAVE_IIN (1 << 3) +#define PMBUS_HAVE_IOUT (1 << 4) +#define PMBUS_HAVE_PIN (1 << 5) +#define PMBUS_HAVE_POUT (1 << 6) +#define PMBUS_HAVE_FAN12 (1 << 7) +#define PMBUS_HAVE_FAN34 (1 << 8) +#define PMBUS_HAVE_TEMP (1 << 9) +#define PMBUS_HAVE_TEMP2 (1 << 10) +#define PMBUS_HAVE_TEMP3 (1 << 11) +#define PMBUS_HAVE_STATUS_VOUT (1 << 12) +#define PMBUS_HAVE_STATUS_IOUT (1 << 13) +#define PMBUS_HAVE_STATUS_INPUT (1 << 14) +#define PMBUS_HAVE_STATUS_TEMP (1 << 15) +#define PMBUS_HAVE_STATUS_FAN12 (1 << 16) +#define PMBUS_HAVE_STATUS_FAN34 (1 << 17) +#define PMBUS_HAVE_VMON (1 << 18) +#define PMBUS_HAVE_STATUS_VMON (1 << 19) + +enum pmbus_data_format { linear = 0, direct, vid }; + +struct pmbus_driver_info { + int pages; /* Total number of pages */ + enum pmbus_data_format format[PSC_NUM_CLASSES]; + /* + * Support one set of coefficients for each sensor type + * Used for chips providing data in direct mode. + */ + int m[PSC_NUM_CLASSES]; /* mantissa for direct data format */ + int b[PSC_NUM_CLASSES]; /* offset */ + int R[PSC_NUM_CLASSES]; /* exponent */ + + u32 func[PMBUS_PAGES]; /* Functionality, per page */ + /* + * The following functions map manufacturing specific register values + * to PMBus standard register values. Specify only if mapping is + * necessary. + * Functions return the register value (read) or zero (write) if + * successful. A return value of -ENODATA indicates that there is no + * manufacturer specific register, but that a standard PMBus register + * may exist. Any other negative return value indicates that the + * register does not exist, and that no attempt should be made to read + * the standard register. + */ + int (*read_byte_data)(struct i2c_client *client, int page, int reg); + int (*read_word_data)(struct i2c_client *client, int page, int reg); + int (*write_word_data)(struct i2c_client *client, int page, int reg, + u16 word); + int (*write_byte)(struct i2c_client *client, int page, u8 value); + /* + * The identify function determines supported PMBus functionality. + * This function is only necessary if a chip driver supports multiple + * chips, and the chip functionality is not pre-determined. + */ + int (*identify)(struct i2c_client *client, + struct pmbus_driver_info *info); + + int fan_num; +}; + +/* Function declarations */ + +void pmbus_clear_cache(struct i2c_client *client); +int pmbus_set_page(struct i2c_client *client, u8 page); +int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg); +int pmbus_write_word_data(struct i2c_client *client, u8 page, u8 reg, u16 word); +int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg); +int pmbus_write_byte(struct i2c_client *client, int page, u8 value); +void _pmbus_clear_faults(struct i2c_client *client); +bool _pmbus_check_byte_register(struct i2c_client *client, int page, int reg); +bool _pmbus_check_word_register(struct i2c_client *client, int page, int reg); +int _pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, + struct pmbus_driver_info *info); +int pmbus_do_remove(struct i2c_client *client); +const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client + *client); + +#endif /* PMBUS_H */ diff --git a/platform/broadcom/sonic-platform-modules-accton/common/modules/ym2651y.c b/platform/broadcom/sonic-platform-modules-accton/common/modules/ym2651y.c new file mode 100644 index 000000000000..47e6a1d06bc5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/common/modules/ym2651y.c @@ -0,0 +1,619 @@ +/* + * An hwmon driver for the 3Y Power YM-2651Y Power Module + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_FAN_DUTY_CYCLE 100 + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { 0x58, 0x5b, I2C_CLIENT_END }; + +enum chips { + YM2651, + YM2401, + YM2851, +}; + +/* Each client has this additional data + */ +struct ym2651y_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 capability; /* Register value */ + u16 status_word; /* Register value */ + u8 fan_fault; /* Register value */ + u8 over_temp; /* Register value */ + u16 v_out; /* Register value */ + u16 i_out; /* Register value */ + u16 p_out; /* Register value */ + u16 temp; /* Register value */ + u16 fan_speed; /* Register value */ + u16 fan_duty_cycle[2]; /* Register value */ + u8 fan_dir[4]; /* Register value */ + u8 pmbus_revision; /* Register value */ + u8 mfr_id[10]; /* Register value */ + u8 mfr_model[10]; /* Register value */ + u8 mfr_revsion[3]; /* Register value */ + u16 mfr_vin_min; /* Register value */ + u16 mfr_vin_max; /* Register value */ + u16 mfr_iin_max; /* Register value */ + u16 mfr_iout_max; /* Register value */ + u16 mfr_pin_max; /* Register value */ + u16 mfr_pout_max; /* Register value */ + u16 mfr_vout_min; /* Register value */ + u16 mfr_vout_max; /* Register value */ +}; + +static ssize_t show_byte(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_word(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_linear(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_over_temp(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_ascii(struct device *dev, struct device_attribute *da, + char *buf); +static struct ym2651y_data *ym2651y_update_device(struct device *dev); +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value); + +enum ym2651y_sysfs_attributes { + PSU_POWER_ON = 0, + PSU_TEMP_FAULT, + PSU_POWER_GOOD, + PSU_FAN1_FAULT, + PSU_FAN_DIRECTION, + PSU_OVER_TEMP, + PSU_V_OUT, + PSU_I_OUT, + PSU_P_OUT, + PSU_P_OUT_UV, /*In Unit of microVolt, instead of mini.*/ + PSU_TEMP1_INPUT, + PSU_FAN1_SPEED, + PSU_FAN1_DUTY_CYCLE, + PSU_PMBUS_REVISION, + PSU_MFR_ID, + PSU_MFR_MODEL, + PSU_MFR_REVISION, + PSU_MFR_VIN_MIN, + PSU_MFR_VIN_MAX, + PSU_MFR_VOUT_MIN, + PSU_MFR_VOUT_MAX, + PSU_MFR_IIN_MAX, + PSU_MFR_IOUT_MAX, + PSU_MFR_PIN_MAX, + PSU_MFR_POUT_MAX +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(psu_power_on, S_IRUGO, show_word, NULL, PSU_POWER_ON); +static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, show_word, NULL, PSU_TEMP_FAULT); +static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_word, NULL, PSU_POWER_GOOD); +static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, show_fan_fault, NULL, PSU_FAN1_FAULT); +static SENSOR_DEVICE_ATTR(psu_over_temp, S_IRUGO, show_over_temp, NULL, PSU_OVER_TEMP); +static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, show_linear, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, show_linear, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, show_linear, NULL, PSU_P_OUT); +static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); +static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, show_linear, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); +static SENSOR_DEVICE_ATTR(psu_fan_dir, S_IRUGO, show_ascii, NULL, PSU_FAN_DIRECTION); +static SENSOR_DEVICE_ATTR(psu_pmbus_revision, S_IRUGO, show_byte, NULL, PSU_PMBUS_REVISION); +static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, show_ascii, NULL, PSU_MFR_ID); +static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, show_ascii, NULL, PSU_MFR_MODEL); +static SENSOR_DEVICE_ATTR(psu_mfr_revision, S_IRUGO, show_ascii, NULL, PSU_MFR_REVISION); +static SENSOR_DEVICE_ATTR(psu_mfr_vin_min, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MIN); +static SENSOR_DEVICE_ATTR(psu_mfr_vin_max, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_vout_min, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MIN); +static SENSOR_DEVICE_ATTR(psu_mfr_vout_max, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_iin_max, S_IRUGO, show_linear, NULL, PSU_MFR_IIN_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_iout_max, S_IRUGO, show_linear, NULL, PSU_MFR_IOUT_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_pin_max, S_IRUGO, show_linear, NULL, PSU_MFR_PIN_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_pout_max, S_IRUGO, show_linear, NULL, PSU_MFR_POUT_MAX); + +/*Duplicate nodes for lm-sensors.*/ +static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_linear, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, show_linear, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(power2_input, S_IRUGO, show_linear, NULL, PSU_P_OUT_UV); +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); +static SENSOR_DEVICE_ATTR(temp1_fault, S_IRUGO, show_word, NULL, PSU_TEMP_FAULT); + +static struct attribute *ym2651y_attributes[] = { + &sensor_dev_attr_psu_power_on.dev_attr.attr, + &sensor_dev_attr_psu_temp_fault.dev_attr.attr, + &sensor_dev_attr_psu_power_good.dev_attr.attr, + &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, + &sensor_dev_attr_psu_over_temp.dev_attr.attr, + &sensor_dev_attr_psu_v_out.dev_attr.attr, + &sensor_dev_attr_psu_i_out.dev_attr.attr, + &sensor_dev_attr_psu_p_out.dev_attr.attr, + &sensor_dev_attr_psu_temp1_input.dev_attr.attr, + &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, + &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, + &sensor_dev_attr_psu_fan_dir.dev_attr.attr, + &sensor_dev_attr_psu_pmbus_revision.dev_attr.attr, + &sensor_dev_attr_psu_mfr_id.dev_attr.attr, + &sensor_dev_attr_psu_mfr_model.dev_attr.attr, + &sensor_dev_attr_psu_mfr_revision.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vin_min.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vin_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_pout_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_iin_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_pin_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vout_min.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vout_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_iout_max.dev_attr.attr, + /*Duplicate nodes for lm-sensors.*/ + &sensor_dev_attr_curr2_input.dev_attr.attr, + &sensor_dev_attr_in3_input.dev_attr.attr, + &sensor_dev_attr_power2_input.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_temp1_fault.dev_attr.attr, + NULL +}; + +static ssize_t show_byte(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + + return (attr->index == PSU_PMBUS_REVISION) ? sprintf(buf, "%d\n", data->pmbus_revision) : + sprintf(buf, "0\n"); +} + +static ssize_t show_word(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + u16 status = 0; + + switch (attr->index) { + case PSU_POWER_ON: /* psu_power_on, low byte bit 6 of status_word, 0=>ON, 1=>OFF */ + status = (data->status_word & 0x40) ? 0 : 1; + break; + case PSU_TEMP_FAULT: /* psu_temp_fault, low byte bit 2 of status_word, 0=>Normal, 1=>temp fault */ + status = (data->status_word & 0x4) >> 2; + break; + case PSU_POWER_GOOD: /* psu_power_good, high byte bit 3 of status_word, 0=>OK, 1=>FAIL */ + status = (data->status_word & 0x800) ? 0 : 1; + break; + } + + return sprintf(buf, "%d\n", status); +} + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + bool is_negative = valid_data >> (valid_bit - 1); + + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} + +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct ym2651y_data *data = i2c_get_clientdata(client); + int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; + long speed; + int error; + + error = kstrtol(buf, 10, &speed); + if (error) + return error; + + if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) + return -EINVAL; + + mutex_lock(&data->update_lock); + data->fan_duty_cycle[nr] = speed; + ym2651y_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t show_linear(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + + u16 value = 0; + int exponent, mantissa; + int multiplier = 1000; + + switch (attr->index) { + case PSU_V_OUT: + value = data->v_out; + break; + case PSU_I_OUT: + value = data->i_out; + break; + case PSU_P_OUT_UV: + multiplier = 1000000; /*For lm-sensors, unit is micro-Volt.*/ + /*Passing through*/ + case PSU_P_OUT: + value = data->p_out; + break; + case PSU_TEMP1_INPUT: + value = data->temp; + break; + case PSU_FAN1_SPEED: + value = data->fan_speed; + multiplier = 1; + break; + case PSU_FAN1_DUTY_CYCLE: + value = data->fan_duty_cycle[0]; + multiplier = 1; + break; + case PSU_MFR_VIN_MIN: + value = data->mfr_vin_min; + break; + case PSU_MFR_VIN_MAX: + value = data->mfr_vin_max; + break; + case PSU_MFR_VOUT_MIN: + value = data->mfr_vout_min; + break; + case PSU_MFR_VOUT_MAX: + value = data->mfr_vout_max; + break; + case PSU_MFR_PIN_MAX: + value = data->mfr_pin_max; + break; + case PSU_MFR_POUT_MAX: + value = data->mfr_pout_max; + break; + case PSU_MFR_IOUT_MAX: + value = data->mfr_iout_max; + break; + case PSU_MFR_IIN_MAX: + value = data->mfr_iin_max; + break; + } + + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + + u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; + + return sprintf(buf, "%d\n", data->fan_fault >> shift); +} + +static ssize_t show_over_temp(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct ym2651y_data *data = ym2651y_update_device(dev); + + return sprintf(buf, "%d\n", data->over_temp >> 7); +} + +static ssize_t show_ascii(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + u8 *ptr = NULL; + + switch (attr->index) { + case PSU_FAN_DIRECTION: /* psu_fan_dir */ + ptr = data->fan_dir; + break; + case PSU_MFR_ID: /* psu_mfr_id */ + ptr = data->mfr_id; + break; + case PSU_MFR_MODEL: /* psu_mfr_model */ + ptr = data->mfr_model; + break; + case PSU_MFR_REVISION: /* psu_mfr_revision */ + ptr = data->mfr_revsion; + break; + default: + return 0; + } + + return sprintf(buf, "%s\n", ptr); +} + +static const struct attribute_group ym2651y_group = { + .attrs = ym2651y_attributes, +}; + +static int ym2651y_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct ym2651y_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct ym2651y_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &ym2651y_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &ym2651y_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int ym2651y_remove(struct i2c_client *client) +{ + struct ym2651y_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &ym2651y_group); + kfree(data); + + return 0; +} + +static const struct i2c_device_id ym2651y_id[] = { + { "ym2651", YM2651 }, + { "ym2401", YM2401 }, + { "ym2851", YM2851 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, ym2651y_id); + +static struct i2c_driver ym2651y_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "ym2651", + }, + .probe = ym2651y_probe, + .remove = ym2651y_remove, + .id_table = ym2651y_id, + .address_list = normal_i2c, +}; + +static int ym2651y_read_byte(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int ym2651y_read_word(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_word_data(client, reg); +} + +static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value) +{ + return i2c_smbus_write_word_data(client, reg, value); +} + +static int ym2651y_read_block(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ + int result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + + if (unlikely(result < 0)) + goto abort; + if (unlikely(result != data_len)) { + result = -EIO; + goto abort; + } + + result = 0; + +abort: + return result; +} + +struct reg_data_byte { + u8 reg; + u8 *value; +}; + +struct reg_data_word { + u8 reg; + u16 *value; +}; + +static struct ym2651y_data *ym2651y_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct ym2651y_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int i, status; + u8 command; + u8 fan_dir[5] = {0}; + struct reg_data_byte regs_byte[] = { {0x19, &data->capability}, + {0x7d, &data->over_temp}, + {0x81, &data->fan_fault}, + {0x98, &data->pmbus_revision} + }; + struct reg_data_word regs_word[] = { {0x79, &data->status_word}, + {0x8b, &data->v_out}, + {0x8c, &data->i_out}, + {0x96, &data->p_out}, + {0x8d, &data->temp}, + {0x3b, &(data->fan_duty_cycle[0])}, + {0x3c, &(data->fan_duty_cycle[1])}, + {0x90, &data->fan_speed}, + {0xa0, &data->mfr_vin_min}, + {0xa1, &data->mfr_vin_max}, + {0xa2, &data->mfr_iin_max}, + {0xa3, &data->mfr_pin_max}, + {0xa4, &data->mfr_vout_min}, + {0xa5, &data->mfr_vout_max}, + {0xa6, &data->mfr_iout_max}, + {0xa7, &data->mfr_pout_max} + }; + + dev_dbg(&client->dev, "Starting ym2651 update\n"); + + /* Read byte data */ + for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { + status = ym2651y_read_byte(client, regs_byte[i].reg); + + if (status < 0) + { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_byte[i].reg, status); + *(regs_byte[i].value) = 0; + } + else { + *(regs_byte[i].value) = status; + } + } + + /* Read word data */ + for (i = 0; i < ARRAY_SIZE(regs_word); i++) { + status = ym2651y_read_word(client, regs_word[i].reg); + + if (status < 0) + { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_word[i].reg, status); + *(regs_word[i].value) = 0; + } + else { + *(regs_word[i].value) = status; + } + } + + /* Read fan_direction */ + command = 0xC3; + status = ym2651y_read_block(client, command, fan_dir, ARRAY_SIZE(fan_dir)-1); + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + } + + strncpy(data->fan_dir, fan_dir+1, ARRAY_SIZE(data->fan_dir)-1); + data->fan_dir[ARRAY_SIZE(data->fan_dir)-1] = '\0'; + + /* Read mfr_id */ + command = 0x99; + status = ym2651y_read_block(client, command, data->mfr_id, + ARRAY_SIZE(data->mfr_id)-1); + data->mfr_id[ARRAY_SIZE(data->mfr_id)-1] = '\0'; + + if (status < 0) + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + + /* Read mfr_model */ + command = 0x9a; + status = ym2651y_read_block(client, command, data->mfr_model, + ARRAY_SIZE(data->mfr_model)-1); + data->mfr_model[ARRAY_SIZE(data->mfr_model)-1] = '\0'; + + if (status < 0) + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + + /* Read mfr_revsion */ + command = 0x9b; + status = ym2651y_read_block(client, command, data->mfr_revsion, + ARRAY_SIZE(data->mfr_revsion)-1); + data->mfr_revsion[ARRAY_SIZE(data->mfr_revsion)-1] = '\0'; + + if (status < 0) + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +module_i2c_driver(ym2651y_driver); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("3Y Power YM-2651Y driver"); +MODULE_LICENSE("GPL"); + + diff --git a/platform/broadcom/sonic-platform-modules-accton/debian/changelog b/platform/broadcom/sonic-platform-modules-accton/debian/changelog new file mode 100755 index 000000000000..2b08b12c206a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/debian/changelog @@ -0,0 +1,18 @@ +sonic-accton-platform-modules (1.1) unstable; urgency=low + + * Add support for AS7816-64X. + + -- Accton Network Tue, 19 Dec 2017 09:35:58 +0800 + +sonic-accton-platform-modules (1.1) unstable; urgency=low + + * Add support for Accton AS5712-54X + + -- Accton Network Wed, 11 Oct 2017 14:21:45 +0800 + +sonic-accton-platform-modules (1.0) unstable; urgency=low + + * Add support for Accton AS7712-32X + * Initial release + + -- Accton Network Thu, 01 Jun 2017 14:06:38 +0800 diff --git a/platform/broadcom/sonic-platform-modules-accton/debian/compat b/platform/broadcom/sonic-platform-modules-accton/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/debian/compat @@ -0,0 +1 @@ +9 diff --git a/platform/broadcom/sonic-platform-modules-accton/debian/control b/platform/broadcom/sonic-platform-modules-accton/debian/control new file mode 100755 index 000000000000..22faf6d202b8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/debian/control @@ -0,0 +1,41 @@ +Source: sonic-accton-platform-modules +Section: main +Priority: extra +Maintainer: Accton network , Accton Network +Build-Depends: debhelper (>= 8.0.0), bzip2 +Standards-Version: 3.9.3 + +Package: sonic-platform-accton-as7712-32x +Architecture: amd64 +Depends: linux-image-3.16.0-5-amd64 +Description: kernel modules for platform devices such as fan, led, sfp + +Package: sonic-platform-accton-as5712-54x +Architecture: amd64 +Depends: linux-image-3.16.0-5-amd64 +Description: kernel modules for platform devices such as fan, led, sfp + +Package: sonic-platform-accton-as7816-64x +Architecture: amd64 +Depends: linux-image-3.16.0-5-amd64 +Description: kernel modules for platform devices such as fan, led, sfp + +Package: sonic-platform-accton-as7716-32x +Architecture: amd64 +Depends: linux-image-3.16.0-5-amd64 +Description: kernel modules for platform devices such as fan, led, sfp + +Package: sonic-platform-accton-as7716-32xb +Architecture: amd64 +Depends: linux-image-3.16.0-5-amd64 +Description: kernel modules for platform devices such as fan, led, sfp + +Package: sonic-platform-accton-as7312-54x +Architecture: amd64 +Depends: linux-image-3.16.0-5-amd64 +Description: kernel modules for platform devices such as fan, led, sfp + +Package: sonic-platform-accton-as7326-56x +Architecture: amd64 +Depends: linux-image-3.16.0-5-amd64 +Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-accton/debian/rules b/platform/broadcom/sonic-platform-modules-accton/debian/rules new file mode 100755 index 000000000000..8274607f27b5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/debian/rules @@ -0,0 +1,86 @@ +#!/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 + +PYTHON ?= python2 + +PACKAGE_PRE_NAME := sonic-platform-accton +KVERSION ?= $(shell uname -r) +KERNEL_SRC := /lib/modules/$(KVERSION) +MOD_SRC_DIR:= $(shell pwd) +MODULE_DIRS:= as7712-32x as5712-54x as7816-64x as7716-32x as7716-32xb as7312-54x as7326-56x +MODULE_DIR := modules +UTILS_DIR := utils +SERVICE_DIR := service +CLASSES_DIR := classes +CONF_DIR := conf + +%: + dh $@ --with systemd,python2,python3 --buildsystem=pybuild + +clean: + dh_testdir + dh_testroot + dh_clean + +build: + #make modules -C $(KERNEL_SRC)/build M=$(MODULE_SRC) + (for mod in $(MODULE_DIRS); do \ + make modules -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ + $(PYTHON) $${mod}/setup.py build; \ + 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}/usr/local/bin; \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system; \ + cp $(MOD_SRC_DIR)/$${mod}/$(MODULE_DIR)/*.ko debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin/; \ + cp $(MOD_SRC_DIR)/$${mod}/$(SERVICE_DIR)/*.service debian/$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system/; \ + $(PYTHON) $${mod}/setup.py install --root=$(MOD_SRC_DIR)/debian/$(PACKAGE_PRE_NAME)-$${mod} --install-layout=deb; \ + done) + # 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 diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista deleted file mode 160000 index a35c7eddaf94..000000000000 --- a/platform/broadcom/sonic-platform-modules-arista +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a35c7eddaf945a1ff09ea71b47f69b6ddba5e892 diff --git a/platform/broadcom/sonic-platform-modules-arista/.gitignore b/platform/broadcom/sonic-platform-modules-arista/.gitignore new file mode 100644 index 000000000000..72220960de3f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/.gitignore @@ -0,0 +1,21 @@ +# kernel module build +*.o +*.ko +*.mod.c +*.mod.o +*.cmd +Module.symvers +modules.order + +# debian packaging +*.debhelper +*.log +DEBIAN +.tmp_versions +.finished.build + +# python +*.pyc +/build +/*.egg-info +/venv diff --git a/platform/broadcom/sonic-platform-modules-arista/LICENSE b/platform/broadcom/sonic-platform-modules-arista/LICENSE new file mode 100644 index 000000000000..ebdb940a0c98 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/LICENSE @@ -0,0 +1,1016 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. + + + + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 3 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, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/platform/broadcom/sonic-platform-modules-arista/Makefile b/platform/broadcom/sonic-platform-modules-arista/Makefile new file mode 100644 index 000000000000..ff463b6e013f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/Makefile @@ -0,0 +1,17 @@ +SHELL = /bin/bash +.ONESHELL: +.SHELLFLAGS += -e + +MAIN_TARGET = $(ARISTA_PLATFORM_MODULE) +EXTRA_TARGETS = $(ARISTA_PLATFORM_MODULE_DRIVERS) \ + $(ARISTA_PLATFORM_MODULE_PYTHON2) \ + $(ARISTA_PLATFORM_MODULE_PYTHON3) + +$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + # Build the package + export PYBUILD_INSTALL_ARGS_python2=--install-scripts=/dev/null + dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) + + mv $(addprefix ../, $* $(EXTRA_TARGETS)) $(DEST)/ + +$(addprefix $(DEST)/, $(EXTRA_TARGETS)): $(DEST)/% : $(DEST)/$(MAIN_TARGET) diff --git a/platform/broadcom/sonic-platform-modules-arista/README.md b/platform/broadcom/sonic-platform-modules-arista/README.md new file mode 100644 index 000000000000..16f1da548dad --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/README.md @@ -0,0 +1,250 @@ +Arista platform support for SONiC +================================= + +Copyright (C) 2016 Arista Networks, 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 3 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, see . + +## License + +All linux kernel code is licensed under the GPLv2. All other code is +licensed under the GPLv3. Please see the LICENSE file for copies of +both licenses. + +## Purpose + +This package contains kernel drivers, a python library and a python binary to +provide platform support for Arista switches. + +The `arista` tool will identify the platform on which it is running and will +then load and initialise the required kernel drivers. Once initialised, the +system will expose transceivers, leds, fans, temperature sensors and gpios +through the sysfs. + +## Supported platforms + +The following platforms are currently supported, + + - DCS-7050QX-32 + - DCS-7050QX-32S + - DCS-7060CX-32 + - DCS-7260CX3-64 + +Some platforms will require some custom kernel patches. +They are available on the Azure/sonic-linux-kernel repository. + +## Usage + +This repository contains both a `systemd` and `LSB` init script to properly +integrate with the system startup and shutdown. + +Alternatively the `arista` tool can be used in standalone to load and unload +the platform support. + +``` + arista --help +``` + +Since the python library knows about the current platform, it can provides a +common and unified implementation of the SONiC plugins. +Currently supports `eeprom`, `sfputil` and `led_control`. + +The python library and tools are python2 and python3 compatible. + +## Drivers + +The kernel drivers in this repository have currently been tested against a +3.16 and 3.18 based kernel image. + +### scd-hwmon vs sonic-support-driver + +The `scd-hwmon` is the newer implementation of the scd driver and is used +for all supported platforms except `DCS-7050QX-32` and `DCS-7050QX-32S` which +use `sonic-support driver`. + +When the `scd-hwmon` driver is loaded, the various gpios and resets can be set +and unset by writing into the sysfs file. +The meaning of the value `0` or `1` read from or written to is determined by +the name of the sysfs entry. + +``` +cd /sys/module/scd/drivers/pci:scd// +echo 1 > switch_chip_reset +``` + +When the legacy `sonic-support-driver` is in use, the gpios and resets behave +according to the gpio subsystem of the kernel. The driver will properly set +`value` and `active_low`, whereas `direction` must be set to `out` when +setting the gpio and to `in` when reading it. Read only entries don't have +a `direction` file. + +``` +cd /sys/module/scd/drivers/pci:scd// +echo out > switch_chip_reset/direction +echo 1 > switch_chip_reset/value +echo 0 > switch_chip_reset/value +``` + +## Components + +This section describes how to interact with the various components exposed by +the kernel drivers. +In order to see them, the platform must be successfully initialized. + +The following sections describe how to manually interact with the components. +Examples shown may differ across platforms but the logic stays the same. + +### LEDs + +LED entries can be found under `/sys/class/leds`. Since the sysfs interface +for LEDs is not very expressive, the brightness field is used here +to toggle between off and different colors. The brightness to LED +color mappings are as follows (0 maps to off for all LEDs): + +``` +status, fan_status, psu1, psu2: + 0 => off + 1 => green + 2 => red + +beacon: + 1+ => blue + +qsfp: + 1 => green + 2 => yellow + +fan: + 1 => green + 2 => red + 3 => yellow +``` + +Given that this repository is primarily aimed at running on SONiC, an +implementation of the `led_control` plugin is available under +`arista.utils.sonic_leds`. It requires access to the `port_config.ini` file to +translate from `interface name` to `front panel port`. + +### Fans + +Fans are exposed under `/sys/class/hwmon/*` and respect the +[sysfs-interface](https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface) +guidelines. + +This repository provides the kernel modules to handle the fans. + +### Temperature sensors + +Temperature sensors are exposed under `/sys/class/hwmon/*` and also respect +the [sysfs-interface](https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface). + +They are all managed by linux standard modules like `lm73` and `max6658`. + +### Power supplies + +Power supplies and power controllers can be managed by the kernel's +generic `pmbus` module. Assuming the pmbus module was compiled into the +kernel. + +Some power supplies may need kernel patches against the `pmbus` driver. + +### System EEPROM + +The system eeprom contains platform specific information like the `SKU`, the +`serial number` and the `base mac address`. + +The way to read the system eeprom from a platform can differ from one SKU to the +other. +The most reliable way to get this information is by issuing `arista syseeprom` + +In the case of SONiC the module `arista.utils.sonic_eeprom` provide the plugin +implementation. + +### Transceivers - QSFPs / SFPs + +Currently only platforms with QSFP+ and SFP+ ports are supported. +These transceivers provide 2 kind of information. + +#### Pins + +The first piece of information is obtained from the transceiver physical pins. + - QSFP: present, reset, low power mode, interrupt, module select + - SFP: present, rxlos, txfault, txdisable + +These knobs are accessible under `/sys/module/scd/drivers/pci:scd/.../` +The name of the entries follow this naming `_` +For example `qsfp2_reset` or `sfp66_txdisable`. + +See [this section](#scd-hwmon-vs-sonic-support-driver) on how to use them. + +#### Eeproms + +The second piece of information provided by a transceiver is the content of its +`eeprom`. It is accessible via `SMBus` at the fixed address `0x50`. + +On linux, an unoffical module called `sff_8436_eeprom` can handle such devices. +The arista initialisation library takes care of loading the module for all the +transceivers. +They should then all be available under +`/sys/module/sff_8436_eeprom/drivers/i2c:sff8436` + +After instantiation, the EEPROM information can be read like so: + +``` +root@sonic# hexdump -C /sys/bus/i2c/devices/19-0050/eeprom +00000000 0d 00 02 f0 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00000010 00 00 00 00 00 00 19 5c 00 00 7f 9c 00 00 00 00 |.......\........| +00000020 00 00 1f cd 20 2e 26 b8 22 94 00 00 00 00 00 00 |.... .&.".......| +00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +00000070 00 00 00 00 00 04 02 00 00 00 00 00 00 00 00 00 |................| +00000080 0d 00 0c 04 00 00 00 00 00 00 00 05 67 00 00 32 |............g..2| +00000090 00 00 00 00 41 72 69 73 74 61 20 4e 65 74 77 6f |....Arista Netwo| +000000a0 72 6b 73 20 00 00 1c 73 51 53 46 50 2d 34 30 47 |rks ...sQSFP-40G| +000000b0 2d 53 52 34 20 20 20 20 30 33 42 68 07 d0 46 0d |-SR4 03Bh..F.| +000000c0 00 00 0f de 58 4d 44 31 34 30 34 30 30 35 56 52 |....XMD1404005VR| +000000d0 20 20 20 20 31 34 30 31 32 36 20 20 08 00 00 d2 | 140126 ....| +000000e0 10 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +000000f0 00 00 00 00 00 00 02 f8 00 00 00 00 98 44 64 d1 |.............Dd.| +00000100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +00000180 40 6b a1 2e 3c f4 2b eb cd c1 e9 51 50 93 bb fe |@k..<.+....QP...| +00000190 05 aa 32 3f 1c 4c 00 00 00 00 00 00 00 00 00 00 |..2?.L..........| +000001a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +00000200 4b 00 fb 00 46 00 00 00 00 00 00 00 00 00 00 00 |K...F...........| +00000210 8d cc 74 04 87 5a 7a 75 00 00 00 00 00 00 00 00 |..t..Zzu........| +00000220 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00000230 55 76 01 be 43 e2 04 62 13 88 00 fa 12 8e 01 f4 |Uv..C..b........| +00000240 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +00000260 00 00 00 00 00 00 00 00 00 00 00 00 33 33 77 77 |............33ww| +00000270 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00000280 +``` + +Before being read, the QSFP+ modules must be taken out of reset and +have their module select signals asserted. This can be done through +the GPIO interface. + +### QSFP - SFP multiplexing + +On the `DCS-7050QX-32S`, the first QSFP port and the 4 SFP ports are multiplexed. +To choose between one or the other, write into the sysfs file located under +`/sys/modules/scd/drivers/pci:scd/.../mux_sfp_qsfp` + +### GPIOs and resets + +Most of the GPIOs are exposed by the `scd-hwmon` and the `sonic-support-driver`. +They should be available under `/sys/module/scd/drivers/pci:scd/.../`. diff --git a/platform/broadcom/sonic-platform-modules-arista/arista/__init__.py b/platform/broadcom/sonic-platform-modules-arista/arista/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/platform/broadcom/sonic-platform-modules-arista/arista/components/__init__.py b/platform/broadcom/sonic-platform-modules-arista/arista/components/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/platform/broadcom/sonic-platform-modules-arista/arista/components/common.py b/platform/broadcom/sonic-platform-modules-arista/arista/components/common.py new file mode 100644 index 000000000000..d925dab7fe98 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/arista/components/common.py @@ -0,0 +1,109 @@ + +import logging +import os +import time + +from ..core.component import Component, DEFAULT_WAIT_TIMEOUT, ASIC_YIELD_TIME +from ..core.driver import KernelDriver +from ..core.utils import klog, inSimulation +from ..core.types import PciAddr, I2cAddr + +class PciComponent(Component): + def __init__(self, addr, **kwargs): + assert isinstance(addr, PciAddr) + super(PciComponent, self).__init__(addr=addr, **kwargs) + +class I2cComponent(Component): + def __init__(self, addr, **kwargs): + assert isinstance(addr, I2cAddr) + super(I2cComponent, self).__init__(addr=addr, **kwargs) + +class I2cKernelComponent(I2cComponent): + def __init__(self, addr, name, waitFile=None, **kwargs): + super(I2cKernelComponent, self).__init__(addr, **kwargs) + self.addDriver(I2cKernelDriver, name, waitFile) + +class PciKernelDriver(KernelDriver): + def __init__(self, component, name, args=None): + assert isinstance(component, PciComponent) + super(PciKernelDriver, self).__init__(component, name, args) + + def getSysfsPath(self): + return os.path.join('/sys/bus/pci/devices', str(self.component.addr)) + +class I2cKernelDriver(KernelDriver): + def __init__(self, component, name, waitFile=None): + assert isinstance(component, I2cComponent) + super(I2cKernelDriver, self).__init__(component, None, waitFile) + self.name = name + + def getSysfsPath(self): + return os.path.join('/sys/bus/i2c/devices', str(self.component.addr)) + + def getSysfsBusPath(self): + return '/sys/bus/i2c/devices/i2c-%d' % self.component.addr.bus + + def setup(self): + addr = self.component.addr + devicePath = self.getSysfsPath() + path = os.path.join(self.getSysfsBusPath(), 'new_device') + logging.debug('creating i2c device %s on bus %d at 0x%02x', + self.name, addr.bus, addr.address) + if inSimulation(): + return + if os.path.exists(devicePath): + logging.debug('i2c device %s already exists', devicePath) + else: + with open(path, 'w') as f: + f.write('%s 0x%02x' % (self.name, self.component.addr.address)) + self.waitFileReady() + + def clean(self): + # i2c kernel devices are automatically cleaned when the module is removed + if inSimulation(): + return + path = os.path.join(self.getSysfsBusPath(), 'delete_device') + addr = self.component.addr + if os.path.exists(self.getSysfsPath()): + logging.debug('removing i2c device %s from bus %d' % (self.name, addr.bus)) + with open(path, 'w') as f: + f.write('0x%02x' % addr.address) + + def __str__(self): + return '%s(%s)' % (self.__class__.__name__, self.name) + +class SwitchChip(PciComponent): + def pciRescan(self): + logging.info('triggering kernel pci rescan') + with open('/sys/bus/pci/rescan', 'w') as f: + f.write('1\n') + + def waitForIt(self, timeout=DEFAULT_WAIT_TIMEOUT): + begin = time.time() + end = begin + timeout + rescanTime = begin + (timeout / 2) + devPath = os.path.join('/sys/bus/pci/devices/', str(self.addr)) + + logging.debug('waiting for switch chip %s', devPath) + if inSimulation(): + return True + + klog('waiting for switch chip') + while True: + now = time.time() + if now > end: + break + if os.path.exists(devPath): + logging.debug('switch chip is ready') + klog('switch chip is ready') + time.sleep(ASIC_YIELD_TIME) + klog('yielding...') + return True + if now > rescanTime: + self.pciRescan() + rescanTime = end + time.sleep(0.1) + + logging.error('timed out waiting for the switch chip %s', devPath) + return False + diff --git a/platform/broadcom/sonic-platform-modules-arista/arista/components/ds125br.py b/platform/broadcom/sonic-platform-modules-arista/arista/components/ds125br.py new file mode 100644 index 000000000000..22f773a39d55 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/arista/components/ds125br.py @@ -0,0 +1,84 @@ +import logging +import copy + +from ..core.utils import SMBus +from .common import I2cComponent + +class Ds125Br(I2cComponent): + def __init__(self, addr, **kwargs): + super(Ds125Br, self).__init__(addr, channels=8, **kwargs) + + def qsfpPortConfig(self, amplitude): + disableCrc = 0x18 + squelchMode = 0x40 + outputAmplitude = amplitude + assert len(outputAmplitude) == self.channels + txDeEmphasis = [0x00] * self.channels + rxEqualization = [0x00] * self.channels + inputTermination = [0x0c] * self.channels + squelch = [0x02] * self.channels + return [disableCrc, squelchMode, outputAmplitude, txDeEmphasis, + rxEqualization, inputTermination, squelch] + + def qsfpPortGroupConfig(self): + portConfig = self.qsfpPortConfig([None, 0xac, None, 0xac, + 0xab, 0xab, 0xab, 0xac]) + txDeEmphasis = portConfig[3] + txDeEmphasis[0] = None + txDeEmphasis[2] = None + portConfig[3] = txDeEmphasis + return portConfig + + def getPortConfigs(self): + qsfp35 = ( + 0x59, + self.qsfpPortConfig([0xaa, 0xaa, 0xaa, 0xaa, 0xa8, 0xa9, 0xa8, 0xa9]) + ) + qsfp36 = ( + 0x58, + self.qsfpPortConfig([0xaa, 0xaa, 0xaa, 0xaa, 0xa9, 0xa9, 0xa9, 0xaa]) + ) + sfp1_2 = ( + 0x5a, + self.qsfpPortGroupConfig() + ) + sfp3_4 = ( + 0x5b, + self.qsfpPortGroupConfig() + ) + return [qsfp35, qsfp36, sfp1_2, sfp3_4] + + def setupPort(self, bus, addr, config): + disableCrc, squelchMode, outputAmplitude, txDeEmphasis, \ + rxEqualization, inputTermination, squelch = config + + bus.write_byte_data(addr, 0x06, disableCrc) + bus.write_byte_data(addr, 0x28, squelchMode) + + baseAddr = 0x0d + for channel in range(0, self.channels): + offset = channel * 7 + if (baseAddr + offset) > 0x27: + offset += 1 + regs = [ + (baseAddr + offset + 0, squelch[channel]), + (baseAddr + offset + 1, inputTermination[channel]), + (baseAddr + offset + 2, rxEqualization[channel]), + (baseAddr + offset + 3, outputAmplitude[channel]), + (baseAddr + offset + 4, txDeEmphasis[channel]), + ] + for reg, data in regs: + if data is not None: + logging.debug('i2c-write %#02x %#02x %#02x', addr, reg, data) + bus.write_byte_data(addr, reg, data) + + def setup(self): + logging.debug('setting up ds125br repeaters') + + bus = SMBus(self.addr.bus) + for addr, config in self.getPortConfigs(): + self.setupPort(bus, addr, config) + + def clean(self): + pass + diff --git a/platform/broadcom/sonic-platform-modules-arista/arista/components/ds460.py b/platform/broadcom/sonic-platform-modules-arista/arista/components/ds460.py new file mode 100644 index 000000000000..ce72beb20a7b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/arista/components/ds460.py @@ -0,0 +1,37 @@ +import logging + +from ..core.utils import SMBus + +from .common import I2cKernelComponent + +class Ds460(I2cKernelComponent): + def __init__(self, addr, **kwargs): + # pmbus if dps460 is not available + super(Ds460, self).__init__(addr, 'dps460', **kwargs) + + def setup(self): + addr = self.addr.address + + logging.debug('initializing ds460 registers') + bus = SMBus(self.addr.bus) + + try: + bus.read_byte_data(addr, 0x00) + except IOError: + logging.debug('device ds460 not found') + bus.close() + return + + try: + byte = bus.read_byte_data(addr, 0x10) + bus.write_byte_data(addr, 0x10, 0) + bus.write_byte_data(addr, 0x03, 1) + bus.write_byte_data(addr, 0x10, byte) + except IOError: + logging.debug('failed to initialize ds460') + + bus.close() + + super(Ds460, self).setup() + + diff --git a/platform/broadcom/sonic-platform-modules-arista/arista/components/scd.py b/platform/broadcom/sonic-platform-modules-arista/arista/components/scd.py new file mode 100644 index 000000000000..ac610068a3a5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/arista/components/scd.py @@ -0,0 +1,473 @@ +from __future__ import print_function, with_statement + +import os +import logging + +from collections import OrderedDict, namedtuple + +from ..core.inventory import Xcvr, Psu +from ..core.types import Gpio, ResetGpio, NamedGpio +from ..core.utils import sysfsFmtHex, sysfsFmtDec, sysfsFmtStr, simulateWith, \ + inSimulation + +from .common import PciComponent, KernelDriver, PciKernelDriver + +class ScdSysfsGroup(object): + def __init__(self, objNum, typeStr, driver): + self.driver = driver + self.prefix = '%s%d_' % (typeStr, objNum) + self.prefixPath = os.path.join(driver.getSysfsPath(), self.prefix) + +class ScdSysfsRW(ScdSysfsGroup): + def __init__(self, objNum, typeStr, driver): + ScdSysfsGroup.__init__(self, objNum, typeStr, driver) + + def getSysfsGpio(self, name): + return '%s%s' % (self.prefixPath, name) + + def readValueSim(self, name): + logging.info('read sysfs %s entry %s', self.prefix, name) + return "1" + + @simulateWith(readValueSim) + def readValue(self, name): + with open(self.getSysfsGpio(name), 'r') as f: + return f.read().rstrip() + + def writeValueSim(self, name, value): + logging.info('write sysfs %s entry %s value %s', self.prefix, name, value) + return True + + @simulateWith(writeValueSim) + def writeValue(self, name, value): + with open(self.getSysfsGpio(name), 'w') as f: + f.write(str(value)) + return True + +class ScdSysfsOldRW(ScdSysfsRW): + def __init__(self, objNum, typeStr, driver): + ScdSysfsRW.__init__(self, objNum, typeStr, driver) + + def readValue(self, name): + gpio = self.getSysfsGpio(name) + directionPath = os.path.join(gpio, 'direction') + if os.path.exists(directionPath): + with open(directionPath, 'w') as f: + f.write("in") + with open(os.path.join(gpio, 'value'), 'r') as f: + return f.read().rstrip() + + def writeValue(self, name, value): + gpio = self.getSysfsGpio(name) + directionPath = os.path.join(gpio, 'direction') + if os.path.exists(directionPath): + with open(directionPath, 'w') as f: + f.write("out") + with open(os.path.join(gpio, 'value'), 'w') as f: + f.write(str(value)) + return True + +class ScdKernelXcvr(Xcvr): + def __init__(self, portNum, xcvrType, eepromAddr, bus, driver, sysfsRWClass): + Xcvr.__init__(self, portNum, xcvrType, eepromAddr, bus) + typeStr = 'qsfp' if xcvrType == Xcvr.QSFP else 'sfp' + self.rw = sysfsRWClass(portNum, typeStr, driver) + + def getPresence(self): + return self.rw.readValue('present') == '1' + + def getLowPowerMode(self): + if self.xcvrType == Xcvr.SFP: + return False + return self.rw.readValue('lp_mode') == '1' + + def setLowPowerMode(self, value): + if self.xcvrType == Xcvr.SFP: + return False + return self.rw.writeValue('lp_mode', '1' if value else '0') + + def reset(self, value): + if self.xcvrType == Xcvr.SFP: + return False + return self.rw.writeValue('reset', '1' if value else '0') + +class ScdKernelPsu(Psu): + def __init__(self, portNum, driver, sysfsRWClass, statusSupported): + self.rw = sysfsRWClass(portNum, 'psu', driver) + self.statusSupported = statusSupported + + def getPresence(self): + return self.rw.readValue('present') == '1' + + def getStatus(self): + if self.statusSupported: + return self.rw.readValue('status') == '1' + else: + return self.getPresence() + +class ScdHwmonKernelDriver(PciKernelDriver): + def __init__(self, scd): + super(ScdHwmonKernelDriver, self).__init__(scd, 'scd-hwmon') + + def writeConfigSim(self, path, data): + for filename, value in data.items(): + logging.info('writting data under %s : %r', + os.path.join(path, filename), value) + + @simulateWith(writeConfigSim) + def writeConfig(self, path, data): + for filename, value in data.items(): + try: + path = os.path.join(path, filename) + with open(path, 'w') as f: + f.write(value) + except IOError as e: + logging.error('%s %s', path, e.strerror) + + def writeComponents(self, components, filename): + PAGE_SIZE = 4096 + data = [] + data_size = 0 + + for entry in components: + entry_size = len(entry) + 1 + if entry_size + data_size > PAGE_SIZE: + self.writeConfig(self.getSysfsPath(), {filename: '\n'.join(data)}) + data_size = 0 + data = [] + data.append(entry) + data_size += entry_size + + if data: + self.writeConfig(self.getSysfsPath(), {filename: '\n'.join(data)}) + + def setup(self): + super(ScdHwmonKernelDriver, self).setup() + + scd = self.component + data = [] + + for addr, info in scd.masters.items(): + data += ["master %#x %d %d" % (addr, info['id'], info['bus'])] + + for addr, name in scd.leds: + data += ["led %#x %s" % (addr, name)] + + for addr, info in scd.qsfps.items(): + data += ["qsfp %#x %u" % (addr, info['id'])] + + for addr, info in scd.sfps.items(): + data += ["sfp %#x %u" % (addr, info['id'])] + + for reset in scd.resets: + data += ["reset %#x %s %u" % (reset.addr, reset.name, reset.bit)] + + for gpio in scd.gpios: + data += ["gpio %#x %s %u %d %d" % (gpio.addr, gpio.name, gpio.bit, + int(gpio.ro), int(gpio.activeLow))] + + tweaks = [] + for tweak in scd.tweaks: + tweaks += ["%#x %#x %#x %#x %#x" % ( + tweak.bus, tweak.addr, tweak.t, tweak.datr, tweak.datw)] + + logging.debug('creating scd objects') + self.writeComponents(data, "new_object") + + if tweaks: + logging.debug('applying scd tweaks') + self.writeComponents(tweaks, "smbus_tweaks") + + def finish(self): + logging.debug('applying scd configuration') + path = self.getSysfsPath() + self.writeConfig(path, {'init_trigger': '1'}) + super(ScdHwmonKernelDriver, self).finish() + + def resetSim(self, value): + resets = self.component.getSysfsResetNameList() + logging.debug('reseting devices %s', resets) + + @simulateWith(resetSim) + def reset(self, value): + path = self.getSysfsPath() + for reset in self.component.getSysfsResetNameList(): + with open(os.path.join(path, reset), 'w') as f: + f.write('1' if value else '0') + + def resetIn(self): + self.reset(True) + + def resetOut(self): + self.reset(False) + +class ScdKernelDriver(PciKernelDriver): + def __init__(self, scd): + super(ScdKernelDriver, self).__init__(scd, 'sonic-support-driver') + + def oldSetup(self): + # converting internals to old format + scd = self.component + + qsfpType = 0 + sfpType = 1 + psuType = 2 + muxType = 3 + + resets = {} + for reset in scd.resets: + assert isinstance(reset, ResetGpio), "Invalid type for reset %s" % reset + v = resets.setdefault(reset.addr, []) + v.append((reset.bit, reset.name)) + + gpios = OrderedDict() + gpio_names = [] + gpio_type = [] + for gpio in scd.gpios: + assert isinstance(gpio, NamedGpio), "Invalid type for gpio %s" % gpio + v = gpios.setdefault(gpio.addr, []) + v.append(Gpio(gpio.bit, gpio.ro, gpio.activeLow)) + + # FIXME: works since only psus are gpios and the driver behave strangely + gpio_type.append(psuType) + gpio_names.append("psu") + if len(scd.gpios) > 2: + gpio_type.append(muxType) + gpio_names.append("mux") + + for addr, data in scd.qsfps.items(): + gpio_names.append("qsfp%d" % data['id']) + gpio_type.append(qsfpType) + gpios[addr] = data['gpios'] + + for addr, data in scd.sfps.items(): + gpio_names.append("sfp%d" % data['id']) + gpio_type.append(sfpType) + gpios[addr] = data['gpios'] + + # generating values + + reset_addrs = sorted(resets) + reset_names = [] + reset_masks = [] + + for addr in reset_addrs: + mask = 0 + (bits, names) = zip(*resets[addr]) + reset_names.extend(names) + for bit in bits: + mask |= (1 << bit) + reset_masks.append(mask) + + gpio_addrs = gpios.keys() + gpio_masks = [] + gpio_ro = [] + gpio_active_low = [] + + for addr in gpio_addrs: + mask = 0 + ro_mask = 0 + active_low_mask = 0 + for (bit, ro, active_low) in gpios[addr]: + mask |= (1 << bit) + if ro: + ro_mask |= (1 << bit) + if active_low: + active_low_mask |= (1 << bit) + gpio_masks.append(mask) + gpio_ro.append(ro_mask) + gpio_active_low.append(active_low_mask) + + (led_addrs, led_names) = zip(*scd.leds) + master_addrs = scd.masters.keys() + + files = [ + ('master_addrs', sysfsFmtHex), + ('reset_addrs', sysfsFmtHex), + ('reset_names', sysfsFmtStr), + ('reset_masks', sysfsFmtHex), + ('gpio_addrs', sysfsFmtHex), + ('gpio_masks', sysfsFmtHex), + ('gpio_names', sysfsFmtStr), + ('gpio_ro', sysfsFmtDec), + ('gpio_type', sysfsFmtHex), + ('gpio_active_low', sysfsFmtDec), + ('led_addrs', sysfsFmtHex), + ('led_names', sysfsFmtStr) + ] + variables = locals() + return {key: ",".join(map(fmt, variables[key])) for key, fmt in files} + + def writeConfig(self, path, data): + if inSimulation(): + print(data) + else: + for filename, value in data.items(): + try: + with open(os.path.join(path, filename), 'w') as f: + f.write(value) + except IOError as e: + logging.error('%s %s' % (e.filename, e.strerror)) + + def getConfigSysfsPath(self): + return os.path.join(self.getSysfsPath(), 'sonic_support_driver', + 'sonic_support_driver') + def setup(self): + super(ScdKernelDriver, self).setup() + data = self.oldSetup() + self.writeConfig(self.getConfigSysfsPath(), data) + + def finish(self): + logging.debug('applying scd configuration') + path = self.getSysfsPath() + self.writeConfig(path, {'init_trigger': '1'}) + + # FIXME: the direction should be set properly by the driver + logging.debug('setting gpio directions') + data = { + os.path.join(name, 'direction'): 'out' + for name, ro in self.component.allGpios() if not ro + } + self.writeConfig(path, data) + super(ScdKernelDriver, self).finish() + + def reset(self, value): + path = self.getSysfsPath() + if inSimulation(): + resets = self.component.getSysfsResetNameList() + logging.debug('reseting devices %s', resets) + return + for reset in self.component.getSysfsResetNameList(): + activeLow = False + with open(os.path.join(path, reset, 'active_low')) as f: + activeLow = bool(int(f.read(), 0)) + with open(os.path.join(path, reset, 'value'), 'w') as f: + f.write('1' if value != activeLow else '0') # logical xor + + def resetIn(self): + self.reset(True) + + def resetOut(self): + self.reset(False) + +class Scd(PciComponent): + BusTweak = namedtuple('BusTweak', 'bus, addr, t, datr, datw') + def __init__(self, addr, newDriver=False): + super(Scd, self).__init__(addr) + self.addDriver(KernelDriver, 'scd') + if newDriver: + self.addDriver(ScdHwmonKernelDriver) + self.rwCls = ScdSysfsRW + else: + self.addDriver(ScdKernelDriver) + self.rwCls = ScdSysfsOldRW + self.masters = OrderedDict() + self.resets = [] + self.gpios = [] + self.qsfps = OrderedDict() + self.sfps = OrderedDict() + self.leds = [] + self.tweaks = [] + + def addBusTweak(self, bus, addr, t=1, datr=1, datw=3): + self.tweaks.append(Scd.BusTweak(bus, addr, t, datr, datw)) + + def addSmbusMaster(self, addr, id, bus=8): + self.masters[addr] = { + 'id': id, + 'bus': bus, + } + + def addSmbusMasterRange(self, addr, count, spacing=0x100, bus=8): + addrs = range(addr, addr + (count + 1) * spacing, spacing) + for i, addr in enumerate(addrs, 0): + self.addSmbusMaster(addr, i, bus) + + def addLed(self, addr, name): + self.leds += [(addr, name)] + + def addLeds(self, leds): + self.leds += leds + + def addReset(self, gpio): + self.resets += [gpio] + + def addResets(self, gpios): + self.resets += gpios + + def addGpio(self, gpio): + self.gpios += [gpio] + + def addGpios(self, gpios): + self.gpios += gpios + + def addQsfp(self, addr, xcvrId, bus, eepromAddr=0x50): + self.qsfps[addr] = { + 'id': xcvrId, + 'bus': bus, + 'gpios': [ + Gpio(0, True, True), + Gpio(2, True, True), + Gpio(3, True, False), + Gpio(5, True, False), + Gpio(6, False, False), + Gpio(7, False, False), + Gpio(8, False, True), + ] + } + return ScdKernelXcvr(xcvrId, Xcvr.QSFP, eepromAddr, bus, self.drivers[1], + self.rwCls) + + def addSfp(self, addr, xcvrId, bus, eepromAddr=0x50): + self.sfps[addr] = { + 'id': xcvrId, + 'bus': bus, + 'gpios': [ + Gpio(0, True, False), + Gpio(1, True, False), + Gpio(2, True, True), + Gpio(3, True, False), + Gpio(4, True, False), + Gpio(5, True, False), + Gpio(6, False, False), + Gpio(7, False, False), + Gpio(8, False, False), + ] + } + return ScdKernelXcvr(xcvrId, Xcvr.SFP, eepromAddr, bus, self.drivers[1], + self.rwCls) + + def createPsu(self, psuId, statusSupported): + return ScdKernelPsu(psuId, self.drivers[1], self.rwCls, statusSupported) + + def allGpios(self): + def zipXcvr(xcvrType, gpio_names, entries): + res = [] + for data in entries.values(): + for name, gpio in zip(gpio_names, data['gpios']): + res += [ ("%s%d_%s" % (xcvrType, data['id'], name), gpio.ro) ] + return res + + sfp_names = [ + "rxlos", "txfault", "present", "rxlos_changed", "txfault_changed", + "present_changed", "txdisable", "rate_select0", "rate_select1", + ] + + qsfp_names = [ + "interrupt", "present", "interrupt_changed", "present_changed", + "lp_mode", "reset", "modsel", + ] + + gpios = [] + gpios += zipXcvr("sfp", sfp_names, self.sfps) + gpios += zipXcvr("qsfp", qsfp_names, self.qsfps) + gpios += [ (gpio.name, gpio.ro) for gpio in self.gpios ] + gpios += [ (reset.name, False) for reset in self.resets ] + return gpios + + def getSysfsResetNameList(self, xcvrs=True): + entries = [reset.name for reset in self.resets] + if xcvrs: + entries += ['qsfp%d_reset' % data['id'] for data in self.qsfps.values()] + return entries + diff --git a/platform/broadcom/sonic-platform-modules-arista/arista/core/__init__.py b/platform/broadcom/sonic-platform-modules-arista/arista/core/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/platform/broadcom/sonic-platform-modules-arista/arista/core/component.py b/platform/broadcom/sonic-platform-modules-arista/arista/core/component.py new file mode 100644 index 000000000000..c05333dd6a87 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/arista/core/component.py @@ -0,0 +1,109 @@ +from __future__ import print_function +from collections import defaultdict + +from .driver import Driver +from .utils import flatten + +import os + +DEFAULT_WAIT_TIMEOUT = 15 +ASIC_YIELD_TIME = os.getenv( 'ASIC_YIELD_TIME', 2 ) + +class Priority: + DEFAULT = 0 + BACKGROUND = 1 + +class Component(object): + def __init__(self, priority=Priority.DEFAULT, **kwargs): + self.components = defaultdict(list) + self.drivers = [] + self.priority = priority + for key, value in kwargs.items(): + setattr(self, key, value) + self.params = kwargs.keys() + + def __str__(self): + kwargs = ['%s=%s' % (k, getattr(self, k)) for k in self.params] + return '%s(%s)' % (self.__class__.__name__, ', '.join(kwargs)) + + def addComponents(self, components): + assert all(isinstance(c, Component) for c in components) + for component in components: + component.priority = max(component.priority, self.priority) + self.components[component.priority].append(component) + return self + + def addComponent(self, component): + assert isinstance(component, Component) + component.priority = max(component.priority, self.priority) + self.components[component.priority].append(component) + return self + + def addDriver(self, driverCls, *args, **kwargs): + assert issubclass(driverCls, Driver) + self.drivers += [driverCls(self, *args, **kwargs)] + return self + + def setup(self): + for driver in self.drivers: + driver.setup() + for driver in self.drivers: + driver.finish() + + def finish(self, priority=Priority.DEFAULT): + # underlying component are initialized recursively but require the parent to + # be fully initialized + for component in self.components[priority]: + component.setup() + for component in self.components[Priority.DEFAULT]: + component.finish(priority) + + def clean(self): + for component in flatten(self.components.values()): + component.clean() + for driver in reversed(self.drivers): + driver.clean() + + def resetIn(self): + for component in flatten(self.components.values()): + component.resetIn() + for driver in reversed(self.drivers): + driver.resetIn() + + def resetOut(self): + for driver in self.drivers: + driver.resetOut() + for component in flatten(self.components.values()): + component.resetOut() + + def waitForIt(self, timeout=DEFAULT_WAIT_TIMEOUT): + for component in flatten(self.components.values()): + component.waitForIt(timeout) + + def _dumpDrivers(self, depth, prefix): + if len(self.drivers) == 1: + self.drivers[0].dump(prefix=' => ') + elif self.drivers: + spacer = ' ' * (depth * 3) + print('%s%sdrivers:' % (spacer, prefix)) + for driver in self.drivers: + driver.dump(depth + 1) + + def _dumpNode(self, depth, prefix): + depth += 1 + spacer = ' ' * (depth * 3) + if self.drivers: + self._dumpDrivers(depth, prefix) + print('%s%scomponents:' % (spacer, prefix)) + for component in flatten(self.components.values()): + component.dump(depth + 1) + + def dump(self, depth=0, prefix=' - '): + spacer = ' ' * (depth * 3) + end = '' if len(self.drivers) == 1 else '\n' + print('%s%s%s' % (spacer, prefix,self), end=end) + if self.components: + self._dumpNode(depth, prefix) + else: + self._dumpDrivers(depth, prefix) + diff --git a/platform/broadcom/sonic-platform-modules-arista/arista/core/driver.py b/platform/broadcom/sonic-platform-modules-arista/arista/core/driver.py new file mode 100644 index 000000000000..ad3ffc0ffc67 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/arista/core/driver.py @@ -0,0 +1,106 @@ +from __future__ import print_function + +import logging +import os +import subprocess +import time + +from .utils import inDebug, inSimulation + +def modprobe(name, args=None): + logging.debug('loading module %s', name) + if args is None: + args = [] + args = ['modprobe', name.replace('-', '_')] + args + if inDebug(): + args += [ 'dyndbg=+pf' ] + if inSimulation(): + logging.debug('exec: %s', ' '.join(args)) + else: + subprocess.check_call(args) + +def rmmod(name): + logging.debug('unloading module %s', name) + args = ['modprobe', '-r', name.replace('-', '_')] + if inSimulation(): + logging.debug('exec: %s', ' '.join(args)) + else: + subprocess.check_call(args) + +def isModuleLoaded(name): + with open('/proc/modules') as f: + start = '%s ' % name.replace('-', '_') + for line in f.readlines(): + if line.startswith(start): + return True + return False + +class Driver(object): + def __init__(self, component): + self.component = component + + def setup(self): + pass + + def finish(self): + pass + + def clean(self): + pass + + def resetIn(self): + pass + + def resetOut(self): + pass + + def dump(self, depth=0, prefix=' - '): + spacer = ' ' * (depth * 3) + print('%s%s%s' % (spacer, prefix, self)) + +class KernelDriver(Driver): + # TODO: handle multiple kernel modules + def __init__(self, component, module, waitFile=None, args=None): + super(KernelDriver, self).__init__(component) + self.component = component + self.module = module + self.args = args if args is not None else [] + self.waitFile = waitFile + + def waitFileReady(self): + if not self.waitFile: + return + + logging.debug('Starting driver. Waiting file %s.', self.waitFile) + + count = 0 + while not os.path.exists(self.waitFile) and count <= 20: + time.sleep(0.05) + count = count + 1 + logging.debug('Starting driver. Waiting file %s attempt %d.', + self.waitFile, count) + if not os.path.exists(self.waitFile): + logging.error('Starting driver. Waiting file %s failed.', + self.waitFile) + + def setup(self): + modprobe(self.module, self.args) + self.waitFileReady() + + def clean(self): + if self.loaded(): + try: + rmmod(self.module) + except Exception as e: + logging.error('Failed to unload %s: %s', self.module, e) + else: + logging.debug('Module %s is not loaded', self.module) + + def loaded(self): + return isModuleLoaded(self.module) + + def getSysfsPath(self): + raise NotImplementedError + + def __str__(self): + return '%s(%s)' % (self.__class__.__name__, self.module) diff --git a/platform/broadcom/sonic-platform-modules-arista/arista/core/inventory.py b/platform/broadcom/sonic-platform-modules-arista/arista/core/inventory.py new file mode 100644 index 000000000000..b5f9b453bca0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/arista/core/inventory.py @@ -0,0 +1,101 @@ +from collections import defaultdict + +class Xcvr(object): + + SFP = 0 + QSFP = 1 + + def __init__(self, portNum, xcvrType, eepromAddr, bus): + self.portNum = portNum + self.xcvrType = xcvrType + self.bus = bus + self.eepromAddr = eepromAddr + + def getPresence(self): + raise NotImplementedError() + + def getLowPowerMode(self): + raise NotImplementedError() + + def setLowPowerMode(self, value): + raise NotImplementedError() + + def reset(self, value): + raise NotImplementedError() + +class Psu(object): + def getPresence(self): + raise NotImplementedError() + + def getStatus(self): + raise NotImplementedError() + +class Inventory(object): + def __init__(self): + self.sfpRange = [] + self.qsfpRange = [] + self.allXcvrsRange = [] + + self.portStart = None + self.portEnd = None + + self.xcvrs = {} + + self.xcvrLeds = defaultdict(list) + self.statusLeds = [] + + self.psus = [] + + def freeze(self): + # XXX: compute the range and some basic information from the various + # collections present in the inventory + # XXX: try to avoid that actually + pass + + def addPorts(self, sfps=None, qsfps=None): + if sfps: + self.sfpRange = sfps + if qsfps: + self.qsfpRange = qsfps + + self.allXcvrsRange = sorted(self.sfpRange + self.qsfpRange) + self.portStart = self.allXcvrsRange[0] + self.portEnd = self.allXcvrsRange[-1] + + def addXcvr(self, xcvr): + self.xcvrs[xcvr.portNum] = xcvr + + def getXcvrs(self): + return self.xcvrs + + def getXcvr(self, xcvrId): + return self.xcvrs[xcvrId] + + def getPortToEepromMapping(self): + eepromPath = '/sys/class/i2c-adapter/i2c-{0}/{0}-{1:04x}/eeprom' + return { xcvrId : eepromPath.format(xcvr.bus, xcvr.eepromAddr) + for xcvrId, xcvr in self.xcvrs.items() } + + def getPortToI2cAdapterMapping(self): + return { xcvrId : xcvr.bus for xcvrId, xcvr in self.xcvrs.items() } + + def addXcvrLed(self, xcvrId, name): + self.xcvrLeds[xcvrId].append(name) + + def addStatusLed(self, name): + self.statusLeds.append(name) + + def addStatusLeds(self, names): + self.statusLeds.extend(names) + + def addPsus(self, psus): + self.psus = psus + + def getPsu(self, index): + return self.psus[index] + + def getNumPsus(self): + return len(self.psus) + + + diff --git a/platform/broadcom/sonic-platform-modules-arista/arista/core/platform.py b/platform/broadcom/sonic-platform-modules-arista/arista/core/platform.py new file mode 100644 index 000000000000..da27c7ba2200 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/arista/core/platform.py @@ -0,0 +1,125 @@ +from __future__ import print_function + +import logging +import subprocess +import os +import sys + +from collections import OrderedDict, namedtuple, defaultdict + +from .inventory import Inventory +from .component import Component, Priority +from .utils import simulateWith +from .driver import modprobe, rmmod, KernelDriver + +from . import prefdl + +platforms = {} +syseeprom = None + +host_prefdl_path = '/host/.system-prefdl' +fmted_prefdl_path = '/etc/sonic/.syseeprom' + +def formatPrefdlData(data): + formatDict = { + "MAC": ["MAC", "MacAddrBase", "Mac"], + "SKU": ["SKU", "Sku"], + "SerialNumber": ["SerialNumber"], + } + fdata = { } + for k, v in data.items(): + for kfmt, vfmt in formatDict.items(): + if k in vfmt: + if kfmt == "MAC": + val = prefdl.showMac(v) + else: + val = v + fdata[kfmt] = val + return fdata + +def writeFormattedPrefdl(pfdl, f): + fdata = formatPrefdlData(pfdl.data()) + with open(f, 'w+') as fp: + for k, v in fdata.items(): + fp.write("%s: %s\n" % (k, v)) + +def readPrefdl(): + if os.path.exists(fmted_prefdl_path): + with open(fmted_prefdl_path) as fp: + logging.debug('reading system eeprom from %s', fmted_prefdl_path) + return prefdl.PreFdlFromFile(fp) + + if os.path.exists(host_prefdl_path): + with open(host_prefdl_path) as fp: + logging.debug('reading system eeprom from %s', host_prefdl_path) + pfdl = prefdl.PreFdlFromFile(fp) + writeFormattedPrefdl(pfdl, fmted_prefdl_path) + with open(fmted_prefdl_path) as fp: + return prefdl.PreFdlFromFile(fp) + + modprobe('eeprom') + for addr in ['1-0052']: + eeprompath = os.path.join('/sys/bus/i2c/drivers/eeprom', addr, 'eeprom') + if not os.path.exists(eeprompath): + continue + try: + with open(eeprompath) as fp: + logging.debug('reading system eeprom from %s', eeprompath) + pfdl = prefdl.decode(fp) + pfdl.writeToFile(fmted_prefdl_path) + return pfdl + except Exception as e: + logging.warn('could not obtain prefdl from %s', eeprompath) + logging.warn('error seen: %s', e) + raise RuntimeError("Could not find valid system eeprom") + +def getPrefdlDataSim(): + logging.debug('bypass prefdl reading by returning default values') + return {'SKU': 'simulation'} + +@simulateWith(getPrefdlDataSim) +def getPrefdlData(): + return readPrefdl().data() + +def getSysEeprom(): + global syseeprom + if not syseeprom: + syseeprom = getPrefdlData() + assert 'SKU' in syseeprom + return syseeprom + +def detectPlatform(): + return getSysEeprom()['SKU'] + +def getPlatform(name=None): + if name == None: + name = detectPlatform() + return platforms[name]() + +def getPlatforms(): + return platforms + +def registerPlatform(skus): + global platforms + def wrapper(cls): + if isinstance(skus, list): + for sku in skus: + platforms[sku] = cls + else: + platforms[skus] = cls + return cls + return wrapper + +class Platform(Component): + def __init__(self): + super(Platform, self).__init__() + self.addDriver(KernelDriver, 'eeprom') + self.addDriver(KernelDriver, 'i2c-dev') + self.inventory = Inventory() + + def setup(self, priority=Priority.DEFAULT): + super(Platform, self).setup() + super(Platform, self).finish(priority) + + def getInventory(self): + return self.inventory diff --git a/platform/broadcom/sonic-platform-modules-arista/arista/core/prefdl.py b/platform/broadcom/sonic-platform-modules-arista/arista/core/prefdl.py new file mode 100755 index 000000000000..036f5be702cd --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/arista/core/prefdl.py @@ -0,0 +1,225 @@ +#!/usr/bin/env python +# +# Copyright (C) 2016 Arista Networks, 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 3 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, see . + +import re +import struct +import sys +import zlib + +def showMac( m ): + return ":".join([m[0:2], m[2:4], m[4:6], m[6:8], m[8:10], m[10:12]]) + +typeMap = { + "END" : ( "00", None, None, None, False ), + "SKU" : ( "03", None, None, None, False ), + "MAC" : ( "05", None, showMac, None, False ), + "SerialNumber" : ( "0E", None, None, None, False ), +} + +idToNameMap = {} +for k, v in typeMap.items(): + idToNameMap[ v[0] ] = k + +def crc32( data ): + return struct.unpack("I",struct.pack("i",zlib.crc32( data )))[0] + +def validSerial( x ): + x = x.replace( " ", "" ) + x = x.replace( "-", "" ) + # All serial numbers are upper case + x = x.upper() + if re.compile( "[A-Z]{3}\d{4}[A-Z0-9]{4}$" ).match( x ): + return x + return None + +class PreFdlField( ): + def __init__( self, name, valid, show, optionName, data=None, append=False ): + self.name = name + if valid: + self.valid = valid + else: + self.valid = lambda x: x + self.show = show + self.optionName = optionName + self.data = [] + self.append = append + if data: + self.dataIs( data ) + + def dataIs( self, data ): + vd = self.valid( data ) + if not vd: + raise InvalidPrefdlData( "Invalid %s: %s" % ( self.name, data ) ) + if self.append: + self.data.append( vd ) + else: + self.data = [ vd ] + +class TlvField( PreFdlField ): + def __init__( self, name ): + args = typeMap.get( name ) + valid = None + show = None + optionName = None + append = False + if args: + self.id, valid, show, optionName, append = args + PreFdlField.__init__( self, name, valid, show, optionName, append=append ) + +class PreFdl(): + def __init__( self, fp=None, preFdlStr=None, version="0002" ): + # populate the required fields + self.requiredFields = [] + + if version == "0002": + preFdlStr, offset = self.initPreFdl2( fp, preFdlStr ) + elif version == "0003": + preFdlStr, offset = self.initPreFdl3( fp, preFdlStr ) + else: + raise NotImplementedError( + "Only Prefdl data format version 0002 or 0003 are supported" ) + + # populate the tlv fileds + self.tlvFields = {} + for k in typeMap.keys(): + self.tlvFields[ k ] = TlvField( k ) + + # create the map option to field + self.optionMap = {} + for f in self.requiredFields + self.tlvFields.values(): + # Do not add the option from TLV if already added by required fields + if f.optionName and f.optionName not in self.optionMap: + self.optionMap[ f.optionName ] = f + + # save the current tlv fields + if fp: + while True: + tlv = fp.read( 6 ) + ( id, lengthStr ) = ( tlv[0:2], tlv[2:6] ) + length = int( lengthStr, base=16 ) + bytes = fp.read( length ) + what = None if id not in idToNameMap.keys() else idToNameMap[ id ] + if what and what != "END": + self.tlvFields[ what ].dataIs( bytes ) + preFdlStr += tlv + bytes + offset += 6 + length + if what == "END": + # End of the tlv list + break + self.crc = fp.read( 8 ) + # Check the CRC + computed = crc32( preFdlStr ) + if int( self.crc, 16 ) != computed: + raise Exception( "Invalid CRC -- saw %s expected %8X" % + ( self.crc, computed ) ) + + # Initialize and parse fixed section for prefdl version 2. Return the offset + # to where the TLV section starts. + def initPreFdl2( self, fp, preFdlStr ): + # if we start with an existing file + if fp: + # if no preFdlStr is specified, read the fixed section, 30 bytes. + # Otherwise, only the 4 byte data version section was written and + # read the remaining 26 bytes from the fixed section. + if not preFdlStr: + preFdlStr = fp.read( 30 ).strip() + elif preFdlStr == "0002": + preFdlStr += fp.read( 26 ).strip() + else: + raise ValueError( "preFdlStr arg has invalid data format" ) + if len( preFdlStr ) < 12: + fatal( "prefdl is too short exiting" ) + data = None if not preFdlStr else preFdlStr[ 16:16 + 11 ] + self.requiredFields.append( + PreFdlField( "SerialNumber", validSerial, None, None, data ) ) + return preFdlStr, 30 + + # Initialize and parse fixed section for prefdl version 3. Return the offset + # to where the TLV section starts. + def initPreFdl3( self, fp, preFdlStr ): + # if we start with an existing file + currPtr = 0 + if fp and not preFdlStr: + preFdlStr = fp.read( 4 ).strip() + if len( preFdlStr ) < 4: + fatal( "prefdl is too short exiting" ) + return preFdlStr, 4 + + def data( self ): + res = {} + for f in self.requiredFields + self.tlvFields.values(): + for d in f.data: + dStr = d if f.show is None else f.show( d ) + res[f.name] = dStr + return res + + def show( self ): + for k, v in self.data().items(): + print("%s: %s" % (k, v)) + + def writeToFile(self, f): + with open(f, 'w+') as fp: + for k, v in self.data().items(): + fp.write("%s: %s\n" % (k, v)) + + def getField( self, name ): + return self.data().get( name, None ) + + def getCrc( self ): + return self.crc + +class PreFdlFromFile(): + def __init__(self, fp): + self._data = {} + for line in fp: + key, val = line.strip().split(': ', 1) + self._data[key] = val + self.crc = self._data.pop('Crc', -1) + + def data(self): + return self._data + + def show(self): + for key, val in self._data.items(): + print("%s: %s" % (key, val)) + + def getField(self, name): + return self._data[name] + + def getCrc(self): + return self.crc + +def decode( fp ): + data = fp.read( 4 ) + data = data.strip() + # For format 0002 and more recent fdls use the new Prefdl class + if data not in ( "0002", "0003" ): + raise ValueError + return PreFdl( fp, data, data ) + +def main(): + output = sys.argv[1] + + if output == "-": + fp = sys.stdin + else: + fp = file( output, "r" ) + + decode( fp ).show() + +if __name__ == "__main__": + main() diff --git a/platform/broadcom/sonic-platform-modules-arista/arista/core/types.py b/platform/broadcom/sonic-platform-modules-arista/arista/core/types.py new file mode 100644 index 000000000000..ab47cabff080 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/arista/core/types.py @@ -0,0 +1,29 @@ +from collections import namedtuple + +Register = namedtuple("Register", ["addr", "ro"]) +NamedRegister = namedtuple("NamedRegister", Register._fields + ("name", )) + +Gpio = namedtuple("Gpio", ["bit", "ro", "activeLow"]) +NamedGpio = namedtuple("NamedGpio", ("addr",) + Gpio._fields + ("name",)) + +ResetGpio = namedtuple("ResetGpio", ["addr", "bit", "activeLow", "name"]) + +class I2cAddr(object): + def __init__(self, bus, address): + self.bus = bus + self.address = address + + def __str__(self): + return '%d-00%02x' % (self.bus, self.address) + +class PciAddr(object): + def __init__(self, domain=0, bus=0, device=0, func=0): + self.domain = domain + self.bus = bus + self.device = device + self.func = func + + def __str__(self): + return '%04x:%02x:%02x.%d' % (self.domain, self.bus, self.device, self.func) + + diff --git a/platform/broadcom/sonic-platform-modules-arista/arista/core/utils.py b/platform/broadcom/sonic-platform-modules-arista/arista/core/utils.py new file mode 100644 index 000000000000..c560accbe010 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/arista/core/utils.py @@ -0,0 +1,129 @@ +import logging +import fcntl + +from functools import wraps + +def sysfsFmtHex(x): + return "0x%08x" % x + +def sysfsFmtDec(x): + return "%d" % x + +def sysfsFmtStr(x): + return str(x) + +def incrange(start, stop): + return list(range(start, stop + 1)) + +def flatten(nestedList): + return [val for sublist in nestedList for val in sublist] + +def klog(msg, level=2, *args): + try: + with open('/dev/kmsg', 'w') as f: + f.write('<%d>arista: %s\n' % (level, msg % tuple(*args))) + except: + pass + +class FileLock: + def __init__(self, lock_file): + self.f = open(lock_file, 'w') + + def lock(self): + fcntl.flock(self.f, fcntl.LOCK_EX) + + def unlock(self): + fcntl.flock(self.f, fcntl.LOCK_UN) + self.f.close() + + def __enter__(self): + self.lock() + + def __exit__(self, exc_type, exc_val, traceback): + self.unlock() + +class NoopObj(object): + def __init__(self, *args, **kwargs): + self.name = self.__class__.__name__ + self.classStr = '%s(%s)' % (self.name, self._fmtArgs(*args, **kwargs)) + logging.debug(self.classStr) + + def _fmtArgs(self, *args, **kwargs): + kw = ['%s=%s' % (k,v) for k, v in kwargs.items()] + return ', '.join(list(map(str, args)) + kw) + + def noop(self, attr): + def wrapped(*args, **kwargs): + funcStr = '%s(%s)' % (attr, self._fmtArgs(*args, **kwargs)) + logging.debug('%s.%s', self.classStr, funcStr) + return wrapped + + def __getattr__(self, attr): + return self.noop(attr) + +CMDLINE_PATH = '/proc/cmdline' + +cmdlineDict = {} +def getCmdlineDict(): + global cmdlineDict + + if cmdlineDict: + return cmdlineDict + + data = {} + with open(CMDLINE_PATH) as f: + for entry in f.read().split(): + idx = entry.find('=') + if idx == -1: + data[entry] = None + else: + data[entry[:idx]] = entry[idx+1:] + + cmdlineDict = data + return data + +# debug flag, if enabled should use the most tracing possible +debug = False + +# force simulation to be True if not on a Arista box +simulation = True + +# simulation related globals +SMBus = None + +def inDebug(): + return debug + +def inSimulation(): + return simulation + +def simulateWith(simulatedFunc): + def simulateThisFunc(func): + @wraps(func) + def funcWrapper(*args, **kwargs): + if inSimulation(): + return simulatedFunc(*args, **kwargs) + return func(*args, **kwargs) + return funcWrapper + return simulateThisFunc + +def libraryInit(): + global simulation, debug, SMBus + + cmdline = getCmdlineDict() + if "Aboot" in cmdline: + simulation = False + + if "arista-debug" in cmdline: + debug = True + + if simulation: + SMBus = type('SMBus', (NoopObj,), {}) + else: + try: + from smbus import SMBus + except ImportError: + pass + +libraryInit() + diff --git a/platform/broadcom/sonic-platform-modules-arista/arista/platforms/__init__.py b/platform/broadcom/sonic-platform-modules-arista/arista/platforms/__init__.py new file mode 100644 index 000000000000..14e93ec982c9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/arista/platforms/__init__.py @@ -0,0 +1,5 @@ + +from . import a7050qx32 +from . import a7050qx32s +from . import a7060cx32s +from . import a7260cx364 diff --git a/platform/broadcom/sonic-platform-modules-arista/arista/platforms/a7050qx32.py b/platform/broadcom/sonic-platform-modules-arista/arista/platforms/a7050qx32.py new file mode 100644 index 000000000000..afc4dd2bcf49 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/arista/platforms/a7050qx32.py @@ -0,0 +1,94 @@ +from ..core.platform import registerPlatform, Platform +from ..core.driver import KernelDriver +from ..core.utils import incrange +from ..core.types import PciAddr, I2cAddr, Gpio, NamedGpio, ResetGpio +from ..core.component import Priority + +from ..components.common import SwitchChip, I2cKernelComponent +from ..components.scd import Scd +from ..components.ds460 import Ds460 + +@registerPlatform('DCS-7050QX-32') +class Cloverdale(Platform): + def __init__(self): + super(Cloverdale, self).__init__() + + self.fanCount = 4 + self.qsfp40gAutoRange = incrange(1, 24) + self.qsfp40gOnlyRange = incrange(25, 32) + self.allQsfps = sorted(self.qsfp40gAutoRange + self.qsfp40gOnlyRange) + self.sfpRange = [] + + self.inventory.addPorts(qsfps=self.allQsfps) + + self.addDriver(KernelDriver, 'raven-fan-driver', '/sys/class/hwmon/hwmon1') + + switchChip = SwitchChip(PciAddr(bus=0x02)) + self.addComponent(switchChip) + + scd = Scd(PciAddr(bus=0x04)) + self.addComponent(scd) + + scd.addComponents([ + I2cKernelComponent(I2cAddr(2, 0x4c), 'max6658', '/sys/class/hwmon/hwmon2'), + I2cKernelComponent(I2cAddr(3, 0x48), 'lm73', '/sys/class/hwmon/hwmon3'), + Ds460(I2cAddr(5, 0x58), priority=Priority.BACKGROUND), + Ds460(I2cAddr(6, 0x58), priority=Priority.BACKGROUND), + + # Due to a risk of an unrecoverable firmware corruption when a pmbus + # transaction is done at the same moment of the poweroff, the handling of + # the DPM is disabled. If you want rail information use it at your own risk + #I2cKernelComponent(I2cAddr(3, 0x4e), 'pmbus'), # ucd90120A + #I2cKernelComponent(I2cAddr(7, 0x4e), 'pmbus'), # ucd90120A + ]) + + scd.addSmbusMasterRange(0x8000, 5) + + scd.addLeds([ + (0x6050, 'status'), + (0x6060, 'fan_status'), + (0x6070, 'psu1'), + (0x6080, 'psu2'), + (0x6090, 'beacon'), + ]) + self.inventory.addStatusLeds(['status', 'fan_status', 'psu1', + 'psu2']) + + scd.addResets([ + ResetGpio(0x4000, 0, False, 'switch_chip_reset'), + ResetGpio(0x4000, 2, False, 'phy1_reset'), + ResetGpio(0x4000, 3, False, 'phy2_reset'), + ResetGpio(0x4000, 4, False, 'phy3_reset'), + ResetGpio(0x4000, 5, False, 'phy4_reset'), + ]) + + scd.addGpios([ + NamedGpio(0x5000, 0, True, False, "psu1_present"), + NamedGpio(0x5000, 1, True, False, "psu2_present"), + ]) + self.inventory.addPsus([scd.createPsu(1, False), scd.createPsu(2, False)]) + + addr = 0x6100 + for xcvrId in self.qsfp40gAutoRange: + for laneId in incrange(1, 4): + name = "qsfp%d_%d" % (xcvrId, laneId) + scd.addLed(addr, name) + self.inventory.addXcvrLed(xcvrId, name) + addr += 0x10 + + addr = 0x6720 + for xcvrId in self.qsfp40gOnlyRange: + name = "qsfp%d" % xcvrId + scd.addLed(addr, name) + self.inventory.addXcvrLed(xcvrId, name) + addr += 0x30 if xcvrId % 2 else 0x50 + + addr = 0x5010 + bus = 10 + for xcvrId in self.allQsfps: + xcvr = scd.addQsfp(addr, xcvrId, bus) + scd.addComponent(I2cKernelComponent( + I2cAddr(bus, xcvr.eepromAddr), 'sff8436')) + self.inventory.addXcvr(xcvr) + addr += 0x10 + bus += 1 diff --git a/platform/broadcom/sonic-platform-modules-arista/arista/platforms/a7050qx32s.py b/platform/broadcom/sonic-platform-modules-arista/arista/platforms/a7050qx32s.py new file mode 100644 index 000000000000..a95dba7e4200 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/arista/platforms/a7050qx32s.py @@ -0,0 +1,116 @@ +from ..core.platform import registerPlatform, Platform +from ..core.driver import KernelDriver +from ..core.utils import incrange +from ..core.types import PciAddr, I2cAddr, Gpio, NamedGpio, ResetGpio +from ..core.component import Priority + +from ..components.common import SwitchChip, I2cKernelComponent +from ..components.scd import Scd +from ..components.ds125br import Ds125Br + +@registerPlatform('DCS-7050QX-32S') +class Clearlake(Platform): + def __init__(self): + super(Clearlake, self).__init__() + + # FIXME: due to an issue with the kernel drivers, the sfp ports are disabled + # self.sfpRange = incrange(1, 4) + self.sfpRange = [] + self.qsfp40gAutoRange = incrange(5, 28) + self.qsfp40gOnlyRange = incrange(29, 36) + self.allQsfps = sorted(self.qsfp40gAutoRange + self.qsfp40gOnlyRange) + + self.inventory.addPorts(qsfps=self.allQsfps) + + self.addDriver(KernelDriver, 'crow-fan-driver', '/sys/class/hwmon/hwmon1') + + switchChip = SwitchChip(PciAddr(bus=0x01)) + self.addComponent(switchChip) + + scd = Scd(PciAddr(bus=0x02)) + self.addComponent(scd) + + scd.addComponents([ + I2cKernelComponent(I2cAddr(2, 0x4c), 'max6658', '/sys/class/hwmon/hwmon2'), + I2cKernelComponent(I2cAddr(3, 0x4c), 'max6658', '/sys/class/hwmon/hwmon3'), + I2cKernelComponent(I2cAddr(3, 0x60), 'crow_cpld', '/sys/class/hwmon/hwmon4'), + # Handling of the DPM is disabled because this functionality is unstable. + #I2cKernelComponent(I2cAddr(3, 0x4e), 'pmbus', + # priority=Priority.BACKGROUND), # ucd90120A + I2cKernelComponent(I2cAddr(5, 0x58), 'pmbus', + priority=Priority.BACKGROUND), + I2cKernelComponent(I2cAddr(6, 0x58), 'pmbus', + priority=Priority.BACKGROUND), + # Handling of the DPM is disabled because this functionality is unstable. + #I2cKernelComponent(I2cAddr(7, 0x4e), 'pmbus', + # priority=Priority.BACKGROUND), # ucd90120A + Ds125Br(I2cAddr(8, 0xff)), + ]) + + scd.addSmbusMasterRange(0x8000, 6) + + scd.addLeds([ + (0x6050, 'status'), + (0x6060, 'fan_status'), + (0x6070, 'psu1'), + (0x6080, 'psu2'), + (0x6090, 'beacon'), + ]) + self.inventory.addStatusLeds(['status', 'fan_status', 'psu1', + 'psu2']) + + scd.addReset(ResetGpio(0x4000, 0, False, 'switch_chip_reset')) + + scd.addGpios([ + NamedGpio(0x5000, 0, True, False, "psu1_present"), + NamedGpio(0x5000, 1, True, False, "psu2_present"), + NamedGpio(0x6940, 0, False, False, "mux"), # FIXME: oldSetup order/name + ]) + self.inventory.addPsus([scd.createPsu(1, False), scd.createPsu(2, False)]) + + addr = 0x6100 + for xcvrId in self.qsfp40gAutoRange: + for laneId in incrange(1, 4): + name = "qsfp%d_%d" % (xcvrId, laneId) + scd.addLed(addr, name) + self.inventory.addXcvrLed(xcvrId, name) + addr += 0x10 + + addr = 0x6720 + for xcvrId in self.qsfp40gOnlyRange: + name = "qsfp%d" % xcvrId + scd.addLed(addr, name) + self.inventory.addXcvrLed(xcvrId, name) + addr += 0x30 if xcvrId % 2 else 0x50 + + addr = 0x6900 + for xcvrId in self.sfpRange: + name = "sfp%d" % xcvrId + scd.addLed(addr, name) + self.inventory.addXcvrLed(xcvrId, name) + addr += 0x10 + + addr = 0x5010 + bus = 10 + for xcvrId in self.allQsfps: + xcvr = scd.addQsfp(addr, xcvrId, bus) + self.inventory.addXcvr(xcvr) + scd.addComponent(I2cKernelComponent( + I2cAddr(bus, xcvr.eepromAddr), 'sff8436')) + addr += 0x10 + bus += 1 + + addr = 0x5210 + bus = 42 + for xcvrId in sorted(self.sfpRange): + xcvr = scd.addSfp(addr, xcvrId, bus) + self.inventory.addXcvr(xcvr) + scd.addComponent(I2cKernelComponent( + I2cAddr(bus, xcvr.eepromAddr), 'sff8436')) + addr += 0x10 + bus += 1 + +@registerPlatform('DCS-7050QX2-32S') +class ClearlakePlus(Clearlake): + pass + diff --git a/platform/broadcom/sonic-platform-modules-arista/arista/platforms/a7060cx32s.py b/platform/broadcom/sonic-platform-modules-arista/arista/platforms/a7060cx32s.py new file mode 100644 index 000000000000..9547fe9f0a39 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/arista/platforms/a7060cx32s.py @@ -0,0 +1,102 @@ +from ..core.platform import registerPlatform, Platform +from ..core.driver import KernelDriver +from ..core.utils import incrange +from ..core.types import PciAddr, I2cAddr, Gpio, NamedGpio, ResetGpio +from ..core.component import Priority + +from ..components.common import SwitchChip, I2cKernelComponent +from ..components.scd import Scd + +@registerPlatform(['DCS-7060CX-32S', 'DCS-7060CX-32S-ES']) +class Upperlake(Platform): + def __init__(self): + super(Upperlake, self).__init__() + + self.sfpRange = incrange(33, 34) + self.qsfp100gRange = incrange(1, 32) + + self.inventory.addPorts(sfps=self.sfpRange, qsfps=self.qsfp100gRange) + + self.addDriver(KernelDriver, 'crow-fan-driver') + + switchChip = SwitchChip(PciAddr(bus=0x01)) + self.addComponent(switchChip) + + scd = Scd(PciAddr(bus=0x02), newDriver=True) + self.addComponent(scd) + + scd.addComponents([ + I2cKernelComponent(I2cAddr(2, 0x1a), 'max6697', '/sys/class/hwmon/hwmon1'), + I2cKernelComponent(I2cAddr(3, 0x4c), 'max6658', '/sys/class/hwmon/hwmon2'), + I2cKernelComponent(I2cAddr(3, 0x60), 'crow_cpld', '/sys/class/hwmon/hwmon3'), + # Handling of the DPM is disabled because this functionality is unstable. + #I2cKernelComponent(I2cAddr(3, 0x4e), 'pmbus', + # priority=Priority.BACKGROUND), # ucd90120A + I2cKernelComponent(I2cAddr(5, 0x58), 'pmbus', + priority=Priority.BACKGROUND), + I2cKernelComponent(I2cAddr(6, 0x58), 'pmbus', + priority=Priority.BACKGROUND), + # Handling of the DPM is disabled because this functionality is unstable. + #I2cKernelComponent(I2cAddr(7, 0x4e), 'pmbus', + # priority=Priority.BACKGROUND), # ucd90120A + ]) + + scd.addSmbusMasterRange(0x8000, 5, 0x80) + + scd.addLeds([ + (0x6050, 'status'), + (0x6060, 'fan_status'), + (0x6070, 'psu1'), + (0x6080, 'psu2'), + (0x6090, 'beacon'), + ]) + self.inventory.addStatusLeds(['status', 'fan_status', 'psu1', 'psu2']) + + scd.addResets([ + ResetGpio(0x4000, 1, False, 'switch_chip_reset'), + ResetGpio(0x4000, 2, False, 'switch_chip_pcie_reset'), + ]) + + scd.addGpios([ + NamedGpio(0x5000, 0, True, False, "psu1_present"), + NamedGpio(0x5000, 1, True, False, "psu2_present"), + ]) + self.inventory.addPsus([scd.createPsu(1, False), scd.createPsu(2, False)]) + + addr = 0x6100 + for xcvrId in self.sfpRange: + name = "sfp%d" % xcvrId + scd.addLed(addr, name) + self.inventory.addXcvrLed(xcvrId, name) + addr += 0x10 + + addr = 0x6140 + for xcvrId in self.qsfp100gRange: + for laneId in incrange(1, 4): + name = "qsfp%d_%d" % (xcvrId, laneId) + scd.addLed(addr, name) + self.inventory.addXcvrLed(xcvrId, name) + addr += 0x10 + + addr = 0x5010 + bus = 10 + for xcvrId in self.sfpRange: + xcvr = scd.addSfp(addr, xcvrId, bus) + self.inventory.addXcvr(xcvr) + scd.addComponent(I2cKernelComponent( + I2cAddr(bus, xcvr.eepromAddr), 'sff8436')) + scd.addBusTweak(bus, xcvr.eepromAddr) + addr += 0x10 + bus += 1 + + addr = 0x5050 + bus = 18 + for xcvrId in self.qsfp100gRange: + xcvr = scd.addQsfp(addr, xcvrId, bus) + self.inventory.addXcvr(xcvr) + scd.addComponent(I2cKernelComponent( + I2cAddr(bus, xcvr.eepromAddr), 'sff8436')) + scd.addBusTweak(bus, xcvr.eepromAddr) + addr += 0x10 + bus += 1 + diff --git a/platform/broadcom/sonic-platform-modules-arista/arista/platforms/a7260cx364.py b/platform/broadcom/sonic-platform-modules-arista/arista/platforms/a7260cx364.py new file mode 100644 index 000000000000..514728f12211 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/arista/platforms/a7260cx364.py @@ -0,0 +1,106 @@ +from ..core.platform import registerPlatform, Platform +from ..core.driver import KernelDriver +from ..core.utils import incrange +from ..core.types import PciAddr, I2cAddr, Gpio, NamedGpio, ResetGpio +from ..core.component import Priority + +from ..components.common import SwitchChip, I2cKernelComponent +from ..components.scd import Scd +from ..components.ds125br import Ds125Br +from ..components.ds460 import Ds460 + +@registerPlatform('DCS-7260CX3-64') +class Gardena(Platform): + def __init__(self): + super(Gardena, self).__init__() + + self.sfpRange = incrange(65, 66) + self.qsfpRange = incrange(1, 64) + + self.inventory.addPorts(qsfps=self.qsfpRange, sfps=self.sfpRange) + + self.addDriver(KernelDriver, 'rook-fan-cpld') + self.addDriver(KernelDriver, 'rook-led-driver') + + switchChip = SwitchChip(PciAddr(bus=0x07)) + self.addComponent(switchChip) + + scd = Scd(PciAddr(bus=0x06), newDriver=True) + self.addComponent(scd) + + scd.addComponents([ + I2cKernelComponent(I2cAddr(1, 0x4c), 'max6658', '/sys/class/hwmon/hwmon1'), + I2cKernelComponent(I2cAddr(3, 0x58), 'pmbus', + priority=Priority.BACKGROUND), + I2cKernelComponent(I2cAddr(4, 0x58), 'pmbus', + priority=Priority.BACKGROUND), + ]) # Incomplete + + scd.addSmbusMasterRange(0x8000, 8, 0x80) + + scd.addResets([ + ResetGpio(0x4000, 0, False, 'switch_chip_reset'), + ResetGpio(0x4000, 1, False, 'switch_chip_pcie_reset'), + ResetGpio(0x4000, 2, False, 'security_asic_reset'), + ]) + + scd.addGpios([ + NamedGpio(0x5000, 0, True, False, "psu1_present"), + NamedGpio(0x5000, 1, True, False, "psu2_present"), + NamedGpio(0x5000, 8, True, False, "psu1_status"), + NamedGpio(0x5000, 9, True, False, "psu2_status"), + NamedGpio(0x5000, 10, True, False, "psu1_ac_status"), + NamedGpio(0x5000, 11, True, False, "psu2_ac_status"), + ]) + self.inventory.addPsus([scd.createPsu(1, True), scd.createPsu(2, True)]) + + addr = 0x6100 + for xcvrId in self.qsfpRange: + for laneId in incrange(1, 4): + name = "qsfp%d_%d" % (xcvrId, laneId) + scd.addLed(addr, name) + self.inventory.addXcvrLed(xcvrId, name) + addr += 0x10 + + addr = 0x7100 + for xcvrId in self.sfpRange: + name = "sfp%d" % xcvrId + scd.addLed(addr, name) + self.inventory.addXcvrLed(xcvrId, name) + addr += 0x10 + + addr = 0xA010 + bus = 9 + for xcvrId in sorted(self.qsfpRange): + xcvr = scd.addQsfp(addr, xcvrId, bus) + self.inventory.addXcvr(xcvr) + scd.addComponent(I2cKernelComponent( + I2cAddr(bus, xcvr.eepromAddr), 'sff8436')) + scd.addBusTweak(bus, xcvr.eepromAddr) + addr += 0x10 + bus += 1 + + addr = 0xA410 + bus = 7 + for xcvrId in sorted(self.sfpRange): + xcvr = scd.addSfp(addr, xcvrId, bus) + self.inventory.addXcvr(xcvr) + scd.addComponent(I2cKernelComponent( + I2cAddr(bus, xcvr.eepromAddr), 'sff8436')) + scd.addBusTweak(bus, xcvr.eepromAddr) + addr += 0x10 + bus += 1 + + cpld = Scd(PciAddr(bus=0xff, device=0x0b, func=3), newDriver=True) + self.addComponent(cpld) + + cpld.addSmbusMasterRange(0x8000, 4, 0x80, 4) + cpld.addComponents([ + I2cKernelComponent(I2cAddr(73, 0x4c), 'max6658', '/sys/class/hwmon/hwmon2'), + # Handling of the DPM is disabled because this functionality is unstable. + #I2cKernelComponent(I2cAddr(74, 0x4e), 'pmbus', + # priority=Priority.BACKGROUND), + I2cKernelComponent(I2cAddr(85, 0x60), 'rook_cpld', '/sys/class/hwmon/hwmon3'), + I2cKernelComponent(I2cAddr(88, 0x20), 'rook_leds'), + I2cKernelComponent(I2cAddr(88, 0x48), 'lm73'), + ]) diff --git a/platform/broadcom/sonic-platform-modules-arista/arista/utils/__init__.py b/platform/broadcom/sonic-platform-modules-arista/arista/utils/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/platform/broadcom/sonic-platform-modules-arista/arista/utils/sonic_eeprom.py b/platform/broadcom/sonic-platform-modules-arista/arista/utils/sonic_eeprom.py new file mode 100644 index 000000000000..dbb2d39adb08 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/arista/utils/sonic_eeprom.py @@ -0,0 +1,67 @@ +""" +This file provides helper for sonic environment + +Currently all arista switches have their eeprom at the same address and use +the same data format. Since it is not an open standard and all our platforms +need this having everything at the same place is easier. + +The eeprom plugin end up being just the following + + import arista.utils.sonic_eeprom + board = arista.utils.sonic_eeprom.getTlvInfoDecoder() + +""" + +from __future__ import absolute_import + +import StringIO +import os + +from ..core import prefdl +from ..core.platform import fmted_prefdl_path + +try: + from sonic_eeprom import eeprom_base + from sonic_eeprom import eeprom_tlvinfo +except ImportError as e: + raise ImportError (str(e) + " - required module not found") + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + self._prefdl_cache = {} + self.prefdl_path = fmted_prefdl_path + super(board, self).__init__(self.prefdl_path, 0, '', True) + + def read_eeprom(self): + with open(self.prefdl_path) as fp: + return fp.read() + + def _decode_eeprom(self, e): + pfdl = self._prefdl_cache.get(e, None) + if pfdl is not None: + return pfdl + + pfdl = prefdl.PreFdlFromFile(StringIO.StringIO(e)) + self._prefdl_cache[e] = pfdl + + return pfdl + + def decode_eeprom(self, e): + pfdl = self._decode_eeprom(e) + return pfdl.show() + + def is_checksum_valid(self, e): + pfdl = self._decode_eeprom(e) + return (True, pfdl.getCrc()) + + def serial_number_str(self, e): + pfdl = self._decode_eeprom(e) + return pfdl.getField('SerialNumber') + + def mgmtaddrstr(self,e): + pfdl = self._decode_eeprom(e) + return pfdl.getField('MAC') + +def getTlvInfoDecoder(): + return board diff --git a/platform/broadcom/sonic-platform-modules-arista/arista/utils/sonic_leds.py b/platform/broadcom/sonic-platform-modules-arista/arista/utils/sonic_leds.py new file mode 100644 index 000000000000..ac63960f48a7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/arista/utils/sonic_leds.py @@ -0,0 +1,99 @@ +import re +from collections import namedtuple, defaultdict + +from ..core import platform +import arista.platforms + +try: + from sonic_led import led_control_base +except ImportError as e: + raise ImportError ('%s - required module not found' % str(e)) + +Port = namedtuple('Port', ['portNum', 'lanes', 'offset', 'singular']) + +def parsePortConfig(portConfigPath): + ''' + Returns a dictionary mapping port name ("Ethernet48") to a named tuple of port + number, # of lanes, the offset (0 to 3 from the first lane in qsfp) and the + singularity of the lane (if it is in 100G/40G mode) + ''' + portMapping = {} + + with open(portConfigPath) as fp: + for line in fp: + line = line.strip() + if not line or line[0] == '#': + continue + + fields = line.split() + # "portNum" is determined from the fourth column (port), or the first number + # in the third column (alias). + # "lanes" is determined from the number of lanes in the second column. + # "offset" is determined from the second number in the third column (alias). + # "singular" is determined by if the alias has a '/' character or not. + if len(fields) < 3: + continue + name = fields[0] + lanes = len(fields[1].split(',')) + alias = fields[2] + aliasRe = re.findall(r'\d+', alias) + try: + portNum = int(fields[3]) + except IndexError: + portNum = int(aliasRe[0]) + if len(aliasRe) < 2: + offset = 0 + singular = True + else: + offset = int(aliasRe[1]) - 1 + singular = False + + portMapping[name] = Port(portNum, lanes, offset, singular) + + return portMapping + +class LedControl(led_control_base.LedControlBase): + PORT_CONFIG_PATH = '/usr/share/sonic/hwsku/port_config.ini' + LED_SYSFS_PATH = '/sys/class/leds/{0}/brightness' + + LED_COLOR_OFF = 0 + LED_COLOR_GREEN = 1 + LED_COLOR_YELLOW = 2 + + def __init__(self): + self.portMapping = parsePortConfig(self.PORT_CONFIG_PATH) + self.portSysfsMapping = defaultdict(list) + + inventory = platform.getPlatform().getInventory() + for port, names in inventory.xcvrLeds.items(): + for name in names: + self.portSysfsMapping[port].append(self.LED_SYSFS_PATH.format(name)) + + # Set status leds to green initially (Rook led driver does this automatically) + for statusLed in inventory.statusLeds: + with open(self.LED_SYSFS_PATH.format(statusLed), 'w') as fp: + fp.write('%d' % self.LED_COLOR_GREEN) + + def port_link_state_change(self, port, state): + ''' + Looks up the port in the port mapping to determine the front number and how + many subsequent LEDs should be affected (hardcoded by the port_config) + ''' + p = self.portMapping.get(port) + if not p: + return + for idx in range(p.lanes): + path = self.portSysfsMapping[p.portNum][p.offset + idx] + with open(path, 'w') as fp: + if state == 'up': + if idx == 0: + fp.write('%d' % self.LED_COLOR_GREEN) + else: + fp.write('%d' % self.LED_COLOR_YELLOW) + elif state == 'down': + fp.write('%d' % self.LED_COLOR_OFF) + if p.singular: + return + +def getLedControl(): + return LedControl diff --git a/platform/broadcom/sonic-platform-modules-arista/arista/utils/sonic_psu.py b/platform/broadcom/sonic-platform-modules-arista/arista/utils/sonic_psu.py new file mode 100644 index 000000000000..8adbfd077276 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/arista/utils/sonic_psu.py @@ -0,0 +1,34 @@ +from __future__ import absolute_import + +from ..core import platform as core_platform +from .. import platforms + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + +def getPsuUtil(): + platform = core_platform.getPlatform() + inventory = platform.getInventory() + + class PsuUtil(PsuBase): + """Platform-specific PsuUtil class""" + + def get_psu_presence(self, index): + if index > inventory.getNumPsus() and index > 0: + return False + + return inventory.getPsu(index-1).getPresence() + + def get_psu_status(self, index): + if index > inventory.getNumPsus() and index > 0: + return False + + return inventory.getPsu(index-1).getStatus() + + def get_num_psus(self): + return inventory.getNumPsus() + + return PsuUtil diff --git a/platform/broadcom/sonic-platform-modules-arista/arista/utils/sonic_sfputil.py b/platform/broadcom/sonic-platform-modules-arista/arista/utils/sonic_sfputil.py new file mode 100644 index 000000000000..0cd16ceeb495 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/arista/utils/sonic_sfputil.py @@ -0,0 +1,95 @@ +import time + +from ..core import platform as core_platform +from .. import platforms + +try: + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + +def getSfpUtil(): + platform = core_platform.getPlatform() + inventory = platform.getInventory() + + class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + @property + def port_start(self): + return inventory.portStart + + @property + def port_end(self): + return inventory.portEnd + + @property + def qsfp_ports(self): + return inventory.qsfpRange + + # XXX: defining the sfp_ports property currently can't be done as + # it affect the code logic of the sfputil tool by preventing + # the qsfp ports from being detected + #@property + #def sfp_ports(self): + # return inventory.sfpRange + + @property + def port_to_eeprom_mapping(self): + return inventory.getPortToEepromMapping() + + @property + def port_to_i2cbus_mapping(self): + return inventory.getPortToI2cAdapterMapping() + + def __init__(self): + SfpUtilBase.__init__(self) + + def get_presence(self, port_num): + if not self._is_valid_port(port_num): + return False + + return inventory.getXcvr(port_num).getPresence() + + def get_low_power_mode(self, port_num): + if not self._is_valid_port(port_num): + return False + + return inventory.getXcvr(port_num).getLowPowerMode() + + def set_low_power_mode(self, port_num, lpmode): + if not self._is_valid_port(port_num): + return False + + try: + return inventory.getXcvr(port_num).setLowPowerMode(lpmode) + except: + #print('failed to set low power mode for xcvr %d' % port_num) + return False + + def reset(self, port_num): + if not self._is_valid_port(port_num): + return False + + xcvr = inventory.getXcvr(port_num) + try: + if not xcvr.reset(True): + return False + except: + #print('failed to put xcvr %d in reset' % port_num) + return False + + # Sleep 1 second to allow it to settle + time.sleep(1) + + try: + if not xcvr.reset(False): + return False + except: + #print('failed to take xcvr %d out of reset' % port_num) + return False + + return True + + return SfpUtil diff --git a/platform/broadcom/sonic-platform-modules-arista/confs/arista-drivers.service b/platform/broadcom/sonic-platform-modules-arista/confs/arista-drivers.service new file mode 100644 index 000000000000..7c6551df9086 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/confs/arista-drivers.service @@ -0,0 +1,14 @@ +[Unit] +Description=Arista kernel modules init +After=local-fs.target +Before=opennsl-modules-3.16.0-5-amd64.service +ConditionKernelCommandLine=Aboot + +[Service] +Type=oneshot +ExecStart=/usr/bin/arista -l /var/log/arista.log setup --reset --background +ExecStop=/usr/bin/arista -l /var/log/arista.log clean +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-arista/confs/gardena-watchdog-stop.service b/platform/broadcom/sonic-platform-modules-arista/confs/gardena-watchdog-stop.service new file mode 100644 index 000000000000..af912ce7cee9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/confs/gardena-watchdog-stop.service @@ -0,0 +1,18 @@ +[Unit] +Description=Disable the watchdog after boot +After=swss.service +After=opennsl-modules-3.16.0-5-amd64.service +ConditionKernelCommandLine=sid=Gardena + +[Service] +User=root +Type=oneshot +RemainAfterExit=true + +ExecStart= +ExecStart=/usr/bin/arista-gardena-watchdog --stop + +ExecStop= + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-arista/debian/changelog b/platform/broadcom/sonic-platform-modules-arista/debian/changelog new file mode 100755 index 000000000000..196c2e26a98b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/debian/changelog @@ -0,0 +1,5 @@ +sonic-platform-arista (1.0) unstable; + + * Initial release + + -- Samuel Angebault Mon, 24 Nov 2016 11:11:11 -0800 diff --git a/platform/broadcom/sonic-platform-modules-arista/debian/compat b/platform/broadcom/sonic-platform-modules-arista/debian/compat new file mode 100755 index 000000000000..ec635144f600 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/debian/compat @@ -0,0 +1 @@ +9 diff --git a/platform/broadcom/sonic-platform-modules-arista/debian/control b/platform/broadcom/sonic-platform-modules-arista/debian/control new file mode 100755 index 000000000000..ae53eea5bc81 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/debian/control @@ -0,0 +1,54 @@ +Source: sonic-platform-arista +Section: main +Priority: extra +Maintainer: Samuel Angebault +Build-Depends: + dh-python, + debhelper (>= 9.0.0), + python-all, + python(>=2.7-3~), + python-setuptools, + python3(>=3.2), + python3-setuptools, + bzip2 +Standards-Version: 1.0.0 +X-Python-Version: >= 2.7 +X-Python3-Version: >= 3.2 +XS-Python-Version: >= 2.7 +XS-Python3-Version: >= 3.2 + +Package: drivers-sonic-platform-arista +Architecture: amd64 +Depends: + ${misc:Depends}, + linux-image-3.16.0-5-amd64 +Description: Arista kernel modules for arista platform devices such as fan, led, sfp, psu + +Package: python-sonic-platform-arista +Architecture: all +Depends: + ${python:Depends}, + ${misc:Depends}, + python-smbus +Description: Arista python2 libraries + These libraries allow to work with devices such as fan, led, sfp, psu + +Package: python3-sonic-platform-arista +Architecture: all +Depends: + ${python3:Depends}, + ${misc:Depends} +Recommends: + python3-smbus +Description: Arista python3 libraries + These libraries allow to work with devices such as fan, led, sfp, psu + +Package: sonic-platform-arista +Architecture: amd64 +Depends: + ${python:Depends}, + ${misc:Depends}, + python-sonic-platform-arista, + python(>=2.7), + i2c-tools +Description: Miscellaneous Arista scripts and tools diff --git a/platform/broadcom/sonic-platform-modules-arista/debian/copyright b/platform/broadcom/sonic-platform-modules-arista/debian/copyright new file mode 100644 index 000000000000..ebdb940a0c98 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/debian/copyright @@ -0,0 +1,1016 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. + + + + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 3 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, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/platform/broadcom/sonic-platform-modules-arista/debian/files b/platform/broadcom/sonic-platform-modules-arista/debian/files new file mode 100644 index 000000000000..2ad60d05f0f1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/debian/files @@ -0,0 +1,4 @@ +drivers-sonic-platform-arista_1.0_amd64.deb main extra +python-sonic-platform-arista_1.0_all.deb main extra +python3-sonic-platform-arista_1.0_all.deb main extra +sonic-platform-arista_1.0_amd64.deb main extra diff --git a/platform/broadcom/sonic-platform-modules-arista/debian/rules b/platform/broadcom/sonic-platform-modules-arista/debian/rules new file mode 100755 index 000000000000..e12a638d8742 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/debian/rules @@ -0,0 +1,54 @@ +#!/usr/bin/make -f + +include /usr/share/dpkg/pkg-info.mk + +#export DH_VERBOSE = 1 + +export INSTALL_MOD_DIR:=extra + +SCRIPT_FILES := reset +BIN_FILES := arista boot-eos arista-gardena-watchdog +SERVICE_FILES := gardena-watchdog-stop.service + +KVERSION ?= $(shell uname -r) +KERNEL_SRC ?= /lib/modules/$(KVERSION)/build +KERNEL_DST := /lib/modules/$(KVERSION) +BASE_DIR := $(shell pwd) +MODULE_SRC := $(BASE_DIR)/src +TEST_DIR := $(BASE_DIR)/tests +SCRIPT_SRC := $(addprefix $(BASE_DIR)/utils/,$(SCRIPT_FILES)) +BIN_SRC := $(addprefix $(BASE_DIR)/utils/,$(BIN_FILES)) +SERVICE_SRC := $(addprefix $(BASE_DIR)/confs/,$(SERVICE_FILES)) + +%: + dh $@ --with python2,python3,systemd --buildsystem=pybuild + +override_dh_auto_build: + $(MAKE) -C $(KERNEL_SRC) M=$(MODULE_SRC) + python2 setup.py build + +override_dh_auto_install: + dh_installdirs -p$(DEB_SOURCE) usr/bin + cp $(BIN_SRC) debian/$(DEB_SOURCE)/usr/bin + dh_installdirs -p$(DEB_SOURCE) usr/share/arista + cp $(SCRIPT_SRC) debian/$(DEB_SOURCE)/usr/share/arista + dh_installdirs -p$(DEB_SOURCE) lib/systemd/system + cp $(SERVICE_SRC) debian/$(DEB_SOURCE)/lib/systemd/system + dh_installdirs -pdrivers-$(DEB_SOURCE) $(KERNEL_DST)/$(INSTALL_MOD_DIR) + cp $(MODULE_SRC)/*.ko debian/drivers-$(DEB_SOURCE)/$(KERNEL_DST)/$(INSTALL_MOD_DIR) + python2 setup.py install --root=$(BASE_DIR)/debian/python-$(DEB_SOURCE) --install-layout=deb + python3 setup.py install --root=$(BASE_DIR)/debian/python3-$(DEB_SOURCE) --install-layout=deb + +override_dh_clean: + dh_clean + $(RM) $(MODULE_SRC)/*.o $(MODULE_SRC)/*.ko $(MODULE_SRC)/*.mod.c $(MODULE_SRC)/.*.cmd + $(RM) $(MODULE_SRC)/Module.markers $(MODULE_SRC)/Module.symvers $(MODULE_SRC)/modules.order + $(RM) -r $(MODULE_SRC)/.tmp_versions + $(RM) -r $(BASE_DIR)/*.egg-info $(BASE_DIR)/build + +override_dh_auto_test: + PYTHON=python2 PYTHONPATH=$(BASE_DIR) $(TEST_DIR)/all-platforms.sh + PYTHON=python3 PYTHONPATH=$(BASE_DIR) $(TEST_DIR)/all-platforms.sh + +print-%: + @echo $($*) diff --git a/platform/broadcom/sonic-platform-modules-arista/debian/sonic-platform-arista.init b/platform/broadcom/sonic-platform-modules-arista/debian/sonic-platform-arista.init new file mode 100755 index 000000000000..7042efadabc3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/debian/sonic-platform-arista.init @@ -0,0 +1,47 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup Arista platform +### END INIT INFO + +drivers_start() { + echo "Loading arista drivers..." + depmod -a + if grep -q sid=Gardena /proc/cmdline; then + timeout=600 + echo "Enabling watchdog for $timeout seconds" + /usr/bin/arista-gardena-watchdog -o $timeout + fi + /usr/bin/arista --syslog -l /var/log/arista.log setup --reset --background + echo "done." +} +drivers_stop() { + echo "Unloading arista drivers..." + /usr/bin/arista --syslog -l /var/log/arista.log clean + echo "done." +} + +case "$1" in + start) drivers_start ;; + stop) drivers_stop ;; + force-reload) echo "Not supported";; + restart) + drivers_stop + drivers_start + ;; + + *) + echo "Usage: $0 {start|stop}" + exit 1 + ;; +esac + +exit 0 + diff --git a/platform/broadcom/sonic-platform-modules-arista/setup.py b/platform/broadcom/sonic-platform-modules-arista/setup.py new file mode 100755 index 000000000000..ea5c86513fde --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/setup.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python + +from setuptools import setup +import os + +setup( + name='platform-arista', + version='%s' % os.environ.get('ARISTA_PLATFORM_MODULE_VERSION', '1.0'), + description='Module to initialize arista platforms', + packages=[ + 'arista', + 'arista.core', + 'arista.components', + 'arista.platforms', + 'arista.utils', + ], +) + diff --git a/platform/broadcom/sonic-platform-modules-arista/src/Makefile b/platform/broadcom/sonic-platform-modules-arista/src/Makefile new file mode 100644 index 000000000000..378fec02c12e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/src/Makefile @@ -0,0 +1,9 @@ +ccflags-y := -Werror + +obj-m += scd.o +obj-m += scd-hwmon.o +obj-m += sonic-support-driver.o +obj-m += crow-fan-driver.o +obj-m += raven-fan-driver.o +obj-m += rook-led-driver.o +obj-m += rook-fan-cpld.o diff --git a/platform/broadcom/sonic-platform-modules-arista/src/crow-fan-driver.c b/platform/broadcom/sonic-platform-modules-arista/src/crow-fan-driver.c new file mode 100644 index 000000000000..851a26f8d95b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/src/crow-fan-driver.c @@ -0,0 +1,505 @@ +/* Copyright (c) 2016 Arista Networks, 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, see . + */ + +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "crow-cpld-fans" + +#define NUM_FANS 4 +#define LED_NAME_MAX_SZ 20 + +#define TACH1LOWREG 0 +#define TACH1HIGHREG 1 +#define TACH2LOWREG 2 +#define TACH2HIGHREG 3 +#define TACH3LOWREG 4 +#define TACH3HIGHREG 5 +#define TACH4LOWREG 6 +#define TACH4HIGHREG 7 + +#define FAN1PWMREG 0x10 +#define FAN1IDREG 0x18 +#define FAN2PWMREG 0x11 +#define FAN2IDREG 0x19 +#define FAN3PWMREG 0x12 +#define FAN3IDREG 0x1A +#define FAN4PWMREG 0x13 +#define FAN4IDREG 0x1B + +#define FANPRESENTREG 0x21 +#define FANGREENLEDREG 0x24 +#define FANREDLEDREG 0x25 +#define CROWCPLDREVREG 0x40 +#define SCRATCHREG 0x41 + +#define FAN_LED_OFF 0 +#define FAN_LED_GREEN 1 +#define FAN_LED_RED 2 +#define FAN_LED_YELLOW 3 + +struct crow_led { + char name[LED_NAME_MAX_SZ]; + struct led_classdev cdev; + int fan_index; +}; + +struct crow_cpld_data { + struct i2c_client *client; + struct crow_led leds[NUM_FANS]; +}; + +static s32 read_cpld(struct device *dev, u8 reg, char *buf) +{ + int err; + struct crow_cpld_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + + err = i2c_smbus_read_byte_data(client, reg); + if (err < 0) { + dev_err(dev, "failed to read reg %d of with error code: %d\n", reg, err); + return err; + } + + *buf = (err & 0xFF); + return 0; +} + +static s32 write_cpld(struct device *dev, u8 reg, u8 byte) +{ + int err; + struct crow_cpld_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + + err = i2c_smbus_write_byte_data(client, reg, byte); + if (err) { + dev_err(dev, "failed to write %02x in reg %02x of with error code: %d\n", + byte, reg, err); + } + + return err; +} + +static s32 read_cpld_buf(struct device *dev, u8 reg, char *buf) +{ + s32 status; + u8 data; + + status = read_cpld(dev, reg, &data); + if (status) { + return status; + } + + return sprintf(buf, "%hhu\n", data); +} + +static s32 write_cpld_buf(struct device *dev, u8 reg, const char *buf) +{ + u8 data; + s32 status; + + if (sscanf(buf, "%hhu", &data) != 1) { + return -EINVAL; + } + + status = write_cpld(dev, reg, data); + + return status; +} + +static s32 read_led_color(struct device *dev, int index, u8 *color) +{ + s32 err; + u8 data; + unsigned char read_value_g = 0; + unsigned char read_value_r = 0; + + err = read_cpld(dev, FANGREENLEDREG, &data); + if (err) + return err; + read_value_g = (data >> index) & 0x01; + + err = read_cpld(dev, FANREDLEDREG, &data); + if (err) + return err; + read_value_r = (data >> index) & 0x01; + + *color = FAN_LED_OFF; + if((!read_value_g) && read_value_r) { + *color = FAN_LED_GREEN; + } else if (read_value_g && (!read_value_r)) { + *color = FAN_LED_RED; + } else if((!read_value_g) && (!read_value_r)) { + *color = FAN_LED_YELLOW; + } + + return 0; +} + +static s32 read_led_color_buf(struct device *dev, char *buf, int index) +{ + int err; + u8 val; + + err = read_led_color(dev, index, &val); + if (err) + return err; + + return sprintf(buf, "%d\n", val); +} + +static s32 write_led_color(struct device *dev, u8 value, int index) +{ + s32 status; + u8 red_value; + u8 green_value; + u8 green_led; + u8 red_led; + + if (value > 3) + return -EINVAL; + + switch (value) { + case FAN_LED_GREEN: + green_led = 1; + red_led = 0; + break; + case FAN_LED_RED: + green_led = 0; + red_led = 1; + break; + case FAN_LED_YELLOW: + green_led = 1; + red_led = 1; + break; + case FAN_LED_OFF: + default: + green_led = 0; + red_led = 0; + break; + } + + status = read_cpld(dev, FANGREENLEDREG, &green_value); + if (status) { + return status; + } + + status = read_cpld(dev, FANREDLEDREG, &red_value); + if (status) { + return status; + } + + if (green_led) { + green_value &= ~(1u << index); + } else { + green_value |= (1u << index); + } + + if (red_led) { + red_value &= ~(1u << index); + } else { + red_value |= (1u << index); + } + + status = write_cpld(dev, FANGREENLEDREG, green_value); + status |= write_cpld(dev, FANREDLEDREG, red_value); + + return status; +} + +static s32 write_led_color_buf(struct device *dev, const char *buf, int index) +{ + u8 value; + + if (sscanf(buf, "%hhu", &value) != 1) { + return -EINVAL; + } + + return write_led_color(dev, value, index); +} + +static s32 read_tach(struct device *dev, u8 tachHigh, u8 tachLow, u32 *speed) +{ + s32 status; + u8 dataHigh; + u8 dataLow; + u32 tachData; + + status = read_cpld(dev, tachHigh, &dataHigh); + status |= read_cpld(dev, tachLow, &dataLow); + if (status) { + return status; + } + + tachData = (dataHigh << 8) + dataLow; + if (!tachData) { + tachData = 1; + } + *speed = 6000000 / tachData; + *speed = *speed / 2; + + return 0; +} + +static s32 read_tach_buf(struct device *dev, u8 tachHigh, u8 tachLow, + char *buf) +{ + u32 speed; + int err; + + err = read_tach(dev, tachHigh, tachLow, &speed); + if (err) + return err; + + return sprintf(buf, "%d\n", speed); +} + +static s32 read_fan_present(struct device *dev, int index, u8 *present) +{ + s32 status; + u8 data; + + *present = 0; + status = read_cpld(dev, FANPRESENTREG, &data); + if (status) { + return status; + } + + *present = ~(data >> index) & 0x01; + return 0; +} + +static s32 read_fan_present_buf(struct device *dev, char *buf, int index) +{ + int err; + u8 present; + + err = read_fan_present(dev, index, &present); + if (err) + return err; + + return sprintf(buf, "%d\n", present); +} + +#define GENERIC_FAN_READ(_name, _dev, _reg) \ +static ssize_t fan_##_name##_##_dev##_show(struct device *dev, \ + struct device_attribute *attr, \ + char *buf) \ +{ \ + return read_cpld_buf(dev, _reg, buf); \ +} \ + +#define GENERIC_FAN_WRITE(_name, _dev, _reg) \ +static ssize_t fan_##_name##_##_dev##_store(struct device *dev, \ + struct device_attribute *attr, \ + const char *buf, size_t count) \ +{ \ + write_cpld_buf(dev, _reg, buf); \ + return count; \ +} \ + +#define GENERIC_LED(_name) \ +static ssize_t fan_##_name##_led_show(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + return read_led_color_buf(dev, buf, _name-1); \ +} \ +static ssize_t fan_##_name##_led_store(struct device *dev, \ + struct device_attribute *attr, \ + const char *buf, size_t count) \ +{ \ + write_led_color_buf(dev, buf, _name-1); \ + return count; \ +} \ +DEVICE_ATTR(fan##_name##_led, S_IRUGO|S_IWGRP|S_IWUSR, \ + fan_##_name##_led_show, fan_##_name##_led_store); \ + + +#define FAN_DEVICE_ATTR(_name) \ +static ssize_t tach_##_name##_show(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + return read_tach_buf(dev, TACH##_name##HIGHREG, TACH##_name##LOWREG, buf); \ +} \ +DEVICE_ATTR(fan##_name##_input, S_IRUGO, tach_##_name##_show, NULL); \ + \ +GENERIC_FAN_READ(_name, id, FAN##_name##IDREG); \ +DEVICE_ATTR(fan##_name##_id, S_IRUGO, fan_##_name##_id_show, NULL); \ + \ +GENERIC_FAN_READ(_name, pwm, FAN##_name##PWMREG); \ +GENERIC_FAN_WRITE(_name, pwm, FAN##_name##PWMREG); \ +DEVICE_ATTR(pwm##_name, S_IRUGO|S_IWGRP|S_IWUSR, \ + fan_##_name##_pwm_show, fan_##_name##_pwm_store); \ + \ +static ssize_t fan_##_name##_present_show(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + return read_fan_present_buf(dev, buf, _name-1); \ +} \ +DEVICE_ATTR(fan##_name##_present, S_IRUGO, fan_##_name##_present_show, NULL); \ + \ +GENERIC_LED(_name) \ + + +static ssize_t crow_cpld_rev_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return read_cpld_buf(dev, CROWCPLDREVREG, buf); +} + +DEVICE_ATTR(crow_cpld_rev, S_IRUGO, crow_cpld_rev_show, NULL); + +FAN_DEVICE_ATTR(1); +FAN_DEVICE_ATTR(2); +FAN_DEVICE_ATTR(3); +FAN_DEVICE_ATTR(4); + +#define FANATTR(_name) \ + &dev_attr_pwm##_name.attr, \ + &dev_attr_fan##_name##_id.attr, \ + &dev_attr_fan##_name##_input.attr, \ + &dev_attr_fan##_name##_present.attr, \ + &dev_attr_fan##_name##_led.attr, \ + + +static struct attribute *fan_attrs[] = { + FANATTR(1) + FANATTR(2) + FANATTR(3) + FANATTR(4) + &dev_attr_crow_cpld_rev.attr, + NULL, +}; + +ATTRIBUTE_GROUPS(fan); + +static void brightness_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + struct crow_led *pled = container_of(led_cdev, struct crow_led, cdev); + struct device *dev = led_cdev->dev->parent; + + write_led_color(dev, value, pled->fan_index); +} + +static enum led_brightness brightness_get(struct led_classdev *led_cdev) +{ + struct crow_led *pled = container_of(led_cdev, struct crow_led, cdev); + struct device *dev = led_cdev->dev->parent; + u8 val; + int err; + + err = read_led_color(dev, pled->fan_index, &val); + if (err) + return 0; + + return val; +} + +static void leds_unregister(struct crow_cpld_data *data, int num_leds) +{ + int i = 0; + + for (i = 0; i < num_leds; i++) + led_classdev_unregister(&data->leds[i].cdev); +} + +static int leds_init(struct crow_led *leds, struct i2c_client *client) +{ + int i; + int err; + struct crow_cpld_data *data = i2c_get_clientdata(client); + + for (i = 0; i < NUM_FANS; i++) { + leds[i].fan_index = i; + leds[i].cdev.brightness_set = brightness_set; + leds[i].cdev.brightness_get = brightness_get; + scnprintf(leds[i].name, LED_NAME_MAX_SZ, "fan%d", leds[i].fan_index + 1); + leds[i].cdev.name = leds[i].name; + } + + // fan leds initialized to green because no fan fault reg on crow + for (i = 0 ; i < NUM_FANS; i++) { + err = led_classdev_register(&client->dev, &leds[i].cdev); + err |= write_led_color(&client->dev, FAN_LED_GREEN, i); + if (err) { + leds_unregister(data, i); + return err; + } + } + + return 0; +} + +static int crow_cpld_remove(struct i2c_client *client) +{ + struct crow_cpld_data *data = i2c_get_clientdata(client); + + leds_unregister(data, NUM_FANS); + + return 0; +} + +static int crow_cpld_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int err; + struct device *dev = &client->dev; + struct device *hwmon_dev; + struct crow_cpld_data *data; + data = devm_kzalloc(dev, sizeof(struct crow_cpld_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + i2c_set_clientdata(client, data); + data->client = client; + hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, + data, fan_groups); + if (IS_ERR(hwmon_dev)) + return PTR_ERR(hwmon_dev); + + err = leds_init(data->leds, client); + if (err) + return err; + + return 0; +} + +static const struct i2c_device_id crow_cpld_id[] = { + { "crow_cpld", 0 }, + { } +}; + +MODULE_DEVICE_TABLE(i2c, crow_cpld_id); + +static struct i2c_driver crow_cpld_driver = { + .driver = { + .name = DRIVER_NAME + }, + .id_table = crow_cpld_id, + .probe = crow_cpld_probe, + .remove = crow_cpld_remove, +}; + +module_i2c_driver(crow_cpld_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Arista Networks"); +MODULE_DESCRIPTION("Crow Fan driver"); diff --git a/platform/broadcom/sonic-platform-modules-arista/src/gpio-kversfix.h b/platform/broadcom/sonic-platform-modules-arista/src/gpio-kversfix.h new file mode 100644 index 000000000000..7abc7de39f6e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/src/gpio-kversfix.h @@ -0,0 +1,70 @@ +/* Copyright (c) 2017 Arista Networks, 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, see . + * + */ + +#ifndef _LINUX_DRIVER_GPIO_FIX_H_ +#define _LINUX_DRIVER_GPIO_FIX_H_ + +#include +#include + +/* + * The following snippet of code is a workaround to support kernel prior to 3.18 + * These previous kernel doesn't benefit of the gpio subsystem refactor that exports + * more functions. + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0) +#include +#include + +#define gpiochip_free_own_desc gpiochip_free_desc_hack +void gpiochip_free_desc_hack(struct gpio_desc *desc) +{ + // this call decrease the refcount of the module which means that it is an issue + // if called outside of the module_exit + gpio_free(desc_to_gpio(desc)); + try_module_get(THIS_MODULE); +} + +#define gpiochip_request_own_desc gpiochip_request_desc_hack +struct gpio_desc *gpiochip_request_desc_hack(struct gpio_chip *chip, + u16 hwnum, const char *label) +{ + struct gpio_desc *desc = gpiochip_get_desc(chip, hwnum); + int err; + + if (IS_ERR(desc)) { + pr_err("gpio: failed to get GPIO descriptor\n"); + return desc; + } + + err = gpio_request(desc_to_gpio(desc), label); + if (err < 0) { + pr_err("gpio: failed to request GPIO"); + return ERR_PTR(err); + } + + // gpio_request increase the refcount on the module + // Since the module asking for its own gpio, the refcount shouldn't be + // increased. Given that this is the only exported symbol available this is the + // is the easiest way to handle this without adding a kernel patch + module_put(chip->owner); + + return desc; +} +#endif /* LINUX_VERSION < 3.18.0 */ + +#endif /* !_LINUX_DRIVER_GPIO_FIX_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-arista/src/raven-fan-driver.c b/platform/broadcom/sonic-platform-modules-arista/src/raven-fan-driver.c new file mode 100644 index 000000000000..60716a8c8d71 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/src/raven-fan-driver.c @@ -0,0 +1,527 @@ +/* Copyright (c) 2016 Arista Networks, 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, see . + * + * The AMD SB800 Register Reference Guide details the behavior of the + * SB800 accesses: http://support.amd.com/TechDocs/45482.pdf + */ + +#include +#include +#include +#include +#include +#include "gpio-kversfix.h" + +#define DRIVER_NAME "sb800-fans" + +#define LED_NAME_MAX_SZ 20 +#define NUM_FANS 4 + +#define SB800_BASE 0xfed80000 +#define SB800_GPIO_BASE (SB800_BASE + 0x0100) +#define SB800_GPIO_SIZE 0xff +#define SB800_PM2_BASE (SB800_BASE + 0x0400) +#define SB800_PM2_SIZE 0xff +#define SB800_IOSIZE 4 + +#define FAN_ID_BASE_ADDR 0xCB +#define FAN_ID_ADDR_OFFSET 6 +#define NUM_FAN_ID_PINS 3 + +#define FAN1_PRESENT_ADDR 206 +#define FAN2_PRESENT_ADDR 212 +#define FAN3_PRESENT_ADDR 220 +#define FAN4_PRESENT_ADDR 224 + +#define GREEN_RED_LED_ADDR_OFFSET 1 +#define FAN1_GREEN_LED_ADDR 207 +#define FAN2_GREEN_LED_ADDR 213 +#define FAN3_GREEN_LED_ADDR 218 +#define FAN4_GREEN_LED_ADDR 225 + +#define FAN_LED_OFF 0 +#define FAN_LED_GREEN 1 +#define FAN_LED_RED 2 +#define FAN_LED_YELLOW 3 + +#define LED_ON_OFF_REG_OFFSET (1 << 6) +#define LED_DIR_REG_OFFSET (1 << 5) + +#define FAN_TACH_BASE_ADDR 0x69 +#define FAN_TACH_ADDR_OFFSET 0x05 +#define FAN_TACH_LOW_HI_ADDR_OFFSET 0x1 + +#define FAN_CTRL_BASE_ADDR 1 +#define FAN_FREQ_BASE_ADDR 2 +#define FAN_DUTY_BASE_ADDR 3 +#define FAN_CTRL_ADDR_OFFSET 0x10 + +#define FAN_DETECT_CTRL_BASE_ADDR 0x66 +#define FAN_DETECT_ADDR_OFFSET 0x05 + +#define FAN_PWM_BASE_ADDR 3 +#define FAN_PWM_ADDR_OFFSET 0x10 + +struct raven_led { + char name[LED_NAME_MAX_SZ]; + struct led_classdev cdev; + int fan_index; +}; + +struct raven_pdata { + struct device *hwmon_dev; + struct raven_led leds[NUM_FANS]; + u8 *gpio_base; + u8 *pm2_base; +}; + +static struct platform_device *sb800_pdev = 0; + +unsigned long const green_led_addrs[NUM_FANS] = {FAN1_GREEN_LED_ADDR, + FAN2_GREEN_LED_ADDR, + FAN3_GREEN_LED_ADDR, + FAN4_GREEN_LED_ADDR}; + +static ssize_t show_fan_present(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct raven_pdata *pdata = dev_get_drvdata(dev->parent); + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + unsigned long const fan_present_addrs[] = {FAN1_PRESENT_ADDR, FAN2_PRESENT_ADDR, + FAN3_PRESENT_ADDR, FAN4_PRESENT_ADDR}; + u32 num_fan = sensor_attr->index - 1; + u8 *fan_present_reg = pdata->gpio_base + fan_present_addrs[num_fan]; + u32 fan_present_val = ((~ioread8(fan_present_reg)) >> 7) & 0x1; + return scnprintf(buf, 5, "%u\n", fan_present_val); +} + +static ssize_t show_fan_id(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct raven_pdata *pdata = dev_get_drvdata(dev->parent); + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + u32 fan_id = sensor_attr->index - 1; + int num_id; + u32 id_vals[NUM_FAN_ID_PINS]; + u8 *reg_id = pdata->gpio_base + FAN_ID_BASE_ADDR + FAN_ID_ADDR_OFFSET * fan_id; + for(num_id = 0; num_id < NUM_FAN_ID_PINS; num_id++) { + reg_id += num_id; + id_vals[num_id] = (ioread8(reg_id) >> 7) & 0x1; + } + return scnprintf(buf, 12, "%u %u %u\n", id_vals[2], id_vals[1], id_vals[0]); +} + +static int read_led(struct raven_pdata *pdata, int fan_id, u8 *value) +{ + unsigned long const green_led_addr = green_led_addrs[fan_id]; + u8 *reg_g = pdata->gpio_base + green_led_addr; + u8 *reg_r = reg_g + GREEN_RED_LED_ADDR_OFFSET; + u32 val_g = ioread8(reg_g); + u32 val_r = ioread8(reg_r); + + *value = FAN_LED_OFF; + + if (!(val_g & LED_ON_OFF_REG_OFFSET) && (val_r & LED_ON_OFF_REG_OFFSET)) { + *value = FAN_LED_GREEN; + } + else if ((val_g & LED_ON_OFF_REG_OFFSET) && !(val_r & LED_ON_OFF_REG_OFFSET)) { + *value = FAN_LED_RED; + } + else if (!(val_g & LED_ON_OFF_REG_OFFSET) && !(val_r & LED_ON_OFF_REG_OFFSET)) { + *value = FAN_LED_YELLOW; + } + + return 0; +} + +static ssize_t show_led(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct raven_pdata *pdata = dev_get_drvdata(dev->parent); + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + int err; + u8 color; + + err = read_led(pdata, sensor_attr->index - 1, &color); + if (err) + return err; + + return scnprintf(buf, 16, "%u\n", color); +} + +static int write_led(struct raven_pdata *pdata, u8 val, int index) +{ + unsigned long const green_led_addr = green_led_addrs[index]; + u8 *reg_g = pdata->gpio_base + green_led_addr; + u8 *reg_r = reg_g + GREEN_RED_LED_ADDR_OFFSET; + u32 val_g = ioread8(reg_g); + u32 val_r = ioread8(reg_r); + + if (val > 3) + return -EINVAL; + + // Enable output + val_g &= ~LED_DIR_REG_OFFSET; + val_r &= ~LED_DIR_REG_OFFSET; + + switch (val) { + case FAN_LED_OFF: + val_g |= LED_ON_OFF_REG_OFFSET; + val_r |= LED_ON_OFF_REG_OFFSET; + break; + case FAN_LED_RED: + val_r &= ~LED_ON_OFF_REG_OFFSET; + val_g |= LED_ON_OFF_REG_OFFSET; + break; + case FAN_LED_YELLOW: + val_g &= ~LED_ON_OFF_REG_OFFSET; + val_r &= ~LED_ON_OFF_REG_OFFSET; + break; + default: // Green + val_g &= ~LED_ON_OFF_REG_OFFSET; + val_r |= LED_ON_OFF_REG_OFFSET; + break; + } + iowrite8(val_g, reg_g); + iowrite8(val_r, reg_r); + + return 0; +} + +static ssize_t store_led(struct device * dev, struct device_attribute * attr, + const char * buf, size_t count) +{ + unsigned long value; + int err; + struct raven_pdata *pdata = dev_get_drvdata(dev->parent); + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + u32 fan_id = sensor_attr->index - 1; + + err = kstrtoul(buf, 10, &value); + if (err) { + return err; + } + + err = write_led(pdata, value, fan_id); + if (err) + return err; + + return count; +} + +static void brightness_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + struct raven_led *pled = container_of(led_cdev, struct raven_led, + cdev); + struct raven_pdata *pdata = dev_get_drvdata(led_cdev->dev->parent); + + write_led(pdata, value, pled->fan_index); +} + +static enum led_brightness brightness_get(struct led_classdev *led_cdev) +{ + int err; + struct raven_led *pled = container_of(led_cdev, struct raven_led, + cdev); + struct raven_pdata *pdata = dev_get_drvdata(led_cdev->dev->parent); + u8 value; + + err = read_led(pdata, pled->fan_index, &value); + if (err) + return 0; + + return value; +} + +static void leds_unregister(struct raven_pdata *pdata, int num_leds) +{ + int i; + + for (i = 0; i < num_leds; i++) + led_classdev_unregister(&pdata->leds[i].cdev); +} + +static int leds_register(struct device* dev, struct raven_pdata *pdata) +{ + int i; + int err; + struct raven_led *led; + + for (i = 0; i < NUM_FANS; i++) { + led = &pdata->leds[i]; + led->fan_index = i; + led->cdev.brightness_set = brightness_set; + led->cdev.brightness_get = brightness_get; + scnprintf(led->name, LED_NAME_MAX_SZ, "fan%d", led->fan_index + 1); + led->cdev.name = led->name; + err = led_classdev_register(dev, &led->cdev); + if (err) { + leds_unregister(pdata, i); + return err; + } + } + + return 0; +} + +static ssize_t show_fan_input(struct device *dev, struct device_attribute *attr, + char *buf) +{ + u32 tach = 0; + u32 tach_lo; + u32 tach_lo_1; + u32 tach_hi; + u32 tach_hi_1; + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + u32 fan_id = sensor_attr->index - 1; + struct raven_pdata *pdata = dev_get_drvdata(dev->parent); + unsigned long tach_lo_addr = FAN_TACH_BASE_ADDR + + (fan_id * FAN_TACH_ADDR_OFFSET ); + u8 *tach_lo_reg = pdata->pm2_base + tach_lo_addr; + u8 *tach_hi_reg = tach_lo_reg + FAN_TACH_LOW_HI_ADDR_OFFSET; + tach_lo = ioread8(tach_lo_reg); + tach_hi = ioread8(tach_hi_reg); + tach_lo_1 = ioread8(tach_lo_reg); + tach_hi_1 = ioread8(tach_hi_reg); + if (tach_lo_1 == tach_lo) { + tach = (tach_hi << 8) + tach_lo; + } else { + tach = (tach_hi_1 << 8) + tach_lo_1; + } + tach = (22700 * 60) / ((tach ?: 1) * 2); + return scnprintf(buf, 12, "%u\n", tach); +} + +static ssize_t show_pwm(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct raven_pdata *pdata = dev_get_drvdata(dev->parent); + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + u32 fan_id = sensor_attr->index - 1; + u8 * reg = pdata->pm2_base + FAN_PWM_BASE_ADDR + (fan_id * FAN_PWM_ADDR_OFFSET); + u32 pwm = ioread8(reg); + return scnprintf(buf, 5, "%u\n", pwm); +} + +static ssize_t store_pwm(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct raven_pdata *pdata = dev_get_drvdata(dev->parent); + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + unsigned long pwm; + int ret = 0; + u32 fan_id = sensor_attr->index - 1; + u8 * reg = pdata->pm2_base + FAN_PWM_BASE_ADDR + (fan_id * FAN_PWM_ADDR_OFFSET); + ret = kstrtoul(buf, 10, &pwm); + if (ret) { + return ret; + } + iowrite8(pwm & 0xff, reg); + return count; +} + +#define FAN_DEVICE_ATTR(_numfan) \ +static SENSOR_DEVICE_ATTR(fan##_numfan##_input, S_IRUGO, \ + show_fan_input, NULL, _numfan); \ +static SENSOR_DEVICE_ATTR(pwm##_numfan, S_IRUGO|S_IWUSR|S_IWGRP, \ + show_pwm, store_pwm, _numfan); \ +static SENSOR_DEVICE_ATTR(fan##_numfan##_present, S_IRUGO, \ + show_fan_present, NULL, _numfan); \ +static SENSOR_DEVICE_ATTR(fan##_numfan##_id, S_IRUGO, \ + show_fan_id, NULL, _numfan); \ +static SENSOR_DEVICE_ATTR(fan##_numfan##_led, S_IRUGO|S_IWUSR|S_IWGRP, \ + show_led, store_led, _numfan); + +FAN_DEVICE_ATTR(1); +FAN_DEVICE_ATTR(2); +FAN_DEVICE_ATTR(3); +FAN_DEVICE_ATTR(4); + +static struct attribute *fan_attrs[] = { + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_pwm1.dev_attr.attr, + &sensor_dev_attr_fan1_led.dev_attr.attr, + &sensor_dev_attr_fan1_present.dev_attr.attr, + &sensor_dev_attr_fan1_id.dev_attr.attr, + &sensor_dev_attr_fan2_input.dev_attr.attr, + &sensor_dev_attr_pwm2.dev_attr.attr, + &sensor_dev_attr_fan2_led.dev_attr.attr, + &sensor_dev_attr_fan2_present.dev_attr.attr, + &sensor_dev_attr_fan2_id.dev_attr.attr, + &sensor_dev_attr_fan3_input.dev_attr.attr, + &sensor_dev_attr_pwm3.dev_attr.attr, + &sensor_dev_attr_fan3_led.dev_attr.attr, + &sensor_dev_attr_fan3_present.dev_attr.attr, + &sensor_dev_attr_fan3_id.dev_attr.attr, + &sensor_dev_attr_fan4_input.dev_attr.attr, + &sensor_dev_attr_pwm4.dev_attr.attr, + &sensor_dev_attr_fan4_led.dev_attr.attr, + &sensor_dev_attr_fan4_present.dev_attr.attr, + &sensor_dev_attr_fan4_id.dev_attr.attr, + NULL, +}; + +ATTRIBUTE_GROUPS(fan); + +static void set_led_init_state(struct device * dev) +{ + int num_fan; + u8 *reg_g = NULL; + u8 *reg_r = NULL; + unsigned long green_led_addr; + u8 val_g, val_r; + struct raven_pdata *pdata = dev_get_drvdata(dev); + + for(num_fan = 0; num_fan < NUM_FANS; num_fan++) { + green_led_addr = green_led_addrs[num_fan]; + reg_g = pdata->gpio_base + green_led_addr; + reg_r = reg_g + GREEN_RED_LED_ADDR_OFFSET; + val_g = ioread8(reg_g); + val_r = ioread8(reg_r); + val_g &= ~LED_DIR_REG_OFFSET; + val_r &= ~LED_DIR_REG_OFFSET; + val_g &= ~LED_ON_OFF_REG_OFFSET; // initialize leds to green + val_r |= LED_ON_OFF_REG_OFFSET; + iowrite8(val_g, reg_g); + iowrite8(val_r, reg_r); + } +} + +static void set_fan_init_state(struct device * dev) +{ + int num_fan; + struct raven_pdata *pdata = dev_get_drvdata(dev); + u8 *reg = pdata->pm2_base; + unsigned long fan_ctrl_offset; + for (num_fan = 0; num_fan < NUM_FANS; num_fan++) { + fan_ctrl_offset = FAN_CTRL_ADDR_OFFSET * num_fan; + iowrite8(0x06, reg + fan_ctrl_offset); /*FanInputControl*/ + iowrite8(0x04, reg + FAN_CTRL_BASE_ADDR + fan_ctrl_offset); + iowrite8(0x01, reg + FAN_FREQ_BASE_ADDR + fan_ctrl_offset); + iowrite8(0xff, reg + FAN_DUTY_BASE_ADDR + fan_ctrl_offset); + + iowrite8(0x01, reg + FAN_DETECT_CTRL_BASE_ADDR + (FAN_DETECT_ADDR_OFFSET * + num_fan)); + } +} + +static int sb_fan_remove(struct platform_device *pdev) +{ + int err = 0; + struct raven_pdata *pdata = platform_get_drvdata(pdev); + + leds_unregister(pdata, NUM_FANS); + + iounmap(pdata->gpio_base); + iounmap(pdata->pm2_base); + release_mem_region(SB800_PM2_BASE, SB800_PM2_SIZE); + release_mem_region(SB800_GPIO_BASE, SB800_GPIO_SIZE); + hwmon_device_unregister(pdata->hwmon_dev); + return err; +} + +static s32 sb_fan_probe(struct platform_device *pdev) +{ + int ret = 0; + int err; + struct raven_pdata *pdata = devm_kzalloc(&pdev->dev, sizeof(struct raven_pdata), + GFP_KERNEL); + + if (!request_mem_region(SB800_PM2_BASE, SB800_PM2_SIZE, "SB800_PM2")) { + dev_err(&pdev->dev, "failed request_mem_region in SB fan initialization\n"); + ret = -EBUSY; + goto fail_request_pm_region; + } + pdata->pm2_base = ioremap(SB800_PM2_BASE, SB800_PM2_SIZE ); + + if (!request_mem_region(SB800_GPIO_BASE, SB800_GPIO_SIZE, "SB800_GPIO")) { + dev_err(&pdev->dev, "Failed request_mem_region in SB GPIO initialization"); + ret = -EBUSY; + goto fail_request_gpio_region; + } + pdata->gpio_base = ioremap(SB800_GPIO_BASE, SB800_GPIO_SIZE); + + pdata->hwmon_dev = hwmon_device_register_with_groups(&pdev->dev, "fans", NULL, + fan_groups); + if (IS_ERR(pdata->hwmon_dev)) { + dev_err(&pdev->dev, "failed to create hwmon sysfs entries\n"); + ret = PTR_ERR(pdata->hwmon_dev); + goto fail_hwmon_register; + } + platform_set_drvdata(pdev, pdata); + set_led_init_state(&pdev->dev); + set_fan_init_state(&pdev->dev); + + err = leds_register(&pdev->dev, pdata); + if (err) { + ret = err; + goto fail_hwmon_register; + } + + return ret; + +fail_hwmon_register: + release_mem_region(SB800_GPIO_BASE, SB800_GPIO_SIZE); + iounmap(pdata->gpio_base); +fail_request_gpio_region: + release_mem_region(SB800_PM2_BASE, SB800_PM2_SIZE); + iounmap(pdata->pm2_base); +fail_request_pm_region: + return ret; +} + +static int __init sb_fan_init(void) +{ + int err; + struct platform_device *pdev = NULL; + + pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); + + if (IS_ERR(pdev)) { + printk(KERN_ERR "failed to register " DRIVER_NAME); + return PTR_ERR(pdev); + } + + err = sb_fan_probe(pdev); + + if (err) { + dev_err(&pdev->dev, "failed to init device "); + platform_device_unregister(pdev); + return err; + } + + sb800_pdev = pdev; + + return err; +} + +static void __exit sb_fan_exit(void) +{ + if (!sb800_pdev) { + return; + } + + sb_fan_remove(sb800_pdev); + platform_device_unregister(sb800_pdev); + + sb800_pdev = 0; +} + +module_init(sb_fan_init); +module_exit(sb_fan_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Arista Networks"); +MODULE_DESCRIPTION("Raven Fan Driver"); diff --git a/platform/broadcom/sonic-platform-modules-arista/src/rook-fan-cpld.c b/platform/broadcom/sonic-platform-modules-arista/src/rook-fan-cpld.c new file mode 100644 index 000000000000..5a6933bdac4f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/src/rook-fan-cpld.c @@ -0,0 +1,963 @@ +/* Copyright (c) 2017 Arista Networks, 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, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "rook-fan-cpld" + +#define LED_NAME_MAX_SZ 20 +#define MAX_FAN_COUNT 8 + +#define MINOR_VERSION_REG 0x00 +#define MAJOR_VERSION_REG 0x01 +#define SCRATCHPAD_REG 0x02 + +#define FAN_TACH_REG_LOW(Id, Num) (0x10 * ((Num) + 1) + (Id) * 2) +#define FAN_TACH_REG_HIGH(Id, Num) (0x10 * ((Num) + 1) + ((Id) * 2) + 1) +#define FAN_TACH_A_REG_LOW(Id) (0x10 + ((Id) * 2)) +#define FAN_TACH_A_REG_HIGH(Id) (0x10 + ((Id) * 2) + 1) +#define FAN_TACH_B_REG_LOW(Id) (0x20 + ((Id) * 2)) +#define FAN_TACH_B_REG_HIGH(Id) (0x20 + ((Id) * 2) + 1) +#define FAN_PWM_REG(Id, Num) (0x30 + (Id) + ((Num) * 8)) +#define FAN_PWM_A_REG(Id) (0x30 + (Id)) +#define FAN_PWM_B_REG(Id) (0x38 + (Id)) + +#define FAN_ID_REG(Id) (0x41 + (Id)) +#define FAN_PRESENT_REG 0x49 +#define FAN_OK_REG 0x4A + +#define FAN_GREEN_LED_REG 0x4B +#define FAN_RED_LED_REG 0x4C + +#define FAN_INT_REG 0x4D +#define FAN_ID_CHNG_REG 0x4E +#define FAN_PRESENT_CHNG_REG 0x4F +#define FAN_OK_CHNG_REG 0x50 + +#define FAN_INT_OK (1 << 0) +#define FAN_INT_PRES (1 << 1) +#define FAN_INT_ID (1 << 2) + +#define FAN_LED_GREEN 1 +#define FAN_LED_RED 2 + +static bool managed_leds = true; +module_param(managed_leds, bool, S_IRUSR | S_IWUSR); +MODULE_PARM_DESC(managed_leds, "let the driver handle the leds"); + +static unsigned long poll_interval = 0; +module_param(poll_interval, ulong, S_IRUSR); +MODULE_PARM_DESC(poll_interval, "interval between two polling in ms"); + +static struct workqueue_struct *rook_cpld_workqueue; + +enum cpld_type { + ROOK_CPLD = 0, +}; + +struct cpld_info { + enum cpld_type id; + u8 fan_count; + u8 rotors; + int pulses; + int hz; +}; + +// these info could also be deducted from the id register +static struct cpld_info cpld_infos[] = { + [ROOK_CPLD] = { + .id = ROOK_CPLD, + .fan_count = 4, + .rotors = 1, + .pulses = 2, + .hz = 100000, + }, +}; + +struct cpld_fan_data { + struct led_classdev cdev; + bool ok; + bool present; + bool forward; + u16 tach; + u8 pwm; + u8 ident; + u8 index; + char led_name[LED_NAME_MAX_SZ]; +}; + +struct cpld_data { + const struct cpld_info *info; + struct mutex lock; + struct i2c_client *client; + struct device *hwmon_dev; + struct delayed_work dwork; + struct cpld_fan_data fans[MAX_FAN_COUNT]; + + const struct attribute_group *groups[1 + MAX_FAN_COUNT + 1]; + + u8 minor; + u8 major; + + u8 present; + u8 ok; + + u8 green_led; + u8 red_led; +}; + +static struct cpld_fan_data *fan_from_cpld(struct cpld_data *cpld, u8 fan_id) { + return &cpld->fans[fan_id]; +} + +static struct cpld_fan_data *fan_from_dev(struct device *dev, u8 fan_id) { + struct cpld_data *cpld = dev_get_drvdata(dev); + return fan_from_cpld(cpld, fan_id); +} + +static struct device *dev_from_cpld(struct cpld_data *cpld) { + return &cpld->client->dev; +} + +static s32 cpld_read_byte(struct cpld_data *cpld, u8 reg, u8 *res) +{ + int err; + + err = i2c_smbus_read_byte_data(cpld->client, reg); + if (err < 0) { + dev_err(&cpld->client->dev, + "failed to read reg 0x%02x error=%d\n", reg, err); + return err; + } + + *res = (err & 0xff); + return 0; +} + +static s32 cpld_write_byte(struct cpld_data *cpld, u8 reg, u8 byte) +{ + int err; + + err = i2c_smbus_write_byte_data(cpld->client, reg, byte); + if (err) { + dev_err(&cpld->client->dev, + "failed to write 0x%02x in reg 0x%02x error=%d\n", byte, reg, err); + } + + return err; +} + +static void cpld_work_start(struct cpld_data *cpld) +{ + if (poll_interval) { + queue_delayed_work(rook_cpld_workqueue, &cpld->dwork, + msecs_to_jiffies(poll_interval)); + } +} + +static s32 cpld_read_fan_id(struct cpld_data *cpld, u8 fan_id) +{ + struct cpld_fan_data *fan = fan_from_cpld(cpld, fan_id); + s32 err; + u8 tmp; + + err = cpld_read_byte(cpld, FAN_ID_REG(fan_id), &tmp); + if (err) + return err; + + fan->ident = tmp & 0xf; + fan->forward = (tmp >> 4) & 0x1; + + return 0; +} + +static int cpld_update_leds(struct cpld_data *cpld) +{ + struct cpld_fan_data *fan; + int err; + int i; + + cpld->green_led = 0; + cpld->red_led = 0; + + for (i = 0; i < cpld->info->fan_count; ++i) { + fan = fan_from_cpld(cpld, i); + if (fan->ok && fan->present) + cpld->green_led |= (1 << i); + else + cpld->red_led |= (1 << i); + } + + err = cpld_write_byte(cpld, FAN_GREEN_LED_REG, ~cpld->green_led); + if (err) + return err; + + err = cpld_write_byte(cpld, FAN_RED_LED_REG, ~cpld->red_led); + if (err) + return err; + + return 0; +} + +static int cpld_update(struct cpld_data *cpld) +{ + struct device *dev = dev_from_cpld(cpld); + struct cpld_fan_data *fan; + const char *str; + int fans_connected = 0; + int err; + int i; + u8 interrupt, id_chng, ok_chng, pres_chng; + + dev_dbg(dev, "polling cpld information\n"); + + err = cpld_read_byte(cpld, FAN_INT_REG, &interrupt); + if (err) + goto fail; + + if (interrupt & FAN_INT_ID) { + err = cpld_read_byte(cpld, FAN_ID_CHNG_REG, &id_chng); + if (err) + goto fail; + } + + if (interrupt & FAN_INT_OK) { + err = cpld_read_byte(cpld, FAN_OK_CHNG_REG, &ok_chng); + if (err) + goto fail; + err = cpld_read_byte(cpld, FAN_OK_REG, &cpld->ok); + if (err) + goto fail; + } + + if (interrupt & FAN_INT_PRES) { + err = cpld_read_byte(cpld, FAN_PRESENT_CHNG_REG, &pres_chng); + if (err) + goto fail; + err = cpld_read_byte(cpld, FAN_OK_REG, &cpld->present); + if (err) + goto fail; + } + + for (i = 0; i < cpld->info->fan_count; ++i) { + fan = fan_from_cpld(cpld, i); + + if ((interrupt & FAN_INT_PRES) && (pres_chng & (1 << i))) { + if (fan->present && (cpld->present & (1 << i))) { + str = "hotswapped"; + } else if (!fan->present && (cpld->present & (1 << i))) { + str = "plugged"; + fan->present = true; + } else { + str = "unplugged"; + fan->present = false; + } + dev_info(dev, "fan %d was %s\n", i + 1, str); + } + + if ((interrupt & FAN_INT_OK) && (ok_chng & (1 << i))) { + if (fan->ok && (cpld->ok & (1 << i))) { + dev_warn(dev, "fan %d had a small snag\n", i + 1); + } else if (fan->ok && !(cpld->ok & (1 << i))) { + dev_warn(dev, "fan %d is in fault, likely stuck\n", i + 1); + fan->ok = false; + } else { + dev_info(dev, "fan %d has recovered a running state\n", i + 1); + fan->ok = true; + } + } + + if ((interrupt & FAN_INT_ID) && (id_chng & (1 << i))) { + dev_info(dev, "fan %d kind has changed\n", i + 1); + cpld_read_fan_id(cpld, i); + } + + if (fan->present) + fans_connected += 1; + } + + if (cpld->info->fan_count - fans_connected > 1) { + dev_warn(dev, "it is not recommended to have more than one fan " + "unplugged. (%d/%d connected)\n", + fans_connected, cpld->info->fan_count); + } + + cpld_write_byte(cpld, FAN_ID_CHNG_REG, id_chng); + cpld_write_byte(cpld, FAN_OK_CHNG_REG, ok_chng); + cpld_write_byte(cpld, FAN_PRESENT_CHNG_REG, pres_chng); + + if (managed_leds) + err = cpld_update_leds(cpld); + +fail: + return err; +} + +static s32 cpld_write_pwm(struct cpld_data *cpld, u8 fan_id, u8 pwm) +{ + struct cpld_fan_data *fan = fan_from_cpld(cpld, fan_id); + int err = 0; + int i; + + for (i = 0; i < cpld->info->rotors; i++) { + err = cpld_write_byte(cpld, FAN_PWM_REG(fan_id, i), pwm); + if (err) + return err; + + fan->pwm = pwm; + } + + return err; +} + +static int cpld_read_present(struct cpld_data *cpld) +{ + struct cpld_fan_data *fan; + int err; + int i; + + err = cpld_read_byte(cpld, FAN_PRESENT_REG, &cpld->present); + if (err) + return err; + + for (i = 0; i < cpld->info->fan_count; ++i) { + fan = fan_from_cpld(cpld, i); + fan->present = !!(cpld->present & (1 << i)); + } + + return 0; +} + +static int cpld_read_fault(struct cpld_data *cpld) +{ + struct cpld_fan_data *fan; + int err; + int i; + + err = cpld_read_byte(cpld, FAN_OK_REG, &cpld->ok); + if (err) + return err; + + for (i = 0; i < cpld->info->fan_count; ++i) { + fan = fan_from_cpld(cpld, i); + fan->ok = !!(cpld->ok & (1 << i)); + } + + return 0; +} + +static s32 cpld_read_tach_single(struct cpld_data *cpld, u8 fan_id, u8 fan_num, + u16 *tach) +{ + int err; + u8 low; + u8 high; + + err = cpld_read_byte(cpld, FAN_TACH_REG_LOW(fan_id, fan_num), &low); + if (err) + return err; + + err = cpld_read_byte(cpld, FAN_TACH_REG_HIGH(fan_id, fan_num), &high); + if (err) + return err; + + *tach = ((u16)high << 8) | low; + + return 0; +} + +static s32 cpld_read_fan_tach(struct cpld_data *cpld, u8 fan_id) +{ + struct cpld_fan_data *fan = fan_from_cpld(cpld, fan_id); + s32 err = 0; + int i; + + for (i = 0; i < cpld->info->rotors; i++) { + err = cpld_read_tach_single(cpld, fan_id, i, &fan->tach); + if (err) + break; + + dev_dbg(dev_from_cpld(cpld), + "fan%d/%d tach=0x%04x\n", fan_id + 1, i + 1, fan->tach); + if (fan->tach == 0xffff) { + cpld_read_present(cpld); + cpld_read_fault(cpld); + if (managed_leds) + cpld_update_leds(cpld); + + if (!fan->present) + return -ENODEV; + + dev_warn(dev_from_cpld(cpld), + "Invalid tach information read from fan %d, this is likely " + "a hardware issue (stuck fan or broken register)\n", fan_id + 1); + + return -EIO; + } + } + + return err; +} + +static s32 cpld_read_pwm_single(struct cpld_data *cpld, u8 fan_id, u8 fan_num, + u8 *pwm) +{ + return cpld_read_byte(cpld, FAN_PWM_REG(fan_id, fan_num), pwm); +} + +static s32 cpld_read_fan_pwm(struct cpld_data *cpld, u8 fan_id) +{ + struct cpld_fan_data *fan = fan_from_cpld(cpld, fan_id); + int err; + u8 pwm_outer; + + err = cpld_read_pwm_single(cpld, fan_id, 0, &pwm_outer); + if (err) + return err; + + // some fans have two rotors but we only fetch the 1st one + fan->pwm = pwm_outer; + + return 0; +} + +static s32 cpld_read_fan_led(struct cpld_data *data, u8 fan_id, u8 *val) +{ + bool red = data->red_led & (1 << fan_id); + bool green = data->green_led & (1 << fan_id); + + *val = 0; + if (green) + *val += FAN_LED_GREEN; + if (red) + *val += FAN_LED_RED; + + return 0; +} + +static s32 cpld_write_fan_led(struct cpld_data *cpld, u8 fan_id, u8 val) +{ + int err = 0; + + if (val > 3) + return -EINVAL; + + if (val & FAN_LED_GREEN) + cpld->green_led |= (1 << fan_id); + else + cpld->green_led &= ~(1 << fan_id); + + if (val & FAN_LED_RED) + cpld->red_led |= (1 << fan_id); + else + cpld->red_led &= ~(1 << fan_id); + + err = cpld_write_byte(cpld, FAN_GREEN_LED_REG, ~cpld->green_led); + if (err) + return err; + + err = cpld_write_byte(cpld, FAN_RED_LED_REG, ~cpld->red_led); + + return err; +} + +static void brightness_set(struct led_classdev *led_cdev, + enum led_brightness val) +{ + struct cpld_fan_data *fan = container_of(led_cdev, struct cpld_fan_data, + cdev); + struct cpld_data *data = dev_get_drvdata(led_cdev->dev->parent); + + cpld_write_fan_led(data, fan->index, val); +} + +static enum led_brightness brightness_get(struct led_classdev *led_cdev) +{ + struct cpld_fan_data *fan = container_of(led_cdev, struct cpld_fan_data, + cdev); + struct cpld_data *data = dev_get_drvdata(led_cdev->dev->parent); + int err; + u8 val; + + err = cpld_read_fan_led(data, fan->index, &val); + if (err) + return 0; + + return val; +} + +static int led_init(struct cpld_fan_data *fan, struct i2c_client *client, + int fan_index) +{ + fan->index = fan_index; + fan->cdev.brightness_set = brightness_set; + fan->cdev.brightness_get = brightness_get; + scnprintf(fan->led_name, LED_NAME_MAX_SZ, "fan%d", fan->index + 1); + fan->cdev.name = fan->led_name; + + return led_classdev_register(&client->dev, &fan->cdev); +} + +static void cpld_leds_unregister(struct cpld_data *cpld, int num_leds) +{ + int i = 0; + struct cpld_fan_data *fan; + + for (i = 0; i < num_leds; i++) { + fan = fan_from_cpld(cpld, i); + led_classdev_unregister(&fan->cdev); + } +} + +static ssize_t cpld_fan_pwm_show(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct cpld_data *cpld = dev_get_drvdata(dev); + struct cpld_fan_data *fan = fan_from_cpld(cpld, attr->index); + int err; + + mutex_lock(&cpld->lock); + err = cpld_read_fan_pwm(cpld, attr->index); + mutex_unlock(&cpld->lock); + if (err) + return err; + + return sprintf(buf, "%hhu\n", fan->pwm); +} + +static ssize_t cpld_fan_pwm_store(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct cpld_data *cpld = dev_get_drvdata(dev); + u8 val; + int err; + + if (sscanf(buf, "%hhu", &val) != 1) + return -EINVAL; + + mutex_lock(&cpld->lock); + err = cpld_write_pwm(cpld, attr->index, val); + mutex_unlock(&cpld->lock); + if (err) + return err; + + return count; +} + +static ssize_t cpld_fan_present_show(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct cpld_data *cpld = dev_get_drvdata(dev); + struct cpld_fan_data *fan = fan_from_cpld(cpld, attr->index); + int err; + + if (!poll_interval) { + mutex_lock(&cpld->lock); + err = cpld_read_present(cpld); + mutex_unlock(&cpld->lock); + if (err) + return err; + } + + return sprintf(buf, "%d\n", fan->present); +} + +static ssize_t cpld_fan_id_show(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct cpld_data *cpld = dev_get_drvdata(dev); + struct cpld_fan_data *fan = fan_from_cpld(cpld, attr->index); + int err = 0; + + if (!poll_interval) { + mutex_lock(&cpld->lock); + err = cpld_read_fan_id(cpld, attr->index); + mutex_unlock(&cpld->lock); + if (err) + return err; + } + + return sprintf(buf, "%hhu\n", fan->ident); +} + +static ssize_t cpld_fan_fault_show(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct cpld_data *cpld = dev_get_drvdata(dev); + struct cpld_fan_data *fan = fan_from_cpld(cpld, attr->index); + int err; + + if (!poll_interval) { + mutex_lock(&cpld->lock); + err = cpld_read_fault(cpld); + mutex_unlock(&cpld->lock); + if (err) + return err; + } + + return sprintf(buf, "%d\n", !fan->ok); +} + +static ssize_t cpld_fan_tach_show(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct cpld_data *cpld = dev_get_drvdata(dev); + struct cpld_fan_data *fan = fan_from_cpld(cpld, attr->index); + int err; + int rpms; + + mutex_lock(&cpld->lock); + err = cpld_read_fan_tach(cpld, attr->index); + mutex_unlock(&cpld->lock); + if (err) + return err; + + if (!fan->tach) { + return -EINVAL; + } + + rpms = ((cpld->info->hz * 60) / fan->tach) / cpld->info->pulses; + + return sprintf(buf, "%d\n", rpms); +} + +static ssize_t cpld_fan_led_show(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct cpld_data *cpld = dev_get_drvdata(dev); + int err; + u8 val; + + err = cpld_read_fan_led(cpld, attr->index, &val); + if (err) + return err; + + return sprintf(buf, "%hhu\n", val); +} + +static ssize_t cpld_fan_led_store(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct cpld_data *cpld = dev_get_drvdata(dev); + int err; + u8 val; + + if (managed_leds) + return -EPERM; + + if (sscanf(buf, "%hhu", &val) != 1) + return -EINVAL; + + mutex_lock(&cpld->lock); + err = cpld_write_fan_led(cpld, attr->index, val); + mutex_unlock(&cpld->lock); + if (err) + return err; + + return count; +} + +static ssize_t cpld_fan_airflow_show(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct cpld_fan_data *fan = fan_from_dev(dev, attr->index); + return sprintf(buf, "%s\n", (fan->forward) ? "forward" : "reverse"); +} + + +#define FAN_DEVICE_ATTR(_name) \ + static SENSOR_DEVICE_ATTR(pwm## _name, S_IRUGO|S_IWGRP|S_IWUSR, \ + cpld_fan_pwm_show, cpld_fan_pwm_store, _name-1); \ + static SENSOR_DEVICE_ATTR(fan##_name##_id, S_IRUGO, \ + cpld_fan_id_show, NULL, _name-1); \ + static SENSOR_DEVICE_ATTR(fan##_name##_input, S_IRUGO, \ + cpld_fan_tach_show, NULL, _name-1); \ + static SENSOR_DEVICE_ATTR(fan##_name##_fault, S_IRUGO, \ + cpld_fan_fault_show, NULL, _name-1); \ + static SENSOR_DEVICE_ATTR(fan##_name##_present, S_IRUGO, \ + cpld_fan_present_show, NULL, _name-1); \ + static SENSOR_DEVICE_ATTR(fan##_name##_led, S_IRUGO|S_IWGRP|S_IWUSR, \ + cpld_fan_led_show, cpld_fan_led_store, _name-1); \ + static SENSOR_DEVICE_ATTR(fan##_name##_airflow, S_IRUGO, \ + cpld_fan_airflow_show, NULL, _name-1); + +#define FAN_ATTR(_name) \ + &sensor_dev_attr_pwm##_name.dev_attr.attr, \ + &sensor_dev_attr_fan##_name##_id.dev_attr.attr, \ + &sensor_dev_attr_fan##_name##_input.dev_attr.attr, \ + &sensor_dev_attr_fan##_name##_fault.dev_attr.attr, \ + &sensor_dev_attr_fan##_name##_present.dev_attr.attr, \ + &sensor_dev_attr_fan##_name##_led.dev_attr.attr, \ + &sensor_dev_attr_fan##_name##_airflow.dev_attr.attr \ + + +#define FAN_ATTR_GROUP(_name) &fan##_name##_attr_group + +#define DEVICE_FAN_ATTR_GROUP(_name) \ + FAN_DEVICE_ATTR(_name); \ + static struct attribute *fan##_name##_attrs[] = { FAN_ATTR(_name), NULL }; \ + static struct attribute_group fan##_name##_attr_group = { \ + .attrs = fan##_name##_attrs, \ + } + +DEVICE_FAN_ATTR_GROUP(1); +DEVICE_FAN_ATTR_GROUP(2); +DEVICE_FAN_ATTR_GROUP(3); +DEVICE_FAN_ATTR_GROUP(4); +DEVICE_FAN_ATTR_GROUP(5); +DEVICE_FAN_ATTR_GROUP(6); +DEVICE_FAN_ATTR_GROUP(7); +DEVICE_FAN_ATTR_GROUP(8); + +static struct attribute_group *fan_groups[] = { + FAN_ATTR_GROUP(1), + FAN_ATTR_GROUP(2), + FAN_ATTR_GROUP(3), + FAN_ATTR_GROUP(4), + FAN_ATTR_GROUP(5), + FAN_ATTR_GROUP(6), + FAN_ATTR_GROUP(7), + FAN_ATTR_GROUP(8), + NULL, +}; + +static ssize_t cpld_revision_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct cpld_data *cpld = dev_get_drvdata(dev); + return sprintf(buf, "%02x.%02x\n", cpld->major, cpld->minor); +} + +DEVICE_ATTR(cpld_revision, S_IRUGO, cpld_revision_show, NULL); + +static ssize_t cpld_update_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct cpld_data *cpld = dev_get_drvdata(dev); + int err; + + mutex_lock(&cpld->lock); + err = cpld_update(cpld); + mutex_unlock(&cpld->lock); + + return err; +} + +DEVICE_ATTR(update, S_IRUGO, cpld_update_show, NULL); + +static struct attribute *cpld_attrs[] = { + &dev_attr_cpld_revision.attr, + &dev_attr_update.attr, + NULL, +}; + +static struct attribute_group cpld_group = { + .attrs = cpld_attrs, +}; + +static void cpld_work_fn(struct work_struct *work) +{ + struct delayed_work *dwork = to_delayed_work(work); + struct cpld_data *cpld = container_of(dwork, struct cpld_data, dwork); + + mutex_lock(&cpld->lock); + cpld_update(cpld); + cpld_work_start(cpld); + mutex_unlock(&cpld->lock); +} + +static int cpld_init(struct cpld_data *cpld) +{ + struct cpld_fan_data *fan; + int err; + int i; + + err = cpld_read_byte(cpld, MINOR_VERSION_REG, &cpld->minor); + if (err) + return -ENODEV; + + err = cpld_read_byte(cpld, MAJOR_VERSION_REG, &cpld->major); + if (err) + return err; + + dev_info(dev_from_cpld(cpld), "rook CPLD version %02x.%02x\n", + cpld->major, cpld->minor); + + err = cpld_read_byte(cpld, FAN_PRESENT_REG, &cpld->present); + if (err) + return err; + + err = cpld_read_byte(cpld, FAN_OK_REG, &cpld->ok); + if (err) + return err; + + for (i = 0; i < cpld->info->fan_count; ++i) { + fan = fan_from_cpld(cpld, i); + fan->present = !!(cpld->present & (1 << i)); + fan->ok = !!(cpld->ok & (1 << i)); + if (fan->present) { + cpld_read_fan_id(cpld, i); + cpld_read_fan_tach(cpld, i); + cpld_read_fan_pwm(cpld, i); + err = led_init(fan, cpld->client, i); + if (err) { + cpld_leds_unregister(cpld, i); + return err; + } + } + } + + cpld_write_byte(cpld, FAN_OK_CHNG_REG, 0xff); + cpld_write_byte(cpld, FAN_ID_CHNG_REG, 0xff); + cpld_write_byte(cpld, FAN_ID_CHNG_REG, 0xff); + + if (managed_leds) { + err = cpld_update_leds(cpld); + if (err) + return err; + } + + INIT_DELAYED_WORK(&cpld->dwork, cpld_work_fn); + cpld_work_start(cpld); + + return err; +} + +static int cpld_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct device *dev = &client->dev; + struct device *hwmon_dev; + struct cpld_data *cpld; + int err; + int i; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_err(dev, "adapter doesn't support byte transactions\n"); + return -ENODEV; + } + + cpld = devm_kzalloc(dev, sizeof(struct cpld_data), GFP_KERNEL); + if (!cpld) + return -ENOMEM; + + i2c_set_clientdata(client, cpld); + cpld->client = client; + + cpld->info = &cpld_infos[id->driver_data]; + mutex_init(&cpld->lock); + + cpld->groups[0] = &cpld_group; + for (i = 0; i < cpld->info->fan_count; ++i) { + cpld->groups[i + 1] = fan_groups[i]; + } + + hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, + cpld, cpld->groups); + if (IS_ERR(hwmon_dev)) + return PTR_ERR(hwmon_dev); + + cpld->hwmon_dev = hwmon_dev; + + mutex_lock(&cpld->lock); + err = cpld_init(cpld); + mutex_unlock(&cpld->lock); + + return err; +} + +static int cpld_remove(struct i2c_client *client) +{ + struct cpld_data *cpld = i2c_get_clientdata(client); + + mutex_lock(&cpld->lock); + cancel_delayed_work_sync(&cpld->dwork); + mutex_unlock(&cpld->lock); + + cpld_leds_unregister(cpld, cpld->info->fan_count); + + return 0; +} + +static const struct i2c_device_id cpld_id[] = { + { "rook_cpld", ROOK_CPLD }, + {} +}; + +MODULE_DEVICE_TABLE(i2c, cpld_id); + +static struct i2c_driver cpld_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = DRIVER_NAME, + }, + .id_table = cpld_id, + .probe = cpld_probe, + .remove = cpld_remove, +}; + +static int __init rook_cpld_init(void) +{ + int err; + + rook_cpld_workqueue = create_singlethread_workqueue(DRIVER_NAME); + if (IS_ERR_OR_NULL(rook_cpld_workqueue)) { + pr_err("failed to initialize workqueue\n"); + return PTR_ERR(rook_cpld_workqueue); + } + + err = i2c_add_driver(&cpld_driver); + if (err < 0) { + destroy_workqueue(rook_cpld_workqueue); + rook_cpld_workqueue = NULL; + return err; + } + + return 0; +} + +static void __exit rook_cpld_exit(void) +{ + i2c_del_driver(&cpld_driver); + destroy_workqueue(rook_cpld_workqueue); + rook_cpld_workqueue = NULL; +} + +module_init(rook_cpld_init); +module_exit(rook_cpld_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Arista Networks"); +MODULE_DESCRIPTION("Rook fan cpld"); diff --git a/platform/broadcom/sonic-platform-modules-arista/src/rook-led-driver.c b/platform/broadcom/sonic-platform-modules-arista/src/rook-led-driver.c new file mode 100644 index 000000000000..090da18f9050 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/src/rook-led-driver.c @@ -0,0 +1,296 @@ +/* Copyright (c) 2017 Arista Networks, 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, see . + * + */ + +#include +#include +#include +#include +#include + +// led -> gpio pin mapping +#define PS2_STATUS_LEDR 0 +#define PS2_STATUS_LEDG 1 +#define PS1_STATUS_LEDR 2 +#define PS1_STATUS_LEDG 3 +#define FAN_STATUS_LEDR 4 +#define FAN_STATUS_LEDG 5 +#define STATUS_LEDR 6 +#define STATUS_LEDG 7 +#define STATUS_LEDB 8 + +// pca9555 register mapping +#define INPUT_PORT_0 0 +#define INPUT_PORT_1 1 +#define OUTPUT_PORT_0 2 +#define OUTPUT_PORT_1 3 +#define POL_INV_PORT_0 4 +#define POL_INV_PORT_1 5 +#define CONFIG_PORT_0 6 +#define CONFIG_PORT_1 7 + +// pca9555 bank info +#define BANK_SZ 8 +#define NGPIO 16 +#define NUM_BANKS 2 +#define BANK_SHIFT 1 +#define NUM_LEDS 9 + +#define LED_ON 1 +#define OUTPUT 0 +#define INPUT 1 + +#define LED_NAME_MAX_SZ 40 + +struct pca9555_led { + char name[LED_NAME_MAX_SZ]; + int pin; + int on; // value to write to pin for led to turn on + struct led_classdev cdev; +}; + +struct pca9555_chip { + u8 reg_output[NUM_BANKS]; + u8 reg_direction[NUM_BANKS]; + int num_leds; + char *dev_name; + struct mutex i2c_lock; + struct i2c_client *client; + struct pca9555_led leds[NUM_LEDS]; +}; + +static u8 new_reg_val(u8 reg_val_prev, int pin, int val) +{ + if (val) + return reg_val_prev | (1u << (pin % BANK_SZ)); + else + return reg_val_prev & ~(1u << (pin % BANK_SZ)); +} + +static int pca9555_write_single(struct pca9555_chip *chip, int reg, int val) +{ + int ret; + + ret = i2c_smbus_write_byte_data(chip->client, reg, val); + if (ret < 0) { + dev_err(&chip->client->dev, "Failed writing register %d\n", reg); + return ret; + } + + return 0; +} + +static int pca9555_set_value(struct pca9555_chip *chip, int pin, int val) +{ + int reg, ret; + u8 reg_val; + + mutex_lock(&chip->i2c_lock); + + reg_val = new_reg_val(chip->reg_output[pin / BANK_SZ], pin, val); + if (pin >= BANK_SZ) + reg = OUTPUT_PORT_1; + else + reg = OUTPUT_PORT_0; + ret = pca9555_write_single(chip, reg, reg_val); + + if (!ret) + chip->reg_output[pin / BANK_SZ] = reg_val; + + mutex_unlock(&chip->i2c_lock); + + return ret; +} + +static void brightness_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + struct pca9555_led *pled = container_of(led_cdev, struct pca9555_led, + cdev); + struct pca9555_chip *chip = dev_get_drvdata(led_cdev->dev->parent); + + if ((int)value == LED_ON) + pca9555_set_value(chip, pled->pin, pled->on); + else + pca9555_set_value(chip, pled->pin, !pled->on); +} + +static void set_led_name(struct i2c_client *client, char *name, const char *color, + const char *fun) +{ + struct pca9555_chip *chip = dev_get_drvdata(&client->dev); + + scnprintf(name, LED_NAME_MAX_SZ, "%s-%d:%s:%s", chip->dev_name, + client->adapter->nr, color, fun); +} + +static void led_init(struct pca9555_led *led, struct i2c_client *client, + const char *color, const char *fun, int pin, int on) +{ + set_led_name(client, led->name, color, fun); + led->cdev.name = led->name; + led->pin = pin; + led->on = on; + led->cdev.brightness_set = brightness_set; +} + +static void leds_init(struct pca9555_led *leds, struct i2c_client *client) +{ + led_init(&leds[0], client, "green", "status", STATUS_LEDG, 0); + led_init(&leds[1], client, "red", "status", STATUS_LEDR, 0); + led_init(&leds[2], client, "green", "fan_status", FAN_STATUS_LEDG, 0); + led_init(&leds[3], client, "red", "fan_status", FAN_STATUS_LEDR, 0); + led_init(&leds[4], client, "green", "psu1_status", PS1_STATUS_LEDG, 0); + led_init(&leds[5], client, "red", "psu1_status", PS1_STATUS_LEDR, 0); + led_init(&leds[6], client, "green", "psu2_status", PS2_STATUS_LEDG, 0); + led_init(&leds[7], client, "red", "psu2_status", PS2_STATUS_LEDR, 0); + led_init(&leds[8], client, "blue", "beacon", STATUS_LEDB, 1); +} + +static int leds_pca9555_detect(struct i2c_client *client) +{ + if (i2c_smbus_read_byte_data(client, CONFIG_PORT_0) < 0) + return -ENODEV; + return 0; +} + +static int leds_pca9555_all_output(struct i2c_client *client) +{ + int err; + struct pca9555_chip *chip; + + chip = dev_get_drvdata(&client->dev); + + err = i2c_smbus_write_byte_data(client, CONFIG_PORT_0, OUTPUT); + if (err) + return err; + chip->reg_direction[0] = OUTPUT; + + err = i2c_smbus_write_byte_data(client, CONFIG_PORT_1, OUTPUT); + if (err) + return err; + chip->reg_direction[1] = OUTPUT; + + return 0; +} + +static int leds_pca9555_all_set(struct i2c_client *client, u8 bank1_val, + u8 bank2_val) +{ + int err; + struct pca9555_chip *chip; + + chip = dev_get_drvdata(&client->dev); + + err = i2c_smbus_write_byte_data(client, OUTPUT_PORT_0, bank1_val); + if (err) + return err; + chip->reg_output[0] = bank1_val; + + err = i2c_smbus_write_byte_data(client, OUTPUT_PORT_1, bank2_val); + if (err) + return err; + chip->reg_output[1] = bank2_val; + + return 0; +} + +static int leds_pca9555_remove(struct i2c_client *client) +{ + int i; + struct pca9555_chip *chip = i2c_get_clientdata(client); + + for (i = 0; i < chip->num_leds; i++) + led_classdev_unregister(&chip->leds[i].cdev); + + return 0; +} + +static int leds_pca9555_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int i, err; + struct pca9555_chip *chip; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_err(&client->dev, "adapter doesn't support byte transactions\n"); + return -ENODEV; + } + + err = leds_pca9555_detect(client); + if (err) + return err; + + chip = devm_kzalloc(&client->dev, sizeof(struct pca9555_chip), + GFP_KERNEL); + if (chip == NULL) + return -ENOMEM; + + mutex_init(&chip->i2c_lock); + chip->client = client; + chip->dev_name = client->name; + i2c_set_clientdata(client, chip); + + leds_init(chip->leds, client); + + // configure all pins as output and off from the start + err = leds_pca9555_all_output(client); + if (err) + return err; + + err = leds_pca9555_all_set(client, 0xff, 0); + if (err) + return err; + + // then set all leds to green + err = leds_pca9555_all_set(client, 0x55, 0); + if (err) + return err; + + chip->num_leds = 0; + for (i = 0; i < NUM_LEDS; i++) { + err = led_classdev_register(&client->dev, &chip->leds[i].cdev); + if (err) { + leds_pca9555_remove(client); + return err; + } + chip->num_leds += 1; + } + + return 0; +} + +static const struct i2c_device_id leds_pca9555_id[] = { + {"rook_leds", 0}, + {}, +}; + +MODULE_DEVICE_TABLE(i2c, leds_pca9555_id); + +static struct i2c_driver leds_pca9555_driver = { + .driver = { + .name = "rook_leds" + }, + .probe = leds_pca9555_probe, + .remove = leds_pca9555_remove, + .id_table = leds_pca9555_id, +}; + +module_i2c_driver(leds_pca9555_driver); + +MODULE_AUTHOR("Arista Networks"); +MODULE_DESCRIPTION("Driver to manage Rook status leds"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-arista/src/scd-hwmon.c b/platform/broadcom/sonic-platform-modules-arista/src/scd-hwmon.c new file mode 100644 index 000000000000..4509bf7629f3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/src/scd-hwmon.c @@ -0,0 +1,1595 @@ +/* Copyright (c) 2017 Arista Networks, 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, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "scd.h" +#include "scd-hwmon.h" + +#define SCD_MODULE_NAME "scd-hwmon" + +#define SMBUS_REQUEST_OFFSET 0x10 +#define SMBUS_CONTROL_STATUS_OFFSET 0x20 +#define SMBUS_RESPONSE_OFFSET 0x30 + +#define RESET_SET_OFFSET 0x00 +#define RESET_CLEAR_OFFSET 0x10 + +#define MASTER_DEFAULT_BUS_COUNT 8 +#define MASTER_DEFAULT_MAX_RETRIES 3 + +#define MAX_CONFIG_LINE_SIZE 100 + +struct scd_context; + +struct scd_master { + struct scd_context *ctx; + struct list_head list; + + u32 id; + u32 req; + u32 cs; + u32 resp; + struct mutex mutex; + struct list_head bus_list; + + int max_retries; +}; + +struct bus_params { + struct list_head list; + u16 addr; + u8 t; + u8 datw; + u8 datr; +}; + +const struct bus_params default_bus_params = { + .t = 1, + .datw = 3, + .datr = 3, +}; + +struct scd_bus { + struct scd_master *master; + struct list_head list; + + u32 id; + struct list_head params; + + struct i2c_adapter adap; +}; + +#define LED_NAME_MAX_SZ 40 +struct scd_led { + struct scd_context *ctx; + struct list_head list; + + u32 addr; + char name[LED_NAME_MAX_SZ]; + struct led_classdev cdev; +}; + +struct scd_gpio_attribute { + struct device_attribute dev_attr; + struct scd_context *ctx; + + u32 addr; + u32 bit; + u32 active_low; +}; + +#define GPIO_NAME_MAX_SZ 50 +struct scd_gpio { + char name[GPIO_NAME_MAX_SZ]; + struct scd_gpio_attribute attr; + struct list_head list; +}; + +#define __ATTR_NAME_PTR(_name, _mode, _show, _store) { \ + .attr = { .name = _name, \ + .mode = VERIFY_OCTAL_PERMISSIONS(_mode) }, \ + .show = _show, \ + .store = _store, \ +} + +#define to_scd_gpio_attr(_dev_attr) \ + container_of(_dev_attr, struct scd_gpio_attribute, dev_attr) + +#define SCD_GPIO_ATTR(_name, _mode, _show, _store, _ctx, _addr, _bit, _active_low) \ + { .dev_attr = __ATTR_NAME_PTR(_name, _mode, _show, _store), \ + .ctx = _ctx, \ + .addr = _addr, \ + .bit = _bit, \ + .active_low = _active_low \ + } + +#define SCD_RW_GPIO_ATTR(_name, _ctx, _addr, _bit, _active_low) \ + SCD_GPIO_ATTR(_name, S_IRUGO | S_IWUSR, attribute_gpio_get, attribute_gpio_set, \ + _ctx, _addr, _bit, _active_low) + +#define SCD_RO_GPIO_ATTR(_name, _ctx, _addr, _bit, _active_low) \ + SCD_GPIO_ATTR(_name, S_IRUGO, attribute_gpio_get, NULL, \ + _ctx, _addr, _bit, _active_low) + +struct scd_reset_attribute { + struct device_attribute dev_attr; + struct scd_context *ctx; + + u32 addr; + u32 bit; +}; + +#define RESET_NAME_MAX_SZ 50 +struct scd_reset { + char name[RESET_NAME_MAX_SZ]; + struct scd_reset_attribute attr; + struct list_head list; +}; + +#define to_scd_reset_attr(_dev_attr) \ + container_of(_dev_attr, struct scd_reset_attribute, dev_attr) + +#define SCD_RESET_ATTR(_name, _ctx, _addr, _bit) \ + { .dev_attr = __ATTR_NAME_PTR(_name, S_IRUGO | S_IWUSR, attribute_reset_get, \ + attribute_reset_set), \ + .ctx = _ctx, \ + .addr = _addr, \ + .bit = _bit, \ + } + +struct scd_context { + struct pci_dev *pdev; + size_t res_size; + + struct list_head list; + + struct mutex mutex; + bool initialized; + + struct list_head gpio_list; + struct list_head reset_list; + struct list_head led_list; + struct list_head master_list; +}; + +union request_reg { + u32 reg; + struct { + u32 d:8; + u32 ss:6; + u32 reserved1:2; + u32 dat:2; + u32 t:2; + u32 sp:1; + u32 da:1; + u32 dod:1; + u32 st:1; + u32 bs:4; + u32 ti:4; + } __packed; +}; + +union ctrl_status_reg { + u32 reg; + struct { + u32 reserved1:13; + u32 foe:1; + u32 reserved2:17; + u32 reset:1; + } __packed; +}; + +union response_reg { + u32 reg; + struct { + u32 d:8; + u32 bus_conflict_error:1; + u32 timeout_error:1; + u32 ack_error:1; + u32 flushed:1; + u32 ti:4; + u32 ss:6; + u32 reserved2:9; + u32 fe:1; + } __packed; +}; + +/* locking functions */ +static struct mutex scd_hwmon_mutex; + +static void module_lock(void) +{ + mutex_lock(&scd_hwmon_mutex); +} + +static void module_unlock(void) +{ + mutex_unlock(&scd_hwmon_mutex); +} + +static void master_lock(struct scd_master *master) +{ + mutex_lock(&master->mutex); +} + +static void master_unlock(struct scd_master *master) +{ + mutex_unlock(&master->mutex); +} + +static void scd_lock(struct scd_context *ctx) +{ + mutex_lock(&ctx->mutex); +} + +static void scd_unlock(struct scd_context *ctx) +{ + mutex_unlock(&ctx->mutex); +} + +/* SMBus functions */ +static void smbus_master_write_req(struct scd_master *master, + union request_reg req) +{ + u32 addr = (u32)master->req; + scd_write_register(master->ctx->pdev, addr, req.reg); +} + +static void smbus_master_write_cs(struct scd_master *master, + union ctrl_status_reg cs) +{ + scd_write_register(master->ctx->pdev, master->cs, cs.reg); +} + +static union ctrl_status_reg smbus_master_read_cs(struct scd_master *master) +{ + union ctrl_status_reg cs; + cs.reg = scd_read_register(master->ctx->pdev, master->cs); + return cs; +} + +static union response_reg smbus_master_read_resp(struct scd_master *master) +{ + union response_reg resp; + u32 retries = 10; + + resp.reg = scd_read_register(master->ctx->pdev, master->resp); + + while (resp.fe && --retries) { + msleep(10); + resp.reg = scd_read_register(master->ctx->pdev, master->resp); + } + + if (resp.fe) { + scd_dbg("smbus response: fifo still empty after retries"); + resp.reg = 0xffffffff; + } + + return resp; +} + +static s32 smbus_check_resp(union response_reg resp, u32 tid) +{ + const char *error; + int error_ret = -EIO; + + if (resp.reg == 0xffffffff) { + error = "fe"; + goto fail; + } + if (resp.ack_error) { + error = "ack"; + goto fail; + } + if (resp.timeout_error) { + error = "timeout"; + goto fail; + } + if (resp.bus_conflict_error) { + error = "conflict"; + goto fail; + } + if (resp.flushed) { + error = "flush"; + goto fail; + } + if (resp.ti != tid) { + error = "tid"; + goto fail; + } + + return 0; + +fail: + scd_dbg("smbus response: %s error. reg=0x%08x", error, resp.reg); + return error_ret; +} + +static u32 scd_smbus_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | + I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_I2C_BLOCK | I2C_FUNC_SMBUS_BLOCK_DATA; +} + +static void smbus_master_reset(struct scd_master *master) +{ + union ctrl_status_reg cs; + cs = smbus_master_read_cs(master); + cs.reset = 1; + cs.foe = 1; + smbus_master_write_cs(master, cs); + mdelay(10); + cs.reset = 0; + smbus_master_write_cs(master, cs); +} + +static const struct bus_params *get_bus_params(struct scd_bus *bus, u16 addr) { + const struct bus_params *params = &default_bus_params; + struct bus_params *params_tmp; + + list_for_each_entry(params_tmp, &bus->params, list) { + if (params_tmp->addr == addr) { + params = params_tmp; + break; + } + } + + return params; +} + +static s32 scd_smbus_do(struct scd_bus *bus, u16 addr, unsigned short flags, + char read_write, u8 command, int size, + union i2c_smbus_data *data) +{ + struct scd_master *master = bus->master; + const struct bus_params *params; + int i; + union request_reg req; + union response_reg resp; + int ret = 0; + u32 ss = 0; + u32 data_offset = 0; + + master_lock(master); + + params = get_bus_params(bus, addr); + + req.reg = 0; + req.bs = bus->id; + req.t = params->t; + + switch (size) { + case I2C_SMBUS_QUICK: + ss = 1; + break; + case I2C_SMBUS_BYTE: + ss = 2; + break; + case I2C_SMBUS_BYTE_DATA: + if (read_write == I2C_SMBUS_WRITE) { + ss = 3; + } else { + ss = 4; + } + break; + case I2C_SMBUS_WORD_DATA: + if (read_write == I2C_SMBUS_WRITE) { + ss = 4; + } else { + ss = 5; + } + break; + case I2C_SMBUS_I2C_BLOCK_DATA: + data_offset = 1; + if (read_write == I2C_SMBUS_WRITE) { + ss = 2 + data->block[0]; + } else { + ss = 3 + data->block[0]; + } + break; + case I2C_SMBUS_BLOCK_DATA: + if (read_write == I2C_SMBUS_WRITE) { + ss = 3 + data->block[0]; + } else { + master_unlock(master); + ret = scd_smbus_do(bus, addr, flags, I2C_SMBUS_READ, command, + I2C_SMBUS_BYTE_DATA, data); + master_lock(master); + if (ret) { + goto fail; + } + ss = 4 + data->block[0]; + } + break; + } + + req.st = 1; + req.ss = ss; + req.d = (((addr & 0xff) << 1) | ((ss <= 2) ? read_write : 0)); + req.dod = 1; + for (i = 0; i < ss; i++) { + if (i == ss - 1) { + req.sp = 1; + if (read_write == I2C_SMBUS_WRITE) { + req.dat = params->datw; + } else { + req.dat = params->datr; + } + } + if (i == 1) { + req.st = 0; + req.ss = 0; + req.d = command; + if (ss == 2) + req.dod = ((read_write == I2C_SMBUS_WRITE) ? 1 : 0); + else + req.dod = 1; + } + if ((i == 2 && read_write == I2C_SMBUS_READ)) { + req.st = 1; + req.d = (((addr & 0xff) << 1) | 1); + } + if (i >= 2 && (read_write == I2C_SMBUS_WRITE)) { + req.d = data->block[data_offset + i - 2]; + } + if ((i == 3 && read_write == I2C_SMBUS_READ)) { + req.dod = 0; + } + req.da = ((!(req.dod || req.sp)) ? 1 : 0); + smbus_master_write_req(master, req); + req.ti++; + req.st = 0; + } + + req.ti = 0; + for (i = 0; i < ss; i++) { + resp = smbus_master_read_resp(master); + ret = smbus_check_resp(resp, req.ti); + if (ret) { + goto fail; + } + req.ti++; + if (read_write == I2C_SMBUS_READ) { + if (size == I2C_SMBUS_BYTE || size == I2C_SMBUS_BYTE_DATA) { + if (i == ss - 1) { + data->byte = resp.d; + } + } else if (size == I2C_SMBUS_WORD_DATA) { + if (i == ss - 2) { + data->word = resp.d; + } else if (i == ss - 1) { + data->word |= (resp.d << 8); + } + } else { + if (i >= 3) { + if (size == I2C_SMBUS_BLOCK_DATA) { + data->block[i - 3] = resp.d; + } else { + data->block[i - 2] = resp.d; + } + } + } + } + } + + master_unlock(master); + return 0; + +fail: + scd_dbg("smbus %s failed addr=0x%02x reg=0x%02x size=0x%02x adapter=\"%s\"\n", + (read_write) ? "read" : "write", addr, command, size, bus->adap.name); + smbus_master_reset(master); + master_unlock(master); + return ret; +} + +static s32 scd_smbus_access(struct i2c_adapter *adap, u16 addr, + unsigned short flags, char read_write, + u8 command, int size, union i2c_smbus_data *data) +{ + struct scd_bus *bus = i2c_get_adapdata(adap); + struct scd_master *master = bus->master; + int retry = 0; + int ret; + + scd_dbg("smbus %s do addr=0x%02x reg=0x%02x size=0x%02x adapter=\"%s\"\n", + (read_write) ? "read" : "write", addr, command, size, bus->adap.name); + do { + ret = scd_smbus_do(bus, addr, flags, read_write, command, size, data); + if (ret != -EIO) + return ret; + retry++; + scd_dbg("smbus retrying... %d/%d", retry, master->max_retries); + } while (retry < master->max_retries); + + scd_warn("smbus %s failed addr=0x%02x reg=0x%02x size=0x%02x " + "adapter=\"%s\"\n", (read_write) ? "read" : "write", + addr, command, size, bus->adap.name); + + return -EIO; +} + +static struct i2c_algorithm scd_smbus_algorithm = { + .smbus_xfer = scd_smbus_access, + .functionality = scd_smbus_func, +}; + +static struct list_head scd_list; + +static struct scd_context *get_context_for_pdev(struct pci_dev *pdev) +{ + struct scd_context *ctx; + + module_lock(); + list_for_each_entry(ctx, &scd_list, list) { + if (ctx->pdev == pdev) { + module_unlock(); + return ctx; + } + } + module_unlock(); + + return NULL; +} + +static struct scd_context *get_context_for_dev(struct device *dev) +{ + struct scd_context *ctx; + + module_lock(); + list_for_each_entry(ctx, &scd_list, list) { + if (&ctx->pdev->dev == dev) { + module_unlock(); + return ctx; + } + } + module_unlock(); + + return NULL; +} + +static int scd_smbus_bus_add(struct scd_master *master, int id) +{ + struct scd_bus *bus; + int err; + + bus = kzalloc(sizeof(*bus), GFP_KERNEL); + if (!bus) { + return -ENOMEM; + } + + bus->master = master; + bus->id = id; + INIT_LIST_HEAD(&bus->params); + bus->adap.owner = THIS_MODULE; + bus->adap.class = 0; + bus->adap.algo = &scd_smbus_algorithm; + bus->adap.dev.parent = &master->ctx->pdev->dev; + scnprintf(bus->adap.name, + sizeof(bus->adap.name), + "SCD %s SMBus master %d bus %d", pci_name(master->ctx->pdev), + master->id, bus->id); + i2c_set_adapdata(&bus->adap, bus); + err = i2c_add_adapter(&bus->adap); + if (err) { + kfree(bus); + return err; + } + + master_lock(master); + list_add_tail(&bus->list, &master->bus_list); + master_unlock(master); + + return 0; +} + +static void scd_smbus_master_remove(struct scd_master *master) +{ + struct scd_bus *bus; + struct scd_bus *tmp_bus; + struct bus_params *params; + struct bus_params *tmp_params; + + list_for_each_entry_safe(bus, tmp_bus, &master->bus_list, list) { + i2c_del_adapter(&bus->adap); + + list_for_each_entry_safe(params, tmp_params, &bus->params, list) { + list_del(¶ms->list); + kfree(params); + } + + list_del(&bus->list); + kfree(bus); + } + + smbus_master_reset(master); + + list_del(&master->list); + kfree(master); +} + +static void scd_smbus_remove_all(struct scd_context *ctx) +{ + struct scd_master *master; + struct scd_master *tmp_master; + + list_for_each_entry_safe(master, tmp_master, &ctx->master_list, list) { + scd_smbus_master_remove(master); + } +} + +static int scd_smbus_master_add(struct scd_context *ctx, u32 addr, u32 id, + u32 bus_count) +{ + struct scd_master *master; + int err = 0; + int i; + + list_for_each_entry(master, &ctx->master_list, list) { + if (master->id == id) { + return -EEXIST; + } + } + + master = kzalloc(sizeof(*master), GFP_KERNEL); + if (!master) { + return -ENOMEM; + } + + master->ctx = ctx; + mutex_init(&master->mutex); + master->id = id; + master->req = addr + SMBUS_REQUEST_OFFSET; + master->cs = addr + SMBUS_CONTROL_STATUS_OFFSET; + master->resp = addr + SMBUS_RESPONSE_OFFSET; + master->max_retries = MASTER_DEFAULT_MAX_RETRIES; + INIT_LIST_HEAD(&master->bus_list); + + for (i = 0; i < bus_count; ++i) { + err = scd_smbus_bus_add(master, i); + if (err) { + goto fail_bus; + } + } + + smbus_master_reset(master); + + list_add_tail(&master->list, &ctx->master_list); + + return 0; + +fail_bus: + scd_smbus_master_remove(master); + return err; +} + +static void led_brightness_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + struct scd_led *led = container_of(led_cdev, struct scd_led, cdev); + u32 reg; + + switch ((int)value) { + case 0: + reg = 0x0006ff00; + break; + case 1: + reg = 0x1006ff00; + break; + case 2: + reg = 0x0806ff00; + break; + case 3: + reg = 0x1806ff00; + break; + case 4: + reg = 0x1406ff00; + break; + case 5: + reg = 0x0C06ff00; + break; + case 6: + reg = 0x1C06ff00; + break; + default: + reg = 0x1806ff00; + break; + } + scd_write_register(led->ctx->pdev, led->addr, reg); +} + +static void scd_led_remove_all(struct scd_context *ctx) +{ + struct scd_led *led; + struct scd_led *led_tmp; + + list_for_each_entry_safe(led, led_tmp, &ctx->led_list, list) { + led_classdev_unregister(&led->cdev); + list_del(&led->list); + kfree(led); + } +} + +static struct scd_led *scd_led_find(struct scd_context *ctx, u32 addr) +{ + struct scd_led *led; + + list_for_each_entry(led, &ctx->led_list, list) { + if (led->addr == addr) + return led; + } + return NULL; +} + +static int scd_led_add(struct scd_context *ctx, const char *name, u32 addr) +{ + struct scd_led *led; + int ret; + + if (scd_led_find(ctx, addr)) + return -EEXIST; + + led = kzalloc(sizeof(*led), GFP_KERNEL); + if (!led) + return -ENOMEM; + + led->ctx = ctx; + led->addr = addr; + strncpy(led->name, name, FIELD_SIZEOF(typeof(*led), name)); + INIT_LIST_HEAD(&led->list); + + led->cdev.name = led->name; + led->cdev.brightness_set = led_brightness_set; + + ret = led_classdev_register(&ctx->pdev->dev, &led->cdev); + if (ret) { + kfree(led); + return ret; + } + + list_add_tail(&led->list, &ctx->led_list); + + return 0; +} + +static ssize_t attribute_gpio_get(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + const struct scd_gpio_attribute *gpio = to_scd_gpio_attr(devattr); + u32 reg = scd_read_register(gpio->ctx->pdev, gpio->addr); + u32 res = !!(reg & (1 << gpio->bit)); + res = (gpio->active_low) ? !res : res; + return sprintf(buf, "%u\n", res); +} + +static ssize_t attribute_gpio_set(struct device *dev, + struct device_attribute *devattr, + const char *buf, size_t count) +{ + const struct scd_gpio_attribute *gpio = to_scd_gpio_attr(devattr); + long value; + int res; + u32 reg; + + res = kstrtol(buf, 10, &value); + if (res < 0) + return res; + + if (value != 0 && value != 1) + return -EINVAL; + + reg = scd_read_register(gpio->ctx->pdev, gpio->addr); + if (gpio->active_low) { + if (value) + reg &= ~(1 << gpio->bit); + else + reg |= ~(1 << gpio->bit); + } else { + if (value) + reg |= 1 << gpio->bit; + else + reg &= ~(1 << gpio->bit); + } + scd_write_register(gpio->ctx->pdev, gpio->addr, reg); + + return count; +} + +static void scd_gpio_unregister(struct scd_context *ctx, struct scd_gpio *gpio) +{ + sysfs_remove_file(&ctx->pdev->dev.kobj, &gpio->attr.dev_attr.attr); +} + +static int scd_gpio_register(struct scd_context *ctx, struct scd_gpio *gpio) +{ + int res; + + res = sysfs_create_file(&ctx->pdev->dev.kobj, &gpio->attr.dev_attr.attr); + if (res < 0) + return res; + + list_add_tail(&gpio->list, &ctx->gpio_list); + return 0; +} + +static void scd_gpio_remove_all(struct scd_context *ctx) +{ + struct scd_gpio *tmp_gpio; + struct scd_gpio *gpio; + + list_for_each_entry_safe(gpio, tmp_gpio, &ctx->gpio_list, list) { + scd_gpio_unregister(ctx, gpio); + list_del(&gpio->list); + kfree(gpio); + } +} + +static ssize_t attribute_reset_get(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + const struct scd_reset_attribute *reset = to_scd_reset_attr(devattr); + u32 reg = scd_read_register(reset->ctx->pdev, reset->addr); + u32 res = !!(reg & (1 << reset->bit)); + return sprintf(buf, "%u\n", res); +} + +// write 1 -> set, 0 -> clear +static ssize_t attribute_reset_set(struct device *dev, + struct device_attribute *devattr, + const char *buf, size_t count) +{ + const struct scd_reset_attribute *reset = to_scd_reset_attr(devattr); + u32 offset = RESET_SET_OFFSET; + long value; + int res; + u32 reg; + + res = kstrtol(buf, 10, &value); + if (res < 0) + return res; + + if (value != 0 && value != 1) + return -EINVAL; + + if (!value) + offset = RESET_CLEAR_OFFSET; + + reg = 1 << reset->bit; + scd_write_register(reset->ctx->pdev, reset->addr + offset, reg); + + return count; +} + +static void scd_reset_unregister(struct scd_context *ctx, struct scd_reset *reset) +{ + sysfs_remove_file(&ctx->pdev->dev.kobj, &reset->attr.dev_attr.attr); +} + +static int scd_reset_register(struct scd_context *ctx, struct scd_reset *reset) +{ + int res; + + res = sysfs_create_file(&ctx->pdev->dev.kobj, &reset->attr.dev_attr.attr); + if (res < 0) + return res; + + list_add_tail(&reset->list, &ctx->reset_list); + return 0; +} + +static void scd_reset_remove_all(struct scd_context *ctx) +{ + struct scd_reset *tmp_reset; + struct scd_reset *reset; + + list_for_each_entry_safe(reset, tmp_reset, &ctx->reset_list, list) { + scd_reset_unregister(ctx, reset); + list_del(&reset->list); + kfree(reset); + } +} + +struct gpio_cfg { + u32 bitpos; + bool readonly; + bool active_low; + const char *name; +}; + +static int scd_xcvr_add(struct scd_context *ctx, const char *prefix, + const struct gpio_cfg *cfgs, size_t gpio_count, + u32 addr, u32 id) +{ + int i; + int err; + const struct gpio_cfg *cfg; + struct scd_gpio *gpio; + + for (i = 0; i < gpio_count; ++i) { + cfg = &cfgs[i]; + + gpio = kzalloc(sizeof(*gpio), GFP_KERNEL); + if (!gpio) { + err = -ENOMEM; + goto fail; + } + + snprintf(gpio->name, FIELD_SIZEOF(typeof(*gpio), name), + "%s%u_%s", prefix, id, cfg->name); + + if (cfg->readonly) + gpio->attr = (struct scd_gpio_attribute)SCD_RO_GPIO_ATTR( + gpio->name, ctx, addr, cfg->bitpos, cfg->active_low); + else + gpio->attr = (struct scd_gpio_attribute)SCD_RW_GPIO_ATTR( + gpio->name, ctx, addr, cfg->bitpos, cfg->active_low); + + err = scd_gpio_register(ctx, gpio); + if (err) { + kfree(gpio); + goto fail; + } + } + + return 0; + +fail: + if (gpio) + kfree(gpio); + + while (i--) { + gpio = list_last_entry(&ctx->gpio_list, struct scd_gpio, list); + if (gpio) + list_del(&gpio->list); + } + + return err; +} + +static int scd_xcvr_sfp_add(struct scd_context *ctx, u32 addr, u32 id) +{ + static const struct gpio_cfg sfp_gpios[] = { + {0, true, false, "rxlos"}, + {1, true, false, "txfault"}, + {2, true, true, "present"}, + {3, true, false, "rxlos_changed"}, + {4, true, false, "txfault_changed"}, + {5, true, false, "present_changed"}, + {6, false, false, "txdisable"}, + {7, false, false, "rate_select0"}, + {8, false, false, "rate_select1"}, + }; + + scd_dbg("sfp %u @ 0x%04x\n", id, addr); + return scd_xcvr_add(ctx, "sfp", sfp_gpios, ARRAY_SIZE(sfp_gpios), addr, id); +} + +static int scd_xcvr_qsfp_add(struct scd_context *ctx, u32 addr, u32 id) +{ + static const struct gpio_cfg qsfp_gpios[] = { + {0, true, true, "interrupt"}, + {2, true, true, "present"}, + {3, true, false, "interrupt_changed"}, + {5, true, false, "present_changed"}, + {6, false, false, "lp_mode"}, + {7, false, false, "reset"}, + {8, false, true, "modsel"}, + }; + + scd_dbg("qsfp %u @ 0x%04x\n", id, addr); + return scd_xcvr_add(ctx, "qsfp", qsfp_gpios, ARRAY_SIZE(qsfp_gpios), addr, id); +} + +static int scd_gpio_add(struct scd_context *ctx, const char *name, + u32 addr, u32 bitpos, bool read_only, bool active_low) +{ + int err; + struct scd_gpio *gpio; + + gpio = kzalloc(sizeof(*gpio), GFP_KERNEL); + if (!gpio) { + return -ENOMEM; + } + + snprintf(gpio->name, FIELD_SIZEOF(typeof(*gpio), name), name); + if (read_only) + gpio->attr = (struct scd_gpio_attribute)SCD_RO_GPIO_ATTR( + gpio->name, ctx, addr, bitpos, active_low); + else + gpio->attr = (struct scd_gpio_attribute)SCD_RW_GPIO_ATTR( + gpio->name, ctx, addr, bitpos, active_low); + + err = scd_gpio_register(ctx, gpio); + if (err) { + kfree(gpio); + return err; + } + + return 0; +} + +static int scd_reset_add(struct scd_context *ctx, const char *name, + u32 addr, u32 bitpos) +{ + int err; + struct scd_reset *reset; + + reset = kzalloc(sizeof(*reset), GFP_KERNEL); + if (!reset) { + return -ENOMEM; + } + + snprintf(reset->name, FIELD_SIZEOF(typeof(*reset), name), name); + reset->attr = (struct scd_reset_attribute)SCD_RESET_ATTR( + reset->name, ctx, addr, bitpos); + + err = scd_reset_register(ctx, reset); + if (err) { + kfree(reset); + return err; + } + + return 0; +} + +#define PARSE_INT_OR_RETURN(Buf, Tmp, Type, Ptr) \ + do { \ + int ___ret = 0; \ + Tmp = strsep(Buf, " "); \ + if (!Tmp || !*Tmp) { \ + return -EINVAL; \ + } \ + ___ret = kstrto##Type(Tmp, 0, Ptr); \ + if (___ret) { \ + return ___ret; \ + } \ + } while(0) + +#define PARSE_ADDR_OR_RETURN(Buf, Tmp, Type, Ptr, Size) \ + do { \ + PARSE_INT_OR_RETURN(Buf, Tmp, Type, Ptr); \ + if (*(Ptr) > (Size)) { \ + return -EINVAL; \ + } \ + } while(0) + +#define PARSE_STR_OR_RETURN(Buf, Tmp, Ptr) \ + do { \ + Tmp = strsep(Buf, " "); \ + if (!Tmp || !*Tmp) { \ + return -EINVAL; \ + } \ + Ptr = Tmp; \ + } while(0) + +#define PARSE_END_OR_RETURN(Buf, Tmp) \ + do { \ + Tmp = strsep(Buf, " "); \ + if (Tmp) { \ + return -EINVAL; \ + } \ + } while(0) + + +// new_master +static ssize_t parse_new_object_master(struct scd_context *ctx, + char *buf, size_t count) +{ + u32 id; + u32 addr; + u32 bus_count = MASTER_DEFAULT_BUS_COUNT; + + const char *tmp; + int res; + + if (!buf) + return -EINVAL; + + PARSE_ADDR_OR_RETURN(&buf, tmp, u32, &addr, ctx->res_size); + PARSE_INT_OR_RETURN(&buf, tmp, u32, &id); + + tmp = strsep(&buf, " "); + if (tmp && *tmp) { + res = kstrtou32(tmp, 0, &bus_count); + if (res) + return res; + PARSE_END_OR_RETURN(&buf, tmp); + } + + res = scd_smbus_master_add(ctx, addr, id, bus_count); + if (res) + return res; + + return count; +} + +// new_led +static ssize_t parse_new_object_led(struct scd_context *ctx, + char *buf, size_t count) +{ + u32 addr; + const char *name; + + const char *tmp; + int res; + + if (!buf) + return -EINVAL; + + PARSE_ADDR_OR_RETURN(&buf, tmp, u32, &addr, ctx->res_size); + PARSE_STR_OR_RETURN(&buf, tmp, name); + PARSE_END_OR_RETURN(&buf, tmp); + + res = scd_led_add(ctx, name, addr); + if (res) + return res; + + return count; +} + +enum xcvr_type { + XCVR_TYPE_SFP, + XCVR_TYPE_QSFP +}; + +static ssize_t parse_new_object_xcvr(struct scd_context *ctx, enum xcvr_type type, + char *buf, size_t count) +{ + u32 addr; + u32 id; + + const char *tmp; + int res; + + if (!buf) + return -EINVAL; + + PARSE_ADDR_OR_RETURN(&buf, tmp, u32, &addr, ctx->res_size); + PARSE_INT_OR_RETURN(&buf, tmp, u32, &id); + PARSE_END_OR_RETURN(&buf, tmp); + + if (type == XCVR_TYPE_SFP) + res = scd_xcvr_sfp_add(ctx, addr, id); + else if (type == XCVR_TYPE_QSFP) + res = scd_xcvr_qsfp_add(ctx, addr, id); + else + res = -EINVAL; + + if (res) + return res; + + return count; +} + +// new_qsfp +static ssize_t parse_new_object_qsfp(struct scd_context *ctx, + char *buf, size_t count) +{ + return parse_new_object_xcvr(ctx, XCVR_TYPE_QSFP, buf, count); +} + +// new_sfp +static ssize_t parse_new_object_sfp(struct scd_context *ctx, + char *buf, size_t count) +{ + return parse_new_object_xcvr(ctx, XCVR_TYPE_SFP, buf, count); +} + +// new_reset +static ssize_t parse_new_object_reset(struct scd_context *ctx, + char *buf, size_t count) +{ + u32 addr; + const char *name; + u32 bitpos; + + const char *tmp; + int res; + + if (!buf) + return -EINVAL; + + PARSE_ADDR_OR_RETURN(&buf, tmp, u32, &addr, ctx->res_size); + PARSE_STR_OR_RETURN(&buf, tmp, name); + PARSE_INT_OR_RETURN(&buf, tmp, u32, &bitpos); + PARSE_END_OR_RETURN(&buf, tmp); + + res = scd_reset_add(ctx, name, addr, bitpos); + if (res) + return res; + + return count; +} + +// new_gpio +static ssize_t parse_new_object_gpio(struct scd_context *ctx, + char *buf, size_t count) +{ + u32 addr; + const char *name; + u32 bitpos; + u32 read_only; + u32 active_low; + + const char *tmp; + int res; + + if (!buf) + return -EINVAL; + + PARSE_ADDR_OR_RETURN(&buf, tmp, u32, &addr, ctx->res_size); + PARSE_STR_OR_RETURN(&buf, tmp, name); + PARSE_INT_OR_RETURN(&buf, tmp, u32, &bitpos); + PARSE_INT_OR_RETURN(&buf, tmp, u32, &read_only); + PARSE_INT_OR_RETURN(&buf, tmp, u32, &active_low); + PARSE_END_OR_RETURN(&buf, tmp); + + res = scd_gpio_add(ctx, name, addr, bitpos, read_only, active_low); + if (res) + return res; + + return count; +} + +typedef ssize_t (*new_object_parse_func)(struct scd_context*, char*, size_t); +static struct { + const char *name; + new_object_parse_func func; +} funcs[] = { + { "master", parse_new_object_master }, + { "led", parse_new_object_led }, + { "qsfp", parse_new_object_qsfp }, + { "sfp", parse_new_object_sfp }, + { "reset", parse_new_object_reset }, + { "gpio", parse_new_object_gpio }, + { NULL, NULL } +}; + +static ssize_t parse_new_object(struct scd_context *ctx, const char *buf, + size_t count) +{ + char tmp[MAX_CONFIG_LINE_SIZE]; + char *ptr = tmp; + char *tok; + int i = 0; + ssize_t err; + + if (count >= MAX_CONFIG_LINE_SIZE) { + scd_warn("new_object line is too long\n"); + return -EINVAL; + } + + strncpy(tmp, buf, count); + tmp[count] = 0; + tok = strsep(&ptr, " "); + if (!tok) + return -EINVAL; + + while (funcs[i].name) { + if (!strcmp(tok, funcs[i].name)) + break; + i++; + } + + if (!funcs[i].name) + return -EINVAL; + + err = funcs[i].func(ctx, ptr, count - (ptr - tmp)); + if (err < 0) + return err; + + return count; +} + +typedef ssize_t (*line_parser_func)(struct scd_context *ctx, const char *buf, + size_t count); + +static ssize_t parse_lines(struct scd_context *ctx, const char *buf, + size_t count, line_parser_func parser) +{ + ssize_t res; + size_t left = count; + const char *nl; + + if (count == 0) + return 0; + + while (true) { + nl = strnchr(buf, left, '\n'); + if (!nl) + nl = buf + left; // points on the \0 + + res = parser(ctx, buf, nl - buf); + if (res < 0) + return res; + left -= res; + + buf = nl; + while (left && *buf == '\n') { + buf++; + left--; + } + if (!left) + break; + } + + return count; +} + +static ssize_t new_object(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + ssize_t res; + struct scd_context *ctx = get_context_for_dev(dev); + + if (!ctx) { + return -ENODEV; + } + + scd_lock(ctx); + if (ctx->initialized) { + scd_unlock(ctx); + return -EBUSY; + } + res = parse_lines(ctx, buf, count, parse_new_object); + scd_unlock(ctx); + return res; +} + +static DEVICE_ATTR(new_object, S_IRUGO|S_IWUSR|S_IWGRP, 0, new_object); + +static struct scd_bus *find_scd_bus(struct scd_context *ctx, u16 bus) { + struct scd_master *master; + struct scd_bus *scd_bus; + + list_for_each_entry(master, &ctx->master_list, list) { + list_for_each_entry(scd_bus, &master->bus_list, list) { + if (scd_bus->adap.nr != bus) + continue; + return scd_bus; + } + } + return NULL; +} + +static ssize_t set_bus_params(struct scd_context *ctx, u16 bus, + struct bus_params *params) { + struct bus_params *p; + struct scd_bus *scd_bus = find_scd_bus(ctx, bus); + + if (!scd_bus) { + scd_err("Cannot find bus %d to add tweak\n", bus); + return -EINVAL; + } + + list_for_each_entry(p, &scd_bus->params, list) { + if (p->addr == params->addr) { + p->t = params->t; + p->datw = params->datw; + p->datr = params->datr; + return 0; + } + } + + p = kzalloc(sizeof(*p), GFP_KERNEL); + if (!p) { + return -ENOMEM; + } + + p->addr = params->addr; + p->t = params->t; + p->datw = params->datw; + p->datr = params->datr; + list_add_tail(&p->list, &scd_bus->params); + return 0; +} + +static ssize_t parse_smbus_tweak(struct scd_context *ctx, const char *buf, + size_t count) +{ + char buf_copy[MAX_CONFIG_LINE_SIZE]; + struct bus_params params; + ssize_t err; + char *ptr = buf_copy; + const char *tmp; + u16 bus; + + if (count >= MAX_CONFIG_LINE_SIZE) { + scd_warn("smbus_tweak line is too long\n"); + return -EINVAL; + } + + strncpy(buf_copy, buf, count); + buf_copy[count] = 0; + + PARSE_INT_OR_RETURN(&ptr, tmp, u16, &bus); + PARSE_INT_OR_RETURN(&ptr, tmp, u16, ¶ms.addr); + PARSE_INT_OR_RETURN(&ptr, tmp, u8, ¶ms.t); + PARSE_INT_OR_RETURN(&ptr, tmp, u8, ¶ms.datr); + PARSE_INT_OR_RETURN(&ptr, tmp, u8, ¶ms.datw); + + err = set_bus_params(ctx, bus, ¶ms); + if (err == 0) + return count; + return err; +} + +static ssize_t smbus_tweaks(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + ssize_t res; + struct scd_context *ctx = get_context_for_dev(dev); + + if (!ctx) { + return -ENODEV; + } + + scd_lock(ctx); + res = parse_lines(ctx, buf, count, parse_smbus_tweak); + scd_unlock(ctx); + return res; +} + +static DEVICE_ATTR(smbus_tweaks, S_IRUGO|S_IWUSR|S_IWGRP, 0, smbus_tweaks); + +static int scd_ext_hwmon_probe(struct pci_dev *pdev) +{ + struct scd_context *ctx = get_context_for_pdev(pdev); + int err; + + if (ctx) { + scd_warn("this pci device has already been probed\n"); + return -EEXIST; + } + + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) { + return -ENOMEM; + } + + ctx->pdev = pdev; + get_device(&pdev->dev); + INIT_LIST_HEAD(&ctx->list); + + ctx->initialized = false; + mutex_init(&ctx->mutex); + + ctx->res_size = scd_resource_len(pdev); + + INIT_LIST_HEAD(&ctx->led_list); + INIT_LIST_HEAD(&ctx->master_list); + INIT_LIST_HEAD(&ctx->gpio_list); + INIT_LIST_HEAD(&ctx->reset_list); + + kobject_get(&pdev->dev.kobj); + err = sysfs_create_file(&pdev->dev.kobj, &dev_attr_new_object.attr); + if (err) { + goto fail_sysfs; + } + + err = sysfs_create_file(&pdev->dev.kobj, &dev_attr_smbus_tweaks.attr); + if (err) { + sysfs_remove_file(&pdev->dev.kobj, &dev_attr_new_object.attr); + goto fail_sysfs; + } + + module_lock(); + list_add_tail(&ctx->list, &scd_list); + module_unlock(); + + return 0; + +fail_sysfs: + kobject_put(&pdev->dev.kobj); + kfree(ctx); + put_device(&pdev->dev); + + return err; +} + +static void scd_ext_hwmon_remove(struct pci_dev *pdev) +{ + struct scd_context *ctx = get_context_for_pdev(pdev); + + if (!ctx) { + return; + } + + scd_info("removing scd components\n"); + + scd_lock(ctx); + scd_smbus_remove_all(ctx); + scd_led_remove_all(ctx); + scd_gpio_remove_all(ctx); + scd_reset_remove_all(ctx); + scd_unlock(ctx); + + module_lock(); + list_del(&ctx->list); + module_unlock(); + + sysfs_remove_file(&pdev->dev.kobj, &dev_attr_new_object.attr); + sysfs_remove_file(&pdev->dev.kobj, &dev_attr_smbus_tweaks.attr); + + kfree(ctx); + + kobject_put(&pdev->dev.kobj); + put_device(&pdev->dev); +} + +static int scd_ext_hwmon_init_trigger(struct pci_dev *pdev) +{ + struct scd_context *ctx = get_context_for_pdev(pdev); + + if (!ctx) { + return -ENODEV; + } + + scd_lock(ctx); + ctx->initialized = true; + scd_unlock(ctx); + return 0; +} + +static struct scd_ext_ops scd_hwmon_ops = { + .probe = scd_ext_hwmon_probe, + .remove = scd_ext_hwmon_remove, + .init_trigger = scd_ext_hwmon_init_trigger, +}; + +static int __init scd_hwmon_init(void) +{ + int err = 0; + + scd_info("loading scd hwmon driver\n"); + mutex_init(&scd_hwmon_mutex); + INIT_LIST_HEAD(&scd_list); + + err = scd_register_ext_ops(&scd_hwmon_ops); + if (err) { + scd_warn("scd_register_ext_ops failed\n"); + return err; + } + + return err; +} + +static void __exit scd_hwmon_exit(void) +{ + scd_info("unloading scd hwmon driver\n"); + scd_unregister_ext_ops(); +} + +module_init(scd_hwmon_init); +module_exit(scd_hwmon_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Arista Networks"); +MODULE_DESCRIPTION("SCD component driver"); diff --git a/platform/broadcom/sonic-platform-modules-arista/src/scd-hwmon.h b/platform/broadcom/sonic-platform-modules-arista/src/scd-hwmon.h new file mode 100644 index 000000000000..e23c69871f0c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/src/scd-hwmon.h @@ -0,0 +1,15 @@ +#ifndef _LINUX_DRIVER_SCD_HWMON_H_ +#define _LINUX_DRIVER_SCD_HWMON_H_ + +#include + +#define scd_err(fmt, ...) \ + pr_err("scd-hwmon: " fmt, ##__VA_ARGS__); +#define scd_warn(fmt, ...) \ + pr_warn("scd-hwmon: " fmt, ##__VA_ARGS__); +#define scd_info(fmt, ...) \ + pr_info("scd-hwmon: " fmt, ##__VA_ARGS__); +#define scd_dbg(fmt, ...) \ + pr_debug("scd-hwmon: " fmt, ##__VA_ARGS__); + +#endif /* !_LINUX_DRIVER_SCD_HWMON_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-arista/src/scd.c b/platform/broadcom/sonic-platform-modules-arista/src/scd.c new file mode 100644 index 000000000000..872cffa9b4b1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/src/scd.c @@ -0,0 +1,1697 @@ +/* + * Copyright (c) 2006-2017 Arista Networks, Inc. All rights reserved. + * Arista Networks, Inc. Confidential and Proprietary. + * + * 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, see . + */ + +/* + * SCD driver. + * + * When a PCI SCD device is detected, this driver initializes the PCI device and + * maps its memory region 0 into virtual memory, but it delays registering an + * interrupt handler for the device. Instead, it creates several device attribute + * files: + * + * interrupt_status_offset + * interrupt_mask_read_offset + * interrupt_mask_set_offset + * interrupt_mask_clear_offset + * interrupt_mask + * interrupt_mask_powerloss + * interrupt_mask_ardma + * crc_error_irq + * crc_error_panic + * ptp_high_offset + * ptp_low_offset + * msi_rearm_offset + * interrupt_irq + * power_loss + * ardma_offset + * interrupt_poll + * nmi_port_io_p + * nmi_control_reg_addr + * nmi_control_mask + * nmi_status_reg_addr + * nmi_status_mask + * nmi_gpio_status_reg_addr + * nmi_gpio_status_mask + * init_trigger + * + * which will appear in the directory /sys/devices/pciAAAA:BB/AAAA:BB:CC.D/. + * + * The first 13 are read/write. The offset within memory region 0 of the interrupt + * status and interrupt mask registers can be configured by writing their values to + * the first four attribute files. The mask of valid bits in the interrupt status + * register can be set by writing its value to the fifth file (all 'invalid' bits + * are expected always to be zero). To handle + * the CRC error interrupt (completely separate from the normal interrupt line), + * write the IRQ number to crc_error_irq. Similarly, if the device interrupt is not + * the PCI interrupt, then write the interrupt_irq file. To raise a kernel panic + * upon a crc interrupt, set crc_error_panic to 1. + * + * The values written to each of these files should be in ASCII decimal. Reading + * from any of these files will return the value last written, also in ASCII decimal. + * + * After the other files have been written, writing (anything) to the + * 'init_trigger' file will cause initialization of the driver to continue, creating + * up to 32 UIO devices (/dev/uio), one for each bit that was set in the + * interrupt_mask, registering an interrupt handler. Reading from 'init_trigger' + * returns a positive initialization error if one occurred, or 0 for success. + * After successful initialization attribute files become read only. Attempts at + * changing their values results in a warning. + * + * Each UIO device corresponds to a bit in the interrupt status/mask registers. + * Reads on one of the UIO device files will complete when an interrupt has occurred + * for that bit, at which point that bit will have been added to the interrupt mask. + * It is up to the userspace code to remove that bit from the interrupt mask when it + * has handled the interrupt and cleared the interrupt at source. + * + * NMI data is also stored per-scd. nmi_priv points to the scd_dev_priv for the + * scd responsible for registering and maintaining the nmi handler. Only + * one scd is configured to handle the nmi. Userspace code (the scd agent) is trusted + * to pick the correct scd and correctly write to the corresponding attribute files. + * nmi_priv is set when writing to the nmi_control_reg_addr file, attempts by other + * devices to change nmi_priv after this point is an error. There is no protection + * against multiple entities concurrently initializing scd attributes. + * + */ + +#include +#include +#include +#include "scd.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SCD_MODULE_NAME "scd" + +#define SCD_PCI_VENDOR_ID 0x3475 +#define SCD_PCI_DEVICE_ID 0x0001 +#define SCD_BAR_REGS 0 +#define SCD_BAR_1 1 +#define SCD_NUM_IRQ_REGISTERS 8 +#define SCD_REVISION_OFFSET 0x100 +#define SCD_MAGIC 0xdeadbeef +#define SCD_UNINITIALIZED 0xffffffff + +#define AMD_PCI_VENDOR_ID 0x1022 +#define AMD_PCI_EKABINI_18F5_DEVICE_ID 0x1535 +#define AMD_PCI_STEPPEEAGLE_18F5_DEVICE_ID 0x1585 + +#define INTEL_PCI_VENDOR_ID 0x8086 +#define INTEL_PCI_BROADWELL_DEVICE_ID 0x6f76 + +#define RECONFIG_PCI_SUBSYSTEM_ID 0x14 +#define RECONFIG_STATE_BAR_VALUE 0xdeadface + +#define NUM_BITS_IN_WORD 32 + +#define ASSERT(expr) do { if (unlikely(!(expr))) \ + printk(KERN_ERR "Assertion failed! %s,%s,%s,line=%d (%s:%d)\n", \ + #expr,__FILE__,__FUNCTION__,__LINE__,current->comm,current->pid); } while (0) + +#define INTR_POLL_INTERVAL ( HZ/10 ) + +#define IOSIZE 4 + +#ifndef _PAGE_CACHE_UC +# define _PAGE_CACHE_UC _PAGE_CACHE_MODE_UC +#endif + +typedef struct scd_irq_info_s { + unsigned long interrupt_status_offset; + unsigned long interrupt_mask_read_offset; + unsigned long interrupt_mask_set_offset; + unsigned long interrupt_mask_clear_offset; + unsigned long interrupt_mask; + unsigned long interrupt_mask_powerloss; + unsigned long interrupt_mask_ardma; + struct uio_info *uio_info[NUM_BITS_IN_WORD]; + unsigned long uio_count[NUM_BITS_IN_WORD]; + char uio_names[NUM_BITS_IN_WORD][40]; +} scd_irq_info_t; + +struct scd_dev_priv { + struct list_head list; + struct pci_dev *pdev; + void __iomem *mem; + size_t mem_len; + spinlock_t ptp_time_spinlock; + scd_irq_info_t irq_info[SCD_NUM_IRQ_REGISTERS]; + unsigned long crc_error_irq; + unsigned long crc_error_panic; + unsigned long ptp_high_offset; + unsigned long ptp_low_offset; + unsigned long ptp_offset_valid; + unsigned long msi_rearm_offset; + unsigned long interrupt_irq; + unsigned long ardma_offset; + void __iomem *localbus; + unsigned long init_error; + bool initialized; + unsigned int magic; + bool sysfs_initialized; + u32 revision; + u32 revision_error_reports; + bool is_reconfig; + unsigned long interrupt_poll; + struct timer_list intr_poll_timer; + + unsigned long interrupts; + unsigned long interrupt_claimed; + unsigned long interrupt_ardma_cnt; + unsigned long interrupt_powerloss_cnt; + const struct scd_driver_cb *driver_cb; + + int lpc_device; + int lpc_vendor; + + // SCD watchdog NMI delivered through GPIO + unsigned long nmi_port_io_p; + unsigned long nmi_control_reg_addr; + unsigned long *nmi_control_reg; + unsigned long nmi_control_mask; + unsigned long nmi_status_reg_addr; + unsigned long *nmi_status_reg; + unsigned long nmi_status_mask; + unsigned long nmi_gpio_status_reg_addr; + unsigned long *nmi_gpio_status_reg; + unsigned long nmi_gpio_status_mask; + bool nmi_registered; // true if this instance registered and owns the NMI +}; + +// number of times to report a revision mismatch. +#define MAX_REV_ERR_RPTS 5 + +// non zero if debug logging is enabled. +static int debug = 0; +// linked list of scd_dev_privs +static struct list_head scd_list; +// mutex and not spinlock because of kmallocs and ardma callbacks +static struct mutex scd_mutex; +// scd_dev_priv for scd running tod counter +static struct scd_dev_priv *ptp_master_priv = NULL; +// spinlock used instead of scd_mutex for reading supe scd timestamps +static spinlock_t scd_ptp_lock; +// nmi_priv points to the scd responsible for the nmi +static struct scd_dev_priv *nmi_priv = NULL; + +#define timestamped_watchdog_panic(msg) do { \ + struct timeval tv; \ + struct tm t; \ + do_gettimeofday(&tv); \ + time_to_tm(tv.tv_sec, 0, &t); \ + panic("%s (%02d:%02d:%02d)",msg, t.tm_hour, t.tm_min, t.tm_sec); \ + }while(0); + +/* prototypes */ +static int scd_probe(struct pci_dev *pdev, const struct pci_device_id *ent); +static void scd_interrupt_poll( unsigned long data ); +static void scd_remove(struct pci_dev *pdev); +static void scd_shutdown(struct pci_dev *pdev); +static void scd_mask_interrupts(struct scd_dev_priv *priv); +static void scd_lock(void); +static void scd_unlock(void); + +static void scd_lock() { + mutex_lock(&scd_mutex); +} + +static void scd_unlock() { + mutex_unlock(&scd_mutex); +} + +struct scd_driver_cb { + int (*enable) (struct pci_dev *dev); + void (*disable) (struct pci_dev *dev); +}; + +// registered ardma handlers +static struct scd_ardma_ops *scd_ardma_ops = NULL; + +// registered scd-em callbacks +static struct scd_em_ops *scd_em_ops = NULL; + +// registered extention callbacks +static struct scd_ext_ops *scd_ext_ops = NULL; + +int scd_register_ardma_ops(struct scd_ardma_ops *ops) { + struct scd_dev_priv *priv; + + ASSERT(scd_ardma_ops == NULL); + scd_ardma_ops = ops; + + // call ardma probe() for any existing scd having ardma + scd_lock(); + list_for_each_entry(priv, &scd_list, list) { + if (priv->initialized && priv->ardma_offset) { + scd_ardma_ops->probe(priv->pdev, (void*)priv->mem, + priv->ardma_offset, + priv->localbus, + priv->irq_info[0].interrupt_mask_ardma, + priv->irq_info[0].interrupt_mask_read_offset, + priv->irq_info[0].interrupt_mask_set_offset, + priv->irq_info[0].interrupt_mask_clear_offset); + } + } + scd_unlock(); + return (0); +} + +void scd_unregister_ardma_ops() { + struct scd_dev_priv *priv; + + if (!scd_ardma_ops) { + return; + } + + // call ardma remove() for any existing scd having ardma + scd_lock(); + list_for_each_entry(priv, &scd_list, list) { + if (priv->initialized && priv->ardma_offset) { + scd_ardma_ops->remove(priv->pdev); + } + } + scd_unlock(); + scd_ardma_ops = NULL; +} + +EXPORT_SYMBOL(scd_register_ardma_ops); +EXPORT_SYMBOL(scd_unregister_ardma_ops); + +int scd_register_em_ops(struct scd_em_ops *ops) { + struct scd_dev_priv *priv; + + ASSERT(scd_em_ops == NULL); + scd_em_ops = ops; + + // call probe() for any existing scd + scd_lock(); + list_for_each_entry(priv, &scd_list, list) { + if (priv->initialized && scd_em_ops->probe) { + scd_em_ops->probe(priv->pdev); + } + } + scd_unlock(); + return (0); +} + +void scd_unregister_em_ops() { + struct scd_dev_priv *priv; + + if (!scd_em_ops) { + return; + } + + // call remove() for any existing scd + scd_lock(); + list_for_each_entry(priv, &scd_list, list) { + if (priv->initialized && scd_em_ops->remove) { + scd_em_ops->remove(priv->pdev); + } + } + scd_unlock(); + scd_em_ops = NULL; +} + +EXPORT_SYMBOL(scd_register_em_ops); +EXPORT_SYMBOL(scd_unregister_em_ops); + +int scd_register_ext_ops(struct scd_ext_ops *ops) { + struct scd_dev_priv *priv; + + ASSERT(scd_ext_ops == NULL); + scd_ext_ops = ops; + + // call probe() for any existing scd + scd_lock(); + list_for_each_entry(priv, &scd_list, list) { + if (scd_ext_ops->probe) { + scd_ext_ops->probe(priv->pdev); + } + } + scd_unlock(); + return (0); +} + +void scd_unregister_ext_ops() { + struct scd_dev_priv *priv; + + if (!scd_ext_ops) { + return; + } + + // call remove() for any existing scd + scd_lock(); + list_for_each_entry(priv, &scd_list, list) { + if (scd_ext_ops->remove) { + scd_ext_ops->remove(priv->pdev); + } + } + scd_unlock(); + scd_ext_ops = NULL; +} + +void scd_ext_init_trigger(void){ + struct scd_dev_priv *priv; + + if (!scd_ext_ops) { + return; + } + + // call init_trigger() for any existing scd + scd_lock(); + list_for_each_entry(priv, &scd_list, list) { + if (scd_ext_ops->init_trigger) { + scd_ext_ops->init_trigger(priv->pdev); + } + } + scd_unlock(); + return; +} + +EXPORT_SYMBOL(scd_register_ext_ops); +EXPORT_SYMBOL(scd_unregister_ext_ops); +EXPORT_SYMBOL(scd_ext_init_trigger); + +static irqreturn_t scd_interrupt(int irq, void *dev_id) +{ + struct device *dev = (struct device *) dev_id; + struct scd_dev_priv *priv = dev_get_drvdata(dev); + u32 interrupt_status; + u32 interrupt_mask; + u32 unmasked_interrupt_status; + irqreturn_t rc = IRQ_NONE; + u32 irq_reg; + u32 unexpected; + u32 scd_ver; + + WARN_ON_ONCE( priv->magic != SCD_MAGIC ); + + priv->interrupts++; + for(irq_reg = 0; irq_reg < SCD_NUM_IRQ_REGISTERS; irq_reg++) { + if( !priv->irq_info[irq_reg].interrupt_status_offset ) { + continue; + } + + scd_ver = ioread32( priv->mem + SCD_REVISION_OFFSET ); + if( scd_ver != priv->revision ) { + // sanity check to make sure we are not trying to read + // a scd that has just been hot removed before we + // have been notified. + // There is a problem with linecard hot removal, the power + // fails very slowly (10ms) and something manages to generate + // an interrupt, by the time we read the registers during the + // 10ms power down we can get garbage back, not just all Fs + // as you would expect from a powered down device. + if( scd_ver != 0xffffffff && + priv->revision_error_reports < MAX_REV_ERR_RPTS ) { + // Update the revision for a reconfigurable fpga. BAR0 and BAR1 will + // initially read 0xdeadface until being reconfigured. After reconfig + // BAR0 will function as a scd and return the correct version number. + if(priv->is_reconfig && priv->revision == RECONFIG_STATE_BAR_VALUE) { + priv->revision = scd_ver; + } else { + // we got garbage, this is bad so let someone know about it + dev_info( dev, "scd: irq chk 0x%x!=0x%x\n", + priv->revision, scd_ver ); + priv->revision_error_reports++; + if(priv->revision_error_reports == MAX_REV_ERR_RPTS) { + // there appear to be some cases where the kernel gets + // very confused with the scd, the physical devices seem + // to have been switched association with the kernel device + // structures, dump out the name of one of the uio, it should allow + // us to see if the device structure has become confused. + dev_err(dev, "scd: rev mismatch overflow, uio[0]:%s\n", + pci_name(priv->pdev)); + } + } + } + break; + } + + + unexpected = 0; + interrupt_status = ioread32(priv->mem + + priv->irq_info[irq_reg].interrupt_status_offset); + interrupt_mask = ioread32(priv->mem + + priv->irq_info[irq_reg].interrupt_mask_read_offset); + unmasked_interrupt_status = interrupt_status & ~interrupt_mask; + + if(debug) { + dev_info(dev, "interrupt status 0x%x interrupt mask 0x%x " + "interrupt status offset 0x%lx interrupt ", + interrupt_status, interrupt_mask, + priv->irq_info[irq_reg].interrupt_status_offset ); + } + + if (!unmasked_interrupt_status) { + /* No unmasked interrupt bits are active. Therefore the interrupt didn't + * originate from the SCD. */ + continue; + } + + /* see if this is an powerLoss interrupt + this is to speed up the handling, we don't have much time if it is a + real power loss */ + if(priv->irq_info[irq_reg].interrupt_mask_powerloss & + unmasked_interrupt_status) { + // it is the end of the line for this run, if this really is a power loss + // we will never complete the printk before the power dies + printk( KERN_INFO "Power Loss detected\n"); + priv->interrupt_powerloss_cnt++; + } + + rc = IRQ_HANDLED; + priv->interrupt_claimed++; + /* Mask all active interrupt bits. Note that we must only mask the bits that + * were not already masked when we read the interrupt mask register above. + * Otherwise, we may mask a bit that has subsequently been cleared by a process + * running on another CPU, without generating another UIO event for that bit, + * causing that process to get stuck waiting for an interrupt that will never + * arrive. */ + iowrite32(unmasked_interrupt_status, priv->mem + + priv->irq_info[irq_reg].interrupt_mask_set_offset); + + // ardma interrupt + if ((unmasked_interrupt_status & priv->irq_info[irq_reg].interrupt_mask_ardma) + && scd_ardma_ops) { + scd_ardma_ops->interrupt(priv->pdev); + unmasked_interrupt_status &= ~priv->irq_info[irq_reg].interrupt_mask_ardma; + priv->interrupt_ardma_cnt++; + } + + /* Notify the UIO layer for each of the newly active interrupt bits. */ + while (unmasked_interrupt_status) { + int bit = ffs(unmasked_interrupt_status) - 1; + if (likely(priv->irq_info[irq_reg].uio_info[bit])) { + uio_event_notify(priv->irq_info[irq_reg].uio_info[bit]); + priv->irq_info[irq_reg].uio_count[bit]++; + } else { + unexpected |= 1 << bit; + } + unmasked_interrupt_status ^= (1 << bit); + } + + if( unexpected ) { + dev_info(dev, "interrupt occurred for unexpected bits 0x%x " + "interrupt_status 0x%x, interrupt_mask 0x%x" + "scd_rev 0x%x interrupt status offset 0x%lx" + "uio mask is 0x%lx\n" , + unexpected, interrupt_status, + interrupt_mask, scd_ver, + priv->irq_info[irq_reg].interrupt_status_offset, + priv->irq_info[irq_reg].interrupt_mask ); + } + } + + /* If using MSI rearm message generation */ + if (priv->msi_rearm_offset) { + iowrite32(1, priv->mem + priv->msi_rearm_offset); + } + + return rc; +} + +static irqreturn_t scd_crc_error_interrupt(int irq, void *dev_id) +{ + struct device *dev = (struct device *) dev_id; + struct scd_dev_priv *priv = dev_get_drvdata(dev); + dev_emerg(dev, "scd: CRC error interrupt occurred!\n"); + + if (priv->initialized && priv->crc_error_panic == 1) { + /* The scd crc error irq is currently NOT shared on any platform. + * The irq source is not cleared to ensure that the capture kernel + * is not interrupted by a corrupt scd. + */ + panic( "scd_crc_error detected, system will reboot.\n" ); + } + + return IRQ_HANDLED; +} + +static int scd_finish_init(struct device *dev) +{ + struct scd_dev_priv *priv = dev_get_drvdata(dev); + int err; + int i; + unsigned int irq; + u32 irq_reg; + u32 scd_ver; + + dev_info(dev, "scd_finish_init\n"); + + // store a copy of the dev->name() for debugging hotswap + for(irq_reg = 0; irq_reg < SCD_NUM_IRQ_REGISTERS; irq_reg++) { + // combine the power loss, and regular interrupt masks + unsigned long interrupt_mask = priv->irq_info[irq_reg].interrupt_mask; + + interrupt_mask |= priv->irq_info[irq_reg].interrupt_mask_powerloss; + for (i = 0; i < NUM_BITS_IN_WORD; i++) { + priv->irq_info[irq_reg].uio_info[i] = NULL; + if (interrupt_mask & (1 << i)) { + priv->irq_info[irq_reg].uio_info[i] = + kzalloc(sizeof(struct uio_info), GFP_KERNEL); + if (!priv->irq_info[irq_reg].uio_info[i]) { + dev_err(dev, "failed to allocate UIO device\n"); + err = -ENOMEM; + goto err_out; + } + snprintf(priv->irq_info[irq_reg].uio_names[i], + sizeof(priv->irq_info[irq_reg].uio_names[i]), + "uio-%s-%d-%d", pci_name(to_pci_dev(dev)), irq_reg, i); + priv->irq_info[irq_reg].uio_info[i]->name = + priv->irq_info[irq_reg].uio_names[i]; + priv->irq_info[irq_reg].uio_info[i]->version = "0.0.1"; + priv->irq_info[irq_reg].uio_info[i]->irq = UIO_IRQ_CUSTOM; + + err = uio_register_device(dev, priv->irq_info[irq_reg].uio_info[i]); + if (err) { + dev_err(dev, "failed to register UIO device (%d)\n", err); + kfree(priv->irq_info[irq_reg].uio_info[i]); + priv->irq_info[irq_reg].uio_info[i] = NULL; + goto err_out; + } + } + } + } + + if (priv->msi_rearm_offset) { + err = pci_enable_msi(to_pci_dev(dev)); + if (err) { + dev_err(dev, "failed to enable msi (%d)\n", err); + goto err_out; + } + pci_set_master(to_pci_dev(dev)); + } + + /* if interrupt_irq has been set, use it instead of pdev->irq */ + irq = (priv->interrupt_irq != SCD_UNINITIALIZED) ? + priv->interrupt_irq : to_pci_dev(dev)->irq; + + err = request_irq(irq, scd_interrupt, IRQF_SHARED, SCD_MODULE_NAME, dev); + if (err) { + dev_err(dev, "failed to request irq %d (%d)\n", irq, err); + goto err_out_misc_dereg; + } + + if (priv->crc_error_irq != SCD_UNINITIALIZED) { + err = request_irq(priv->crc_error_irq, scd_crc_error_interrupt, 0, + SCD_MODULE_NAME, dev); + if (err) { + dev_err(dev, "failed to request CRC error IRQ %lu (%d)\n", + priv->crc_error_irq, err); + goto err_out_free_irq; + } + } + + // enable power loss interrupts + for(irq_reg = 0; irq_reg < SCD_NUM_IRQ_REGISTERS; irq_reg++) { + if(priv->irq_info[irq_reg].interrupt_mask_powerloss && + priv->irq_info[irq_reg].interrupt_mask_clear_offset) { + iowrite32(priv->irq_info[irq_reg].interrupt_mask_powerloss, priv->mem + + priv->irq_info[irq_reg].interrupt_mask_clear_offset); + } + } + + // ardma probe + if (priv->ardma_offset && scd_ardma_ops) { + scd_ardma_ops->probe(priv->pdev, (void*)priv->mem, + priv->ardma_offset, + priv->localbus, + priv->irq_info[0].interrupt_mask_ardma, + priv->irq_info[0].interrupt_mask_read_offset, + priv->irq_info[0].interrupt_mask_set_offset, + priv->irq_info[0].interrupt_mask_clear_offset); + } + + // scd_em probe + if (scd_em_ops && scd_em_ops->probe) { + scd_em_ops->probe(priv->pdev); + } + + // scd_ext init_trigger + if (scd_ext_ops && scd_ext_ops->init_trigger) { + scd_ext_ops->init_trigger(priv->pdev); + } + + // interrupt polling + if( priv->interrupt_poll != SCD_UNINITIALIZED ) { + setup_timer( &priv->intr_poll_timer, scd_interrupt_poll, (unsigned long)priv ); + priv->intr_poll_timer.expires = jiffies + INTR_POLL_INTERVAL; + add_timer( &priv->intr_poll_timer ); + } + + // If using MSI rearm message generation + if (priv->msi_rearm_offset) { + iowrite32(1, priv->mem + priv->msi_rearm_offset); + } + + // verify that the scd is actually programmed by performing a sanity check + // on the revision register + scd_ver = ioread32( priv->mem + SCD_REVISION_OFFSET ); + if (scd_ver == SCD_UNINITIALIZED) { + dev_err(dev, "scd is not programmed\n"); + err = -ENODEV; + goto err_out_free_irq; + } + + dev_info(dev, "scd device initialization complete\n"); + return 0; + +err_out_free_irq: + free_irq(irq, dev); + +err_out_misc_dereg: + if (priv->msi_rearm_offset) { + pci_disable_msi(to_pci_dev(dev)); + } + +err_out: + for(irq_reg = 0; irq_reg < SCD_NUM_IRQ_REGISTERS; irq_reg++) { + for (i = 0; i < NUM_BITS_IN_WORD; i++) { + if (priv->irq_info[irq_reg].uio_info[i]) { + uio_unregister_device(priv->irq_info[irq_reg].uio_info[i]); + kfree(priv->irq_info[irq_reg].uio_info[i]); + priv->irq_info[irq_reg].uio_info[i] = NULL; + } + } + } + dev_err( dev, "scd device initialization failed with error %d", err ); + return err; +} + +static ssize_t show_attr(struct scd_dev_priv *priv, unsigned long *value, char *buf) +{ + ssize_t ret; + scd_lock(); + ret = sprintf(buf, "%lu\n", *value); + scd_unlock(); + return ret; +} + +static ssize_t store_attr(struct device *dev, const char *name, + unsigned long *value, const char *buf, size_t count) +{ + struct scd_dev_priv *priv = dev_get_drvdata(dev); + unsigned long new_value = simple_strtoul(buf, NULL, 10); + scd_lock(); + if (!priv->initialized) { + *value = new_value; + } else if (new_value != *value) { + dev_warn(dev, "attempt to change %s after device initialized\n", name); + } + scd_unlock(); + return count; +} + +#define SCD_DEVICE_ATTR(_name) \ +static ssize_t show_##_name(struct device *dev, struct device_attribute *attr, \ +char *buf) \ +{ \ + struct scd_dev_priv *priv = dev_get_drvdata(dev); \ + return show_attr(priv, &priv->_name, buf); \ +} \ +static ssize_t store_##_name(struct device *dev, struct device_attribute *attr, \ +const char *buf, size_t count) \ +{ \ + struct scd_dev_priv *priv = dev_get_drvdata(dev); \ + return store_attr(dev, #_name, &priv->_name, buf, count); \ +} \ +static DEVICE_ATTR(_name, S_IRUGO|S_IWUSR|S_IWGRP, show_##_name, store_##_name); + + +#define SCD_IRQ_DEVICE_ATTR(_name, _num) \ +static ssize_t show_##_name##_num(struct device *dev, struct device_attribute *attr,\ + char *buf) \ +{ \ + struct scd_dev_priv *priv = dev_get_drvdata(dev); \ + return show_attr(priv, &priv->irq_info[_num]._name, buf); \ +} \ +static ssize_t store_##_name##_num(struct device *dev, \ + struct device_attribute *attr, \ + const char *buf, size_t count) \ +{ \ + struct scd_dev_priv *priv = dev_get_drvdata(dev); \ + return store_attr(dev, #_name #_num, &priv->irq_info[_num]._name, buf, count); \ +} \ +static DEVICE_ATTR(_name##_num, S_IRUGO|S_IWUSR|S_IWGRP, show_##_name##_num, \ + store_##_name##_num); + +#define SCD_IRQ_ATTRS(num) \ +SCD_IRQ_DEVICE_ATTR(interrupt_status_offset, num); \ +SCD_IRQ_DEVICE_ATTR(interrupt_mask_read_offset, num); \ +SCD_IRQ_DEVICE_ATTR(interrupt_mask_set_offset, num); \ +SCD_IRQ_DEVICE_ATTR(interrupt_mask_clear_offset, num); \ +SCD_IRQ_DEVICE_ATTR(interrupt_mask, num); \ +SCD_IRQ_DEVICE_ATTR(interrupt_mask_powerloss, num); \ +SCD_IRQ_DEVICE_ATTR(interrupt_mask_ardma, num); + +#define SCD_IRQ_ATTRS_POINTERS(num) \ +&dev_attr_interrupt_status_offset##num.attr, \ +&dev_attr_interrupt_mask_read_offset##num.attr, \ +&dev_attr_interrupt_mask_set_offset##num.attr, \ +&dev_attr_interrupt_mask_clear_offset##num.attr, \ +&dev_attr_interrupt_mask##num.attr, \ +&dev_attr_interrupt_mask_powerloss##num.attr, \ +&dev_attr_interrupt_mask_ardma##num.attr + +struct pci_dev * +scd_get_pdev(const char *name) +{ + struct scd_dev_priv *priv = NULL; + + scd_lock(); + list_for_each_entry(priv, &scd_list, list) { + if (!strcmp(dev_name(&priv->pdev->dev), name)) { + scd_unlock(); + return (priv->pdev); + } + } + scd_unlock(); + return (NULL); +} +EXPORT_SYMBOL(scd_get_pdev); + +u32 +scd_read_register(struct pci_dev *pdev, u32 offset) +{ + void __iomem *reg; + u32 res = 0; + struct scd_dev_priv *priv; + + priv = pci_get_drvdata(pdev); + ASSERT( priv ); + ASSERT( offset < priv->mem_len ); + if (priv) { + reg = priv->mem + offset; + res = ioread32(reg); + } + dev_dbg(&pdev->dev, "io:read 0x%04x => 0x%08x", offset, res); + return res; +} +EXPORT_SYMBOL(scd_read_register); + +void +scd_write_register(struct pci_dev *pdev, u32 offset, u32 val) +{ + void __iomem *reg; + struct scd_dev_priv *priv; + + priv = pci_get_drvdata(pdev); + ASSERT( priv ); + ASSERT( offset < priv->mem_len ); + dev_dbg(&pdev->dev, "io:write 0x%04x <= 0x%08x", offset, val); + if (priv) { + reg = priv->mem + offset; + iowrite32(val, reg); + } +} +EXPORT_SYMBOL(scd_write_register); + +size_t +scd_resource_len(struct pci_dev *pdev) +{ + struct scd_dev_priv *priv; + + priv = pci_get_drvdata(pdev); + ASSERT( priv ); + if (priv) + return priv->mem_len; + return 0; +} +EXPORT_SYMBOL(scd_resource_len); + +// scd_list_lock mutex is not held in this function. +// scd_lock mutex is not held in this function. +u64 +scd_ptp_timestamp(void) +{ + unsigned long flags, ptp_lock_flags; + u64 ts = 0; + u32 low = 0; + u32 high = 0; + struct scd_dev_priv *priv = ptp_master_priv; + + spin_lock_irqsave(&scd_ptp_lock, ptp_lock_flags); + + if (priv && priv->initialized && (priv->ptp_offset_valid != SCD_UNINITIALIZED)) { + ASSERT(priv->ptp_low_offset != SCD_UNINITIALIZED); + ASSERT(priv->ptp_high_offset != SCD_UNINITIALIZED); + // Reading the high register also latches the current time into the low + // register, so we don't need any special handling of the rollover case. + spin_lock_irqsave(&priv->ptp_time_spinlock, flags); + high = ioread32(priv->mem + priv->ptp_high_offset); + low = ioread32(priv->mem + priv->ptp_low_offset); + spin_unlock_irqrestore(&priv->ptp_time_spinlock, flags); + ts = (((u64)high) << 32) | low; + } + + spin_unlock_irqrestore(&scd_ptp_lock, ptp_lock_flags); + if (ts == 0) + printk(KERN_INFO "%s %s returned zero\n", SCD_MODULE_NAME, __FUNCTION__); + + return (ts); +} + +static ssize_t show_init_trigger(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct scd_dev_priv *priv = dev_get_drvdata(dev); + return show_attr(priv, &priv->init_error, buf); +} + +static ssize_t store_init_trigger(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scd_dev_priv *priv; + int error = 0; + + priv = dev_get_drvdata(dev); + + scd_lock(); + + // If private data is dead, return + if( priv->magic != SCD_MAGIC ) { + scd_unlock(); + return -ENODEV; + } + + if (!priv->initialized) { + if (!(error = scd_finish_init(dev))) { + priv->initialized = 1; + } + } + + // Save the error code from scd_finish_init. + // We flip this back to positive so that the conversion to unsigned won't + // produce weird, hard to read values + priv->init_error = -error; + + scd_unlock(); + + return error ? error : count; +} + +static ssize_t scd_set_debug(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { + sscanf( buf, "%d", &debug ); + return count; +} + +static ssize_t scd_set_ptp_offset_valid(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { + + struct scd_dev_priv *priv = dev_get_drvdata(dev); + unsigned long valid = simple_strtoul(buf, NULL, 10); + + scd_lock(); + if (!priv->initialized) { + priv->ptp_offset_valid = valid; + if((priv->ptp_offset_valid != SCD_UNINITIALIZED) && !ptp_master_priv) { + ptp_master_priv = priv; + } + } else if (priv->ptp_offset_valid != valid) { + dev_warn(dev, "attempt to change ptp_offset_valid after device initialized\n"); + } + scd_unlock(); + return count; +} + +static ssize_t scd_set_nmi_control_reg_addr(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { + + struct scd_dev_priv *priv = dev_get_drvdata(dev); + unsigned long value = (unsigned int)simple_strtoul(buf, NULL, 10); + scd_lock(); + if (!priv->initialized) { + if (nmi_priv && priv != nmi_priv) { + dev_err(dev, "Multiple devices attempting to set NMI attributes\n"); + scd_unlock(); + return count; + } + if (value != SCD_UNINITIALIZED && !nmi_priv) { + nmi_priv = priv; + } + priv->nmi_control_reg_addr = value; + } else if (priv->nmi_control_reg_addr != value) { + dev_warn(dev, + "attempt to change nmi_control_reg_addr after device initialized\n"); + } + scd_unlock(); + return count; +} + +static DEVICE_ATTR(init_trigger, S_IRUGO|S_IWUSR|S_IWGRP, + show_init_trigger, store_init_trigger); +static DEVICE_ATTR(debug, S_IWUSR|S_IWGRP, NULL, scd_set_debug ); +static DEVICE_ATTR(ptp_offset_valid, S_IWUSR|S_IWGRP, + NULL, scd_set_ptp_offset_valid ); +static DEVICE_ATTR(nmi_control_reg_addr, S_IWUSR|S_IWGRP, + NULL, scd_set_nmi_control_reg_addr ); + +SCD_DEVICE_ATTR(crc_error_irq); +SCD_DEVICE_ATTR(crc_error_panic); +SCD_DEVICE_ATTR(ptp_high_offset); +SCD_DEVICE_ATTR(ptp_low_offset); +SCD_DEVICE_ATTR(msi_rearm_offset); +SCD_DEVICE_ATTR(interrupt_irq); +SCD_DEVICE_ATTR(ardma_offset); +SCD_DEVICE_ATTR(interrupt_poll); + +SCD_DEVICE_ATTR(nmi_port_io_p); +SCD_DEVICE_ATTR(nmi_control_mask); +SCD_DEVICE_ATTR(nmi_status_reg_addr); +SCD_DEVICE_ATTR(nmi_status_mask); +SCD_DEVICE_ATTR(nmi_gpio_status_reg_addr); +SCD_DEVICE_ATTR(nmi_gpio_status_mask); + +/* the number of SCD_IRQ_ATTRS() must match SCD_NUM_IRQ_REGISTERS above */ +SCD_IRQ_ATTRS(0); +SCD_IRQ_ATTRS(1); +SCD_IRQ_ATTRS(2); +SCD_IRQ_ATTRS(3); +SCD_IRQ_ATTRS(4); +SCD_IRQ_ATTRS(5); +SCD_IRQ_ATTRS(6); +SCD_IRQ_ATTRS(7); + +static struct attribute *scd_attrs[] = { + SCD_IRQ_ATTRS_POINTERS(0), + SCD_IRQ_ATTRS_POINTERS(1), + SCD_IRQ_ATTRS_POINTERS(2), + SCD_IRQ_ATTRS_POINTERS(3), + SCD_IRQ_ATTRS_POINTERS(4), + SCD_IRQ_ATTRS_POINTERS(5), + SCD_IRQ_ATTRS_POINTERS(6), + SCD_IRQ_ATTRS_POINTERS(7), + &dev_attr_crc_error_irq.attr, + &dev_attr_crc_error_panic.attr, + &dev_attr_ptp_high_offset.attr, + &dev_attr_ptp_low_offset.attr, + &dev_attr_msi_rearm_offset.attr, + &dev_attr_interrupt_irq.attr, + &dev_attr_ardma_offset.attr, + &dev_attr_init_trigger.attr, + &dev_attr_interrupt_poll.attr, + &dev_attr_debug.attr, + &dev_attr_nmi_port_io_p.attr, + &dev_attr_nmi_control_reg_addr.attr, + &dev_attr_nmi_control_mask.attr, + &dev_attr_nmi_status_reg_addr.attr, + &dev_attr_nmi_status_mask.attr, + &dev_attr_nmi_gpio_status_reg_addr.attr, + &dev_attr_nmi_gpio_status_mask.attr, + &dev_attr_ptp_offset_valid.attr, + NULL, +}; + +static struct attribute_group scd_attr_group = { + .attrs = scd_attrs, +}; + +static void scd_pci_disable(struct pci_dev *pdev) +{ + struct scd_dev_priv *priv = pci_get_drvdata(pdev); + + if (priv->mem) { + pci_iounmap(pdev, priv->mem); + pci_release_region(pdev, SCD_BAR_REGS); + priv->mem = NULL; + } + + if (priv->localbus) { + pci_iounmap(pdev, priv->localbus); + pci_release_region(pdev, SCD_BAR_1); + priv->localbus = NULL; + } + + pci_disable_device(pdev); +} + +static int +scd_pci_enable(struct pci_dev *pdev) +{ + struct scd_dev_priv *priv = pci_get_drvdata(pdev); + int err; + u16 ssid; + + err = pci_enable_device(pdev); + if (err) { + dev_err(&pdev->dev, "cannot enable PCI device (%d)\n", err); + goto fail; + } + + err = pci_request_region(pdev, SCD_BAR_REGS, SCD_MODULE_NAME); + if (err) { + dev_err(&pdev->dev, "cannot obtain PCI memory region (%d)\n", err); + goto fail; + } + + priv->mem = pci_iomap(pdev, SCD_BAR_REGS, 0); + if(!priv->mem) { + dev_err(&pdev->dev, "cannot remap PCI memory region\n"); + err = -ENOMEM; + goto fail; + } + + priv->mem_len = pci_resource_len(pdev, SCD_BAR_REGS); + + // check if this device uses partial reconfiguration to load the scd image + pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &ssid); + if (ssid == RECONFIG_PCI_SUBSYSTEM_ID) { + priv->is_reconfig = true; + } else { + if (pci_resource_flags(pdev, SCD_BAR_1) & IORESOURCE_MEM) { + err = pci_request_region(pdev, SCD_BAR_1, SCD_MODULE_NAME); + if (err) { + dev_err(&pdev->dev, "cannot obtain PCI memory region 1 (%d)\n", err); + goto fail; + } + priv->localbus = pci_iomap(pdev, SCD_BAR_1, 0); + if (!priv->localbus) { + dev_err(&pdev->dev, "cannot remap memory region 1\n"); + err = -ENOMEM; + goto fail; + } + } + } + fail: + return err; +} + +static const struct scd_driver_cb scd_pci_cb = { + .enable = scd_pci_enable, + .disable = scd_pci_disable, +}; + +static int scd_lpc_enable(struct pci_dev *pdev); +static void scd_lpc_disable(struct pci_dev *pdev); +static const struct scd_driver_cb scd_lpc_cb = { + .enable = scd_lpc_enable, + .disable = scd_lpc_disable, +}; + +static struct pci_device_id scd_lpc_table[] = { + { PCI_DEVICE( AMD_PCI_VENDOR_ID, AMD_PCI_EKABINI_18F5_DEVICE_ID ) }, + { PCI_DEVICE( AMD_PCI_VENDOR_ID, AMD_PCI_STEPPEEAGLE_18F5_DEVICE_ID ) }, + { PCI_DEVICE( INTEL_PCI_VENDOR_ID, INTEL_PCI_BROADWELL_DEVICE_ID ) }, + { 0 }, +}; + +// +// the LPC driver takes three parameters +// scd.lpc_res_addr - beginning of the LPC physical memory +// scd.lpc_res_size - size of the LPC block, in 4K increments +// scd.lpc_irq - assigned interrupt number +// this driver uses the LPC-ISA bridge available in the AMD-Kabini chip +// as the PCI device to export the resource0 for EOS application code to +// map. +static unsigned long lpc_res_addr; +module_param(lpc_res_addr, long, 0); +MODULE_PARM_DESC(lpc_res_addr, "physical address of LPC resource"); +static int lpc_res_size; +module_param(lpc_res_size, int, 0); +MODULE_PARM_DESC(lpc_res_size, "size of LPC resource"); +static int lpc_irq = -1; +module_param(lpc_irq, int, 0); +MODULE_PARM_DESC(lpc_irq, "interrupt of LPC SCD"); +static const struct scd_driver_cb scd_lpc_cb; + +static int scd_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + struct scd_dev_priv *priv; + u32 fpga_rev, board_rev; + int err; + const struct scd_driver_cb *scd_cb; + + if (pci_match_id(scd_lpc_table, pdev)) { + // matched LPC device + if (!((lpc_irq >= 0) || lpc_res_addr || lpc_res_size)) { + // nothing is enabled, we are not running in LPC mode, return + return -ENODEV; + } + + if (lpc_irq < 0) { + dev_err(&pdev->dev, "Invalid LPC interrupt %d", lpc_irq); + return -EINVAL; + } + + if (!lpc_res_addr) { + dev_err(&pdev->dev, "No LPC scd address specified"); + return -EINVAL; + } + + if (!lpc_res_size) { + dev_err(&pdev->dev, "No LPC scd size specified"); + return -EINVAL; + } + scd_cb = &scd_lpc_cb; + } else { + scd_cb = &scd_pci_cb; + } + + if (pci_get_drvdata(pdev)) { + dev_warn(&pdev->dev, "private data already attached %p", + pci_get_drvdata(pdev)); + } + + priv = kmalloc(sizeof(struct scd_dev_priv), GFP_KERNEL); + if (priv == NULL) { + dev_err(&pdev->dev, "cannot allocate private data, aborting\n"); + err = -ENOMEM; + goto fail; + } + + memset(priv, 0, sizeof (struct scd_dev_priv)); + INIT_LIST_HEAD(&priv->list); + priv->pdev = pdev; + priv->crc_error_irq = SCD_UNINITIALIZED; + priv->crc_error_panic = SCD_UNINITIALIZED; + priv->interrupt_irq = SCD_UNINITIALIZED; + priv->interrupt_poll = SCD_UNINITIALIZED; + priv->ptp_high_offset = SCD_UNINITIALIZED; + priv->ptp_low_offset = SCD_UNINITIALIZED; + priv->ptp_offset_valid = SCD_UNINITIALIZED; + + priv->nmi_port_io_p = SCD_UNINITIALIZED; + priv->nmi_control_reg_addr = SCD_UNINITIALIZED; + priv->nmi_control_reg = NULL; + priv->nmi_control_mask = SCD_UNINITIALIZED; + priv->nmi_status_reg_addr = SCD_UNINITIALIZED; + priv->nmi_status_reg = NULL; + priv->nmi_status_mask = SCD_UNINITIALIZED; + priv->nmi_gpio_status_reg_addr = SCD_UNINITIALIZED; + priv->nmi_gpio_status_reg = NULL; + priv->nmi_gpio_status_mask = SCD_UNINITIALIZED; + priv->nmi_registered = false; + + spin_lock_init(&priv->ptp_time_spinlock); + priv->magic = SCD_MAGIC; + priv->localbus = NULL; + priv->driver_cb = scd_cb; + + pci_set_drvdata(pdev, priv); + + err = scd_cb->enable(pdev); + if (err) { + goto fail; + } + + err = sysfs_create_group(&pdev->dev.kobj, &scd_attr_group); + if (err) { + dev_err(&pdev->dev, "sysfs_create_group() error %d\n", err); + goto fail; + } + priv->sysfs_initialized = 1; + priv->initialized = 0; + + // add to our list + scd_lock(); + list_add_tail(&priv->list, &scd_list); + scd_unlock(); + + priv->revision = ioread32(priv->mem + SCD_REVISION_OFFSET); + fpga_rev = (priv->revision & 0xffff0000) >> 16; + board_rev = priv->revision & 0x00000fff; + + if (priv->is_reconfig && (priv->revision==RECONFIG_STATE_BAR_VALUE)) { + dev_info(&pdev->dev, "scd detected\n FPGA in reconfig state\n"); + } else { + dev_info(&pdev->dev, "scd detected\n FPGA revision %d, board revision %d\n", + fpga_rev, board_rev); + } + + return 0; + +fail: + scd_remove(pdev); + + return err; +} + +static void scd_interrupt_poll( unsigned long data ) +{ + struct scd_dev_priv * dev = ( struct scd_dev_priv * ) data; + struct pci_dev * pdev = dev->pdev; + scd_interrupt( 0, ( void* ) &pdev->dev ); + dev->intr_poll_timer.expires = jiffies + INTR_POLL_INTERVAL; + add_timer( &dev->intr_poll_timer ); +} + +static void scd_remove(struct pci_dev *pdev) +{ + struct scd_dev_priv *priv = pci_get_drvdata(pdev); + unsigned int irq; + int i; + u32 irq_reg; + + if (priv == NULL) + return; + + spin_lock(&scd_ptp_lock); + if(ptp_master_priv == priv) { + ptp_master_priv = NULL; + } + spin_unlock(&scd_ptp_lock); + + scd_lock(); + + if (priv == nmi_priv) { + if (priv->nmi_registered) { + unregister_nmi_handler(NMI_LOCAL, "WATCHDOG_NMI"); + priv->nmi_registered = false; + } + nmi_priv = NULL; + } + + // call ardma remove() if scd has ardma + if (priv->initialized && priv->ardma_offset && scd_ardma_ops) { + scd_ardma_ops->remove(pdev); + } + + // call scd_em's remove callback + if (scd_em_ops && scd_em_ops->remove) { + scd_em_ops->remove(pdev); + } + + // call scd_sonic remove callback + if (scd_ext_ops && scd_ext_ops->remove) { + scd_ext_ops->remove(pdev); + } + + //stop interrupt polling if we've initialized it + if( priv->interrupt_poll != SCD_UNINITIALIZED ) { + del_timer_sync( &priv->intr_poll_timer ); + } + + // remove from our list + list_del_init(&priv->list); + + irq = (priv->interrupt_irq != SCD_UNINITIALIZED) ? + priv->interrupt_irq : pdev->irq; + + if (priv->initialized) { + scd_mask_interrupts(priv); + free_irq(irq, &pdev->dev); + if (priv->crc_error_irq != SCD_UNINITIALIZED) + free_irq(priv->crc_error_irq, &pdev->dev); + if (priv->msi_rearm_offset) { + pci_disable_msi(pdev); + } + } + + // call pci bits to release + priv->driver_cb->disable( pdev ); + + if (priv->initialized) { + for(irq_reg = 0; irq_reg < SCD_NUM_IRQ_REGISTERS; irq_reg++) { + for (i = 0; i < NUM_BITS_IN_WORD; i++) { + if (priv->irq_info[irq_reg].uio_info[i]) { + uio_unregister_device(priv->irq_info[irq_reg].uio_info[i]); + kfree(priv->irq_info[irq_reg].uio_info[i]); + priv->irq_info[irq_reg].uio_info[i] = NULL; + } + } + } + } + priv->magic = 0; + + // release lock before removing sysfs to avoid deadlocks + scd_unlock(); + + if (priv->sysfs_initialized) { + sysfs_remove_group(&pdev->dev.kobj, &scd_attr_group); + } + + ASSERT( !priv->localbus ); + ASSERT( !priv->mem ); + if( priv->initialized ) { + for(irq_reg = 0; irq_reg < SCD_NUM_IRQ_REGISTERS; irq_reg++) { + for (i = 0; i < NUM_BITS_IN_WORD; i++) { + ASSERT( !priv->irq_info[irq_reg].uio_info[i] ); + } + } + } + + pci_set_drvdata(pdev, NULL); + memset(priv, 0, sizeof (struct scd_dev_priv)); + + kfree(priv); + + dev_info(&pdev->dev, "scd removed\n"); +} + +static void scd_shutdown(struct pci_dev *pdev) { + struct scd_dev_priv *priv = pci_get_drvdata(pdev); + dev_info(&pdev->dev, "scd shutdown\n"); + scd_mask_interrupts(priv); + + // call ardma shutdown() if scd has ardma + if (priv->initialized && priv->ardma_offset && scd_ardma_ops) { + scd_ardma_ops->shutdown(pdev); + } +} + +static void scd_mask_interrupts(struct scd_dev_priv *priv) { + u32 i; + + if (priv == NULL || !priv->initialized) { + return; + } + + for (i = 0; i < SCD_NUM_IRQ_REGISTERS; i++) { + if (priv->irq_info[i].interrupt_mask_set_offset) { + iowrite32(0xffffffff, + priv->mem + priv->irq_info[i].interrupt_mask_set_offset); + // stall until previous write completes + (void) ioread32(priv->mem + priv->irq_info[i].interrupt_mask_set_offset); + } + } +} + +static pci_ers_result_t scd_error_detected(struct pci_dev *pdev, + enum pci_channel_state state) { + dev_err(&pdev->dev, "error detected (state=%d)\n", state); + return PCI_ERS_RESULT_DISCONNECT; +} + +static struct pci_device_id scd_pci_table[] = { + { PCI_DEVICE( SCD_PCI_VENDOR_ID, SCD_PCI_DEVICE_ID ) }, + { PCI_DEVICE( AMD_PCI_VENDOR_ID, AMD_PCI_EKABINI_18F5_DEVICE_ID ) }, + { PCI_DEVICE( AMD_PCI_VENDOR_ID, AMD_PCI_STEPPEEAGLE_18F5_DEVICE_ID ) }, + { PCI_DEVICE( INTEL_PCI_VENDOR_ID, INTEL_PCI_BROADWELL_DEVICE_ID ) }, + { 0, }, +}; + +static int scd_dump(struct seq_file *m, void *p) { + struct scd_dev_priv *priv; + u32 irq_reg; + int i; + unsigned long uio_count; + + scd_lock(); + seq_printf(m, "\ndebug 0x%x\n\n", debug); + list_for_each_entry(priv, &scd_list, list) { + if(priv->magic == SCD_MAGIC) { + seq_printf(m, "scd %s\n", pci_name(priv->pdev)); + + seq_printf(m, "revision 0x%x revision_error_reports %u\n", + priv->revision, + priv->revision_error_reports); + + seq_printf(m, "initialized %d sysfs_initialized %d" + " interrupt_poll %lu magic 0x%x" + " is_reconfig %d\n", priv->initialized, + priv->sysfs_initialized, + priv->interrupt_poll, + priv->magic, + priv->is_reconfig); + + seq_printf(m, "ptp_offset_valid 0x%lx ptp_high_offset 0x%lx" + " ptp_low_offset 0x%lx ardma_offset %lu msi_rearm_offset %lu\n", + priv->ptp_offset_valid, priv->ptp_high_offset, + priv->ptp_low_offset, priv->ardma_offset, + priv->msi_rearm_offset); + + seq_printf(m, "nmi_port_io_p 0x%lx nmi_control_reg_addr 0x%lx " + "nmi_control_mask 0x%lx\nnmi_status_reg_addr 0x%lx " + "nmi_status_mask 0x%lx nmi_gpio_status_reg_addr 0x%lx\n" + "nmi_gpio_status_mask 0x%lx nmi_registered %d\n", + priv->nmi_port_io_p, priv->nmi_control_reg_addr, + priv->nmi_control_mask, priv->nmi_status_reg_addr, + priv->nmi_status_mask, priv->nmi_gpio_status_reg_addr, + priv->nmi_gpio_status_mask, priv->nmi_registered); + + for(irq_reg = 0; irq_reg < SCD_NUM_IRQ_REGISTERS; irq_reg++) { + if(!priv->irq_info[irq_reg].interrupt_status_offset || + !priv->irq_info[irq_reg].interrupt_mask_read_offset || + !priv->irq_info[irq_reg].interrupt_mask_set_offset) { + continue; + } + seq_printf(m, "interrupt register %u:\n", irq_reg); + seq_printf(m, "interrupt_status_offset 0x%lx " + "interrupt_mask_read_offset 0x%lx " + "interrupt_mask_set_offset 0x%lx\n" + "interrupt_mask_clear_offset 0x%lx " + "interrupt_mask 0x%lx " + "interrupt_mask_power_loss 0x%lx\n" + "ardma_interrupt_mask 0x%lx\n", + priv->irq_info[irq_reg].interrupt_status_offset, + priv->irq_info[irq_reg].interrupt_mask_read_offset, + priv->irq_info[irq_reg].interrupt_mask_set_offset, + priv->irq_info[irq_reg].interrupt_mask_clear_offset, + priv->irq_info[irq_reg].interrupt_mask, + priv->irq_info[irq_reg].interrupt_mask_powerloss, + priv->irq_info[irq_reg].interrupt_mask_ardma); + + } + + seq_printf(m, "irq %u\n", priv->pdev->irq ); + seq_printf(m, "interrupts %lu interrupts_claimed %lu\n", + priv->interrupts, priv->interrupt_claimed ); + + seq_printf(m, "interrupt status bit counts:\n"); + + for(irq_reg = 0; irq_reg < SCD_NUM_IRQ_REGISTERS; irq_reg++) { + if(!priv->irq_info[irq_reg].interrupt_status_offset || + !priv->irq_info[irq_reg].interrupt_mask_read_offset || + !priv->irq_info[irq_reg].interrupt_mask_set_offset) { + continue; + } + + for (i = 0; i < NUM_BITS_IN_WORD; i++) { + uio_count = priv->irq_info[irq_reg].uio_count[i]; + if(uio_count) { + seq_printf(m, "%d[%d] %lu\n", irq_reg, i, uio_count ); + } + } + + if(priv->interrupt_ardma_cnt) + seq_printf(m, "ardma interrupts %lu ", priv->interrupt_ardma_cnt); + if(priv->interrupt_powerloss_cnt) + seq_printf(m, "power loss interrupts %lu\n", + priv->interrupt_powerloss_cnt); + } + } + seq_printf(m, "\n"); + } + + scd_unlock(); + return 0; +} + +static int scd_dump_open( struct inode *inode, struct file *file ) { + return (single_open(file, scd_dump, NULL)); +} + +static const struct file_operations scd_dump_file_ops = { + .owner = THIS_MODULE, + .open = scd_dump_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static void scd_procfs_create( void ) { + struct proc_dir_entry *entry; + entry = proc_create( SCD_MODULE_NAME, 0, NULL, &scd_dump_file_ops ); +} + +static void scd_procfs_remove( void ) { + (void) remove_proc_entry( SCD_MODULE_NAME, NULL ); +} + +MODULE_DEVICE_TABLE(pci, scd_pci_table); + +static struct pci_error_handlers scd_error_handlers = { + .error_detected = scd_error_detected, +}; + +static struct pci_driver scd_driver = { + .name = "scd", + .id_table = scd_pci_table, + .probe = scd_probe, + .remove = scd_remove, + .err_handler = &scd_error_handlers, + .shutdown = &scd_shutdown, +}; + +static int +scd_lpc_mmap_resource(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + struct vm_area_struct *vma) +{ + struct pci_dev *pdev = to_pci_dev(container_of(kobj, + struct device, kobj)); + unsigned long prot; + int rc; + + // validate range of mapping + if ((vma->vm_pgoff + ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT)) > + (attr->size >> PAGE_SHIFT)) { + dev_err(&pdev->dev, "invalid vm region addr 0x%lx-0x%lx offset pages %lu\n", + vma->vm_start, vma->vm_end, vma->vm_pgoff); + return -EINVAL; + } + + vma->vm_pgoff += lpc_res_addr >> PAGE_SHIFT; + prot = pgprot_val(vma->vm_page_prot); +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0) + prot |= _PAGE_CACHE_UC; +#else + prot |= cachemode2protval(_PAGE_CACHE_MODE_UC); +#endif + vma->vm_page_prot = __pgprot(prot); + + // map resource0 into user space + rc = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, + vma->vm_end - vma->vm_start, + vma->vm_page_prot); + if (rc) { + dev_err(&pdev->dev, "resource mapping failed. rc %d", rc); + } + + return rc; +} + +static int +scd_lpc_enable(struct pci_dev *pdev) +{ + struct scd_dev_priv *priv = pci_get_drvdata(pdev); + struct bin_attribute *res_attr; + int rc = 0; + char *res_attr_name; + + if (pdev->res_attr[0]) { + dev_err(&pdev->dev, "Resources already attached at %d\n", 0); + return -EINVAL; + } + + // map address specified into kernel + priv->mem = (void __iomem*) ioremap_nocache((unsigned int) lpc_res_addr, + lpc_res_size); + priv->mem_len = lpc_res_size; + // save the irq for later use, application can still override later + // by writing into /sys/devices/.../interrupt_irq + priv->interrupt_irq = lpc_irq; + + res_attr = NULL; + res_attr_name = NULL; + priv->lpc_vendor = pdev->vendor; + priv->lpc_device = pdev->device; + pdev->vendor = SCD_PCI_VENDOR_ID; + pdev->device = SCD_PCI_DEVICE_ID; + + // create the resource0 file for the scd + res_attr = kzalloc(sizeof(*res_attr), GFP_ATOMIC); + if (!res_attr) { + rc = -ENOMEM; + goto cleanup; + } + + #define RESOURCE_NAME "resource0" + res_attr_name = kzalloc(sizeof(RESOURCE_NAME) + 1, GFP_ATOMIC); + if (!res_attr_name) { + rc = -ENOMEM; + goto cleanup; + } + sprintf(res_attr_name, RESOURCE_NAME); + + sysfs_bin_attr_init(res_attr); + res_attr->attr.name = res_attr_name; + res_attr->attr.mode = S_IRUSR | S_IWUSR; + res_attr->size = lpc_res_size; + res_attr->mmap = scd_lpc_mmap_resource; + res_attr->private = &pdev->resource[0]; + rc = sysfs_create_bin_file(&pdev->dev.kobj, res_attr); + if (rc) { + dev_err(&pdev->dev, "sysfs resource0 creation failed %d\n", rc); + goto cleanup; + } + pdev->res_attr[0] = res_attr; + return rc; + +cleanup: + // let the general cleanup handle unrolling records already created + if (res_attr) { + kfree(res_attr); + } + if (res_attr_name) { + kfree(res_attr_name); + } + + return rc; +} + +static void +scd_lpc_disable(struct pci_dev *pdev) +{ + struct scd_dev_priv *priv = pci_get_drvdata(pdev); + + if (priv->mem) { + iounmap(priv->mem); + priv->mem = NULL; + } + + if (pdev->res_attr[0]) { + sysfs_remove_bin_file(&pdev->dev.kobj, pdev->res_attr[0]); + kfree(pdev->res_attr[0]->attr.name); + kfree(pdev->res_attr[0]); + pdev->res_attr[0] = 0; + } + + pdev->vendor = priv->lpc_vendor; + pdev->device = priv->lpc_device; + return; +} + +static int __init scd_init(void) +{ + int err; + mutex_init(&scd_mutex); + spin_lock_init(&scd_ptp_lock); + INIT_LIST_HEAD(&scd_list); + + printk(KERN_INFO "scd module installed\n"); + err = pci_register_driver(&scd_driver); + if(!err) + scd_procfs_create(); + + return err; +} + +static void __exit scd_exit(void) +{ + pci_unregister_driver(&scd_driver); + scd_procfs_remove(); + printk(KERN_INFO "scd module removed\n"); +} + +module_init(scd_init); +module_exit(scd_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Hugh Holbrook and James Lingard"); +MODULE_DESCRIPTION("scd driver"); diff --git a/platform/broadcom/sonic-platform-modules-arista/src/scd.h b/platform/broadcom/sonic-platform-modules-arista/src/scd.h new file mode 100644 index 000000000000..b3dbbbf38fc4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/src/scd.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2010-2016 Arista Networks, 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, see . + * + */ + +// scd linux kernel driver public definitions + +// Allow an ardma handler set to be registered. +struct scd_ardma_ops { + void (*probe)(struct pci_dev *pdev, void *scdregs, + unsigned long ardma_offset, + void *localbus, + unsigned long interrupt_mask_ardma, + unsigned long interrupt_mask_read_offset, + unsigned long interrupt_mask_set_offset, + unsigned long interrupt_mask_clear_offset); + void (*remove)(struct pci_dev *pdev); + void (*shutdown)(struct pci_dev *pdev); + bool (*interrupt)(struct pci_dev *pdev); +}; + +// Allow scd-em callbacks to be registered +struct scd_em_ops { + void (*probe)(struct pci_dev *pdev); + void (*remove)(struct pci_dev *pdev); +}; + +// Allow scd-ext callbacks to be registered +struct scd_ext_ops { + int (*probe)(struct pci_dev *pdev); + void (*remove)(struct pci_dev *pdev); + int (*init_trigger)(struct pci_dev *pdev); +}; + +int scd_register_ardma_ops(struct scd_ardma_ops *ops); +void scd_unregister_ardma_ops(void); +int scd_register_em_ops(struct scd_em_ops *ops); +void scd_unregister_em_ops(void); +int scd_register_ext_ops(struct scd_ext_ops *ops); +void scd_unregister_ext_ops(void); +struct pci_dev *scd_get_pdev(const char *name); +u32 scd_read_register(struct pci_dev *pdev, u32 offset); +void scd_write_register(struct pci_dev *pdev, u32 offset, u32 val); +size_t scd_resource_len(struct pci_dev *pdev); +u64 scd_ptp_timestamp(void); + +// Copyright (c) 2010-2016 Arista Networks, Inc. All rights reserved. +// Arista Networks, Inc. Confidential and Proprietary. diff --git a/platform/broadcom/sonic-platform-modules-arista/src/sonic-support-driver.c b/platform/broadcom/sonic-platform-modules-arista/src/sonic-support-driver.c new file mode 100644 index 000000000000..0ceae5787a1d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/src/sonic-support-driver.c @@ -0,0 +1,1270 @@ +/* Copyright (c) 2017 Arista Networks, 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, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "scd.h" +#include "sonic-support-driver.h" +#include "gpio-kversfix.h" + +#define SCD_MODULE_NAME "scd" + +#define NUM_SMBUS_MASTERS 8 +#define NUM_SMBUS_BUSES 8 +#define SMBUS_RETRY_COUNT 3 +#define SMBUS_REQUEST_OFFSET 0x10 +#define SMBUS_CONTROL_STATUS_OFFSET 0x20 +#define SMBUS_RESPONSE_OFFSET 0x30 + +#define NUM_LEDS 200 +#define NUM_GPIO_ADDRS 200 +#define NUM_GPIOS 500 +#define NUM_RESET_ADDRS 10 +#define NUM_RESETS 100 +#define RESET_SET_OFFSET 0x00 +#define RESET_CLEAR_OFFSET 0x10 +#define NAME_LENGTH 50 + +/* String constants for SFP/QSFP gpio names */ +static const char *qsfpGpioSuffixes[] = { + "_interrupt", + "_present", + "_interrupt_changed", + "_present_changed", + "_lp_mode", + "_reset", + "_modsel" +}; + +static const char *sfpGpioSuffixes[] = { + "_rxlos", + "_txfault", + "_present", + "_rxlos_changed", + "_txfault_changed", + "_present_changed", + "_txdisable", + "_rate_select0", + "_rate_select1" +}; + +static const char *psuGpioSuffixes[] = { + "1_present", + "2_present" +}; + +static const char *muxGpioSuffixes[] = { + "_sfp_qsfp" +}; + +#define QSFPTYPE 0 +#define SFPTYPE 1 +#define PSUTYPE 2 +#define MUXTYPE 3 + +static int numQsfpBits = ARRAY_SIZE(qsfpGpioSuffixes); +static int numSfpBits = ARRAY_SIZE(sfpGpioSuffixes); +static int numPsuBits = ARRAY_SIZE(psuGpioSuffixes); +static int numMuxBits = ARRAY_SIZE(muxGpioSuffixes); + +struct sonic_master; + +struct sonic_bus { + struct sonic_master *master; + u32 id; + struct i2c_adapter adap; +}; + +struct sonic_master { + u32 id; + u32 req; + u32 cs; + u32 resp; + struct mutex mutex; + struct sonic_bus bus[NUM_SMBUS_BUSES]; +}; + +struct sonic_led { + u32 addr; + struct led_classdev cdev; +}; + + +struct sonic_gpio { + char name[40]; + u32 addr; + u32 mask; + u32 ro; + u32 active_low; + u32 gpio_type; + struct gpio_chip chip; +}; + +struct sonic_reset { + char name[40]; + u32 addr; + u32 mask; + struct gpio_chip chip; +}; + + +struct sonic_master master[NUM_SMBUS_MASTERS]; +u32 master_addrs[NUM_SMBUS_MASTERS + 1]; + +struct sonic_led led[NUM_LEDS]; +u32 led_addrs[NUM_LEDS + 1]; +char led_names[NUM_LEDS + 1][NAME_LENGTH]; +u32 num_led_names; + +struct sonic_gpio gpio[NUM_GPIO_ADDRS]; +u32 gpio_addrs[NUM_GPIO_ADDRS + 1]; +u32 gpio_masks[NUM_GPIO_ADDRS + 1]; +u32 gpio_ro[NUM_GPIO_ADDRS + 1]; +u32 gpio_type[NUM_GPIO_ADDRS + 1]; +u32 gpio_active_low[NUM_GPIO_ADDRS + 1]; +char gpio_names[NUM_GPIOS + 1][NAME_LENGTH]; +u32 num_gpio_names; + +struct sonic_reset reset[NUM_RESET_ADDRS]; +u32 reset_addrs[NUM_RESET_ADDRS + 1]; +u32 reset_masks[NUM_RESET_ADDRS + 1]; +char reset_names[NUM_RESETS + 1][NAME_LENGTH]; +u32 num_reset_names; + +union Request { + u32 reg; + struct { + u32 d:8; + u32 ss:6; + u32 reserved1:2; + u32 dat:2; + u32 t:2; + u32 sp:1; + u32 da:1; + u32 dod:1; + u32 st:1; + u32 bs:4; + u32 ti:4; + } __packed; +}; + +union ControlStatus { + u32 reg; + struct { + u32 reserved1:13; + u32 foe:1; + u32 reserved2:17; + u32 reset:1; + } __packed; +}; + +union Response { + u32 reg; + struct { + u32 d:8; + u32 bus_conflict_error:1; + u32 timeout_error:1; + u32 ack_error:1; + u32 flushed:1; + u32 ti:4; + u32 ss:6; + u32 reserved2:9; + u32 fe:1; + } __packed; +}; + +/* Reference to the pci device */ +static struct pci_dev *pdev_ref; +/* Flag to indicate initialization */ +static int initialized; +/* kobj for the sonic driver */ +static struct kobject *sonic_kobject; + +/* i2c client */ +struct sonic_i2c_client { + int master; + int bus; + int addr; + struct i2c_client *client; + struct list_head next; +}; + +static struct list_head client_list; + +static void master_lock(struct sonic_master *pmaster) +{ + mutex_lock(&pmaster->mutex); +} + +static void master_unlock(struct sonic_master *pmaster) +{ + mutex_unlock(&pmaster->mutex); +} + +static struct mutex sonic_mutex; + +static void sonic_lock(void) +{ + mutex_lock(&sonic_mutex); +} + +static void sonic_unlock(void) +{ + mutex_unlock(&sonic_mutex); +} + +/* SMBus functions */ +static void write_req(struct sonic_master *pmaster, + union Request req) +{ + u32 addr = (u32)pmaster->req; + scd_write_register(pdev_ref, addr, req.reg); +} + +static void write_cs(struct sonic_master *pmaster, + union ControlStatus cs) +{ + scd_write_register(pdev_ref, pmaster->cs, cs.reg); +} + +static union ControlStatus read_cs(struct sonic_master *pmaster) +{ + union ControlStatus cs; + cs.reg = scd_read_register(pdev_ref, pmaster->cs); + return cs; +} + +static union Response read_resp(struct sonic_master *pmaster) +{ + union Response resp; + u32 retry = 10; + + resp.reg = scd_read_register(pdev_ref, pmaster->resp); + while (resp.fe && --retry) { + msleep(10); + resp.reg = scd_read_register(pdev_ref, pmaster->resp); + } + + if (resp.fe) { + sonic_dbg("smbus response: fifo still empty after retries"); + resp.reg = 0xffffffff; + } + + return resp; +} + +static s32 check_resp(struct sonic_master *pmaster, + union Response resp, u32 tid) +{ + const char *error; + int error_ret = -EIO; + + if (resp.ack_error) { + error = "ack"; + goto fail; + } + if (resp.timeout_error) { + error = "timeout"; + goto fail; + } + if (resp.bus_conflict_error) { + error = "conflict"; + goto fail; + } + if (resp.flushed) { + error = "flush"; + goto fail; + } + if (resp.ti != tid) { + error = "tid"; + goto fail; + } + return 0; + + fail: + sonic_dbg("smbus response: %s error. reg = 0x%08x", error, resp.reg); + return error_ret; +} + +static u32 sonic_smbus_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | + I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_I2C_BLOCK | I2C_FUNC_SMBUS_BLOCK_DATA; +} + +static void smbus_reset(struct sonic_master *pmaster) +{ + union ControlStatus cs; + cs = read_cs(pmaster); + cs.reset = 1; + cs.foe = 1; + write_cs(pmaster, cs); + mdelay(10); + cs.reset = 0; + write_cs(pmaster, cs); +} + +static s32 sonic_smbus_access(struct i2c_adapter *adap, u16 addr, + unsigned short flags, char read_write, + u8 command, int size, union i2c_smbus_data *data) +{ + int i; + union Request req; + union Response resp; + int ret = 0; + u32 ss = 0; + u32 data_offset = 0; + struct sonic_master *pmaster; + struct sonic_bus *bus; + bus = i2c_get_adapdata(adap); + pmaster = bus->master; + + master_lock(pmaster); + + req.reg = 0; + req.bs = bus->id; + req.t = 1; + + switch (size) { + case I2C_SMBUS_QUICK: + ss = 1; + break; + case I2C_SMBUS_BYTE: + ss = 2; + break; + case I2C_SMBUS_BYTE_DATA: + if (read_write == I2C_SMBUS_WRITE) { + ss = 3; + } else { + ss = 4; + } + break; + case I2C_SMBUS_WORD_DATA: + if (read_write == I2C_SMBUS_WRITE) { + ss = 4; + } else { + ss = 5; + } + break; + case I2C_SMBUS_I2C_BLOCK_DATA: + data_offset = 1; + if (read_write == I2C_SMBUS_WRITE) { + ss = 2 + data->block[0]; + } else { + ss = 3 + data->block[0]; + } + break; + case I2C_SMBUS_BLOCK_DATA: + if (read_write == I2C_SMBUS_WRITE) { + ss = 3 + data->block[0]; + } else { + master_unlock(pmaster); + ret = sonic_smbus_access(adap, addr, flags, I2C_SMBUS_READ, command, + I2C_SMBUS_BYTE_DATA, data); + master_lock(pmaster); + if (ret) { + goto fail; + } + ss = 4 + data->block[0]; + } + break; + } + + req.st = 1; + req.ss = ss; + req.d = (((addr & 0xff) << 1) | ((ss <= 2) ? read_write : 0)); + req.dod = 1; + for (i = 0; i < ss; i++) { + if (i == ss - 1) { + req.sp = 1; + req.dat = 3; + } + if (i == 1) { + req.st = 0; + req.ss = 0; + req.d = command; + if (ss == 2) + req.dod = ((read_write == I2C_SMBUS_WRITE) ? 1 : 0); + else + req.dod = 1; + } + if ((i == 2 && read_write == I2C_SMBUS_READ)) { + req.st = 1; + req.d = (((addr & 0xff) << 1) | 1); + } + if (i >= 2 && (read_write == I2C_SMBUS_WRITE)) { + req.d = data->block[data_offset + i - 2]; + } + if ((i == 3 && read_write == I2C_SMBUS_READ)) { + req.dod = 0; + } + req.da = ((!(req.dod || req.sp)) ? 1 : 0); + write_req(pmaster, req); + req.ti++; + req.st = 0; + } + + req.ti = 0; + for (i = 0; i < ss; i++) { + resp = read_resp(pmaster); + ret = check_resp(pmaster, resp, req.ti); + if (ret) { + goto fail; + } + req.ti++; + if (read_write == I2C_SMBUS_READ) { + if (size == I2C_SMBUS_BYTE || size == I2C_SMBUS_BYTE_DATA) { + if (i == ss - 1) { + data->byte = resp.d; + } + } else if (size == I2C_SMBUS_WORD_DATA) { + if (i == ss - 2) { + data->word = resp.d; + } else if (i == ss - 1) { + data->word |= (resp.d << 8); + } + } else { + if (i >= 3) { + if (size == I2C_SMBUS_BLOCK_DATA) { + data->block[i - 3] = resp.d; + } else { + data->block[i - 2] = resp.d; + } + } + } + } + } + + master_unlock(pmaster); + return 0; + + fail: + sonic_dbg("smbus %s failed addr=0x%02x reg=0x%02x size=0x%02x adapter=\"%s\"\n", + (read_write) ? "read" : "write", addr, command, size, adap->name); + smbus_reset(pmaster); + master_unlock(pmaster); + return ret; +} + +static s32 sonic_smbus_access_retry(struct i2c_adapter *adap, u16 addr, + unsigned short flags, char read_write, + u8 command, int size, + union i2c_smbus_data *data) +{ + int retry = 0; + int ret; + + do { + ret = sonic_smbus_access(adap, addr, flags, read_write, command, size, data); + if (ret != -EIO) + return ret; + retry++; + sonic_dbg("smbus retrying... %d/%d", retry, SMBUS_RETRY_COUNT); + } while (retry < SMBUS_RETRY_COUNT); + + sonic_warn("smbus %s failed addr=0x%02x reg=0x%02x size=0x%02x " + "adapter=\"%s\"\n", (read_write) ? "read" : "write", + addr, command, size, adap->name); + + return -EIO; +} + +static struct i2c_algorithm sonic_smbus_algorithm = { + .smbus_xfer = sonic_smbus_access_retry, + .functionality = sonic_smbus_func, +}; + +static void smbus_remove(void) +{ + int master_id; + int bus_id; + struct sonic_master *pmaster; + struct sonic_bus *bus; + struct list_head *ptr; + struct sonic_i2c_client *entry; + + /* unregister all i2c clients */ + ptr = client_list.next; + while (ptr != &client_list) { + entry = list_entry(ptr, struct sonic_i2c_client, next); + ptr = ptr->next; + i2c_unregister_device(entry->client); + kfree(entry); + } + + for (master_id = 0; master_id < master_addrs[0]; master_id++) { + pmaster = &master[master_id]; + if (!pmaster) { + continue; + } + for (bus_id = 0; bus_id < ARRAY_SIZE(master->bus); bus_id++) { + bus = &pmaster->bus[bus_id]; + i2c_del_adapter(&bus->adap); + } + } +} + +static s32 smbus_init(void) +{ + int master_id; + int bus_id; + int err; + u32 addr; + struct sonic_master *pmaster; + struct sonic_bus *bus; + + for (master_id = 0; master_id < master_addrs[0]; master_id++) { + addr = master_addrs[master_id + 1]; + pmaster = &master[master_id]; + pmaster->id = master_id; + pmaster->req = addr + SMBUS_REQUEST_OFFSET; + pmaster->cs = addr + SMBUS_CONTROL_STATUS_OFFSET; + pmaster->resp = addr + SMBUS_RESPONSE_OFFSET; + + mutex_init(&pmaster->mutex); + smbus_reset(pmaster); + for (bus_id = 0; bus_id < ARRAY_SIZE(pmaster->bus); bus_id++) { + bus = &pmaster->bus[bus_id]; + bus->master = pmaster; + bus->id = bus_id; + bus->adap.owner = THIS_MODULE; + bus->adap.class = 0; + bus->adap.algo = &sonic_smbus_algorithm; + bus->adap.dev.parent = &(pdev_ref->dev); + scnprintf(bus->adap.name, + sizeof(bus->adap.name), + "SCD SMBus master %d bus %d", pmaster->id, bus->id); + i2c_set_adapdata(&bus->adap, bus); + err = i2c_add_adapter(&bus->adap); + + if (err) { + err = -ENODEV; + goto fail; + } + } + } + return 0; + +fail: + smbus_reset(pmaster); + return err; +} + +static void brightness_set(struct led_classdev *led_cdev, enum led_brightness value) +{ + struct sonic_led *pled = container_of(led_cdev, struct sonic_led, cdev); + u32 reg; + + switch ((int)value) { + case 0: + reg = 0x0006ff00; + break; + case 1: + reg = 0x1006ff00; + break; + case 2: + reg = 0x0806ff00; + break; + case 3: + reg = 0x1806ff00; + break; + case 4: + reg = 0x1406ff00; + break; + case 5: + reg = 0x0C06ff00; + break; + case 6: + reg = 0x1C06ff00; + break; + default: + reg = 0x1806ff00; + break; + } + scd_write_register(pdev_ref, pled->addr, reg); +} + +static void led_remove(void) +{ + int i; + struct sonic_led *pled; + for (i = 0; i < led_addrs[0]; i++) { + pled = &led[i]; + if (pled) { + led_classdev_unregister(&pled->cdev); + } + } +} + + +static s32 led_init(void) +{ + int i; + struct sonic_led *pled; + int ret = 0; + for (i = 0; i < led_addrs[0]; i++) { + pled = &led[i]; + pled->addr = led_addrs[i + 1]; + pled->cdev.name = led_names[i]; + pled->cdev.brightness_set = brightness_set; + ret = led_classdev_register(&(pdev_ref->dev), &pled->cdev); + if (ret) { + goto fail; + } + } + + return 0; + + fail: + led_remove(); + return ret; +} + +static u32 bit_mask(u32 mask, unsigned num) +{ + /* Returns the numth set bit in mask */ + int i; + for (i = 0; i < num; i++) { + mask &= mask - 1; + } + return mask & ~(mask - 1); +} + +static int gpio_get(struct gpio_chip *gc, unsigned gpio_num) +{ + struct sonic_gpio *pgpio = container_of(gc, struct sonic_gpio, chip); + u32 mask = bit_mask(pgpio->mask, gpio_num); + return (scd_read_register(pdev_ref, pgpio->addr) & mask); +} + +static void gpio_set(struct gpio_chip *gc, unsigned gpio_num, int val) +{ + struct sonic_gpio *pgpio = container_of(gc, struct sonic_gpio, chip); + u32 mask = bit_mask(pgpio->mask, gpio_num); + u32 reg = scd_read_register(pdev_ref, pgpio->addr); + reg ^= (((-val) ^ reg) & mask); + scd_write_register(pdev_ref, pgpio->addr, reg); +} + +static int direction_input(struct gpio_chip *gc, unsigned gpio_num) +{ + return 0; +} + +static int direction_output(struct gpio_chip *gc, unsigned gpio_num, int val) +{ + struct sonic_gpio *pgpio = container_of(gc, struct sonic_gpio, chip); + u32 mask = bit_mask(pgpio->mask, gpio_num); + if (pgpio->ro & mask) { + return -EINVAL; + } else { + gpio_set(gc, gpio_num, val); + } + return 0; +} + +static int sonic_gpio_add(struct gpio_chip *chip, u16 hwnum, const char *name, + bool direction_may_change, int active_low) +{ + int ret = 0; + struct gpio_desc *desc; + + sonic_dbg("creating gpio %s hwnum %d\n", name, hwnum); + + desc = gpiochip_request_own_desc(chip, hwnum, name); + if (IS_ERR(desc)) { + sonic_err("failed to request desc for GPIO %s\n", name); + goto fail; + } + + ret = gpiod_export(desc, direction_may_change); + if (ret) { + sonic_err("failed to export GPIO %s\n", name); + goto fail_export; + } + + ret = gpiod_export_link(chip->dev, name, desc); + if (ret) { + sonic_err("failed to export link for GPIO %s\n", name); + goto fail_export_link; + } + + ret = gpiod_sysfs_set_active_low(desc, active_low); + if (ret) { + sonic_err("failed to set active_low setting for GPIO %s\n", name); + goto fail_set_active_mode; + } + + return ret; + + fail_set_active_mode: + sysfs_remove_link(&pdev_ref->dev.kobj, name); + fail_export_link: + gpiod_unexport(desc); + fail_export: + gpiochip_free_own_desc(desc); + fail: + return ret; +} + +static void sonic_gpio_remove(struct gpio_chip *chip, u16 hwnum, const char *name) +{ + u16 gpio = chip->base + hwnum; + struct gpio_desc *desc = gpio_to_desc(gpio); + + sysfs_remove_link(&pdev_ref->dev.kobj, name); + gpiod_unexport(desc); + gpiochip_free_own_desc(desc); +} + +static void gpio_remove(void) +{ + int i; + int j; + int k = 0; + struct sonic_gpio *pgpio; + u32 addr; + char gpio_name_buffer[50]; + + for (i = 0; i < gpio_addrs[0]; i++) { + addr = gpio_addrs[i + 1]; + pgpio = &gpio[i]; + if (!pgpio->addr) { + continue; + } + for (j = 0; j < pgpio->chip.ngpio; j++) { + + strcpy(gpio_name_buffer, gpio_names[k]); + switch (pgpio->gpio_type) { + case QSFPTYPE: + strcat(gpio_name_buffer, qsfpGpioSuffixes[j]); + if (j == numQsfpBits - 1) { + k++; + } + break; + case SFPTYPE: + strcat(gpio_name_buffer, sfpGpioSuffixes[j]); + if (j == numSfpBits - 1) { + k++; + } + break; + case PSUTYPE: + strcat(gpio_name_buffer, psuGpioSuffixes[j]); + if (j == numPsuBits - 1) { + k++; + } + break; + case MUXTYPE: + strcat(gpio_name_buffer, muxGpioSuffixes[j]); + if (j == numMuxBits - 1) { + k++; + } + break; + default: + k++; + break; + } + + sonic_gpio_remove(&pgpio->chip, j, gpio_name_buffer); + } + if (gpiochip_remove(&pgpio->chip) < 0) { + sonic_err("Failed to remove GPIO chip\n"); + } + } +} + +static s32 gpio_init(void) +{ + int i; + int j; + int k = 0; + struct sonic_gpio *pgpio; + int ret = 0; + u32 addr; + u32 mask; + char gpio_name_buffer[50]; + + for (i = 0; i < gpio_addrs[0]; i++) { + addr = gpio_addrs[i + 1]; + pgpio = &gpio[i]; + pgpio->addr = addr; + pgpio->mask = gpio_masks[i + 1]; + pgpio->ro = gpio_ro[0] ? gpio_ro[i + 1] : 0; + pgpio->active_low = gpio_active_low[0] ? gpio_active_low[i + 1] : 0; + snprintf(pgpio->name, sizeof(pgpio->name), "gpio%d", i + 1); + pgpio->gpio_type = gpio_type[0] ? gpio_type[i + 1] : 0; + pgpio->chip.label = pgpio->name; + pgpio->chip.owner = THIS_MODULE; + pgpio->chip.base = -1; + pgpio->chip.ngpio = hweight_long(pgpio->mask); + pgpio->chip.dev = &(pdev_ref->dev); + pgpio->chip.get = gpio_get; + pgpio->chip.set = gpio_set; + pgpio->chip.direction_input = direction_input; + pgpio->chip.direction_output = direction_output; + ret = gpiochip_add(&pgpio->chip); + if (ret) { + sonic_err("Failed to create GPIO chip\n"); + goto fail; + } + for (j = 0; j < pgpio->chip.ngpio; j++) { + mask = bit_mask(pgpio->mask, j); + strcpy(gpio_name_buffer, gpio_names[k]); + + switch (pgpio->gpio_type) { + case QSFPTYPE: + strcat(gpio_name_buffer, qsfpGpioSuffixes[j]); + if (j == numQsfpBits - 1) { + k++; + } + break; + case SFPTYPE: + strcat(gpio_name_buffer, sfpGpioSuffixes[j]); + if (j == numSfpBits - 1) { + k++; + } + break; + case PSUTYPE: + strcat(gpio_name_buffer, psuGpioSuffixes[j]); + if (j == numPsuBits - 1) { + k++; + } + break; + case MUXTYPE: + strcat(gpio_name_buffer, muxGpioSuffixes[j]); + if (j == numMuxBits - 1) { + k++; + } + break; + default: + k++; + break; + } + + ret = sonic_gpio_add(&pgpio->chip, j, gpio_name_buffer, !(pgpio->ro & mask), + !!(pgpio->active_low & mask)); + if (ret) { + goto fail; + } + } + } + + return 0; + + fail: + sonic_err("Failed to initialize GPIOs\n"); + gpio_remove(); + return ret; +} + +static int reset_get(struct gpio_chip *gc, unsigned reset_num) +{ + struct sonic_reset *pReset = container_of(gc, struct sonic_reset, chip); + u32 mask = bit_mask(pReset->mask, reset_num); + return (scd_read_register(pdev_ref, pReset->addr) & mask); +} + +static void reset_set(struct gpio_chip *gc, unsigned reset_num, int val) +{ + struct sonic_reset *pReset = container_of(gc, struct sonic_reset, chip); + u32 mask = bit_mask(pReset->mask, reset_num); + u32 offset = (val ? RESET_SET_OFFSET : RESET_CLEAR_OFFSET); + scd_write_register(pdev_ref, pReset->addr+offset, mask); +} + +static int reset_direction_input(struct gpio_chip *gc, unsigned reset_num) +{ + return 0; +} + +static int reset_direction_output(struct gpio_chip *gc, unsigned reset_num, int val) +{ + reset_set(gc, reset_num, val); + return 0; +} + +static void reset_remove(void) +{ + int i; + int j; + int k = 0; + struct sonic_reset *pReset; + u32 addr; + for (i = 0; i < reset_addrs[0]; i++) { + addr = reset_addrs[i + 1]; + pReset = &reset[i]; + if (!pReset) { + continue; + } + for (j = 0; j < pReset->chip.ngpio; j++, k++) { + sonic_gpio_remove(&pReset->chip, j, reset_names[k]); + } + if (gpiochip_remove(&pReset->chip) < 0) { + sonic_err("Failed to remove GPIO chip for reset\n"); + } + } +} + +static s32 reset_init(void) +{ + int i; + int j; + int k = 0; + struct sonic_reset *pReset; + int ret = 0; + u32 addr; + for (i = 0; i < reset_addrs[0]; i++) { + addr = reset_addrs[i + 1]; + pReset = &reset[i]; + pReset->addr = addr; + pReset->mask = reset_masks[i + 1]; + snprintf(pReset->name, sizeof(pReset->name), "pReset%d", i + 1); + pReset->chip.label = pReset->name; + pReset->chip.owner = THIS_MODULE; + pReset->chip.base = -1; + pReset->chip.ngpio = hweight_long(pReset->mask); + pReset->chip.dev = &(pdev_ref->dev); + pReset->chip.get = reset_get; + pReset->chip.set = reset_set; + pReset->chip.direction_input = reset_direction_input; + pReset->chip.direction_output = reset_direction_output; + ret = gpiochip_add(&pReset->chip); + if (ret) { + goto fail; + } + for (j = 0; j < pReset->chip.ngpio; j++, k++) { + ret = sonic_gpio_add(&pReset->chip, j, reset_names[k], true, 0); + if (ret) { + goto fail; + } + } + } + + return 0; + + fail: + reset_remove(); + return ret; +} + +static int sonic_finish_init(void) +{ + int err = 0; + + sonic_dbg("Initialize SCD SMBus adapters\n"); + err = smbus_init(); + if (err) { + sonic_err("Error initializing SCD SMBus adapter\n"); + goto fail_smbus; + } + + sonic_dbg("Initialize SCD LEDs adapters\n"); + err = led_init(); + if (err) { + sonic_err("Error initializing SCD LEDs\n"); + goto fail_led; + } + + sonic_dbg("Initialize SCD GPIOs\n"); + err = gpio_init(); + if (err) { + sonic_err("Error initializing GPIOs\n"); + goto fail_gpio; + } + + sonic_dbg("Initialize SCD resets\n"); + err = reset_init(); + if (err) { + sonic_err("Error initializing resets\n"); + goto fail_reset; + } + + initialized = 1; + sonic_info("sonic support initialization complete\n"); + return 0; + +fail_reset: + gpio_remove(); +fail_gpio: + led_remove(); +fail_led: + smbus_remove(); +fail_smbus: + return err; +} + +static ssize_t read_u32_array(u32 array[], char *buf) +{ + ssize_t len = 0; + int i; + sonic_lock(); + for (i = 1; i < array[0] + 1; i++) { + len += scnprintf(buf + len, PAGE_SIZE - len, "0x%08x\n", array[i]); + } + sonic_unlock(); + return len; +} +static ssize_t write_u32_array(u32 array[], int arraylen, const char *buf, + struct device *dev) +{ + ssize_t status = 0; + char * parse; + + sonic_lock(); + if (!initialized) { + parse = get_options(buf, arraylen, array); + } else { + dev_warn(dev, "attempt to change parameter after device initialization\n"); + } + sonic_unlock(); + return status; +} +static ssize_t read_str_array(char array[][NAME_LENGTH], u32 arraylen, char *buf) +{ + ssize_t len = 0; + int i; + sonic_lock(); + for (i = 0; i < arraylen; i++) { + len += scnprintf(buf + len, PAGE_SIZE - len, "%s\n", array[i]); + } + sonic_unlock(); + return len; +} +static ssize_t write_str_array(char array[][NAME_LENGTH], u32 *arraylen, + const char *buf, struct device *dev) +{ + ssize_t status = 0; + char *running = (char *) buf; + char *token; + int i = 0; + sonic_lock(); + if (!initialized) { + do { + token = strsep(&running, ",\n"); + if (token && token[0]) { + strncpy(array[i], token, sizeof(array[i])); + i++; + } + } while (token); + *arraylen = i; + } else { + dev_warn(dev, "attempt to change parameter after device initialization\n"); + } + sonic_unlock(); + return status; +} + +#define SCD_U32_ARRAY_ATTR(_name) \ +static ssize_t show_##_name(struct device *dev, struct device_attribute *attr, \ +char *buf) \ +{ \ + return read_u32_array(_name, buf); \ +} \ +static ssize_t store_##_name(struct device *dev, struct device_attribute *attr, \ +const char *buf, size_t count) \ +{ \ + write_u32_array(_name, ARRAY_SIZE(_name), buf, dev); \ + return count; \ +} \ +static DEVICE_ATTR(_name, S_IRUGO|S_IWUSR|S_IWGRP, show_##_name, store_##_name); + +#define SCD_STR_ARRAY_ATTR(_name) \ +static ssize_t show_##_name(struct device *dev, struct device_attribute *attr, \ +char *buf) \ +{ \ + return read_str_array(_name, num_##_name, buf); \ +} \ +static ssize_t store_##_name(struct device *dev, struct device_attribute *attr, \ +const char *buf, size_t count) \ +{ \ + write_str_array(_name, &num_##_name, buf, dev); \ + return count; \ +} \ +static DEVICE_ATTR(_name, S_IRUGO|S_IWUSR|S_IWGRP, show_##_name, store_##_name); + +#define SCD_DEVICE_ATTR(_name) \ +static ssize_t show_##_name(struct device *dev, struct device_attribute *attr, \ +char *buf) \ +{ \ + int count = 0; \ + sonic_lock(); \ + count = sprintf(buf, "%lu\n", _name); \ + sonic_unlock(); \ + return count; \ +} \ +static ssize_t store_##_name(struct device *dev, struct device_attribute *attr, \ +const char *buf, size_t count) \ +{ \ + unsigned long new_value = simple_strtoul(buf, NULL, 10); \ + sonic_lock(); \ + _name = new_value; \ + sonic_unlock(); \ + return count; \ +} \ +static DEVICE_ATTR(_name, S_IRUGO|S_IWUSR|S_IWGRP, show_##_name, store_##_name); + +SCD_U32_ARRAY_ATTR(master_addrs); + +SCD_U32_ARRAY_ATTR(led_addrs); +SCD_STR_ARRAY_ATTR(led_names); + +SCD_U32_ARRAY_ATTR(gpio_addrs); +SCD_U32_ARRAY_ATTR(gpio_masks); +SCD_U32_ARRAY_ATTR(gpio_ro); +SCD_U32_ARRAY_ATTR(gpio_type); +SCD_U32_ARRAY_ATTR(gpio_active_low); +SCD_STR_ARRAY_ATTR(gpio_names); + +SCD_U32_ARRAY_ATTR(reset_addrs); +SCD_U32_ARRAY_ATTR(reset_masks); +SCD_STR_ARRAY_ATTR(reset_names); + +static struct attribute *sonic_attrs[] = { + &dev_attr_master_addrs.attr, + &dev_attr_led_addrs.attr, + &dev_attr_led_names.attr, + &dev_attr_reset_addrs.attr, + &dev_attr_reset_masks.attr, + &dev_attr_gpio_addrs.attr, + &dev_attr_gpio_masks.attr, + &dev_attr_gpio_ro.attr, + &dev_attr_gpio_type.attr, + &dev_attr_gpio_active_low.attr, + &dev_attr_gpio_names.attr, + &dev_attr_reset_names.attr, + NULL, +}; + +static struct attribute_group sonic_attr_group = { + .attrs = sonic_attrs, + .name = "sonic_support_driver", +}; + +static int +sonic_probe(struct pci_dev *pdev) +{ + int error = 0; + + master_addrs[0] = 0; + led_addrs[0] = 0; + num_led_names = 0; + gpio_addrs[0] = 0; + gpio_masks[0] = 0; + gpio_ro[0] = 0; + gpio_type[0] = 0; + gpio_active_low[0] = 0; + num_gpio_names = 0; + reset_addrs[0] = 0; + reset_masks[0] = 0; + num_reset_names = 0; + + pdev_ref = pdev; + + error = sysfs_create_link(&pdev->dev.kobj, sonic_kobject, sonic_attr_group.name); + if (error) { + sonic_err("Failed to create the sonic sysfs entry link in scd driver\n"); + dev_err(&(pdev->dev), "sysfs_create_link() error %d\n", error); + return -ENODEV; + } + initialized = 0; + + return 0; +} + +static void +sonic_remove(struct pci_dev *pdev) +{ + smbus_remove(); + led_remove(); + gpio_remove(); + reset_remove(); + + sysfs_remove_link(&pdev->dev.kobj, sonic_attr_group.name); + + initialized = 0; + pdev_ref = NULL; + sonic_info("Removed sonic Support Driver\n"); +} + +static int +sonic_init_trigger(struct pci_dev *pdev) { + sonic_finish_init(); + initialized = 1; + return 0; +} + +static struct scd_ext_ops sonic_ops = { + .probe = sonic_probe, + .remove = sonic_remove, + .init_trigger = sonic_init_trigger, +}; + +static int __init sonic_init(void) +{ + int err = 0; + + sonic_info("Module sonic support init\n"); + + mutex_init(&sonic_mutex); + INIT_LIST_HEAD(&client_list); + sonic_kobject = kobject_get(kernel_kobj); + + err = sysfs_create_group(sonic_kobject, &sonic_attr_group); + if (err) { + sonic_err("Could not create sonic sysfs entries\n"); + goto fail_sysfs; + } + + err = scd_register_ext_ops(&sonic_ops); + if (err) { + sonic_warn("scd-sonic: scd_register_sonic_ops failed\n"); + goto fail_ops; + } + + return err; + +fail_ops: + sysfs_remove_group(sonic_kobject, &sonic_attr_group); +fail_sysfs: + mutex_destroy(&sonic_mutex); + return err; +} + +static void __exit sonic_exit(void) +{ + scd_unregister_ext_ops(); + sysfs_remove_group(sonic_kobject, &sonic_attr_group); + kobject_put(sonic_kobject); + sonic_info("Module sonic support driver removed\n"); +} + +module_init(sonic_init); +module_exit(sonic_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Arista Networks"); +MODULE_DESCRIPTION("Sonic Support Driver"); diff --git a/platform/broadcom/sonic-platform-modules-arista/src/sonic-support-driver.h b/platform/broadcom/sonic-platform-modules-arista/src/sonic-support-driver.h new file mode 100644 index 000000000000..38b7eb2024d5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/src/sonic-support-driver.h @@ -0,0 +1,19 @@ +// Copyright (c) 2016 Arista Networks, Inc. All rights reserved. +// Arista Networks, Inc. Confidential and Proprietary. + +#ifndef DRIVER_SONICSUPPORTDRIVER_H +#define DRIVER_SONICSUPPORTDRIVER_H + +#include + +#define sonic_err(fmt, ...) \ + pr_info("sonic: " fmt, ##__VA_ARGS__); +#define sonic_warn(fmt, ...) \ + pr_warn("sonic: " fmt, ##__VA_ARGS__); +#define sonic_info(fmt, ...) \ + pr_info("sonic: " fmt, ##__VA_ARGS__); +#define sonic_dbg(fmt, ...) \ + pr_debug("sonic: " fmt, ##__VA_ARGS__); + +#endif // DRIVER_SOINCSUPPORTDRIVER_H + diff --git a/platform/broadcom/sonic-platform-modules-arista/tests/all-platforms.sh b/platform/broadcom/sonic-platform-modules-arista/tests/all-platforms.sh new file mode 100755 index 000000000000..44a58592cf88 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/tests/all-platforms.sh @@ -0,0 +1,52 @@ +#!/bin/bash +# +# This script provides a simple helper to test if the initscripts for all +# platforms work. +# It runs in simulation mode and don't actually initialize anything but still +# checks most of the codepaths +# + +# enable simulation mode +extra_args="-s" +errors=false + +continue_on_failure=${CONTINUE_ON_FAILURE:-false} +python=${PYTHON:-python} + +# TODO: check if library in venv +script="arista" +[ -x /usr/bin/arista ] && script="/usr/bin/arista" +[ -x utils/arista ] && script="utils/arista" + +try_execute() { + echo "Run: $script $extra_args $@" + if ! $python $script $extra_args "$@" &>/dev/null; then + $python $script $extra_args -v "$@" + errors=true + $continue_on_failure || exit 1 + fi +} + +echo "Trying general commands" +for cmd in help syseeprom platforms; do + try_execute $cmd +done +echo + +# per platform commands +echo "Trying per platform commands" +for platform in $($script $extra_args platforms | awk '/ - / { print $2 }'); do + try_execute -p $platform setup + try_execute -p $platform setup --reset --background + try_execute -p $platform reset --toggle + try_execute -p $platform clean + try_execute -p $platform dump + echo +done + +if $errors; then + echo "Error were seen during testing" + exit 1 +fi + +echo "All done!" diff --git a/platform/broadcom/sonic-platform-modules-arista/utils/98-scd-uio.rules b/platform/broadcom/sonic-platform-modules-arista/utils/98-scd-uio.rules new file mode 100644 index 000000000000..18083d94d245 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/utils/98-scd-uio.rules @@ -0,0 +1,6 @@ +# rule to create a uio device name for the scds uio devices, +# name is "/dev/uio+$PCI_ADDRESS+$REG+$INDEX" where +# PCI_ADDRESS is the scd's pci address in DDDD:BB:SS.F format, +# REG is the irq register index on the scd (there can be more than 1 on modular) +# INDEX is the zero-based index of the uio on the scd (the bit) +KERNEL=="uio*", DRIVERS=="scd", SYMLINK+="%s{name}" diff --git a/platform/broadcom/sonic-platform-modules-arista/utils/arista b/platform/broadcom/sonic-platform-modules-arista/utils/arista new file mode 100755 index 000000000000..f4d944f0292d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/utils/arista @@ -0,0 +1,233 @@ +#!/usr/bin/env python + +from __future__ import print_function, with_statement + +import logging +import logging.handlers +import argparse +import tempfile +import time +import sys +import os + +import arista.platforms +import arista.core.utils as utils +from arista.core.platform import getPlatform, getSysEeprom, getPlatforms +from arista.core.component import Priority + +lock_file = '/var/lock/arista.lock' + +def checkRootPermissions(): + if utils.inSimulation(): + return + + if os.geteuid() != 0: + log.error('You must be root to use this feature') + sys.exit(1) + +def getHostname(): + import socket + try: + return socket.gethostname() + except: + return 'localhost' + +def setupLogging(verbose=False, logfile=None, syslog=False): + loglevel = logging.DEBUG if verbose else logging.INFO + dateFmt = '%Y-%m-%d %H:%M:%S' + + log = logging.getLogger() + log.setLevel(logging.DEBUG) + + logOut = logging.StreamHandler(sys.stdout) + logOut.setFormatter(logging.Formatter('%(levelname)s: %(message)s')) + logOut.setLevel(loglevel) + log.addHandler(logOut) + + if logfile: + logFile = logging.FileHandler(logfile) + logFile.setFormatter(logging.Formatter( + '%(asctime)s.%(msecs)03d %(levelname)s: %(message)s', datefmt=dateFmt)) + log.addHandler(logFile) + + if syslog: + logSys = logging.handlers.SysLogHandler() + # format to rfc5424 format + logSys.setFormatter( + logging.Formatter('{} arista: %(message)s'.format(getHostname()))) + logSys.setLevel(logging.WARNING) + log.addHandler(logSys) + try: + # the connection to the syslog socket happens with the first message + log.info('Attaching to syslog') + except: + log.warning('Failed open syslog') + + +def setupSimulation(): + global lock_file, log_file + + utils.simulation = True + assert utils.inSimulation() + + logging.info('Running in simulation mode') + lock_file = tempfile.mktemp(prefix='arista-', suffix='.lock') + log_file = tempfile.mktemp(prefix='arista-', suffix='.log') + +def forkForLateInitialization(platform): + try: + pid = os.fork() + except OSError: + logging.warn('fork failed, setting up background drivers normally') + else: + if pid > 0: + logging.debug('initializing slow drivers in child %d', pid) + platform.waitForIt() + os._exit(0) + +def doSetup(args, platform): + checkRootPermissions() + + if args.debug: + utils.debug = True + + with utils.FileLock(lock_file): + logging.debug('setting up critical drivers') + platform.setup(Priority.DEFAULT) + + # NOTE: This assumes that none of the resetable devices are + # initialized in background. + # This should stay true in the future. + if args.reset: + logging.debug('taking devices out of reset') + platform.resetOut() + + if args.background: + logging.debug('forking and setting up slow drivers in background') + forkForLateInitialization(platform) + else: + logging.debug('setting up slow drivers normally') + + platform.setup(Priority.BACKGROUND) + + if not args.background: + platform.waitForIt() + +def doClean(args, platform): + checkRootPermissions() + + if args.reset: + logging.debug('putting devices in reset') + platform.resetIn() + + logging.debug('cleaning up platform') + with utils.FileLock(lock_file): + platform.clean() + +def doReset(args, platform): + if args.reset_out: + platform.resetOut() + elif args.reset_in: + platform.resetIn() + elif args.reset_toggle: + platform.resetIn() + time.sleep(args.reset_delay) + platform.resetOut() + else: + logging.info('nothing to do') + +def doPlatforms(args): + print('supported platforms:') + for platform in sorted(getPlatforms()): + print(' -', platform) + +def doSysEeprom(args): + for key, value in getSysEeprom().items(): + print('%s: %s' % (key, value)) + +def todo(*args, **kwargs): + raise NotImplementedError + +def parseArgs(): + parser = argparse.ArgumentParser( + description='Arista driver initialisation framework', + formatter_class=argparse.ArgumentDefaultsHelpFormatter + ) + parser.add_argument('-p', '--platform', type=str, + help='name of the platform to load') + parser.add_argument('-l', '--logfile', type=str, + help='log file to log to') + parser.add_argument('-v', '--verbose', action='store_true', + help='increase verbosity') + parser.add_argument('-s', '--simulation', action='store_true', + help='force simulation mode') + parser.add_argument('--syslog', action='store_true', + help='also send logs to syslog' ) + + subparsers = parser.add_subparsers(dest='action') + sub = subparsers.add_parser('help', help='print a help message') + sub = subparsers.add_parser('platforms', help='show supported platforms') + sub = subparsers.add_parser('syseeprom', help='show system eeprom content') + + sub = subparsers.add_parser('dump', help='dump information on this platform') + sub = subparsers.add_parser('setup', help='setup drivers for this platform') + sub.add_argument('-r', '--reset', action='store_true', + help='put devices out of reset after init') + sub.add_argument('-d', '--debug', action='store_true', + help='enable debug features for the drivers') + sub.add_argument('-b', '--background', action='store_true', + help='initialize slow, non-critical drivers in background') + sub = subparsers.add_parser('clean', help='unload drivers for this platform') + sub.add_argument('-r', '--reset', action='store_true', + help='put devices in reset before cleanup') + sub = subparsers.add_parser('reset', help='put component in or out reset') + sub.add_argument('device', nargs='*', # TODO: use this + help='device(s) to put in or out of reset') + sub.add_argument('-t', '--toggle', action='store_true', dest='reset_toggle', + help='put components in and out of reset') + sub.add_argument('-i', '--in', action='store_true', dest='reset_in', + help='put components in reset') + sub.add_argument('-o', '--out', action='store_true', dest='reset_out', + help='put components out of reset') + sub.add_argument('-d', '--delay', type=int, default=1, dest='reset_delay', + help='time to wait between in and out in seconds') + + args = parser.parse_args() + if args.action == 'help': + parser.print_help() + sys.exit(0) + return args + +def main(): + args = parseArgs() + + setupLogging(args.verbose, args.logfile, args.syslog) + + if args.simulation: + setupSimulation() + + logging.debug(args) + + generic_commands = { + 'platforms': doPlatforms, + 'syseeprom': doSysEeprom, + } + + platform_commands = { + 'dump': lambda _, x: x.dump(), + 'setup': doSetup, + 'clean': doClean, + 'status': todo, + 'reset': doReset, + } + + if args.action in generic_commands: + generic_commands[args.action](args) + elif args.action in platform_commands: + platform_commands[args.action](args, getPlatform(args.platform)) + else: + logging.error("Command %s doesn't exists", args.command) + +if __name__ == '__main__': + main() + diff --git a/platform/broadcom/sonic-platform-modules-arista/utils/arista-gardena-watchdog b/platform/broadcom/sonic-platform-modules-arista/utils/arista-gardena-watchdog new file mode 100644 index 000000000000..3f028156859b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/utils/arista-gardena-watchdog @@ -0,0 +1,144 @@ +#!/usr/bin/env python + +# Copyright (c) 2018 Arista Networks, Inc. All rights reserved. +# Arista Networks, Inc. Confidential and Proprietary. + +from __future__ import print_function +import sys +import mmap, os +import argparse +import subprocess +from struct import pack, unpack + +WATCHDOG_REG = 0x0120 + +class MmapResource( object ): + """Resource implementation for a directly-mapped memory region.""" + def __init__( self, path ): + try: + fd = os.open( path, os.O_RDWR ) + except EnvironmentError: + print( "FAIL can not open scd memory-map resource file" ) + print( "FAIL are you running on the proper platform?" ) + sys.exit( 1 ) + + try: + size = os.fstat( fd ).st_size + except EnvironmentError: + print( "FAIL can not fstat scd memory-map resource file" ) + print( "FAIL are you running on the proper platform?" ) + sys.exit( 1 ) + + try: + self.mmap_ = mmap.mmap( fd, size, mmap.MAP_SHARED, + mmap.PROT_READ | mmap.PROT_WRITE ) + except EnvironmentError: + print( "FAIL can not map scd memory-map file" ) + print( "FAIL are you running on the proper platform?" ) + sys.exit( 1 ) + finally: + try: + # Note that closing the file descriptor has no effect on the memory map + os.close( fd ) + except EnvironmentError: + print( "FAIL failed to close scd memory-map file" ) + sys.exit( 1 ) + + def read32( self, addr ): + return unpack( 'arista: %s\n' % ( level, msg % tuple( *args ) ) ) + except: + pass + +def scdRegTest( scd, offset, val1, count ): + scd.write32( offset, val1 ) + val2 = scd.read32( offset ) + if val1 != val2: + print( "FAIL: scd write 0x%08x but read back 0x%08x in iter %d" % + ( val1, val2, count ) ) + sys.exit( 17 ) + +def scdScrRegTest( scd ): + scrOffset = 0x0130 + for i in range( 0, 3 ): + scdRegTest( scd, scrOffset, 0xdeadbeef, i ) + scdRegTest( scd, scrOffset, 0xa5a5a5a5, i ) + scdRegTest( scd, scrOffset, 0x00000000, i ) + +def arm( scd, time ): + regValue = 0 + + if time > 0: + # Set enable bit + regValue |= 1 << 31 + + # Powercycle + regValue |= 2 << 29 + + # Timeout value + regValue |= time + + print( 'Reg = {0:32b}'.format( regValue ) ) + scd.write32( WATCHDOG_REG, regValue ) + +def convertToTensMs( timeSec ): + return timeSec * 100 + +def status( scd ): + regValue = scd.read32( WATCHDOG_REG ) + enabled = bool( regValue >> 31 ) + timeout = regValue & ( ( 1 << 16 ) - 1 ) + return { + "enabled": enabled, + "timeout": timeout, + } + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument( '-o', '--arm', type=int, + help='Arm the watchdog for X seconds' ) + parser.add_argument( '--stop', action='store_true', + help='Disable the watchdog' ) + parser.add_argument( '--status', action='store_true', + help='Show watchdog status' ) + args = parser.parse_args() + + if not args.arm and not args.stop and not args.status: + print( 'No option specified' ) + sys.exit( 1 ) + + busName = "/sys/bus/pci/devices/0000:06:00.0/resource0" + subprocess.call( [ 'modprobe', 'scd' ] ) + scd = MmapResource( busName ) + + scdScrRegTest( scd ) + + if args.status: + s = status( scd ) + kv = ' '.join( '%s=%s' % ( k, v ) for k, v in s.items() ) + print( 'watchdog: %s' % kv ) + sys.exit( 0 ) + + + time = 0 + if args.arm: + klog( 'watchdog: arm for %ds' % args.arm ) + # Tens of milliseconds + time = args.arm * 100 + if time >= 65536: + print( 'Error Time value is too big' ) + sys.exit( 1 ) + else: + klog( 'watchdog: disable' ) + + arm( scd, time ) + +if __name__ == "__main__": + main() diff --git a/platform/broadcom/sonic-platform-modules-arista/utils/boot-eos b/platform/broadcom/sonic-platform-modules-arista/utils/boot-eos new file mode 100755 index 000000000000..2933446d81e2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/utils/boot-eos @@ -0,0 +1,207 @@ +#!/usr/bin/env python + +from __future__ import print_function + +import argparse +import hashlib +import logging +import os +import re +import shutil +import subprocess +import urllib +import zipfile + + +sonicMount = "/host" + +def verifySWI(swiPath): + zf = zipfile.ZipFile(swiPath, 'r') + reVer = re.compile(r'.*SWI_VERSION=.*(\d+)\.(\d+)\.(\d+).*') + for str in zf.read("version").splitlines(): + m = reVer.match(str) + if m: + if int(m.group(1)) >= 4 and int(m.group(2)) >= 19 and int(m.group(3)) >= 0: + return "" + else: + return "Unsupported version of EOS" + return "Cannot find version of EOS in SWI file" + +unsupportedPlatforms = ["x86_64-arista_7050_qx32", "x86_64-arista_7050_qx32s"] + +def verifyPlatform(): + # Check that this script run on an ext4 flash + platform = subprocess.check_output(["sonic-cfggen", "-v", "platform", "-m", + "/etc/sonic/minigraph.xml"]) + return (platform.rstrip() not in unsupportedPlatforms) + +def checkSpace(swiPath): + # for EOS we need ~(2 * ). swi already on fs, so we need additional + # bytes. + mb = (1 << 20) + swiMB = os.stat(swiPath).st_size / mb / 100 * 100 + 100 + statvfs = os.statvfs(sonicMount) + freeMB = statvfs.f_frsize * statvfs.f_bavail / mb + return swiMB - freeMB + +def getEOSFiles(ignoreFile): + res = [] + eosFile = os.path.join( sonicMount, "EOS.swi" ) + if eosFile != ignoreFile and os.path.exists(eosFile): + res.append(eosFile) + eosFile = os.path.join( sonicMount, ".boot-image.swi" ) + if eosFile != ignoreFile and os.path.exists(eosFile): + res.append(eosFile) + return res + +def deleteFiles(files): + for file in files: + os.remove(file) + +def queryYesNo(question, default="yes"): + """Ask a yes/no question via raw_input() and return their answer. + + "question" is a string that is presented to the user. + "default" is the presumed answer if the user just hits . + It must be "yes" (the default), "no" or None (meaning + an answer is required of the user). + + The "answer" return value is True for "yes" or False for "no". + """ + valid = {"yes": True, "y": True, "ye": True, + "no": False, "n": False} + if default is None: + prompt = " [y/n] " + elif default == "yes": + prompt = " [Y/n] " + elif default == "no": + prompt = " [y/N] " + else: + raise ValueError("invalid default answer: '%s'" % default) + + while True: + print(question + prompt) + choice = raw_input().lower() + if default is not None and choice == '': + return valid[default] + elif choice in valid: + return valid[choice] + else: + print("Please respond with 'yes' or 'no' " + "(or 'y' or 'n').\n") + +def main(): + parser = argparse.ArgumentParser( + description='Arista tool to boot EOS', + formatter_class=argparse.ArgumentDefaultsHelpFormatter + ) + + parser._action_groups.pop() + required = parser.add_argument_group('required arguments') + optional = parser.add_argument_group('optional arguments') + required.add_argument('--swi', "-s", help="EOS.swi file", required=True) + optional.add_argument("--md5", "-m", help="MD5 of EOS.swi file") + startupConfig = os.path.join(sonicMount, "startup-config") + startupHelp = "EOS startup-config url. Or you can just put your " \ + "startup-config file to %s" % startupConfig + if os.path.exists(startupConfig): + optional.add_argument("--config", "-c", help=startupHelp) + else: + required.add_argument("--config", "-c", help=startupHelp, required=True) + optional.add_argument("--remove", "-r", help="remove old EOS files if there " + "is not enough space for installation of new version of EOS", + action="store_true") + optional.add_argument("--no-reboot", "-n", help="config only (without reboot)", + action="store_true") + + args = parser.parse_args() + + # 1) check that we have root privileges + if os.geteuid() != 0: + exit("You need to have root privileges to run this script. Please try " + "again using 'sudo'. Exiting.") + + # 2) download EOS swi + if args.swi.startswith(('http://', 'https://', 'ftp://')): + swi_path = "/tmp/EOS.swi" + try: + urllib.urlretrieve(args.swi, swi_path) + except IOError as e: + exit("Cannot download SWI '{}'. Error: '{}'. Exiting.".format( + args.swi, e)) + else: + swi_path = args.swi + if not os.path.exists(swi_path): + exit("SWI path %s does not exists. Exiting." % swi_path) + + # 3) check MD5 of EOS swi + if args.md5: + hash_md5 = hashlib.md5() + with open(swi_path, "rb") as f: + for chunk in iter(lambda: f.read(10 * (1 << 20)), b""): + hash_md5.update(chunk) + if hash_md5.hexdigest() != args.md5: + exit("Invalid MD5 %s. Exiting." % hash_md5.hexdigest()) + + # 4) check that platform supports ext4 + if not verifyPlatform(): + exit("Unsupported platform. Exiting.") + + # 5) check that EOS supports installation on ext4 + err = verifySWI(swi_path) + if err != "": + exit("%s. Exiting." % err) + + # 6) check that we have enough free space for EOS installation + need = checkSpace(swi_path) + if need > 0: + filesToDelete = getEOSFiles(swi_path) + if len(filesToDelete): + if args.remove or queryYesNo("There is not enough space. Do you want to " + "delete old EOS files: "): + deleteFiles(filesToDelete) + need = checkSpace(swi_path) + if need > 0: + exit("Do not have enough space. We need additional ~%dMB in %s to install " + "EOS. Exiting." % (need, sonicMount)) + + # 7) download startup-config + if args.config: + try: + urllib.urlretrieve(args.config, startupConfig) + except Exception as e: + exit("Cannot download startup-config '{}'. Error: '{}'. Exiting.".format( + args.config, e)) + + # 8) move EOS swi file to /host/EOS.swi + swiName = os.path.basename(swi_path) + swiPath = os.path.join(sonicMount, swiName) + logging.info('moving %s to %s', swi_path, swiPath) + shutil.move(swi_path, swiPath) + + # 9) create backup copy of boot-config and create new boot-config to start EOS + bootConfig = os.path.join(sonicMount, "boot-config") + bootConfigBk = os.path.join(sonicMount, "boot-config.sonic") + if os.path.exists(bootConfig): + if os.path.exists(bootConfigBk): + logging.warning('creating backup of current boot-config: %s, but old ' + 'version of boot-config was found', + bootConfigBk + ".1") + os.rename(bootConfig, bootConfigBk + ".1") + else: + logging.info('creating backup of sonic boot-config: %s', bootConfigBk) + os.rename(bootConfig, bootConfigBk) + with open(bootConfig, 'w+') as f: + logging.info('creating EOS boot-config') + f.write("SWI=flash:/%s" % swiName) + + subprocess.call(['sync']) + + # 10) reboot to EOS + if not args.no_reboot: + logging.info('rebooting to EOS') + subprocess.call(['reboot']) + +if __name__ == '__main__': + main() + diff --git a/platform/broadcom/sonic-platform-modules-arista/utils/boot0 b/platform/broadcom/sonic-platform-modules-arista/utils/boot0 new file mode 100755 index 000000000000..e9053f74698a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-arista/utils/boot0 @@ -0,0 +1,122 @@ +#!/bin/sh +# Copyright (C) 2016 Arista Networks, 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 3 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, see . + +# Aboot stage 0 boot + +set -x + +kernel=boot/vmlinuz-3.16.0-5-amd64 +initrd=boot/initrd.img-3.16.0-5-amd64 +kernel_params=kernel-params + +aboot_machine="arista_unknown" + +target_path=/mnt/flash + +# expect the swi to be a non empty file +[ -s "$swipath" ] || exit 1 + +bootconfigvars="SWI SWI_COPY POST_LEVEL CONSOLESPEED PASSWORD NETDEV NETAUTO NETIP NETMASK NETGW NETDOMAIN NETDNS NETHW memtest" + +parse_environment_config() { + for n in ${bootconfigvars}; do + eval v="\$$n" + if [ "$v" ]; then + echo "$n=$v" + fi + done +} + +extract_image() { + ## Clean old directory for read-write layer + rm -rf "$target_path/rw" + + ## Unzip the image + unzip -oq "$swipath" -x boot0 -d "$target_path" +} + +write_machine_config() { + ## Detect SKU and create a hardware description file + aboot_version=$(grep ^Aboot /etc/cmdline | sed 's/^.*norcal.-//') + aboot_build_date=$(stat -c %y /bin/sysinit | sed 's/ /T/') + cat < ${target_path}/machine.conf +aboot_version=$aboot_version +aboot_vendor=arista +aboot_platform=x86_64-$aboot_machine +aboot_machine=$aboot_machine +aboot_arch=x86_64 +aboot_build_date=$aboot_build_date +EOF +} + +platform_specific() { + local platform="$(grep -Eo 'platform=[^ ]+' /etc/cmdline | cut -f2 -d=)" + local sid="$(grep -Eo 'sid=[^ ]+' /etc/cmdline | cut -f2 -d=)" + # This is temporary as the platform= and sid= parameters don't provide enough + # information to identify the SKU + # An initramfs hook or a later processing done by the initscripts will be + # required to read the system eeprom + if [ "$platform" = "raven" ]; then + aboot_machine=arista_7050_qx32 + echo "modprobe.blacklist=radeon" >>/tmp/append + fi + if [ "$platform" = "crow" ]; then + aboot_machine=arista_7050_qx32s + echo "modprobe.blacklist=radeon" >>/tmp/append + fi + if [ "$sid" = "Upperlake" ]; then + aboot_machine=arista_7060_cx32s + echo "amd_iommu=off" >> /tmp/append + fi +} + +echo "$append" >/tmp/append +parse_environment_config >>/tmp/append +cat /etc/cmdline | sed "/^\(${bootconfigvars// /\|}\|crashkernel\|loglevel\|ignore_loglevel\)\(\$\|=\)/d;/^\$/d" >>/tmp/append + +echo "rw loop=fs.squashfs loopfstype=squashfs apparmor=1 security=apparmor quiet" >>/tmp/append + +# process platform specific operations +platform_specific + +# use extra parameters from kernel-params hook if the file exists +if [ -f "$target_path/$kernel_params" ]; then + cat "$target_path/$kernel_params" >>/tmp/append +fi + +# setting root partition if not overridden by kernel-params +if ! grep -q "root=" /tmp/append; then + rootdev=$(mount | grep '/mnt/flash' | cut -f1 -d' ') + rootfstype=$(mount | grep '/mnt/flash' | cut -f5 -d' ') + echo "root=$rootdev" >>/tmp/append +fi + +# check the hash file in the image, and determine to install or just skip +GIT_REVISION=$(unzip -p "$swipath" .imagehash) +LOCAL_IMAGEHASH=$(cat $target_path/.imagehash 2>/dev/null || true) +if [ "$GIT_REVISION" != "$LOCAL_IMAGEHASH" ]; then + extract_image + write_machine_config +fi + +# chainloading using kexec +initrd_path="$target_path/$initrd" +kernel_path="$target_path/$kernel" +cmdline="$(tr '\n' ' ' &2 + exit 1 +} + +warn() { + echo "WARNING: $@" 1>&2 + EXIT_CODE=1 +} + +cmd_help () { + echo "usage: reset -s -d [-l]" + echo " -s state: set the resetting state to \"on\" or \"off\"" + echo " -d device: name for a specific device, or \"ALL\" for all devices" + echo " -l: list devices that support reset" +} + +error_and_help() { + echo "ERROR: $@" 1>&2 + cmd_help + exit 1 +} + +get_scd_address() { + SCD_ADDRESS=`ls /sys/module/scd/drivers/pci\:scd | grep -E '[0-9]{4}:[0-9]{2}:[0-9]{2}'` + debug "$SCD_ADDRESS" + [ -z "$SCD_ADDRESS" ] && fatal 'Scd address not not exist.' + local scd_num=`ls -l /sys/module/scd/drivers/pci\:scd | wc -l` + debug $scd_num + if [ $scd_num -lt 1 ]; then + fatal "Scd address not found." + elif [ $scd_num -gt 1 ]; then + fatal "More than 1 SCD, not supported." + fi +} + +#obtain device list +get_devices() { + #scd address + PREFIX=${PREFIX}${SCD_ADDRESS} + #update device list + for device_path in `echo ${PREFIX}/*_reset`; do + local device_name=`basename $device_path | rev | cut -f2- -d '_' | rev` + DEVICES+=("$device_name") + done +} + +write_file() { + if [ ! -f $1 ]; then + warn "Sys file not found: $1." + return 1 + fi + echo $2 > $1 + if [ $? != 0 ]; then + warn "Sys file write error: $1." + return 1 + fi + return 0 +} + +READ_BUFFER="Unknown" +read_file() { + READ_BUFFER="Unknown" + local result=`cat $1 2>/dev/null` + if [ $? != 0 ]; then + warn "Sys file read error: $1." + return 1 + else + READ_BUFFER="$result" + return 0 + fi +} + +#enter reset for 1 device +set_reset () { + local device="$1" + local state="$2" + debug "$device $state" + write_file "$PREFIX/${device}_reset/direction" out || return 1 + read_file "$PREFIX/${device}_reset/active_low" || return 1 + local active_low="$READ_BUFFER" + if [[ ( "$state" == "on" && "$active_low" == "0" ) || \ + ( "$state" == "off" && "$active_low" == "1" ) ]]; then + data='1' + else + data='0' + fi + local value_file="$PREFIX/${device}_reset/value" + write_file "$value_file" "$data" || return 1 +} + + +list_all_devices() { + printf '%-15s %-10s %-10s %-10s\n' 'name' 'direction' 'value' 'active_low' + for dev in "${DEVICES[@]}"; do + read_file "$PREFIX/${dev}_reset/direction" + local direction="$READ_BUFFER" + read_file "$PREFIX/${dev}_reset/value" + local value="$READ_BUFFER" + read_file "$PREFIX/${dev}_reset/active_low" + local active_low="$READ_BUFFER" + printf '%-15s %-10s %-10s %-10s\n' "$dev" "$direction" "$value" "$active_low" + done +} + +set_reset_all() { + for dev in "${DEVICES[@]}"; do + set_reset "$dev" "$1" || warn "Failed to set device $dev." + done +} + +########## main start ########### +if [ $EUID -ne 0 ]; then + echo "Please run as root." + exit 1 +fi + +STATE="" +DEVICE="" +LIST=false + +while getopts ":s:d:hl" opt; do + case $opt in + s) + [ "$STATE" ] && error_and_help "Duplicate: $opt." + STATE="$OPTARG" + ;; + d) + [ "$DEVICE" ] && error_and_help "Duplicate: $opt." + DEVICE="$OPTARG" + ;; + l) + LIST=true + break + ;; + h) + cmd_help + exit 0 + ;; + *) + error_and_help "Unknown argument: $opt." + ;; + esac +done + +get_scd_address +get_devices + +if [ $LIST == true ]; then + list_all_devices + exit $EXIT_CODE +fi + +[ -z "$DEVICE" ] && error_and_help 'Device not specified.' +[ -z "$STATE" ] && error_and_help 'State not specified.' + +if [ "$STATE" == "on" ] || [ "$STATE" == "off" ]; then + if [ "$DEVICE" == "ALL" ]; then + set_reset_all "$STATE" + else + set_reset "$DEVICE" "$STATE" || warn "Failed to set device $DEVICE." + fi +else + error_and_help "Illegal argument -s." +fi + +exit $EXIT_CODE +########## main end ########### diff --git a/platform/broadcom/sonic-platform-modules-cel b/platform/broadcom/sonic-platform-modules-cel deleted file mode 160000 index 4c8bcd1584e5..000000000000 --- a/platform/broadcom/sonic-platform-modules-cel +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 4c8bcd1584e5afb05476a67e0ed82ca02fba6da0 diff --git a/platform/broadcom/sonic-platform-modules-cel/.gitignore b/platform/broadcom/sonic-platform-modules-cel/.gitignore new file mode 100644 index 000000000000..f805e810e5c6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/.gitignore @@ -0,0 +1,33 @@ +# Object files +*.o +*.ko +*.obj +*.elf + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su diff --git a/platform/broadcom/sonic-platform-modules-cel/LICENSE b/platform/broadcom/sonic-platform-modules-cel/LICENSE new file mode 100644 index 000000000000..2386a3920c07 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/LICENSE @@ -0,0 +1,15 @@ +Copyright (C) 2017 Celestica, 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/broadcom/sonic-platform-modules-cel/README.md b/platform/broadcom/sonic-platform-modules-cel/README.md new file mode 100644 index 000000000000..b09a36b51d95 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/README.md @@ -0,0 +1 @@ +platform drivers for Celestica DX010 for the SONiC project diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/changelog b/platform/broadcom/sonic-platform-modules-cel/debian/changelog new file mode 100644 index 000000000000..3b194229773c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/debian/changelog @@ -0,0 +1,44 @@ +sonic-cel-platform-modules (0.7) unstable; urgency=low + + * Add dx010 plaform gpio sysfs exported when module load. + + -- Pradchaya Phucharoen Wed, 21 Jun 2018 13:29:05 +0700 + +sonic-cel-platform-modules (0.6) unstable; urgency=low + + * Remove unused port-mode switch script. This should be done by hwsku config script. + * Add script to turn off QSFP low power mode when boot up. + + -- Pradchaya Phucharoen Wed, 26 July 2017 10:43:00 +0700 + +sonic-cel-platform-modules (0.5) unstable; urgency=low + + * Add port-mode switch script to support 100G 50G 10G_50G qsfp modes. + * Fix garbage data when using sfputil to read QSFP-transceiver's eeprom. + * Fix incorrect endian in eeprom read word data. + + -- Pradchaya Phucharoen Tue, 18 July 2017 11:30:00 +0700 + +sonic-cel-platform-modules (0.4) unstable; urgency=low + + * Add support for DX010's fancontrol, automatic run-up and FIX bug lpmod + + -- Pariwat Leamsumran Thu, 14 June 2017 16:25:00 +0700 + +sonic-cel-platform-modules (0.3) unstable; urgency=low + + * Add support for DX010's DPS800 + + -- Abhisit Sangjan Thu, 29 May 2017 19:23:00 +0700 + +sonic-cel-platform-modules (0.2) unstable; urgency=low + + * Add support for DX010's LM75B, Watchdog and EMC2305 + + -- Abhisit Sangjan Thu, 25 May 2017 15:26:00 +0700 + +sonic-cel-platform-modules (0.1) unstable; urgency=low + + * Initial release + + -- Abhisit Sangjan Mon, 2 May 2017 14:47:00 +0700 diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/compat b/platform/broadcom/sonic-platform-modules-cel/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/debian/compat @@ -0,0 +1 @@ +9 diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/control b/platform/broadcom/sonic-platform-modules-cel/debian/control new file mode 100644 index 000000000000..72bcd54ee62c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/debian/control @@ -0,0 +1,12 @@ +Source: sonic-cel-platform-modules +Section: main +Priority: extra +Maintainer: Abhisit Sangjan +Build-Depends: debhelper (>= 8.0.0), bzip2 +Standards-Version: 3.9.3 + +Package: platform-modules-dx010 +Architecture: amd64 +Depends: linux-image-3.16.0-5-amd64 +Description: kernel modules for platform devices such as fan, led, sfp + diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init new file mode 100644 index 000000000000..34ea6ddc807d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init @@ -0,0 +1,147 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board +# Required-Start: $portmap +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup DX010 board. +### END INIT INFO + +function export_gpio { +label=$2 +gpio_num=$1 +gpio_base=`( cat /sys/class/gpio/gpiochip*/base | head -1 ) 2>/dev/null` +gpio_label=`( cat /sys/class/gpio/gpiochip*/label | head -1 ) 2>/dev/null` +if [[ "X$gpio_base" == "X" ]] || +( [[ "X$label" != "X" ]] && [[ "$label" != "$gpio_label" ]] ); then + echo "Platform driver error: No gpiochip found!" + exit 1; +fi +ionum=$((gpio_base+gpio_num)) +echo $ionum > /sys/class/gpio/export +if [ $? -ne 0 ]; then + echo "Platform driver error: Cannot export gpio$ionum!" + exit 1; +fi +} + +case "$1" in +start) + echo -n "Setting up board... " + + depmod -a + modprobe i2c-dev + modprobe i2c-mux-pca954x + modprobe dx010_wdt + modprobe leds-dx010 + + found=0 + for devnum in 0 1; do + devname=`cat /sys/bus/i2c/devices/i2c-${devnum}/name` + # iSMT adapter can be at either dffd0000 or dfff0000 + if [[ $devname == 'SMBus iSMT adapter at '* ]]; then + found=1 + break + fi + done + + [ $found -eq 0 ] && echo "cannot find iSMT" && exit 1 + + i2cset -y ${devnum} 0x70 0x10 0x00 0x01 i + + # Attach PCA9541 Ox70 Master Selector + chmod 755 /sys/bus/i2c/devices/i2c-${devnum}/new_device + echo pca9541 0x70 > /sys/bus/i2c/devices/i2c-${devnum}/new_device + sleep 1 + + # Attach PCA9548 0x71 Channel Extender for Main Board + echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-${devnum}/new_device + sleep 1 + + # Attach PCA9548 0x73 Channel Extender for CPU Board + echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-${devnum}/new_device + sleep 1 + + # Attach PCA9548 0x77 Channel Extender for Fan's EEPROMs + echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-${devnum}/new_device + sleep 1 + + # Attach syseeprom + echo 24lc64t 0x50 > /sys/bus/i2c/devices/i2c-12/new_device + + # Attach temperature sensors + echo dx010_lm75b 0x48 > /sys/bus/i2c/devices/i2c-5/new_device + echo dx010_lm75b 0x49 > /sys/bus/i2c/devices/i2c-6/new_device + echo dx010_lm75b 0x4a > /sys/bus/i2c/devices/i2c-7/new_device + echo dx010_lm75b 0x48 > /sys/bus/i2c/devices/i2c-14/new_device + echo dx010_lm75b 0x4e > /sys/bus/i2c/devices/i2c-15/new_device + + # Attach fans + echo emc2305 0x2e > /sys/bus/i2c/devices/i2c-13/new_device + echo emc2305 0x4d > /sys/bus/i2c/devices/i2c-13/new_device + + # Attach PSUs + echo dps460 0x5a > /sys/bus/i2c/devices/i2c-10/new_device + echo dps460 0x5b > /sys/bus/i2c/devices/i2c-11/new_device + + # Attach PCA9506 GPIO expander for 40 pins + echo pca9505 0x20 > /sys/bus/i2c/devices/i2c-17/new_device + + modprobe dx010_cpld + sleep 2 + + # Export platform gpio sysfs + export_gpio 10 # Fan 1 present + export_gpio 11 # Fan 2 present + export_gpio 12 # Fan 3 present + export_gpio 13 # Fan 4 present + export_gpio 14 # Fan 5 present + + export_gpio 22 # PSU L PWOK + export_gpio 25 # PSU R PWOK + export_gpio 27 # PSU L ABS + export_gpio 28 # PSU R ABS + + export_gpio 29 # Fan 1 LED: Red + export_gpio 30 # Fan 1 LED: Yellow + export_gpio 31 # Fan 2 LED: Red + export_gpio 32 # Fan 2 LED: Yellow + export_gpio 33 # Fan 3 LED: Red + export_gpio 34 # Fan 3 LED: Yellow + export_gpio 35 # Fan 4 LED: Red + export_gpio 36 # Fan 4 LED: Yellow + export_gpio 37 # Fan 5 LED: Red + export_gpio 38 # Fan 5 LED: Yellow + + # Turn off/down lpmod by defult (0 - Normal, 1 - Low Pow) + echo 0x00000000 > /sys/devices/platform/dx010_cpld/qsfp_lpmode + + # Attach 32 instances of EEPROM driver QSFP ports + for ((n=26;n<=58;n++)); + do + echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-$n/new_device + sleep 0.1 + done + + echo "done." + ;; + +stop) + echo "done." + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/platform-modules-dx010.init {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install new file mode 100644 index 000000000000..329b584dc427 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install @@ -0,0 +1,2 @@ +dx010/scripts/dx010_check_qsfp.sh usr/local/bin +dx010/cfg/dx010-modules.conf etc/modules-load.d diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/rules b/platform/broadcom/sonic-platform-modules-cel/debian/rules new file mode 100644 index 000000000000..fa9bb741d5a6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/debian/rules @@ -0,0 +1,33 @@ +#!/usr/bin/make -f + +export INSTALL_MOD_DIR:=extra + +KVERSION ?= $(shell uname -r) +KERNEL_SRC := /lib/modules/$(KVERSION) +MOD_SRC_DIR:= $(shell pwd) +MODULE_DIRS:= dx010 + +%: + dh $@ + +override_dh_auto_build: + (for mod in $(MODULE_DIRS); do \ + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ + done) + +override_dh_auto_install: + (for mod in $(MODULE_DIRS); do \ + dh_installdirs -pplatform-modules-$${mod} \ + $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp $(MOD_SRC_DIR)/$${mod}/modules/*.ko \ + debian/platform-modules-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + done) + +override_dh_usrlocal: + +override_dh_clean: + dh_clean + (for mod in $(MODULE_DIRS); do \ + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules clean; \ + done) + diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/cfg/dx010-modules.conf b/platform/broadcom/sonic-platform-modules-cel/dx010/cfg/dx010-modules.conf new file mode 100644 index 000000000000..66f002a5fc94 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/cfg/dx010-modules.conf @@ -0,0 +1,15 @@ +# /etc/modules: kernel modules to load at boot time. +# +# This file contains the names of kernel modules that should be loaded +# at boot time, one per line. Lines beginning with "#" are ignored. + +i2c-i801 +i2c-isch +i2c-ismt +i2c-dev +i2c-mux +i2c-smbus + +i2c-mux-gpio +i2c-mux-pca954x + diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/Makefile b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/Makefile new file mode 100644 index 000000000000..c4109ec772ea --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/Makefile @@ -0,0 +1 @@ +obj-m := dx010_cpld.o mc24lc64t.o emc2305.o dx010_wdt.o leds-dx010.o lm75.o diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010_cpld.c b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010_cpld.c new file mode 100644 index 000000000000..ab0692faab78 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010_cpld.c @@ -0,0 +1,506 @@ +/* + * dx010_cpld.c - driver for SeaStone's CPLD + * + * Copyright (C) 2017 Celestica Corp. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "dx010_cpld" + +#define LPMOD0108 0x252 +#define LPMOD0910 0x253 +#define LPMOD1118 0x2d2 +#define LPMOD1921 0x2d3 +#define LPMOD2229 0x3d2 +#define LPMOD3032 0x3d3 + +#define ABS0108 0x254 +#define ABS0910 0x255 +#define ABS1118 0x2d4 +#define ABS1921 0x2d5 +#define ABS2229 0x3d4 +#define ABS3032 0x3d5 + +#define INT0108 0x256 +#define INT0910 0x257 +#define INT1118 0x2d6 +#define INT1921 0x2d7 +#define INT2229 0x3d6 +#define INT3032 0x3d7 + +#define LENGTH_PORT_CPLD 34 +#define PORT_BANK1_START 1 +#define PORT_BANK1_END 10 +#define PORT_BANK2_START 11 +#define PORT_BANK2_END 21 +#define PORT_BANK3_START 22 +#define PORT_BANK3_END 32 +#define PORT_SFPP1 33 +#define PORT_SFPP2 34 + +#define PORT_ID_BANK1 0x210 +#define PORT_ID_BANK2 0x290 +#define PORT_ID_BANK3 0x390 + +#define OPCODE_ID_BANK1 0x211 +#define OPCODE_ID_BANK2 0x291 +#define OPCODE_ID_BANK3 0x391 + +#define DEVADDR_ID_BANK1 0x212 +#define DEVADDR_ID_BANK2 0x292 +#define DEVADDR_ID_BANK3 0x392 + +#define CMDBYT_ID_BANK1 0x213 +#define CMDBYT_ID_BANK2 0x293 +#define CMDBYT_ID_BANK3 0x393 + +#define WRITE_ID_BANK1 0x220 +#define WRITE_ID_BANK2 0x2A0 +#define WRITE_ID_BANK3 0x3A0 + +#define READ_ID_BANK1 0x230 +#define READ_ID_BANK2 0x2B0 +#define READ_ID_BANK3 0x3B0 + +#define SSRR_ID_BANK1 0x216 +#define SSRR_ID_BANK2 0x296 +#define SSRR_ID_BANK3 0x396 + +#define HST_CNTL2_QUICK 0x00 +#define HST_CNTL2_BYTE 0x01 +#define HST_CNTL2_BYTE_DATA 0x02 +#define HST_CNTL2_WORD_DATA 0x03 +#define HST_CNTL2_BLOCK 0x05 + +struct dx010_i2c_data { + int portid; +}; + +struct dx010_cpld_data { + struct i2c_adapter *i2c_adapter[LENGTH_PORT_CPLD]; + struct mutex cpld_lock; +}; + +struct dx010_cpld_data *cpld_data; + +static ssize_t get_lpmode(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned long lpmod = 0; + + mutex_lock(&cpld_data->cpld_lock); + + lpmod = + (inb(LPMOD3032) & 0x07) << (24+5) | + inb(LPMOD2229) << (24-3) | + (inb(LPMOD1921) & 0x07) << (16 + 2) | + inb(LPMOD1118) << (16-6) | + (inb(LPMOD0910) & 0x03 ) << 8 | + inb(LPMOD0108); + + mutex_unlock(&cpld_data->cpld_lock); + + return sprintf(buf,"0x%8.8lx\n", lpmod & 0xffffffff); +} + +static ssize_t set_lpmode(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + unsigned long lpmod; + int err; + + mutex_lock(&cpld_data->cpld_lock); + + err = kstrtoul(buf, 16, &lpmod); + if (err) + { + mutex_unlock(&cpld_data->cpld_lock); + return err; + } + + outb( (lpmod >> 0) & 0xFF, LPMOD0108); + outb( (lpmod >> 8) & 0x03, LPMOD0910); + outb( (lpmod >> 10) & 0xFF, LPMOD1118); + outb( (lpmod >> 18) & 0x07, LPMOD1921); + outb( (lpmod >> 21) & 0xFF, LPMOD2229); + outb( (lpmod >> 29) & 0x07, LPMOD3032); + + mutex_unlock(&cpld_data->cpld_lock); + + return count; +} + +static ssize_t get_modprs(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned long present; + + mutex_lock(&cpld_data->cpld_lock); + + present = + (inb(ABS3032) & 0x07) << (24+5) | + inb(ABS2229) << (24-3) | + (inb(ABS1921) & 0x07) << (16 + 2) | + inb(ABS1118) << (16-6) | + (inb(ABS0910) & 0x03) << 8 | + inb(ABS0108); + + mutex_unlock(&cpld_data->cpld_lock); + + return sprintf(buf,"0x%8.8lx\n", present & 0xffffffff); +} + +static ssize_t get_modirq(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned long irq; + + mutex_lock(&cpld_data->cpld_lock); + + irq = + (inb(INT3032) & 0x07) << (24+5) | + inb(INT2229) << (24-3) | + (inb(INT1921) & 0x07) << (16 + 2) | + inb(INT1118) << (16-6) | + (inb(INT0910) & 0x03) << 8 | + inb(INT0108); + + mutex_unlock(&cpld_data->cpld_lock); + + return sprintf(buf,"0x%8.8lx\n", irq & 0xffffffff); +} + +static DEVICE_ATTR(qsfp_lpmode, S_IRUGO | S_IWUSR, get_lpmode, set_lpmode); +static DEVICE_ATTR(qsfp_modprs, S_IRUGO, get_modprs, NULL); +static DEVICE_ATTR(qsfp_modirq, S_IRUGO, get_modirq, NULL); + +static struct attribute *dx010_lpc_attrs[] = { + &dev_attr_qsfp_lpmode.attr, + &dev_attr_qsfp_modprs.attr, + &dev_attr_qsfp_modirq.attr, + NULL, +}; + +static struct attribute_group dx010_lpc_attr_grp = { + .attrs = dx010_lpc_attrs, +}; + +static struct resource cel_dx010_lpc_resources[] = { + { + .flags = IORESOURCE_IO, + }, +}; + +static void cel_dx010_lpc_dev_release( struct device * dev) +{ + return; +} + +static struct platform_device cel_dx010_lpc_dev = { + .name = DRIVER_NAME, + .id = -1, + .num_resources = ARRAY_SIZE(cel_dx010_lpc_resources), + .resource = cel_dx010_lpc_resources, + .dev = { + .release = cel_dx010_lpc_dev_release, + } +}; + + +/** + * Read eeprom of QSFP device. + * @param a i2c adapter. + * @param addr address to read. + * @param new_data QSFP port number struct. + * @param cmd i2c command. + * @return 0 if not error, else the error code. + */ +static int i2c_read_eeprom(struct i2c_adapter *a, u16 addr, + struct dx010_i2c_data *new_data, u8 cmd, union i2c_smbus_data *data){ + + u32 reg; + int ioBase=0; + char byte; + short temp; + short portid, opcode, devaddr, cmdbyte0, ssrr, writedata, readdata; + __u16 word_data; + char read_byte; + int error = -EIO; + + mutex_lock(&cpld_data->cpld_lock); + + if (((new_data->portid >= PORT_BANK1_START) + && (new_data->portid <= PORT_BANK1_END)) + || (new_data->portid == PORT_SFPP1) + || (new_data->portid == PORT_SFPP2)) + { + portid = PORT_ID_BANK1; + opcode = OPCODE_ID_BANK1; + devaddr = DEVADDR_ID_BANK1; + cmdbyte0 = CMDBYT_ID_BANK1; + ssrr = SSRR_ID_BANK1; + writedata = WRITE_ID_BANK1; + readdata = READ_ID_BANK1; + }else if ((new_data->portid >= PORT_BANK2_START) && (new_data->portid <= PORT_BANK2_END)){ + portid = PORT_ID_BANK2; + opcode = OPCODE_ID_BANK2; + devaddr = DEVADDR_ID_BANK2; + cmdbyte0 = CMDBYT_ID_BANK2; + ssrr = SSRR_ID_BANK2; + writedata = WRITE_ID_BANK2; + readdata = READ_ID_BANK2; + }else if ((new_data->portid >= PORT_BANK3_START) && (new_data->portid <= PORT_BANK3_END)){ + portid = PORT_ID_BANK3; + opcode = OPCODE_ID_BANK3; + devaddr = DEVADDR_ID_BANK3; + cmdbyte0 = CMDBYT_ID_BANK3; + ssrr = SSRR_ID_BANK3; + writedata = WRITE_ID_BANK3; + readdata = READ_ID_BANK3; + }else{ + /* Invalid parameter! */ + error = -EINVAL; + goto exit; + } + + while ((inb(ioBase + ssrr) & 0x40)); + if ((inb(ioBase + ssrr) & 0x80) == 0x80) { + error = -EIO; + /* Read error reset the port */ + outb(0x00, ioBase + ssrr); + udelay(3000); + outb(0x01, ioBase + ssrr); + goto exit; + } + + byte = 0x40 +new_data->portid; + reg = cmd; + outb(byte, ioBase + portid); + outb(reg,ioBase + cmdbyte0); + byte = 33; + outb(byte, ioBase + opcode); + addr = addr << 1; + addr |= 0x01; + outb(addr, ioBase + devaddr); + while ((inb(ioBase + ssrr) & 0x40)) + { + udelay(100); + } + + if ((inb(ioBase + ssrr) & 0x80) == 0x80) { + /* Read error reset the port */ + error = -EIO; + outb(0x00, ioBase + ssrr); + udelay(3000); + outb(0x01, ioBase + ssrr); + goto exit; + } + + temp = ioBase + readdata; + word_data = inb(temp); + word_data |= (inb(++temp) << 8); + + mutex_unlock(&cpld_data->cpld_lock); + data->word = word_data; + return 0; + +exit: + mutex_unlock(&cpld_data->cpld_lock); + return error; +} + +static int dx010_i2c_access(struct i2c_adapter *a, u16 addr, + unsigned short flags, char rw, u8 cmd, + int size, union i2c_smbus_data *data) +{ + + int error = 0; + + struct dx010_i2c_data *new_data; + + /* Write the command register */ + new_data = i2c_get_adapdata(a); + + /* Map the size to what the chip understands */ + switch (size) { + case I2C_SMBUS_QUICK: + size = HST_CNTL2_QUICK; + break; + case I2C_SMBUS_BYTE: + size = HST_CNTL2_BYTE; + break; + case I2C_SMBUS_BYTE_DATA: + size = HST_CNTL2_BYTE_DATA; + break; + case I2C_SMBUS_WORD_DATA: + size = HST_CNTL2_WORD_DATA; + break; + case I2C_SMBUS_BLOCK_DATA: + size = HST_CNTL2_BLOCK; + break; + default: + dev_warn(&a->dev, "Unsupported transaction %d\n", size); + error = -EOPNOTSUPP; + goto Done; + } + + switch (size) { + case HST_CNTL2_BYTE: /* Result put in SMBHSTDAT0 */ + break; + case HST_CNTL2_BYTE_DATA: + break; + case HST_CNTL2_WORD_DATA: + if( 0 == i2c_read_eeprom(a,addr,new_data,cmd,data)){ + error = 0; + }else{ + error = -EIO; + } + break; + } + +Done: + return error; +} + +static u32 dx010_i2c_func(struct i2c_adapter *a) +{ + return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | + I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_BLOCK_DATA; +} + +static const struct i2c_algorithm dx010_i2c_algorithm = { + .smbus_xfer = dx010_i2c_access, + .functionality = dx010_i2c_func, +}; + +static struct i2c_adapter * cel_dx010_i2c_init(struct platform_device *pdev, int portid) +{ + int error; + + struct i2c_adapter *new_adapter; + struct dx010_i2c_data *new_data; + + new_adapter = kzalloc(sizeof(*new_adapter), GFP_KERNEL); + if (!new_adapter) + return NULL; + + new_adapter->dev.parent = &pdev->dev; + new_adapter->owner = THIS_MODULE; + new_adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + new_adapter->algo = &dx010_i2c_algorithm; + + snprintf(new_adapter->name, sizeof(new_adapter->name), + "SMBus dx010 i2c Adapter portid@%04x", portid); + + new_data = kzalloc(sizeof(*new_data), GFP_KERNEL); + if (!new_data) + return NULL; + + new_data->portid = portid; + + i2c_set_adapdata(new_adapter,new_data); + + error = i2c_add_adapter(new_adapter); + if(error) + return NULL; + + return new_adapter; +}; + +static int cel_dx010_lpc_drv_probe(struct platform_device *pdev) +{ + struct resource *res; + int ret =0; + int portid_count; + + cpld_data = devm_kzalloc(&pdev->dev, sizeof(struct dx010_cpld_data), + GFP_KERNEL); + if (!cpld_data) + return -ENOMEM; + + mutex_init(&cpld_data->cpld_lock); + + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + if (unlikely(!res)) { + printk(KERN_ERR " Specified Resource Not Available...\n"); + return -1; + } + + ret = sysfs_create_group(&pdev->dev.kobj, &dx010_lpc_attr_grp); + if (ret) { + printk(KERN_ERR "Cannot create sysfs\n"); + } + + for(portid_count=1 ; portid_count<=LENGTH_PORT_CPLD ; portid_count++) + cpld_data->i2c_adapter[portid_count-1] = + cel_dx010_i2c_init(pdev, portid_count); + + return 0; +} + +static int cel_dx010_lpc_drv_remove(struct platform_device *pdev) +{ + int portid_count; + struct dx010_i2c_data *new_data; + + sysfs_remove_group(&pdev->dev.kobj, &dx010_lpc_attr_grp); + + for (portid_count=1 ; portid_count<=LENGTH_PORT_CPLD ; portid_count++) + i2c_del_adapter(cpld_data->i2c_adapter[portid_count-1]); + + return 0; +} + +static struct platform_driver cel_dx010_lpc_drv = { + .probe = cel_dx010_lpc_drv_probe, + .remove = __exit_p(cel_dx010_lpc_drv_remove), + .driver = { + .name = DRIVER_NAME, + }, +}; + +int cel_dx010_lpc_init(void) +{ + platform_device_register(&cel_dx010_lpc_dev); + platform_driver_register(&cel_dx010_lpc_drv); + + return 0; +} + +void cel_dx010_lpc_exit(void) +{ + platform_driver_unregister(&cel_dx010_lpc_drv); + platform_device_unregister(&cel_dx010_lpc_dev); +} + +module_init(cel_dx010_lpc_init); +module_exit(cel_dx010_lpc_exit); + +MODULE_AUTHOR("Abhisit Sangjan "); +MODULE_AUTHOR("Pariwat Leamsumran "); +MODULE_DESCRIPTION("Celestica SeaStone DX010 LPC Driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010_wdt.c b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010_wdt.c new file mode 100644 index 000000000000..a386c065051a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010_wdt.c @@ -0,0 +1,215 @@ +/* + * Watchdog driver for the Seastone DX010 + * + * Copyright (C) 2017 Celestica Corp. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define DRIVER_NAME "dx010_wdt" + +#define RESET_CTRL 0x102 +#define WDT_MASK 0x04 +#define WDI_GPIO_DIR 0x504 +#define WDI_GPIO 0x508 + +static bool nowayout = WATCHDOG_NOWAYOUT; + +struct dx010_wdt_drvdata { + struct watchdog_device wdt; + struct mutex lock; +}; + +static struct resource dx010_wdt_resources[] = { + { + .flags = IORESOURCE_IO, + }, +}; + +static void dx010_wdt_dev_release( struct device * dev) +{ + return; +} + +static struct platform_device dx010_wdt_dev = { + .name = DRIVER_NAME, + .id = -1, + .num_resources = ARRAY_SIZE(dx010_wdt_resources), + .resource = dx010_wdt_resources, + .dev = { + .release = dx010_wdt_dev_release, + } +}; + +static int dx010_wdt_start(struct watchdog_device *wdt_dev) +{ + struct dx010_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev); + unsigned char reset_ctrl = 0x00; + unsigned long gpio ,dir; + + mutex_lock(&drvdata->lock); + + gpio = inl(WDI_GPIO); + gpio |= 1 << 15; + outl(gpio, WDI_GPIO); + + outl((inl(WDI_GPIO_DIR) & (~(1 << 15))), WDI_GPIO_DIR); + + reset_ctrl = inb(RESET_CTRL); + + gpio = inl(WDI_GPIO); + gpio &= ~(1 << 15); + outl_p( gpio, WDI_GPIO ); + + mdelay(10); + + gpio = inl(WDI_GPIO); + gpio |= (1 << 15); + outl_p( gpio, WDI_GPIO ); + + reset_ctrl |= WDT_MASK; + outb(reset_ctrl, RESET_CTRL); + + mutex_unlock(&drvdata->lock); + + return 0; +} + +static int dx010_wdt_stop(struct watchdog_device *wdt_dev) +{ + struct dx010_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev); + unsigned long reset_ctrl; + + mutex_lock(&drvdata->lock); + + reset_ctrl = inb(RESET_CTRL); + reset_ctrl &= ~WDT_MASK; + outb(reset_ctrl, RESET_CTRL); + + mutex_unlock(&drvdata->lock); + + return 0; +} + +static int dx010_wdt_ping(struct watchdog_device *wdt_dev) +{ + struct dx010_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev); + unsigned long gpio; + + mutex_lock(&drvdata->lock); + + gpio = inl(WDI_GPIO); + gpio &= ~(1 << 15); + outl_p( gpio, WDI_GPIO ); + + mdelay(10); + + gpio = inl(WDI_GPIO); + gpio |= (1 << 15); + outl_p( gpio, WDI_GPIO ); + + mutex_unlock(&drvdata->lock); + + return 0; +} + +static const struct watchdog_info dx010_wdt_info = { + .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, + .identity = "DX010 Watchdog", +}; + +static const struct watchdog_ops dx010_wdt_ops = { + .owner = THIS_MODULE, + .start = dx010_wdt_start, + .stop = dx010_wdt_stop, + .ping = dx010_wdt_ping, +}; + +static int dx010_wdt_probe(struct platform_device *pdev) +{ + struct dx010_wdt_drvdata *drvdata; + int ret; + + drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), + GFP_KERNEL); + if (!drvdata) { + ret = -ENOMEM; + goto err; + } + + mutex_init(&drvdata->lock); + + drvdata->wdt.info = &dx010_wdt_info; + drvdata->wdt.ops = &dx010_wdt_ops; + + watchdog_set_nowayout(&drvdata->wdt, nowayout); + watchdog_set_drvdata(&drvdata->wdt, drvdata); + + ret = watchdog_register_device(&drvdata->wdt); + if (ret != 0) { + dev_err(&pdev->dev, "watchdog_register_device() failed: %d\n", + ret); + goto err; + } + + platform_set_drvdata(pdev, drvdata); + +err: + return ret; +} + +static int dx010_wdt_remove(struct platform_device *pdev) +{ + struct dx010_wdt_drvdata *drvdata = platform_get_drvdata(pdev); + + watchdog_unregister_device(&drvdata->wdt); + + return 0; +} + +static struct platform_driver dx010_wdt_drv = { + .probe = dx010_wdt_probe, + .remove = dx010_wdt_remove, + .driver = { + .name = DRIVER_NAME, + }, +}; + +int dx010_wdt_init(void) +{ + platform_device_register(&dx010_wdt_dev); + platform_driver_register(&dx010_wdt_drv); + + return 0; +} + +void dx010_wdt_exit(void) +{ + platform_driver_unregister(&dx010_wdt_drv); + platform_device_unregister(&dx010_wdt_dev); +} + +module_init(dx010_wdt_init); +module_exit(dx010_wdt_exit); + +MODULE_AUTHOR("Abhisit Sangjan "); +MODULE_AUTHOR("Pariwat Leamsumran "); +MODULE_DESCRIPTION("Seastone DX010 Watchdog"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:dx010-watchdog"); diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/emc2305.c b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/emc2305.c new file mode 100644 index 000000000000..b406a29fd9be --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/emc2305.c @@ -0,0 +1,886 @@ +/* + * emc2305.c - hwmon driver for SMSC EMC2305 fan controller + * (C) Copyright 2013 + * Reinhard Pfau, Guntermann & Drunck GmbH + * + * Based on emc2103 driver by SMSC. + * + * Datasheet available at: + * http://www.smsc.com/Downloads/SMSC/Downloads_Public/Data_Sheets/2305.pdf + * + * Also supports the EMC2303 fan controller which has the same functionality + * and register layout as EMC2305, but supports only up to 3 fans instead of 5. + * + * Also supports EMC2302 (up to 2 fans) and EMC2301 (1 fan) fan controller. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * TODO / IDEAS: + * - expose more of the configuration and features + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Addresses scanned. + * Listed in the same order as they appear in the EMC2305, EMC2303 data sheets. + * + * Note: these are the I2C adresses which are possible for EMC2305 and EMC2303 + * chips. + * The EMC2302 supports only 0x2e (EMC2302-1) and 0x2f (EMC2302-2). + * The EMC2301 supports only 0x2f. + */ +static const unsigned short i2c_adresses[] = { + 0x2E, + 0x2F, + 0x2C, + 0x2D, + 0x4C, + 0x4D, + I2C_CLIENT_END +}; + +/* + * global registers + */ +enum { + REG_CONFIGURATION = 0x20, + REG_FAN_STATUS = 0x24, + REG_FAN_STALL_STATUS = 0x25, + REG_FAN_SPIN_STATUS = 0x26, + REG_DRIVE_FAIL_STATUS = 0x27, + REG_FAN_INTERRUPT_ENABLE = 0x29, + REG_PWM_POLARITY_CONFIG = 0x2a, + REG_PWM_OUTPUT_CONFIG = 0x2b, + REG_PWM_BASE_FREQ_1 = 0x2c, + REG_PWM_BASE_FREQ_2 = 0x2d, + REG_SOFTWARE_LOCK = 0xef, + REG_PRODUCT_FEATURES = 0xfc, + REG_PRODUCT_ID = 0xfd, + REG_MANUFACTURER_ID = 0xfe, + REG_REVISION = 0xff +}; + +/* + * fan specific registers + */ +enum { + REG_FAN_SETTING = 0x30, + REG_PWM_DIVIDE = 0x31, + REG_FAN_CONFIGURATION_1 = 0x32, + REG_FAN_CONFIGURATION_2 = 0x33, + REG_GAIN = 0x35, + REG_FAN_SPIN_UP_CONFIG = 0x36, + REG_FAN_MAX_STEP = 0x37, + REG_FAN_MINIMUM_DRIVE = 0x38, + REG_FAN_VALID_TACH_COUNT = 0x39, + REG_FAN_DRIVE_FAIL_BAND_LOW = 0x3a, + REG_FAN_DRIVE_FAIL_BAND_HIGH = 0x3b, + REG_TACH_TARGET_LOW = 0x3c, + REG_TACH_TARGET_HIGH = 0x3d, + REG_TACH_READ_HIGH = 0x3e, + REG_TACH_READ_LOW = 0x3f, +}; + +#define SEL_FAN(fan, reg) (reg + fan * 0x10) + +/* + * Factor by equations [2] and [3] from data sheet; valid for fans where the + * number of edges equals (poles * 2 + 1). + */ +#define FAN_RPM_FACTOR 3932160 + + +struct emc2305_fan_data { + bool enabled; + bool valid; + unsigned long last_updated; + bool rpm_control; + u8 multiplier; + u8 poles; + u16 target; + u16 tach; + u16 rpm_factor; + u8 pwm; +}; + +struct emc2305_data { + struct device *hwmon_dev; + struct mutex update_lock; + int fans; + struct emc2305_fan_data fan[5]; +}; + +static int read_u8_from_i2c(struct i2c_client *client, u8 i2c_reg, u8 *output) +{ + int status = i2c_smbus_read_byte_data(client, i2c_reg); + if (status < 0) { + dev_warn(&client->dev, "reg 0x%02x, err %d\n", + i2c_reg, status); + } else { + *output = status; + } + return status; +} + +static void read_fan_from_i2c(struct i2c_client *client, u16 *output, + u8 hi_addr, u8 lo_addr) +{ + u8 high_byte, lo_byte; + + if (read_u8_from_i2c(client, hi_addr, &high_byte) < 0) + return; + + if (read_u8_from_i2c(client, lo_addr, &lo_byte) < 0) + return; + + *output = ((u16)high_byte << 5) | (lo_byte >> 3); +} + +static void write_fan_target_to_i2c(struct i2c_client *client, int fan, + u16 new_target) +{ + const u8 lo_reg = SEL_FAN(fan, REG_TACH_TARGET_LOW); + const u8 hi_reg = SEL_FAN(fan, REG_TACH_TARGET_HIGH); + u8 high_byte = (new_target & 0x1fe0) >> 5; + u8 low_byte = (new_target & 0x001f) << 3; + i2c_smbus_write_byte_data(client, lo_reg, low_byte); + i2c_smbus_write_byte_data(client, hi_reg, high_byte); +} + +static void read_fan_config_from_i2c(struct i2c_client *client, int fan) + +{ + struct emc2305_data *data = i2c_get_clientdata(client); + u8 conf1; + + if (read_u8_from_i2c(client, SEL_FAN(fan, REG_FAN_CONFIGURATION_1), + &conf1) < 0) + return; + + data->fan[fan].rpm_control = (conf1 & 0x80) != 0; + data->fan[fan].multiplier = 1 << ((conf1 & 0x60) >> 5); + data->fan[fan].poles = ((conf1 & 0x18) >> 3) + 1; +} + +static void read_fan_setting(struct i2c_client *client, int fan) +{ + struct emc2305_data *data = i2c_get_clientdata(client); + u8 setting; + + if (read_u8_from_i2c(client, SEL_FAN(fan, REG_FAN_SETTING), + &setting) < 0) + return; + + data->fan[fan].pwm = setting; +} + +static void read_fan_data(struct i2c_client *client, int fan_idx) +{ + struct emc2305_data *data = i2c_get_clientdata(client); + + read_fan_from_i2c(client, &data->fan[fan_idx].target, + SEL_FAN(fan_idx, REG_TACH_TARGET_HIGH), + SEL_FAN(fan_idx, REG_TACH_TARGET_LOW)); + read_fan_from_i2c(client, &data->fan[fan_idx].tach, + SEL_FAN(fan_idx, REG_TACH_READ_HIGH), + SEL_FAN(fan_idx, REG_TACH_READ_LOW)); +} + +static struct emc2305_fan_data * +emc2305_update_fan(struct i2c_client *client, int fan_idx) +{ + struct emc2305_data *data = i2c_get_clientdata(client); + struct emc2305_fan_data *fan_data = &data->fan[fan_idx]; + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, fan_data->last_updated + HZ + HZ / 2) + || !fan_data->valid) { + read_fan_config_from_i2c(client, fan_idx); + read_fan_data(client, fan_idx); + read_fan_setting(client, fan_idx); + fan_data->valid = true; + fan_data->last_updated = jiffies; + } + + mutex_unlock(&data->update_lock); + return fan_data; +} + +static struct emc2305_fan_data * +emc2305_update_device_fan(struct device *dev, struct device_attribute *da) +{ + struct i2c_client *client = to_i2c_client(dev); + int fan_idx = to_sensor_dev_attr(da)->index; + + return emc2305_update_fan(client, fan_idx); +} + +/* + * set/ config functions + */ + +/* + * Note: we also update the fan target here, because its value is + * determined in part by the fan clock divider. This follows the principle + * of least surprise; the user doesn't expect the fan target to change just + * because the divider changed. + */ +static int +emc2305_set_fan_div(struct i2c_client *client, int fan_idx, long new_div) +{ + struct emc2305_data *data = i2c_get_clientdata(client); + struct emc2305_fan_data *fan = emc2305_update_fan(client, fan_idx); + const u8 reg_conf1 = SEL_FAN(fan_idx, REG_FAN_CONFIGURATION_1); + int new_range_bits, old_div = 8 / fan->multiplier; + int status = 0; + + if (new_div == old_div) /* No change */ + return 0; + + switch (new_div) { + case 1: + new_range_bits = 3; + break; + case 2: + new_range_bits = 2; + break; + case 4: + new_range_bits = 1; + break; + case 8: + new_range_bits = 0; + break; + default: + return -EINVAL; + } + + mutex_lock(&data->update_lock); + + status = i2c_smbus_read_byte_data(client, reg_conf1); + if (status < 0) { + dev_dbg(&client->dev, "reg 0x%02x, err %d\n", + reg_conf1, status); + status = -EIO; + goto exit_unlock; + } + status &= 0x9F; + status |= (new_range_bits << 5); + status = i2c_smbus_write_byte_data(client, reg_conf1, status); + if (status < 0) { + status = -EIO; + goto exit_invalidate; + } + + fan->multiplier = 8 / new_div; + + /* update fan target if high byte is not disabled */ + if ((fan->target & 0x1fe0) != 0x1fe0) { + u16 new_target = (fan->target * old_div) / new_div; + fan->target = min_t(u16, new_target, 0x1fff); + write_fan_target_to_i2c(client, fan_idx, fan->target); + } + +exit_invalidate: + /* invalidate fan data to force re-read from hardware */ + fan->valid = false; +exit_unlock: + mutex_unlock(&data->update_lock); + return status; +} + +static int +emc2305_set_fan_target(struct i2c_client *client, int fan_idx, long rpm_target) +{ + struct emc2305_data *data = i2c_get_clientdata(client); + struct emc2305_fan_data *fan = emc2305_update_fan(client, fan_idx); + + /* + * Datasheet states 16000 as maximum RPM target + * (table 2.2 and section 4.3) + */ + if ((rpm_target < 0) || (rpm_target > 16000)) + return -EINVAL; + + mutex_lock(&data->update_lock); + + if (rpm_target == 0) + fan->target = 0x1fff; + else + fan->target = clamp_val( + (FAN_RPM_FACTOR * fan->multiplier) / rpm_target, + 0, 0x1fff); + + write_fan_target_to_i2c(client, fan_idx, fan->target); + + mutex_unlock(&data->update_lock); + return 0; +} + +static int +emc2305_set_pwm_enable(struct i2c_client *client, int fan_idx, long enable) +{ + struct emc2305_data *data = i2c_get_clientdata(client); + struct emc2305_fan_data *fan = emc2305_update_fan(client, fan_idx); + const u8 reg_fan_conf1 = SEL_FAN(fan_idx, REG_FAN_CONFIGURATION_1); + int status = 0; + u8 conf_reg; + + mutex_lock(&data->update_lock); + switch (enable) { + case 0: + fan->rpm_control = false; + break; + case 3: + fan->rpm_control = true; + break; + default: + status = -EINVAL; + goto exit_unlock; + } + + status = read_u8_from_i2c(client, reg_fan_conf1, &conf_reg); + if (status < 0) { + status = -EIO; + goto exit_unlock; + } + + if (fan->rpm_control) + conf_reg |= 0x80; + else + conf_reg &= ~0x80; + + status = i2c_smbus_write_byte_data(client, reg_fan_conf1, conf_reg); + if (status < 0) + status = -EIO; + +exit_unlock: + mutex_unlock(&data->update_lock); + return status; +} + +static int +emc2305_set_pwm(struct i2c_client *client, int fan_idx, long pwm) +{ + struct emc2305_data *data = i2c_get_clientdata(client); + struct emc2305_fan_data *fan = emc2305_update_fan(client, fan_idx); + const u8 reg_fan_setting = SEL_FAN(fan_idx, REG_FAN_SETTING); + int status = 0; + + /* + * Datasheet states 255 as maximum PWM + * (section 5.7) + */ + if ((pwm < 0) || (pwm > 255)) + return -EINVAL; + + fan->pwm = pwm; + + mutex_lock(&data->update_lock); + + status = i2c_smbus_write_byte_data(client, reg_fan_setting, fan->pwm); + + mutex_unlock(&data->update_lock); + return status; +} +/* + * sysfs callback functions + * + * Note: + * Naming of the funcs is modelled after the naming scheme described in + * Documentation/hwmon/sysfs-interface: + * + * For a sysfs file _ the functions are named like this: + * the show function: show__ + * the store function: set__ + * For read only (RO) attributes of course only the show func is required. + * + * This convention allows us to define the sysfs attributes by using macros. + */ + +static ssize_t +show_fan_input(struct device *dev, struct device_attribute *da, char *buf) +{ + struct emc2305_fan_data *fan = emc2305_update_device_fan(dev, da); + int rpm = 0; + if (fan->tach != 0) + rpm = (FAN_RPM_FACTOR * fan->multiplier) / fan->tach; + return sprintf(buf, "%d\n", rpm); +} + +static ssize_t +show_fan_fault(struct device *dev, struct device_attribute *da, char *buf) +{ + struct emc2305_fan_data *fan = emc2305_update_device_fan(dev, da); + bool fault = ((fan->tach & 0x1fe0) == 0x1fe0); + return sprintf(buf, "%d\n", fault ? 1 : 0); +} + +static ssize_t +show_fan_div(struct device *dev, struct device_attribute *da, char *buf) +{ + struct emc2305_fan_data *fan = emc2305_update_device_fan(dev, da); + int fan_div = 8 / fan->multiplier; + return sprintf(buf, "%d\n", fan_div); +} + +static ssize_t +show_fan_alarm(struct device *dev, struct device_attribute *da, char *buf) +{ + struct emc2305_fan_data *fan = emc2305_update_device_fan(dev, da); + bool fault = ((fan->tach & 0x1fe0) == 0x1fe0); + return sprintf(buf, "%d\n", fault ? 1 : 0); +} + +static ssize_t +set_fan_div(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + int fan_idx = to_sensor_dev_attr(da)->index; + long new_div; + int status; + + status = kstrtol(buf, 10, &new_div); + if (status < 0) + return -EINVAL; + + status = emc2305_set_fan_div(client, fan_idx, new_div); + if (status < 0) + return status; + + return count; +} + +static ssize_t +show_fan_target(struct device *dev, struct device_attribute *da, char *buf) +{ + struct emc2305_fan_data *fan = emc2305_update_device_fan(dev, da); + int rpm = 0; + + /* high byte of 0xff indicates disabled so return 0 */ + if ((fan->target != 0) && ((fan->target & 0x1fe0) != 0x1fe0)) + rpm = (FAN_RPM_FACTOR * fan->multiplier) + / fan->target; + + return sprintf(buf, "%d\n", rpm); +} + +static ssize_t set_fan_target(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + int fan_idx = to_sensor_dev_attr(da)->index; + long rpm_target; + int status; + + status = kstrtol(buf, 10, &rpm_target); + if (status < 0) + return -EINVAL; + + status = emc2305_set_fan_target(client, fan_idx, rpm_target); + if (status < 0) + return status; + + return count; +} + +static ssize_t +show_pwm_enable(struct device *dev, struct device_attribute *da, char *buf) +{ + struct emc2305_fan_data *fan = emc2305_update_device_fan(dev, da); + return sprintf(buf, "%d\n", fan->rpm_control ? 3 : 0); +} + +static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + int fan_idx = to_sensor_dev_attr(da)->index; + long new_value; + int status; + + status = kstrtol(buf, 10, &new_value); + if (status < 0) + return -EINVAL; + status = emc2305_set_pwm_enable(client, fan_idx, new_value); + return count; +} + +static ssize_t show_pwm(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct emc2305_fan_data *fan = emc2305_update_device_fan(dev, da); + return sprintf(buf, "%d\n", fan->pwm); +} + +static ssize_t set_pwm(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + int fan_idx = to_sensor_dev_attr(da)->index; + unsigned long val; + int ret; + int status; + + ret = kstrtoul(buf, 10, &val); + if (ret) + return ret; + if (val > 255) + return -EINVAL; + + status = emc2305_set_pwm(client, fan_idx, val); + return count; +} + +/* define a read only attribute */ +#define EMC2305_ATTR_RO(_type, _item, _num) \ + SENSOR_ATTR(_type ## _num ## _ ## _item, S_IRUGO, \ + show_## _type ## _ ## _item, NULL, _num - 1) + +/* define a read/write attribute */ +#define EMC2305_ATTR_RW(_type, _item, _num) \ + SENSOR_ATTR(_type ## _num ## _ ## _item, S_IRUGO | S_IWUSR, \ + show_## _type ##_ ## _item, \ + set_## _type ## _ ## _item, _num - 1) + +/* + * TODO: Ugly hack, but temporary as this whole logic needs + * to be rewritten as per standard HWMON sysfs registration + */ + +/* define a read/write attribute */ +#define EMC2305_ATTR_RW2(_type, _num) \ + SENSOR_ATTR(_type ## _num, S_IRUGO | S_IWUSR, \ + show_## _type, set_## _type, _num - 1) + +/* defines the attributes for a single fan */ +#define EMC2305_DEFINE_FAN_ATTRS(_num) \ + static const \ + struct sensor_device_attribute emc2305_attr_fan ## _num[] = { \ + EMC2305_ATTR_RO(fan, input, _num), \ + EMC2305_ATTR_RO(fan, fault, _num), \ + EMC2305_ATTR_RW(fan, div, _num), \ + EMC2305_ATTR_RO(fan, alarm, _num), \ + EMC2305_ATTR_RW(fan, target, _num), \ + EMC2305_ATTR_RW(pwm, enable, _num), \ + EMC2305_ATTR_RW2(pwm, _num) \ + } + +#define EMC2305_NUM_FAN_ATTRS ARRAY_SIZE(emc2305_attr_fan1) + +/* common attributes for EMC2303 and EMC2305 */ +static const struct sensor_device_attribute emc2305_attr_common[] = { +}; + +/* fan attributes for the single fans */ +EMC2305_DEFINE_FAN_ATTRS(1); +EMC2305_DEFINE_FAN_ATTRS(2); +EMC2305_DEFINE_FAN_ATTRS(3); +EMC2305_DEFINE_FAN_ATTRS(4); +EMC2305_DEFINE_FAN_ATTRS(5); +EMC2305_DEFINE_FAN_ATTRS(6); + +/* fan attributes */ +static const struct sensor_device_attribute *emc2305_fan_attrs[] = { + emc2305_attr_fan1, + emc2305_attr_fan2, + emc2305_attr_fan3, + emc2305_attr_fan4, + emc2305_attr_fan5, +}; + +/* + * driver interface + */ + +static int emc2305_remove(struct i2c_client *client) +{ + struct emc2305_data *data = i2c_get_clientdata(client); + int fan_idx, i; + + hwmon_device_unregister(data->hwmon_dev); + + for (fan_idx = 0; fan_idx < data->fans; ++fan_idx) + for (i = 0; i < EMC2305_NUM_FAN_ATTRS; ++i) + device_remove_file( + &client->dev, + &emc2305_fan_attrs[fan_idx][i].dev_attr); + + for (i = 0; i < ARRAY_SIZE(emc2305_attr_common); ++i) + device_remove_file(&client->dev, + &emc2305_attr_common[i].dev_attr); + + kfree(data); + return 0; +} + + +#ifdef CONFIG_OF +/* + * device tree support + */ + +struct of_fan_attribute { + const char *name; + int (*set)(struct i2c_client*, int, long); +}; + +struct of_fan_attribute of_fan_attributes[] = { + {"fan-div", emc2305_set_fan_div}, + {"fan-target", emc2305_set_fan_target}, + {"pwm-enable", emc2305_set_pwm_enable}, + {NULL, NULL} +}; + +static int emc2305_config_of(struct i2c_client *client) +{ + struct emc2305_data *data = i2c_get_clientdata(client); + struct device_node *node; + unsigned int fan_idx; + + if (!client->dev.of_node) + return -EINVAL; + if (!of_get_next_child(client->dev.of_node, NULL)) + return 0; + + for (fan_idx = 0; fan_idx < data->fans; ++fan_idx) + data->fan[fan_idx].enabled = false; + + for_each_child_of_node(client->dev.of_node, node) { + const __be32 *property; + int len; + struct of_fan_attribute *attr; + + property = of_get_property(node, "reg", &len); + if (!property || len != sizeof(int)) { + dev_err(&client->dev, "invalid reg on %s\n", + node->full_name); + continue; + } + + fan_idx = be32_to_cpup(property); + if (fan_idx >= data->fans) { + dev_err(&client->dev, + "invalid fan index %d on %s\n", + fan_idx, node->full_name); + continue; + } + + data->fan[fan_idx].enabled = true; + + for (attr = of_fan_attributes; attr->name; ++attr) { + int status = 0; + long value; + property = of_get_property(node, attr->name, &len); + if (!property) + continue; + if (len != sizeof(int)) { + dev_err(&client->dev, "invalid %s on %s\n", + attr->name, node->full_name); + continue; + } + value = be32_to_cpup(property); + status = attr->set(client, fan_idx, value); + if (status == -EINVAL) { + dev_err(&client->dev, + "invalid value for %s on %s\n", + attr->name, node->full_name); + } + } + } + + return 0; +} + +#endif + +static void emc2305_get_config(struct i2c_client *client) +{ + int i; + struct emc2305_data *data = i2c_get_clientdata(client); + + for (i = 0; i < data->fans; ++i) { + data->fan[i].enabled = true; + emc2305_update_fan(client, i); + } + +#ifdef CONFIG_OF + emc2305_config_of(client); +#endif + +} + +static int +emc2305_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct emc2305_data *data; + int status; + int i; + int fan_idx; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -EIO; + + data = kzalloc(sizeof(struct emc2305_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + status = i2c_smbus_read_byte_data(client, REG_PRODUCT_ID); + switch (status) { + case 0x34: /* EMC2305 */ + data->fans = 5; + break; + case 0x35: /* EMC2303 */ + data->fans = 3; + break; + case 0x36: /* EMC2302 */ + data->fans = 2; + break; + case 0x37: /* EMC2301 */ + data->fans = 1; + break; + default: + if (status >= 0) + status = -EINVAL; + goto exit_free; + } + + emc2305_get_config(client); + + for (i = 0; i < ARRAY_SIZE(emc2305_attr_common); ++i) { + status = device_create_file(&client->dev, + &emc2305_attr_common[i].dev_attr); + if (status) + goto exit_remove; + } + for (fan_idx = 0; fan_idx < data->fans; ++fan_idx) + for (i = 0; i < EMC2305_NUM_FAN_ATTRS; ++i) { + if (!data->fan[fan_idx].enabled) + continue; + status = device_create_file( + &client->dev, + &emc2305_fan_attrs[fan_idx][i].dev_attr); + if (status) + goto exit_remove_fans; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove_fans; + } + + dev_info(&client->dev, "%s: sensor '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove_fans: + for (fan_idx = 0; fan_idx < data->fans; ++fan_idx) + for (i = 0; i < EMC2305_NUM_FAN_ATTRS; ++i) + device_remove_file( + &client->dev, + &emc2305_fan_attrs[fan_idx][i].dev_attr); + +exit_remove: + for (i = 0; i < ARRAY_SIZE(emc2305_attr_common); ++i) + device_remove_file(&client->dev, + &emc2305_attr_common[i].dev_attr); +exit_free: + kfree(data); + return status; +} + +static const struct i2c_device_id emc2305_id[] = { + { "emc2305", 0 }, + { "emc2303", 0 }, + { "emc2302", 0 }, + { "emc2301", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, emc2305_id); + +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int +emc2305_detect(struct i2c_client *new_client, struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = new_client->adapter; + int manufacturer, product; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -ENODEV; + + manufacturer = + i2c_smbus_read_byte_data(new_client, REG_MANUFACTURER_ID); + if (manufacturer != 0x5D) + return -ENODEV; + + product = i2c_smbus_read_byte_data(new_client, REG_PRODUCT_ID); + + switch (product) { + case 0x34: + strlcpy(info->type, "emc2305", I2C_NAME_SIZE); + break; + case 0x35: + strlcpy(info->type, "emc2303", I2C_NAME_SIZE); + break; + case 0x36: + strlcpy(info->type, "emc2302", I2C_NAME_SIZE); + break; + case 0x37: + strlcpy(info->type, "emc2301", I2C_NAME_SIZE); + break; + default: + return -ENODEV; + } + + return 0; +} + +static struct i2c_driver emc2305_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "emc2305", + }, + .probe = emc2305_probe, + .remove = emc2305_remove, + .id_table = emc2305_id, +/* + .detect = emc2305_detect, + .address_list = i2c_adresses, +*/ +}; + +module_i2c_driver(emc2305_driver); + +MODULE_AUTHOR("Reinhard Pfau "); +MODULE_DESCRIPTION("SMSC EMC2305 hwmon driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/leds-dx010.c b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/leds-dx010.c new file mode 100644 index 000000000000..fac8322f06b0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/leds-dx010.c @@ -0,0 +1,289 @@ +/* + * leds-dx010-status.c - Driver for Seastone DX010 front panel LEDs + * + * Copyright (C) 2017 Celestica Corp. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include + +#define DRIVER_NAME "leds_dx010" +#define FRONT_LED_STAT 0x303 + +static int dx010_led_blink_stat(struct led_classdev *led_cdev, + unsigned long *delay_on, + unsigned long *delay_off) +{ + unsigned char led; + + if (!(*delay_on == 0 && *delay_off == 0) && + !(*delay_on == 250 && *delay_off == 250) && + !(*delay_on == 500 && *delay_off == 500)) + return -EINVAL; + + led = inb(FRONT_LED_STAT); + led &= 0xfc; + + if ((*delay_on == 250) && (*delay_off == 250)) + led |= 0x02; + else if ((*delay_on == 500) && (*delay_off == 500)) + led |= 0x01; + + outb(led, FRONT_LED_STAT); + + return 0; +} + +static ssize_t dx010_led_blink_show_stat(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct led_classdev *leddev = dev_get_drvdata(dev); + unsigned char led; + const char *msg; + + led = inb(FRONT_LED_STAT); + led &= 0x03; + + switch (led) + { + case 0: + msg = "No blinking, turn on"; + break; + case 1: + msg = "1 Hz is blinking"; + break; + case 2: + msg = "4 Hz is blinking"; + break; + case 3: + msg = "No blinking, turn off"; + break; + default: + msg = "Unknown error"; + break; + } + + return sprintf(buf, "%s\n", msg); +} + +static ssize_t dx010_led_blink_store_stat(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + struct led_classdev *leddev = dev_get_drvdata(dev); + unsigned long blink_state; + unsigned char led; + + ret = kstrtoul(buf, 10, &blink_state); + if (ret) + return ret; + + led = inb(FRONT_LED_STAT); + led &= 0xfc; + + switch (blink_state) + { + case 0: + led |= 0x03; + break; + case 1: + break; + case 250: + led |= 0x02; + break; + case 500: + led |= 0x01; + break; + default: + return -EINVAL; + break; + } + + outb(led, FRONT_LED_STAT); + + return size; +} +static DEVICE_ATTR(blink, 0644, dx010_led_blink_show_stat, dx010_led_blink_store_stat); + +static void dx010_led_brightness_set_stat(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + unsigned char led; + + led = inb(FRONT_LED_STAT); + led &= 0xfc; + + if (!brightness) + led |= 0x03; + + outb( led, FRONT_LED_STAT); +} + +enum led_brightness dx010_led_brightness_get_p2(struct led_classdev *led_cdev) +{ + unsigned char led; + + led = inb(FRONT_LED_STAT); + + return (led & 0x08) ? LED_OFF : LED_FULL; +} + +static void dx010_led_brightness_set_p2(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + unsigned char led; + + led = inb(FRONT_LED_STAT); + led &= 0xf7; + + if (!brightness) + led |= 0x08; + + outb( led, FRONT_LED_STAT); +} + +enum led_brightness dx010_led_brightness_get_p1(struct led_classdev *led_cdev) +{ + unsigned char led; + + led = inb(FRONT_LED_STAT); + + return (led & 0x04) ? LED_OFF : LED_FULL; +} + +static void dx010_led_brightness_set_p1(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + unsigned char led; + + led = inb(FRONT_LED_STAT); + led &= 0xfb; + + if (!brightness) + led |= 0x04; + + outb( led, FRONT_LED_STAT); +} + +static struct led_classdev dx010_leds[] = { + { + .name = "dx010:green:p-1", + .brightness = LED_OFF, + .max_brightness = 1, + .brightness_get = dx010_led_brightness_get_p1, + .brightness_set = dx010_led_brightness_set_p1, + }, + { + .name = "dx010:green:p-2", + .brightness = LED_OFF, + .max_brightness = 1, + .brightness_get = dx010_led_brightness_get_p2, + .brightness_set = dx010_led_brightness_set_p2, + }, + { + .name = "dx010:green:stat", + .brightness = LED_OFF, + .max_brightness = 1, + .brightness_set = dx010_led_brightness_set_stat, + .blink_set = dx010_led_blink_stat, + .flags = LED_CORE_SUSPENDRESUME, + }, +}; + +static struct resource dx010_led_resources[] = { + { + .flags = IORESOURCE_IO, + }, +}; + +static void dx010_led_dev_release( struct device * dev) +{ + return; +} + +static struct platform_device dx010_lpc_dev = { + .name = DRIVER_NAME, + .id = -1, + .num_resources = ARRAY_SIZE(dx010_led_resources), + .resource = dx010_led_resources, + .dev = { + .release = dx010_led_dev_release, + } +}; + +static int dx010_led_drv_probe(struct platform_device *pdev) +{ + int i, ret; + + for (i = 0; i < ARRAY_SIZE(dx010_leds); i++) { + ret = led_classdev_register(&pdev->dev, &dx010_leds[i]); + if (ret < 0) + goto exit; + } + + ret = device_create_file(&pdev->dev, &dev_attr_blink); + if (ret) + { + for (i = 0; i < ARRAY_SIZE(dx010_leds); i++) + led_classdev_unregister(&dx010_leds[i]); + } +exit: + return ret; +} + +static int dx010_led_drv_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(dx010_leds); i++) + led_classdev_unregister(&dx010_leds[i]); + + device_remove_file(&pdev->dev, &dev_attr_blink); + + return 0; +} + +static struct platform_driver dx010_led_drv = { + .probe = dx010_led_drv_probe, + .remove = __exit_p(dx010_led_drv_remove), + .driver = { + .name = DRIVER_NAME, + }, +}; + +int dx010_led_init(void) +{ + platform_device_register(&dx010_lpc_dev); + platform_driver_register(&dx010_led_drv); + + return 0; +} + +void dx010_led_exit(void) +{ + platform_driver_unregister(&dx010_led_drv); + platform_device_unregister(&dx010_lpc_dev); +} + +module_init(dx010_led_init); +module_exit(dx010_led_exit); + +MODULE_AUTHOR("Abhisit Sangjan "); +MODULE_DESCRIPTION("Celestica SeaStone DX010 LEDs Front Panel Status Driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.c b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.c new file mode 100644 index 000000000000..a83745212bbf --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.c @@ -0,0 +1,553 @@ +/* + * lm75.c - Part of lm_sensors, Linux kernel modules for hardware + * monitoring + * Copyright (c) 1998, 1999 Frodo Looijaard + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lm75.h" + + +/* + * This driver handles the LM75 and compatible digital temperature sensors. + */ + +enum lm75_type { /* keep sorted in alphabetical order */ + adt75, + ds1775, + ds75, + ds7505, + g751, + lm75, + lm75a, + lm75b, + max6625, + max6626, + mcp980x, + stds75, + tcn75, + tmp100, + tmp101, + tmp105, + tmp112, + tmp175, + tmp275, + tmp75, +}; + +/* Addresses scanned */ +static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, + 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; + + +/* The LM75 registers */ +#define LM75_REG_CONF 0x01 +static const u8 LM75_REG_TEMP[3] = { + 0x00, /* input */ + 0x03, /* max */ + 0x02, /* hyst */ +}; + +/* Each client has this additional data */ +struct lm75_data { + struct i2c_client *client; + struct device *hwmon_dev; + struct thermal_zone_device *tz; + struct mutex update_lock; + u8 orig_conf; + u8 resolution; /* In bits, between 9 and 12 */ + u8 resolution_limits; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + unsigned long sample_time; /* In jiffies */ + s16 temp[3]; /* Register values, + 0 = input + 1 = max + 2 = hyst */ +}; + +static int lm75_read_value(struct i2c_client *client, u8 reg); +static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value); +static struct lm75_data *lm75_update_device(struct device *dev); + + +/*-----------------------------------------------------------------------*/ + +static inline long lm75_reg_to_mc(s16 temp, u8 resolution) +{ + return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8); +} + +/* sysfs attributes for hwmon */ + +static int lm75_read_temp(void *dev, long *temp) +{ + struct lm75_data *data = lm75_update_device(dev); + + if (IS_ERR(data)) + return PTR_ERR(data); + + *temp = lm75_reg_to_mc(data->temp[0], data->resolution); + + return 0; +} + +static ssize_t show_temp(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct lm75_data *data = lm75_update_device(dev); + + if (IS_ERR(data)) + return PTR_ERR(data); + + return sprintf(buf, "%ld\n", lm75_reg_to_mc(data->temp[attr->index], + data->resolution)); +} + +static ssize_t set_temp(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct lm75_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + int nr = attr->index; + long temp; + int error; + u8 resolution; + + error = kstrtol(buf, 10, &temp); + if (error) + return error; + + /* + * Resolution of limit registers is assumed to be the same as the + * temperature input register resolution unless given explicitly. + */ + if (attr->index && data->resolution_limits) + resolution = data->resolution_limits; + else + resolution = data->resolution; + + mutex_lock(&data->update_lock); + temp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX); + data->temp[nr] = DIV_ROUND_CLOSEST(temp << (resolution - 8), + 1000) << (16 - resolution); + lm75_write_value(client, LM75_REG_TEMP[nr], data->temp[nr]); + mutex_unlock(&data->update_lock); + return count; +} + +static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, + show_temp, set_temp, 1); +static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, + show_temp, set_temp, 2); +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); + +static struct attribute *lm75_attrs[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, + + NULL +}; +ATTRIBUTE_GROUPS(lm75); + +/*-----------------------------------------------------------------------*/ + +/* device probe and removal */ + +static int +lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct device *dev = &client->dev; + struct lm75_data *data; + int status; + u8 set_mask, clr_mask; + int new; + enum lm75_type kind = id->driver_data; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) + return -EIO; + + data = devm_kzalloc(dev, sizeof(struct lm75_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->client = client; + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + /* Set to LM75 resolution (9 bits, 1/2 degree C) and range. + * Then tweak to be more precise when appropriate. + */ + set_mask = 0; + clr_mask = LM75_SHUTDOWN; /* continuous conversions */ + + switch (kind) { + case adt75: + clr_mask |= 1 << 5; /* not one-shot mode */ + data->resolution = 12; + data->sample_time = HZ / 8; + break; + case ds1775: + case ds75: + case stds75: + clr_mask |= 3 << 5; + set_mask |= 2 << 5; /* 11-bit mode */ + data->resolution = 11; + data->sample_time = HZ; + break; + case ds7505: + set_mask |= 3 << 5; /* 12-bit mode */ + data->resolution = 12; + data->sample_time = HZ / 4; + break; + case g751: + case lm75: + case lm75a: + data->resolution = 9; + data->sample_time = HZ / 2; + break; + case lm75b: + data->resolution = 11; + data->sample_time = HZ / 4; + break; + case max6625: + data->resolution = 9; + data->sample_time = HZ / 4; + break; + case max6626: + data->resolution = 12; + data->resolution_limits = 9; + data->sample_time = HZ / 4; + break; + case tcn75: + data->resolution = 9; + data->sample_time = HZ / 8; + break; + case mcp980x: + data->resolution_limits = 9; + /* fall through */ + case tmp100: + case tmp101: + set_mask |= 3 << 5; /* 12-bit mode */ + data->resolution = 12; + data->sample_time = HZ; + clr_mask |= 1 << 7; /* not one-shot mode */ + break; + case tmp112: + set_mask |= 3 << 5; /* 12-bit mode */ + clr_mask |= 1 << 7; /* not one-shot mode */ + data->resolution = 12; + data->sample_time = HZ / 4; + break; + case tmp105: + case tmp175: + case tmp275: + case tmp75: + set_mask |= 3 << 5; /* 12-bit mode */ + clr_mask |= 1 << 7; /* not one-shot mode */ + data->resolution = 12; + data->sample_time = HZ / 2; + break; + } + + /* configure as specified */ + status = lm75_read_value(client, LM75_REG_CONF); + if (status < 0) { + dev_dbg(dev, "Can't read config? %d\n", status); + return status; + } + data->orig_conf = status; + new = status & ~clr_mask; + new |= set_mask; + if (status != new) + lm75_write_value(client, LM75_REG_CONF, new); + dev_dbg(dev, "Config %02x\n", new); + + data->hwmon_dev = hwmon_device_register_with_groups(dev, client->name, + data, lm75_groups); + if (IS_ERR(data->hwmon_dev)) + return PTR_ERR(data->hwmon_dev); + + data->tz = thermal_zone_of_sensor_register(data->hwmon_dev, + 0, + data->hwmon_dev, + lm75_read_temp, NULL); + if (IS_ERR(data->tz)) + data->tz = NULL; + + dev_info(dev, "%s: sensor '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; +} + +static int lm75_remove(struct i2c_client *client) +{ + struct lm75_data *data = i2c_get_clientdata(client); + + thermal_zone_of_sensor_unregister(data->hwmon_dev, data->tz); + hwmon_device_unregister(data->hwmon_dev); + lm75_write_value(client, LM75_REG_CONF, data->orig_conf); + return 0; +} + +static const struct i2c_device_id lm75_ids[] = { + { "adt75", adt75, }, + { "ds1775", ds1775, }, + { "ds75", ds75, }, + { "ds7505", ds7505, }, + { "g751", g751, }, + { "lm75", lm75, }, + { "lm75a", lm75a, }, + { "dx010_lm75b", lm75b, }, + { "max6625", max6625, }, + { "max6626", max6626, }, + { "mcp980x", mcp980x, }, + { "stds75", stds75, }, + { "tcn75", tcn75, }, + { "tmp100", tmp100, }, + { "tmp101", tmp101, }, + { "tmp105", tmp105, }, + { "tmp112", tmp112, }, + { "tmp175", tmp175, }, + { "tmp275", tmp275, }, + { "tmp75", tmp75, }, + { /* LIST END */ } +}; +MODULE_DEVICE_TABLE(i2c, lm75_ids); + +#define LM75A_ID 0xA1 + +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int lm75_detect(struct i2c_client *new_client, + struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = new_client->adapter; + int i; + int conf, hyst, os; + bool is_lm75a = 0; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA)) + return -ENODEV; + + /* + * Now, we do the remaining detection. There is no identification- + * dedicated register so we have to rely on several tricks: + * unused bits, registers cycling over 8-address boundaries, + * addresses 0x04-0x07 returning the last read value. + * The cycling+unused addresses combination is not tested, + * since it would significantly slow the detection down and would + * hardly add any value. + * + * The National Semiconductor LM75A is different than earlier + * LM75s. It has an ID byte of 0xaX (where X is the chip + * revision, with 1 being the only revision in existence) in + * register 7, and unused registers return 0xff rather than the + * last read value. + * + * Note that this function only detects the original National + * Semiconductor LM75 and the LM75A. Clones from other vendors + * aren't detected, on purpose, because they are typically never + * found on PC hardware. They are found on embedded designs where + * they can be instantiated explicitly so detection is not needed. + * The absence of identification registers on all these clones + * would make their exhaustive detection very difficult and weak, + * and odds are that the driver would bind to unsupported devices. + */ + + /* Unused bits */ + conf = i2c_smbus_read_byte_data(new_client, 1); + if (conf & 0xe0) + return -ENODEV; + + /* First check for LM75A */ + if (i2c_smbus_read_byte_data(new_client, 7) == LM75A_ID) { + /* LM75A returns 0xff on unused registers so + just to be sure we check for that too. */ + if (i2c_smbus_read_byte_data(new_client, 4) != 0xff + || i2c_smbus_read_byte_data(new_client, 5) != 0xff + || i2c_smbus_read_byte_data(new_client, 6) != 0xff) + return -ENODEV; + is_lm75a = 1; + hyst = i2c_smbus_read_byte_data(new_client, 2); + os = i2c_smbus_read_byte_data(new_client, 3); + } else { /* Traditional style LM75 detection */ + /* Unused addresses */ + hyst = i2c_smbus_read_byte_data(new_client, 2); + if (i2c_smbus_read_byte_data(new_client, 4) != hyst + || i2c_smbus_read_byte_data(new_client, 5) != hyst + || i2c_smbus_read_byte_data(new_client, 6) != hyst + || i2c_smbus_read_byte_data(new_client, 7) != hyst) + return -ENODEV; + os = i2c_smbus_read_byte_data(new_client, 3); + if (i2c_smbus_read_byte_data(new_client, 4) != os + || i2c_smbus_read_byte_data(new_client, 5) != os + || i2c_smbus_read_byte_data(new_client, 6) != os + || i2c_smbus_read_byte_data(new_client, 7) != os) + return -ENODEV; + } + + /* Addresses cycling */ + for (i = 8; i <= 248; i += 40) { + if (i2c_smbus_read_byte_data(new_client, i + 1) != conf + || i2c_smbus_read_byte_data(new_client, i + 2) != hyst + || i2c_smbus_read_byte_data(new_client, i + 3) != os) + return -ENODEV; + if (is_lm75a && i2c_smbus_read_byte_data(new_client, i + 7) + != LM75A_ID) + return -ENODEV; + } + + strlcpy(info->type, is_lm75a ? "lm75a" : "lm75", I2C_NAME_SIZE); + + return 0; +} + +#ifdef CONFIG_PM +static int lm75_suspend(struct device *dev) +{ + int status; + struct i2c_client *client = to_i2c_client(dev); + status = lm75_read_value(client, LM75_REG_CONF); + if (status < 0) { + dev_dbg(&client->dev, "Can't read config? %d\n", status); + return status; + } + status = status | LM75_SHUTDOWN; + lm75_write_value(client, LM75_REG_CONF, status); + return 0; +} + +static int lm75_resume(struct device *dev) +{ + int status; + struct i2c_client *client = to_i2c_client(dev); + status = lm75_read_value(client, LM75_REG_CONF); + if (status < 0) { + dev_dbg(&client->dev, "Can't read config? %d\n", status); + return status; + } + status = status & ~LM75_SHUTDOWN; + lm75_write_value(client, LM75_REG_CONF, status); + return 0; +} + +static const struct dev_pm_ops lm75_dev_pm_ops = { + .suspend = lm75_suspend, + .resume = lm75_resume, +}; +#define LM75_DEV_PM_OPS (&lm75_dev_pm_ops) +#else +#define LM75_DEV_PM_OPS NULL +#endif /* CONFIG_PM */ + +static struct i2c_driver lm75_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "dx010_lm75", + .pm = LM75_DEV_PM_OPS, + }, + .probe = lm75_probe, + .remove = lm75_remove, + .id_table = lm75_ids, +/* + .detect = lm75_detect, + .address_list = normal_i2c, +*/ +}; + +/*-----------------------------------------------------------------------*/ + +/* register access */ + +/* + * All registers are word-sized, except for the configuration register. + * LM75 uses a high-byte first convention, which is exactly opposite to + * the SMBus standard. + */ +static int lm75_read_value(struct i2c_client *client, u8 reg) +{ + if (reg == LM75_REG_CONF) + return i2c_smbus_read_byte_data(client, reg); + else + return i2c_smbus_read_word_swapped(client, reg); +} + +static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value) +{ + if (reg == LM75_REG_CONF) + return i2c_smbus_write_byte_data(client, reg, value); + else + return i2c_smbus_write_word_swapped(client, reg, value); +} + +static struct lm75_data *lm75_update_device(struct device *dev) +{ + struct lm75_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + struct lm75_data *ret = data; + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + data->sample_time) + || !data->valid) { + int i; + dev_dbg(&client->dev, "Starting lm75 update\n"); + + for (i = 0; i < ARRAY_SIZE(data->temp); i++) { + int status; + + status = lm75_read_value(client, LM75_REG_TEMP[i]); + if (unlikely(status < 0)) { + dev_dbg(dev, + "LM75: Failed to read value: reg %d, error %d\n", + LM75_REG_TEMP[i], status); + ret = ERR_PTR(status); + data->valid = 0; + goto abort; + } + data->temp[i] = status; + } + data->last_updated = jiffies; + data->valid = 1; + } + +abort: + mutex_unlock(&data->update_lock); + return ret; +} + +module_i2c_driver(lm75_driver); + +MODULE_AUTHOR("Frodo Looijaard "); +MODULE_DESCRIPTION("LM75 driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.h b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.h new file mode 100644 index 000000000000..5cde94e56f17 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.h @@ -0,0 +1,49 @@ +/* + lm75.h - Part of lm_sensors, Linux kernel modules for hardware + monitoring + Copyright (c) 2003 Mark M. Hoffman + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + This file contains common code for encoding/decoding LM75 type + temperature readings, which are emulated by many of the chips + we support. As the user is unlikely to load more than one driver + which contains this code, we don't worry about the wasted space. +*/ + +#include + +/* straight from the datasheet */ +#define LM75_TEMP_MIN (-55000) +#define LM75_TEMP_MAX 125000 +#define LM75_SHUTDOWN 0x01 + +/* TEMP: 0.001C/bit (-55C to +125C) + REG: (0.5C/bit, two's complement) << 7 */ +static inline u16 LM75_TEMP_TO_REG(long temp) +{ + int ntemp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX); + ntemp += (ntemp < 0 ? -250 : 250); + return (u16)((ntemp / 500) << 7); +} + +static inline int LM75_TEMP_FROM_REG(u16 reg) +{ + /* use integer division instead of equivalent right shift to + guarantee arithmetic shift and preserve the sign */ + return ((s16)reg / 128) * 500; +} diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/mc24lc64t.c b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/mc24lc64t.c new file mode 100644 index 000000000000..a391056d09a7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/mc24lc64t.c @@ -0,0 +1,142 @@ +/* + * mc24lc64t.c - driver for Microchip 24LC64T + * + * Copyright (C) 2017 Celestica Corp. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct mc24lc64t_data { + struct i2c_client *fake_client; + struct mutex update_lock; +}; + +static ssize_t mc24lc64t_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = kobj_to_i2c_client(kobj); + struct mc24lc64t_data *drvdata = i2c_get_clientdata(client); + unsigned long timeout, read_time, i = 0; + int status; + + mutex_lock(&drvdata->update_lock); + + if (i2c_smbus_write_byte_data(client, off>>8, off)) + { + status = -EIO; + goto exit; + } + + msleep(1); + +begin: + + if (i < count) + { + timeout = jiffies + msecs_to_jiffies(25); /* 25 mS timeout*/ + do { + read_time = jiffies; + + status = i2c_smbus_read_byte(client); + if (status >= 0) + { + buf[i++] = status; + goto begin; + } + } while (time_before(read_time, timeout)); + + status = -ETIMEDOUT; + goto exit; + } + + status = count; + +exit: + mutex_unlock(&drvdata->update_lock); + + return status; +} + +static struct bin_attribute mc24lc64t_bit_attr = { + .attr = { + .name = "eeprom", + .mode = S_IRUGO, + }, + .size = 65536, + .read = mc24lc64t_read, +}; + +static int mc24lc64t_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adapter = client->adapter; + struct mc24lc64t_data *drvdata; + int err; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA + | I2C_FUNC_SMBUS_READ_BYTE)) + return -EPFNOSUPPORT; + + if (!(drvdata = devm_kzalloc(&client->dev, + sizeof(struct mc24lc64t_data), GFP_KERNEL))) + return -ENOMEM; + + drvdata->fake_client = i2c_new_dummy(client->adapter, client->addr + 1); + if (!drvdata->fake_client) + return -ENOMEM; + + i2c_set_clientdata(client, drvdata); + mutex_init(&drvdata->update_lock); + + err = sysfs_create_bin_file(&client->dev.kobj, &mc24lc64t_bit_attr); + if (err) + i2c_unregister_device(drvdata->fake_client); + + return err; +} + +static int mc24lc64t_remove(struct i2c_client *client) +{ + struct mc24lc64t_data *drvdata = i2c_get_clientdata(client); + + i2c_unregister_device(drvdata->fake_client); + + sysfs_remove_bin_file(&client->dev.kobj, &mc24lc64t_bit_attr); + + return 0; +} + +static const struct i2c_device_id mc24lc64t_id[] = { + { "24lc64t", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, mc24lc64t_id); + +static struct i2c_driver mc24lc64t_driver = { + .driver = { + .name = "mc24lc64t", + .owner = THIS_MODULE, + }, + .probe = mc24lc64t_probe, + .remove = mc24lc64t_remove, + .id_table = mc24lc64t_id, +}; + +module_i2c_driver(mc24lc64t_driver); + +MODULE_AUTHOR("Abhisit Sangjan "); +MODULE_DESCRIPTION("Microchip 24LC64T Driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/scripts/dx010_check_qsfp.sh b/platform/broadcom/sonic-platform-modules-cel/dx010/scripts/dx010_check_qsfp.sh new file mode 100644 index 000000000000..938b07952e0d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/scripts/dx010_check_qsfp.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +#Usage: +# TBD + +echo "Do we need to check qsfp?" + diff --git a/platform/broadcom/sonic-platform-modules-dell b/platform/broadcom/sonic-platform-modules-dell deleted file mode 160000 index 811e6207330e..000000000000 --- a/platform/broadcom/sonic-platform-modules-dell +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 811e6207330e05ba68d950d4a19ccc573e7b9ee4 diff --git a/platform/broadcom/sonic-platform-modules-dell/.gitignore b/platform/broadcom/sonic-platform-modules-dell/.gitignore new file mode 100644 index 000000000000..f805e810e5c6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/.gitignore @@ -0,0 +1,33 @@ +# Object files +*.o +*.ko +*.obj +*.elf + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su diff --git a/platform/broadcom/sonic-platform-modules-dell/LICENSE b/platform/broadcom/sonic-platform-modules-dell/LICENSE new file mode 100644 index 000000000000..243a846ea80b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/LICENSE @@ -0,0 +1,16 @@ +Copyright (C) 2016 Microsoft, Inc +Copyright (C) 2017 Dell, 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/broadcom/sonic-platform-modules-dell/README.md b/platform/broadcom/sonic-platform-modules-dell/README.md new file mode 100644 index 000000000000..a9f5358192ad --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/README.md @@ -0,0 +1 @@ +platform drivers for Dell Z9100 for the SONiC project diff --git a/platform/broadcom/sonic-platform-modules-dell/common/dell_i2c_utils.sh b/platform/broadcom/sonic-platform-modules-dell/common/dell_i2c_utils.sh new file mode 100755 index 000000000000..896e0166dc59 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/common/dell_i2c_utils.sh @@ -0,0 +1,62 @@ +# Perform an i2c device configuration : instantiate / delete. +# Input is of the form: +# "echo [driver] > " +# where operation = "new_device" or "delete_device" + +i2c_config() { + local count=0 + local MAX_BUS_RETRY=20 + local MAX_I2C_OP_RETRY=10 + + i2c_bus_op=`echo "$@" | cut -d'>' -f 2` + i2c_bus=$(dirname $i2c_bus_op) + + # check if bus exists + while [[ "$count" -lt "$MAX_BUS_RETRY" ]]; do + [[ -e $i2c_bus ]] && break || sleep .1 + count=$((count+1)) + done + + if [[ "$count" -eq "$MAX_BUS_RETRY" ]]; then + echo "ERROR: $@ : i2c bus not created" + return + fi + + # perform the add/delete + count=0 + while [[ "$count" -lt "$MAX_I2C_OP_RETRY" ]]; do + eval "$@" > /dev/null 2>&1 + [[ $? == 0 ]] && break || sleep .2 + count=$((count+1)) + done + + if [[ "$count" -eq "$MAX_I2C_OP_RETRY" ]]; then + echo "ERROR: $@ : i2c operation failed" + return + fi +} + +# Check if a i2c bus exists. Poll for upto 2 seconds since mux creation may take time.. +# Input: bus to check for existence + +i2c_poll_bus_exists() { + local count=0 + local MAX_BUS_RETRY=20 + local i2c_bus + + i2c_bus=$1 + + # check if bus exists + while [[ "$count" -lt "$MAX_BUS_RETRY" ]]; do + [[ -e $i2c_bus ]] && break || sleep .1 + count=$((count+1)) + done + + if [[ "$count" -eq "$MAX_BUS_RETRY" ]]; then + echo "ERROR: $@ : i2c bus not created" + return 1 + else + return 0 + fi +} + diff --git a/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c b/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c new file mode 100644 index 000000000000..557976457503 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c @@ -0,0 +1,1919 @@ +/* Copyright (c) 2017 Dell Inc.* + * dell_s6100_smf.c - driver for Dell SMF + * + * Author: Per Fremrot + * Author: Paavaanan + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SIO_DRVNAME "SMF" +#define DEBUG 1 +#define LABELS 1 + +#define FANIN_MAX 12 /* Counted from 1 */ +#define VSEN_MAX 48 /* VSEN1.. */ +#define CURR_MAX 6 +#define TCPU_MAX 15 +#define PSU_MAX 4 /* TODO change to actual sensors */ + +/* Where are the sensors address/data + registers relative to the region offset */ + +#define IOREGION_OFFSET 0x10 +#define IOREGION_LENGTH 0x4 +#define SMF_ADDR_REG_OFFSET 0 +#define SMF_READ_DATA_REG_OFFSET 2 +#define SMF_REG_ADDR 0x200 +#define SMF_PROBE_ADDR 0x210 + +#define SIO_REG_DEVID 0x1 +#define SIO_Z9100_ID 0x1 +#define SIO_S6100_ID 0x2 +#define SIO_S4200_ID 0x3 +#define SIO_S5148_ID 0x4 + +/* IOM presence */ +#define IO_MODULE_STATUS 0x0310 +#define IO_MODULE_PRESENCE 0x0311 + +/* FAN Tray */ +#define S6100_MAX_NUM_FAN_TRAYS 4 +#define Z9100_MAX_NUM_FAN_TRAYS 5 + +#define MAX_NUM_FAN_TRAYS 0x00F0 +#define MAX_NUM_FANS_PER_TRAY 0x00F1 +#define FAN_TRAY_PRESENCE 0x0113 +#define FAN_STATUS_GROUP_A 0x0114 +#define FAN_STATUS_GROUP_B 0x0115 +#define FAN_TRAY_AIRFLOW 0x0116 + + +/* FAN Z9100 */ +#define SMF_FAN_SPEED_ADDR 0x00F3 +#define FAN_TRAY_1_SPEED 0x00F3 +#define FAN_TRAY_1_FAN_2_SPEED 0x00F5 +#define FAN_TRAY_2_SPEED 0x00F7 +#define FAN_TRAY_2_FAN_2_SPEED 0x00F9 +#define FAN_TRAY_3_SPEED 0x00FB +#define FAN_TRAY_3_FAN_2_SPEED 0x00FD +#define FAN_TRAY_4_SPEED 0x00FF +#define FAN_TRAY_4_FAN_2_SPEED 0x0101 +#define FAN_TRAY_5_FAN_1_SPEED 0x0103 +#define FAN_TRAY_5_FAN_2_SPEED 0x0105 +#define FAN_TRAY_5 4 +#define FAN_601_FAULT (2 + 1) +#define IN28_INPUT (27 + 1) +#define IN404_INPUT (43 + 1) +#define IOM_PRESENCE (44 + 1) +#define IOM_PRESENCE_MAX (45 + 1) +#define IN602_INPUT (1 + 1) +#define CURR22_INPUT (1 + 1) +#define CURR602_INPUT (3 + 1) +#define TEMP13_INPUT (12 + 1) +#define TEMP601_INPUT (13 + 1) + +/* PSUs */ +#define S6100_MAX_NUM_PSUS 2 +#define MAX_NUM_PSUS 0x0231 +#define CURRENT_TOTAL_POWER 0x0232 + +/* PSU1 */ +#define PSU_1_MAX_POWER 0x0234 +#define PSU_1_FUNCTION_SUPPORT 0x0236 +#define PSU_1_STATUS 0x0237 +#define PSU_1_TEMPERATURE 0x0239 +#define PSU_1_FAN_SPEED 0x023B +#define PSU_1_FAN_STATUS 0x023D +#define PSU_1_INPUT_VOLTAGE 0x023E +#define PSU_1_OUTPUT_VOLTAGE 0x0240 +#define PSU_1_INPUT_CURRENT 0x0242 +#define PSU_1_OUTPUT_CURRENT 0x0244 +#define PSU_1_INPUT_POWER 0x0246 +#define PSU_1_OUTPUT_POWER 0x0248 +#define PSU_1_FAN_SPEED 0x023B + +/* PSU2 */ +#define PSU_2_MAX_POWER 0x026D +#define PSU_2_FUNCTION_SUPPORT 0x026F +#define PSU_2_STATUS 0x0270 +#define PSU_2_TEMPERATURE 0x0272 +#define PSU_2_FAN_SPEED 0x0274 +#define PSU_2_FAN_STATUS 0x0276 +#define PSU_2_INPUT_VOLTAGE 0x0277 +#define PSU_2_OUTPUT_VOLTAGE 0x0279 +#define PSU_2_INPUT_CURRENT 0x027B +#define PSU_2_OUTPUT_CURRENT 0x027D +#define PSU_2_INPUT_POWER 0x027F +#define PSU_2_OUTPUT_POWER 0x0281 + +/* TEMP */ +#define TEMP_SENSOR_1 0x0014 +#define TEMP_SENSOR_1_STATUS 0x00DC +#define TEMP_SENSOR_1_HW_LIMIT 0x003E + +/* VOLTAGE */ +#define CPU_1_VOLTAGE 0x02A8 +#define IO_MODULE_1_VOLTAGE 0x02E8 +#define SWITCH_CURRENT_S6100 0x02E4 +#define SWITCH_CURRENT_Z9100 0x02E2 + +/* VOLTAGE S6100 */ +#define CPU_1_MONITOR_STATUS 0x0308 +#define CPU_2_MONITOR_STATUS 0x0309 +#define CPU_3_MONITOR_STATUS 0x030A +#define CPU_4_MONITOR_STATUS 0x030B + +/* VOLTAGE Z9100 */ +#define CPU_5_MONITOR_STATUS 0x02E6 +#define CPU_6_MONITOR_STATUS 0x02E7 +#define CPU_7_MONITOR_STATUS 0x02E8 +#define CPU_8_MONITOR_STATUS 0x02E9 + + +unsigned long *mmio; +static struct kobject *dell_kobj; +static unsigned short force_id; +module_param(force_id, ushort, 0); +int smf_ver; + + +enum kinds { + z9100smf, s6100smf +}; + + +struct smf_devices { + const char *name; + u64 tcpu_mask; + u64 vsen_mask; + u32 curr_mask; + u64 fanin_mask; + u64 psu_mask; + const char *const *temp_label; + const char *const *vsen_label; + const char *const *curr_label; + const char *const *fan_label; + const char *const *psu_label; +}; + + +static const char *const z9100_temp_label[] = { + "CPU On-board (U2900)", + "BCM Switch On-Board #1 (U44)", + "Front BCM On-Board (U4)", + "Front BCM On-Board (U2)", + "Unused", + "BCM Switch On-Board #1 (U38)", + "Unused", + "Unused", + "Rear (U2900)", + "", + "", + "", + "", + "", + "PSU 1", + "PSU 2" +}; + + +static const char *const s6100_temp_label[] = { + "CPU On-board (U2900)", + "BCM On-Board #1 (U44)", + "Front BCM On-board (U4)", + "Front BCM On-board (U2)", + "IOM #1", + "IOM #2", + "IOM #3", + "IOM #4", + "U2 Switch board?", + "Front GE", + "Front SFP+", + "BCM Internal", + "CPU Internal", + "", + "PSU 1", + "PSU 2" +}; + + +static const char *const z9100_vsen_label[] = { + /* CPU Board */ + "CPU XP3R3V_EARLY", + "CPU XP5R0V_CP", + "CPU XP3R3V_STD", + "CPU XP3R3V_CP ", + "CPU XP0R75V_VTT_A", + "CPU XP0R75V_VTT_B", + "CPU XP1R07V_CPU", + "CPU XP1R0V_CPU", + "CPU XP12R0V", + "CPU VDDR_CPU_2", + "CPU VDDR_CPU_1", + "CPU XP1R5V_CLK", + "CPU XP1R35V_CPU", + "CPU XP1R8V_CPU", + "CPU XP1R0V_CPU_VNN", + "CPU XP1R0V_CPU_VCC", + "CPU XP1R5V_EARLY", + /* Switch Board */ + "SW XP12R0V_MON", + "SW XP3R3V_MON", + "SW XP1R8V_MON", + "SW XP1R25V_MON", + "SW XP1R2V_MON", + "SW XP1R0V_SW_MON", + "SW XP1R0V_ROV_SW_MON", + "SW XP5V_MB_MON", + "SW XP1R8V_FPGA_MON", + "SW XP3R3V_FPGA_MON", + "SW XP3R3V_EARLY_MON", + /* PSU */ + "PSU1 VIN", + "PSU1 VOUT", + "PSU2 VIN", + "PSU2 VOUT", + /* IOM 1 */ + "", + "", + "", + "", + /* IOM 2 */ + "", + "", + "", + "", + /* IOM 3 */ + "", + "", + "", + "", + /* IOM 4 */ + "", + "", + "", + "" +}; + + +static const char *const s6100_vsen_label[] = { + /* CPU Board */ + "CPU XP3R3V_EARLY", + "CPU XP5R0V_CP", + "CPU XP3R3V_STD", + "CPU XP3R3V_CP ", + "CPU XP0R75V_VTT_A", + "CPU XP0R75V_VTT_B", + "CPU XP1R07V_CPU", + "CPU XP1R0V_CPU", + "CPU XP12R0V", + "CPU VDDR_CPU_2", + "CPU VDDR_CPU_1", + "CPU XP1R5V_CLK", + "CPU XP1R35V_CPU", + "CPU XP1R8V_CPU", + "CPU XP1R0V_CPU_VNN", + "CPU XP1R0V_CPU_VCC", + "CPU XP1R5V_EARLY", + /* Switch Board */ + "SW XP12R0V_MON", + "SW XP3R3V_MON", + "SW XP1R8V_MON", + "SW XP1R25V_MON", + "SW XP1R2V_MON", + "SW XP1R0V_SW_MON", + "SW XP1R0V_ROV_SW_MON", + "XR1R0V_BCM84752_MON", + "SW XP5V_MB_MON", + "SW XP1R8V_FPGA_MON", + "SW XP3R3V_FPGA_MON", + + /* PSU */ + "PSU1 VIN", + "PSU1 VOUT", + "PSU2 VIN", + "PSU2 VOUT", + + /* IOM 1 */ + "IOM 1 #1", + "IOM 1 #2", + "IOM 1 #3", + "IOM 1 #4", + /* IOM 2 */ + "IOM 2 #1", + "IOM 2 #2", + "IOM 2 #3", + "IOM 2 #4", + /* IOM 1 */ + "IOM 3 #1", + "IOM 3 #2", + "IOM 3 #3", + "IOM 3 #4", + /* IOM 1 */ + "IOM 4 #1", + "IOM 4 #2", + "IOM 4 #3", + "IOM 4 #4" +}; + + +static const char *const z9100_curr_label[] = { + "XP1R0V", + "XP1R0V_ROV" +}; + + +static const char *const s6100_fan_label[] = { + "Tray1 Fan1", + "", + "Tray2 Fan1", + "", + "Tray3 Fan1", + "", + "Tray4 Fan1", + "", + "", + "", + "Psu1 Fan", + "Psu2 Fan" +}; + +static const char *const z9100_fan_label[] = { + "Tray1 Fan1", + "Tray1 Fan2", + "Tray2 Fan1", + "Tray2 Fan2", + "Tray3 Fan1", + "Tray3 Fan2", + "Tray4 Fan1", + "Tray4 Fan2", + "Tray5 Fan1", + "Tray5 Fan2", + "Psu1 Fan", + "Psu2 Fan" +}; + + +static const char *const s6100_psu_label[] = { + "Psu1 Input", + "Psu1 Output", + "Psu2 Input", + "Psu2 Output", +}; + +static const struct smf_devices smf_devices[] = { + [z9100smf] = { + .name = "SMF_Z9100_ON", + .tcpu_mask=0xe1ff, + .vsen_mask=0xfffdffff, + .curr_mask=0x3f, + .fanin_mask=0xfff, + .psu_mask=0xf, + .temp_label = z9100_temp_label, + .vsen_label = z9100_vsen_label, + .curr_label = z9100_curr_label, + .fan_label = z9100_fan_label, + .psu_label = s6100_psu_label + }, + [s6100smf] = { + .name = "SMF_S6100_ON", + .tcpu_mask=0x7fff, + .vsen_mask=0xfffffefdffff, + .curr_mask=0x3f, + .fanin_mask=0xc55, + .psu_mask=0xf, + .temp_label = s6100_temp_label, + .vsen_label = s6100_vsen_label, + .curr_label = z9100_curr_label, + .fan_label = s6100_fan_label, + .psu_label = s6100_psu_label + + } +}; + + +/* + * For each registered chip, we need to keep some data in memory. + * The structure is dynamically allocated. + */ +struct smf_data { + enum kinds kind; /* Inherited from SuperIO kind */ + unsigned short addr; + struct device *hwmon_dev; + struct mutex lock; + u64 tcpu_mask; + u64 vsen_mask; + u32 curr_mask; + u64 fanin_mask; + u64 psu_mask; + const char * const *temp_label; + const char * const *vsen_label; + const char * const *curr_label; + const char * const *fan_label; + const char * const *psu_label; +}; + + +struct smf_sio_data { + int sioreg; + enum kinds kind; +}; + + +static int smf_read_reg(struct smf_data *data, u16 reg) +{ + int res; + + mutex_lock(&data->lock); + outb_p(reg>> 8, data->addr + SMF_ADDR_REG_OFFSET); + outb_p(reg & 0xff, data->addr + SMF_ADDR_REG_OFFSET + 1); + res = inb_p(data->addr + SMF_READ_DATA_REG_OFFSET); + mutex_unlock(&data->lock); + return res; +} + + +static int smf_read_reg16(struct smf_data *data, u16 reg) +{ + int res; + + mutex_lock(&data->lock); + outb_p(reg>> 8, data->addr + SMF_ADDR_REG_OFFSET); + outb_p(reg & 0xff, data->addr + SMF_ADDR_REG_OFFSET + 1); + + res = inb_p(data->addr + SMF_READ_DATA_REG_OFFSET); + + outb_p((reg + 1)>> 8, data->addr + SMF_ADDR_REG_OFFSET); + outb_p((reg + 1) & 0xff, data->addr + SMF_ADDR_REG_OFFSET + 1); + + res = (res << 8) + inb_p(data->addr + SMF_READ_DATA_REG_OFFSET); + + mutex_unlock(&data->lock); + return res; +} + + +/* FANIN ATTR */ +static ssize_t +show_fan_label(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct smf_data *data = dev_get_drvdata(dev); + int nr = to_sensor_dev_attr(attr)->index; + return sprintf(buf, "%s\n", data->fan_label[nr]); +} + + +static ssize_t show_fan(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct smf_data *data = dev_get_drvdata(dev); + int export_hex=0; + unsigned int ret = -1; + unsigned rpm; + + + if (index <10) + ret = smf_read_reg16(data, SMF_FAN_SPEED_ADDR + index * 2); + else switch (index) { + case 10: + ret = smf_read_reg16(data, PSU_1_FAN_SPEED); + break; + case 11: + ret = smf_read_reg16(data, PSU_2_FAN_SPEED); + break; + case 12: + ret = ~smf_read_reg(data, FAN_TRAY_PRESENCE); + export_hex = 1; + break; + + default: + return ret; + } + + + if (ret < 0) + return ret; + + rpm = ret; + + if(export_hex) + return sprintf(buf, "%x\n", rpm); + else + return sprintf(buf, "%u\n", rpm); +} + + +static ssize_t show_fan_fault(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct smf_data *data = dev_get_drvdata(dev); + int ret=1, fan_status; + + index = index / 2; + fan_status = ~smf_read_reg(data, FAN_TRAY_PRESENCE); + + if (fan_status & (1 << (index))) + ret=0; + + if (ret < 0) + return ret; + + return sprintf(buf, "%d\n", ret); +} + + +static ssize_t show_fan_alarm(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct smf_data *data = dev_get_drvdata(dev); + int ret, psu_fan_status=0; + + if(index < 2) + psu_fan_status = smf_read_reg(data, FAN_STATUS_GROUP_B); + + if (psu_fan_status & (1 << (index))) + ret=0; + + if (ret < 0) + return ret; + + return sprintf(buf, "%d\n", ret); +} + + +static ssize_t show_fan_airflow(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct smf_data *data = dev_get_drvdata(dev); + int ret=1, fan_airflow; + + if (data->kind == s6100smf && index == FAN_TRAY_5) + return 0; + + fan_airflow = smf_read_reg(data, FAN_TRAY_AIRFLOW); + + if (fan_airflow & (1 << (index))) + ret=1; + + if (ret < 0) + return ret; + + return sprintf(buf, "%d\n", ret); +} + + +static ssize_t show_psu_fan(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct smf_data *data = dev_get_drvdata(dev); + int ret=0, fan_status; + + if (index < FAN_601_FAULT){ + fan_status = smf_read_reg(data, PSU_1_FAN_STATUS); + ret = fan_status & (1 << index); + + } + else{ + fan_status = smf_read_reg(data, PSU_2_FAN_STATUS); + ret = fan_status & (1 << (index - 3)); + } + + if (ret < 0) + return ret; + + return sprintf(buf, "%d\n", ret); +} + + + +static umode_t smf_fanin_is_visible(struct kobject *kobj, + struct attribute *a, int n) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct smf_data *data = dev_get_drvdata(dev); + + if (data->fanin_mask & (1 << (n % FANIN_MAX))) + return a->mode; + + return 0; +} + +static umode_t smf_dell_is_visible(struct kobject *kobj, + struct attribute *a, int n) +{ + return a->mode; + +} + +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); +static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1); +static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2); +static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3); +static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4); +static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_fan, NULL, 5); +static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_fan, NULL, 6); +static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, show_fan, NULL, 7); +static SENSOR_DEVICE_ATTR(fan9_input, S_IRUGO, show_fan, NULL, 8); +static SENSOR_DEVICE_ATTR(fan10_input, S_IRUGO, show_fan, NULL,9); +/* PSU1 FAN */ +static SENSOR_DEVICE_ATTR(fan11_input, S_IRUGO, show_fan, NULL, 10); +/* PSU2 FAN */ +static SENSOR_DEVICE_ATTR(fan12_input, S_IRUGO, show_fan, NULL, 11); + +static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0); +static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 1); +static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 2); +static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 3); +static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_fan_alarm, NULL, 4); +static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_fan_alarm, NULL, 5); +static SENSOR_DEVICE_ATTR(fan7_alarm, S_IRUGO, show_fan_alarm, NULL, 6); +static SENSOR_DEVICE_ATTR(fan8_alarm, S_IRUGO, show_fan_alarm, NULL, 7); +static SENSOR_DEVICE_ATTR(fan9_alarm, S_IRUGO, show_fan_alarm, NULL, 8); +static SENSOR_DEVICE_ATTR(fan10_alarm, S_IRUGO, show_fan_alarm, NULL, 9); +static SENSOR_DEVICE_ATTR(fan11_alarm, S_IRUGO, show_psu_fan, NULL, 1); +static SENSOR_DEVICE_ATTR(fan12_alarm, S_IRUGO, show_psu_fan, NULL, 4); + +static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, show_fan_fault, NULL, 0); +static SENSOR_DEVICE_ATTR(fan2_fault, S_IRUGO, show_fan_fault, NULL, 1); +static SENSOR_DEVICE_ATTR(fan3_fault, S_IRUGO, show_fan_fault, NULL, 2); +static SENSOR_DEVICE_ATTR(fan4_fault, S_IRUGO, show_fan_fault, NULL, 3); +static SENSOR_DEVICE_ATTR(fan5_fault, S_IRUGO, show_fan_fault, NULL, 4); +static SENSOR_DEVICE_ATTR(fan6_fault, S_IRUGO, show_fan_fault, NULL, 5); +static SENSOR_DEVICE_ATTR(fan7_fault, S_IRUGO, show_fan_fault, NULL, 6); +static SENSOR_DEVICE_ATTR(fan8_fault, S_IRUGO, show_fan_fault, NULL, 7); +static SENSOR_DEVICE_ATTR(fan9_fault, S_IRUGO, show_fan_fault, NULL, 8); +static SENSOR_DEVICE_ATTR(fan10_fault, S_IRUGO, show_fan_fault, NULL, 9); +static SENSOR_DEVICE_ATTR(fan11_fault, S_IRUGO, show_psu_fan, NULL, 2); +static SENSOR_DEVICE_ATTR(fan12_fault, S_IRUGO, show_psu_fan, NULL, 5); + +static SENSOR_DEVICE_ATTR(fan1_label, S_IRUGO, show_fan_label, NULL, 0); +static SENSOR_DEVICE_ATTR(fan2_label, S_IRUGO, show_fan_label, NULL, 1); +static SENSOR_DEVICE_ATTR(fan3_label, S_IRUGO, show_fan_label, NULL, 2); +static SENSOR_DEVICE_ATTR(fan4_label, S_IRUGO, show_fan_label, NULL, 3); +static SENSOR_DEVICE_ATTR(fan5_label, S_IRUGO, show_fan_label, NULL, 4); +static SENSOR_DEVICE_ATTR(fan6_label, S_IRUGO, show_fan_label, NULL, 5); +static SENSOR_DEVICE_ATTR(fan7_label, S_IRUGO, show_fan_label, NULL, 6); +static SENSOR_DEVICE_ATTR(fan8_label, S_IRUGO, show_fan_label, NULL, 7); +static SENSOR_DEVICE_ATTR(fan9_label, S_IRUGO, show_fan_label, NULL, 8); +static SENSOR_DEVICE_ATTR(fan10_label, S_IRUGO, show_fan_label, NULL, 9); +static SENSOR_DEVICE_ATTR(fan11_label, S_IRUGO, show_fan_label, NULL, 10); +static SENSOR_DEVICE_ATTR(fan12_label, S_IRUGO, show_fan_label, NULL, 11); + + +static struct attribute *smf_fanin_attrs[] = { + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan2_input.dev_attr.attr, + &sensor_dev_attr_fan3_input.dev_attr.attr, + &sensor_dev_attr_fan4_input.dev_attr.attr, + &sensor_dev_attr_fan5_input.dev_attr.attr, + &sensor_dev_attr_fan6_input.dev_attr.attr, + &sensor_dev_attr_fan7_input.dev_attr.attr, + &sensor_dev_attr_fan8_input.dev_attr.attr, + &sensor_dev_attr_fan9_input.dev_attr.attr, + &sensor_dev_attr_fan10_input.dev_attr.attr, + &sensor_dev_attr_fan11_input.dev_attr.attr, + &sensor_dev_attr_fan12_input.dev_attr.attr, + + &sensor_dev_attr_fan1_label.dev_attr.attr, + &sensor_dev_attr_fan2_label.dev_attr.attr, + &sensor_dev_attr_fan3_label.dev_attr.attr, + &sensor_dev_attr_fan4_label.dev_attr.attr, + &sensor_dev_attr_fan5_label.dev_attr.attr, + &sensor_dev_attr_fan6_label.dev_attr.attr, + &sensor_dev_attr_fan7_label.dev_attr.attr, + &sensor_dev_attr_fan8_label.dev_attr.attr, + &sensor_dev_attr_fan9_label.dev_attr.attr, + &sensor_dev_attr_fan10_label.dev_attr.attr, + &sensor_dev_attr_fan11_label.dev_attr.attr, + &sensor_dev_attr_fan12_label.dev_attr.attr, + + + &sensor_dev_attr_fan1_alarm.dev_attr.attr, + &sensor_dev_attr_fan2_alarm.dev_attr.attr, + &sensor_dev_attr_fan3_alarm.dev_attr.attr, + &sensor_dev_attr_fan4_alarm.dev_attr.attr, + &sensor_dev_attr_fan5_alarm.dev_attr.attr, + &sensor_dev_attr_fan6_alarm.dev_attr.attr, + &sensor_dev_attr_fan7_alarm.dev_attr.attr, + &sensor_dev_attr_fan8_alarm.dev_attr.attr, + &sensor_dev_attr_fan9_alarm.dev_attr.attr, + &sensor_dev_attr_fan10_alarm.dev_attr.attr, + &sensor_dev_attr_fan11_alarm.dev_attr.attr, + &sensor_dev_attr_fan12_alarm.dev_attr.attr, + + &sensor_dev_attr_fan1_fault.dev_attr.attr, + &sensor_dev_attr_fan2_fault.dev_attr.attr, + &sensor_dev_attr_fan3_fault.dev_attr.attr, + &sensor_dev_attr_fan4_fault.dev_attr.attr, + &sensor_dev_attr_fan5_fault.dev_attr.attr, + &sensor_dev_attr_fan6_fault.dev_attr.attr, + &sensor_dev_attr_fan7_fault.dev_attr.attr, + &sensor_dev_attr_fan8_fault.dev_attr.attr, + &sensor_dev_attr_fan9_fault.dev_attr.attr, + &sensor_dev_attr_fan10_fault.dev_attr.attr, + &sensor_dev_attr_fan11_fault.dev_attr.attr, + &sensor_dev_attr_fan12_fault.dev_attr.attr, + + NULL +}; + + + + +/* VSEN ATTR */ +static ssize_t +show_voltage_label(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct smf_data *data = dev_get_drvdata(dev); + int nr = to_sensor_dev_attr(attr)->index; + return sprintf(buf, "%s\n", data->vsen_label[nr]); +} + + +static ssize_t show_voltage(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct smf_data *data = dev_get_drvdata(dev); + int volt, ret=0; + int export_hex=0; + + /*0 to 27 */ + if (index < IN28_INPUT) /* Voltage sensors */ + ret = smf_read_reg16(data, CPU_1_VOLTAGE + index * 2); + else if ((data->kind == s6100smf) && (index < IN404_INPUT)) + ret = smf_read_reg16(data, IO_MODULE_1_VOLTAGE + index * 2); + else if ((data->kind == s6100smf) && (index < IOM_PRESENCE)) + ret = smf_read_reg(data, IO_MODULE_STATUS); + else if ((data->kind == s6100smf) && (index < IOM_PRESENCE_MAX)) + ret = smf_read_reg(data, IO_MODULE_PRESENCE); + + if (ret < 0) + return ret; + + if(index < 44) + volt = ret*10; + else + export_hex=1; + + if(export_hex) + return sprintf(buf, "%x\n", ret); + else + return sprintf(buf, "%d\n", volt); +} + + +static ssize_t show_psu_voltage(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct smf_data *data = dev_get_drvdata(dev); + int ret; + + if (index < 2) /* PSU1 */ + ret = smf_read_reg16(data, PSU_1_INPUT_VOLTAGE + index * 2); + else /* PSU2 */ + ret = smf_read_reg16(data, PSU_2_INPUT_VOLTAGE + ((index - 2) * 2)); + + if (ret < 0) + return ret; + + return sprintf(buf, "%d\n", ret*10); +} + + +static ssize_t show_voltage_alarm(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct smf_data *data = dev_get_drvdata(dev); + unsigned status=0; + int ret; + + if (index < 8) { + + if (data->kind == s6100smf) + status = smf_read_reg16(data, CPU_1_MONITOR_STATUS); + else + status = smf_read_reg16(data, CPU_5_MONITOR_STATUS); + + ret = status & (1 << index); + } + else if (index < 15) { + + if (data->kind == s6100smf) + ret = smf_read_reg16(data, CPU_2_MONITOR_STATUS); + else + ret = smf_read_reg16(data, CPU_6_MONITOR_STATUS); + + ret = status & (1 << index); + } + else if (index < 23) { + + if (data->kind == s6100smf) + ret = smf_read_reg16(data, CPU_3_MONITOR_STATUS); + else + ret = smf_read_reg16(data, CPU_7_MONITOR_STATUS); + + ret = status & (1 << index); + } + else { + + if (data->kind == s6100smf) + ret = smf_read_reg16(data, CPU_4_MONITOR_STATUS); + else + ret = smf_read_reg16(data, CPU_8_MONITOR_STATUS); + + ret = status & (1 << index); + } + + + if (ret < 0) + return ret; + + return sprintf(buf, "%d\n", ret); +} + + +static umode_t smf_vsen_is_visible(struct kobject *kobj, + struct attribute *a, int n) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct smf_data *data = dev_get_drvdata(dev); + + if (data->vsen_mask & (1 << (n % VSEN_MAX))) + return a->mode; + return 0; +} + +static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_voltage, NULL, 0); +static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_voltage, NULL, 1); +static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_voltage, NULL, 2); +static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_voltage, NULL, 3); +static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_voltage, NULL, 4); +static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_voltage, NULL, 5); +static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_voltage, NULL, 6); +static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, show_voltage, NULL, 7); +static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, show_voltage, NULL, 8); +static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, show_voltage, NULL, 9); +static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, show_voltage, NULL, 10); +static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, show_voltage, NULL, 11); +static SENSOR_DEVICE_ATTR(in13_input, S_IRUGO, show_voltage, NULL, 12); +static SENSOR_DEVICE_ATTR(in14_input, S_IRUGO, show_voltage, NULL, 13); +static SENSOR_DEVICE_ATTR(in15_input, S_IRUGO, show_voltage, NULL, 14); +static SENSOR_DEVICE_ATTR(in16_input, S_IRUGO, show_voltage, NULL, 15); +static SENSOR_DEVICE_ATTR(in17_input, S_IRUGO, show_voltage, NULL, 16); +static SENSOR_DEVICE_ATTR(in18_input, S_IRUGO, show_voltage, NULL, 17); +static SENSOR_DEVICE_ATTR(in19_input, S_IRUGO, show_voltage, NULL, 18); +static SENSOR_DEVICE_ATTR(in20_input, S_IRUGO, show_voltage, NULL, 19); +static SENSOR_DEVICE_ATTR(in21_input, S_IRUGO, show_voltage, NULL, 20); +static SENSOR_DEVICE_ATTR(in22_input, S_IRUGO, show_voltage, NULL, 21); +static SENSOR_DEVICE_ATTR(in23_input, S_IRUGO, show_voltage, NULL, 22); +static SENSOR_DEVICE_ATTR(in24_input, S_IRUGO, show_voltage, NULL, 23); +static SENSOR_DEVICE_ATTR(in25_input, S_IRUGO, show_voltage, NULL, 24); +static SENSOR_DEVICE_ATTR(in26_input, S_IRUGO, show_voltage, NULL, 25); +static SENSOR_DEVICE_ATTR(in27_input, S_IRUGO, show_voltage, NULL, 26); +static SENSOR_DEVICE_ATTR(in28_input, S_IRUGO, show_voltage, NULL, 27); + +/* PSU1 Voltage*/ +static SENSOR_DEVICE_ATTR(in29_input, S_IRUGO, show_psu_voltage, NULL, 0); +static SENSOR_DEVICE_ATTR(in30_input, S_IRUGO, show_psu_voltage, NULL, 1); + +/* PSU2 Voltage*/ +static SENSOR_DEVICE_ATTR(in31_input, S_IRUGO, show_psu_voltage, NULL, 2); +static SENSOR_DEVICE_ATTR(in32_input, S_IRUGO, show_psu_voltage, NULL, 3); + +/*IO Modules Voltage*/ +static SENSOR_DEVICE_ATTR(in101_input, S_IRUGO, show_voltage, NULL, 28); +static SENSOR_DEVICE_ATTR(in102_input, S_IRUGO, show_voltage, NULL, 29); +static SENSOR_DEVICE_ATTR(in103_input, S_IRUGO, show_voltage, NULL, 30); +static SENSOR_DEVICE_ATTR(in104_input, S_IRUGO, show_voltage, NULL, 31); +static SENSOR_DEVICE_ATTR(in201_input, S_IRUGO, show_voltage, NULL, 32); +static SENSOR_DEVICE_ATTR(in202_input, S_IRUGO, show_voltage, NULL, 33); +static SENSOR_DEVICE_ATTR(in203_input, S_IRUGO, show_voltage, NULL, 34); +static SENSOR_DEVICE_ATTR(in204_input, S_IRUGO, show_voltage, NULL, 35); +static SENSOR_DEVICE_ATTR(in301_input, S_IRUGO, show_voltage, NULL, 36); +static SENSOR_DEVICE_ATTR(in302_input, S_IRUGO, show_voltage, NULL, 37); +static SENSOR_DEVICE_ATTR(in303_input, S_IRUGO, show_voltage, NULL, 38); +static SENSOR_DEVICE_ATTR(in304_input, S_IRUGO, show_voltage, NULL, 39); +static SENSOR_DEVICE_ATTR(in401_input, S_IRUGO, show_voltage, NULL, 40); +static SENSOR_DEVICE_ATTR(in402_input, S_IRUGO, show_voltage, NULL, 41); +static SENSOR_DEVICE_ATTR(in403_input, S_IRUGO, show_voltage, NULL, 42); +static SENSOR_DEVICE_ATTR(in404_input, S_IRUGO, show_voltage, NULL, 43); + + + +static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO, show_voltage_label, NULL, 0); +static SENSOR_DEVICE_ATTR(in2_label, S_IRUGO, show_voltage_label, NULL, 1); +static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_voltage_label, NULL, 2); +static SENSOR_DEVICE_ATTR(in4_label, S_IRUGO, show_voltage_label, NULL, 3); +static SENSOR_DEVICE_ATTR(in5_label, S_IRUGO, show_voltage_label, NULL, 4); +static SENSOR_DEVICE_ATTR(in6_label, S_IRUGO, show_voltage_label, NULL, 5); +static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_voltage_label, NULL, 6); +static SENSOR_DEVICE_ATTR(in8_label, S_IRUGO, show_voltage_label, NULL, 7); +static SENSOR_DEVICE_ATTR(in9_label, S_IRUGO, show_voltage_label, NULL, 8); +static SENSOR_DEVICE_ATTR(in10_label, S_IRUGO, show_voltage_label, NULL, 9); +static SENSOR_DEVICE_ATTR(in11_label, S_IRUGO, show_voltage_label, NULL, 10); +static SENSOR_DEVICE_ATTR(in12_label, S_IRUGO, show_voltage_label, NULL, 11); +static SENSOR_DEVICE_ATTR(in13_label, S_IRUGO, show_voltage_label, NULL, 12); +static SENSOR_DEVICE_ATTR(in14_label, S_IRUGO, show_voltage_label, NULL, 13); +static SENSOR_DEVICE_ATTR(in15_label, S_IRUGO, show_voltage_label, NULL, 14); +static SENSOR_DEVICE_ATTR(in16_label, S_IRUGO, show_voltage_label, NULL, 15); +static SENSOR_DEVICE_ATTR(in17_label, S_IRUGO, show_voltage_label, NULL, 16); +static SENSOR_DEVICE_ATTR(in18_label, S_IRUGO, show_voltage_label, NULL, 17); +static SENSOR_DEVICE_ATTR(in19_label, S_IRUGO, show_voltage_label, NULL, 18); +static SENSOR_DEVICE_ATTR(in20_label, S_IRUGO, show_voltage_label, NULL, 19); +static SENSOR_DEVICE_ATTR(in21_label, S_IRUGO, show_voltage_label, NULL, 20); +static SENSOR_DEVICE_ATTR(in22_label, S_IRUGO, show_voltage_label, NULL, 21); +static SENSOR_DEVICE_ATTR(in23_label, S_IRUGO, show_voltage_label, NULL, 22); +static SENSOR_DEVICE_ATTR(in24_label, S_IRUGO, show_voltage_label, NULL, 23); +static SENSOR_DEVICE_ATTR(in25_label, S_IRUGO, show_voltage_label, NULL, 24); +static SENSOR_DEVICE_ATTR(in26_label, S_IRUGO, show_voltage_label, NULL, 25); +static SENSOR_DEVICE_ATTR(in27_label, S_IRUGO, show_voltage_label, NULL, 26); +static SENSOR_DEVICE_ATTR(in28_label, S_IRUGO, show_voltage_label, NULL, 27); + +/* PSU1 Voltage Label*/ +static SENSOR_DEVICE_ATTR(in29_label, S_IRUGO, show_voltage_label, NULL, 28); +static SENSOR_DEVICE_ATTR(in30_label, S_IRUGO, show_voltage_label, NULL, 29); + +/* PSU2 Voltage Label*/ +static SENSOR_DEVICE_ATTR(in31_label, S_IRUGO, show_voltage_label, NULL, 30); +static SENSOR_DEVICE_ATTR(in32_label, S_IRUGO, show_voltage_label, NULL, 31); + +/*IO Modules Labels*/ +static SENSOR_DEVICE_ATTR(in101_label, S_IRUGO, show_voltage_label, NULL, 32); +static SENSOR_DEVICE_ATTR(in102_label, S_IRUGO, show_voltage_label, NULL, 33); +static SENSOR_DEVICE_ATTR(in103_label, S_IRUGO, show_voltage_label, NULL, 34); +static SENSOR_DEVICE_ATTR(in104_label, S_IRUGO, show_voltage_label, NULL, 35); +static SENSOR_DEVICE_ATTR(in201_label, S_IRUGO, show_voltage_label, NULL, 36); +static SENSOR_DEVICE_ATTR(in202_label, S_IRUGO, show_voltage_label, NULL, 37); +static SENSOR_DEVICE_ATTR(in203_label, S_IRUGO, show_voltage_label, NULL, 38); +static SENSOR_DEVICE_ATTR(in204_label, S_IRUGO, show_voltage_label, NULL, 39); +static SENSOR_DEVICE_ATTR(in301_label, S_IRUGO, show_voltage_label, NULL, 40); +static SENSOR_DEVICE_ATTR(in302_label, S_IRUGO, show_voltage_label, NULL, 41); +static SENSOR_DEVICE_ATTR(in303_label, S_IRUGO, show_voltage_label, NULL, 42); +static SENSOR_DEVICE_ATTR(in304_label, S_IRUGO, show_voltage_label, NULL, 43); +static SENSOR_DEVICE_ATTR(in401_label, S_IRUGO, show_voltage_label, NULL, 44); +static SENSOR_DEVICE_ATTR(in402_label, S_IRUGO, show_voltage_label, NULL, 45); +static SENSOR_DEVICE_ATTR(in403_label, S_IRUGO, show_voltage_label, NULL, 46); +static SENSOR_DEVICE_ATTR(in404_label, S_IRUGO, show_voltage_label, NULL, 47); + + + +/* CPU Voltage Alarm */ +static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_voltage_alarm, NULL, 0); +static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_voltage_alarm, NULL, 1); +static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_voltage_alarm, NULL, 2); +static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_voltage_alarm, NULL, 3); +static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_voltage_alarm, NULL, 4); +static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_voltage_alarm, NULL, 5); +static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_voltage_alarm, NULL, 6); +static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_voltage_alarm, NULL, 7); + +static SENSOR_DEVICE_ATTR(in9_alarm, S_IRUGO, show_voltage_alarm, NULL, 8); +static SENSOR_DEVICE_ATTR(in10_alarm, S_IRUGO, show_voltage_alarm, NULL, 9); +static SENSOR_DEVICE_ATTR(in11_alarm, S_IRUGO, show_voltage_alarm, NULL, 10); +static SENSOR_DEVICE_ATTR(in12_alarm, S_IRUGO, show_voltage_alarm, NULL, 11); +static SENSOR_DEVICE_ATTR(in13_alarm, S_IRUGO, show_voltage_alarm, NULL, 12); +static SENSOR_DEVICE_ATTR(in14_alarm, S_IRUGO, show_voltage_alarm, NULL, 13); +static SENSOR_DEVICE_ATTR(in15_alarm, S_IRUGO, show_voltage_alarm, NULL, 14); +static SENSOR_DEVICE_ATTR(in16_alarm, S_IRUGO, show_voltage_alarm, NULL, 15); + +static SENSOR_DEVICE_ATTR(in17_alarm, S_IRUGO, show_voltage_alarm, NULL, 16); +static SENSOR_DEVICE_ATTR(in18_alarm, S_IRUGO, show_voltage_alarm, NULL, 17); +static SENSOR_DEVICE_ATTR(in19_alarm, S_IRUGO, show_voltage_alarm, NULL, 18); +static SENSOR_DEVICE_ATTR(in20_alarm, S_IRUGO, show_voltage_alarm, NULL, 19); +static SENSOR_DEVICE_ATTR(in21_alarm, S_IRUGO, show_voltage_alarm, NULL, 20); +static SENSOR_DEVICE_ATTR(in22_alarm, S_IRUGO, show_voltage_alarm, NULL, 21); +static SENSOR_DEVICE_ATTR(in23_alarm, S_IRUGO, show_voltage_alarm, NULL, 22); +static SENSOR_DEVICE_ATTR(in24_alarm, S_IRUGO, show_voltage_alarm, NULL, 23); + +static SENSOR_DEVICE_ATTR(in25_alarm, S_IRUGO, show_voltage_alarm, NULL, 24); +static SENSOR_DEVICE_ATTR(in26_alarm, S_IRUGO, show_voltage_alarm, NULL, 25); +static SENSOR_DEVICE_ATTR(in27_alarm, S_IRUGO, show_voltage_alarm, NULL, 26); +static SENSOR_DEVICE_ATTR(in28_alarm, S_IRUGO, show_voltage_alarm, NULL, 27); + + + +static struct attribute *smf_vsen_attrs[] = { + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_in3_input.dev_attr.attr, + &sensor_dev_attr_in4_input.dev_attr.attr, + &sensor_dev_attr_in5_input.dev_attr.attr, + &sensor_dev_attr_in6_input.dev_attr.attr, + &sensor_dev_attr_in7_input.dev_attr.attr, + &sensor_dev_attr_in8_input.dev_attr.attr, + &sensor_dev_attr_in9_input.dev_attr.attr, + &sensor_dev_attr_in10_input.dev_attr.attr, + &sensor_dev_attr_in11_input.dev_attr.attr, + &sensor_dev_attr_in12_input.dev_attr.attr, + &sensor_dev_attr_in13_input.dev_attr.attr, + &sensor_dev_attr_in14_input.dev_attr.attr, + &sensor_dev_attr_in15_input.dev_attr.attr, + &sensor_dev_attr_in16_input.dev_attr.attr, + &sensor_dev_attr_in17_input.dev_attr.attr, + &sensor_dev_attr_in18_input.dev_attr.attr, + &sensor_dev_attr_in19_input.dev_attr.attr, + &sensor_dev_attr_in20_input.dev_attr.attr, + &sensor_dev_attr_in21_input.dev_attr.attr, + &sensor_dev_attr_in22_input.dev_attr.attr, + &sensor_dev_attr_in23_input.dev_attr.attr, + &sensor_dev_attr_in24_input.dev_attr.attr, + &sensor_dev_attr_in25_input.dev_attr.attr, + &sensor_dev_attr_in26_input.dev_attr.attr, + &sensor_dev_attr_in27_input.dev_attr.attr, + &sensor_dev_attr_in28_input.dev_attr.attr, + + &sensor_dev_attr_in29_input.dev_attr.attr, + &sensor_dev_attr_in30_input.dev_attr.attr, + &sensor_dev_attr_in31_input.dev_attr.attr, + &sensor_dev_attr_in32_input.dev_attr.attr, + + &sensor_dev_attr_in101_input.dev_attr.attr, + &sensor_dev_attr_in102_input.dev_attr.attr, + &sensor_dev_attr_in103_input.dev_attr.attr, + &sensor_dev_attr_in104_input.dev_attr.attr, + &sensor_dev_attr_in201_input.dev_attr.attr, + &sensor_dev_attr_in202_input.dev_attr.attr, + &sensor_dev_attr_in203_input.dev_attr.attr, + &sensor_dev_attr_in204_input.dev_attr.attr, + &sensor_dev_attr_in301_input.dev_attr.attr, + &sensor_dev_attr_in302_input.dev_attr.attr, + &sensor_dev_attr_in303_input.dev_attr.attr, + &sensor_dev_attr_in304_input.dev_attr.attr, + &sensor_dev_attr_in401_input.dev_attr.attr, + &sensor_dev_attr_in402_input.dev_attr.attr, + &sensor_dev_attr_in403_input.dev_attr.attr, + &sensor_dev_attr_in404_input.dev_attr.attr, + + + &sensor_dev_attr_in1_label.dev_attr.attr, + &sensor_dev_attr_in2_label.dev_attr.attr, + &sensor_dev_attr_in3_label.dev_attr.attr, + &sensor_dev_attr_in4_label.dev_attr.attr, + &sensor_dev_attr_in5_label.dev_attr.attr, + &sensor_dev_attr_in6_label.dev_attr.attr, + &sensor_dev_attr_in7_label.dev_attr.attr, + &sensor_dev_attr_in8_label.dev_attr.attr, + &sensor_dev_attr_in9_label.dev_attr.attr, + &sensor_dev_attr_in10_label.dev_attr.attr, + &sensor_dev_attr_in11_label.dev_attr.attr, + &sensor_dev_attr_in12_label.dev_attr.attr, + &sensor_dev_attr_in13_label.dev_attr.attr, + &sensor_dev_attr_in14_label.dev_attr.attr, + &sensor_dev_attr_in15_label.dev_attr.attr, + &sensor_dev_attr_in16_label.dev_attr.attr, + &sensor_dev_attr_in17_label.dev_attr.attr, + &sensor_dev_attr_in18_label.dev_attr.attr, + &sensor_dev_attr_in19_label.dev_attr.attr, + &sensor_dev_attr_in20_label.dev_attr.attr, + &sensor_dev_attr_in21_label.dev_attr.attr, + &sensor_dev_attr_in22_label.dev_attr.attr, + &sensor_dev_attr_in23_label.dev_attr.attr, + &sensor_dev_attr_in24_label.dev_attr.attr, + &sensor_dev_attr_in25_label.dev_attr.attr, + &sensor_dev_attr_in26_label.dev_attr.attr, + &sensor_dev_attr_in27_label.dev_attr.attr, + &sensor_dev_attr_in28_label.dev_attr.attr, + + &sensor_dev_attr_in29_label.dev_attr.attr, + &sensor_dev_attr_in30_label.dev_attr.attr, + &sensor_dev_attr_in31_label.dev_attr.attr, + &sensor_dev_attr_in32_label.dev_attr.attr, + + &sensor_dev_attr_in101_label.dev_attr.attr, + &sensor_dev_attr_in102_label.dev_attr.attr, + &sensor_dev_attr_in103_label.dev_attr.attr, + &sensor_dev_attr_in104_label.dev_attr.attr, + &sensor_dev_attr_in201_label.dev_attr.attr, + &sensor_dev_attr_in202_label.dev_attr.attr, + &sensor_dev_attr_in203_label.dev_attr.attr, + &sensor_dev_attr_in204_label.dev_attr.attr, + &sensor_dev_attr_in301_label.dev_attr.attr, + &sensor_dev_attr_in302_label.dev_attr.attr, + &sensor_dev_attr_in303_label.dev_attr.attr, + &sensor_dev_attr_in304_label.dev_attr.attr, + &sensor_dev_attr_in401_label.dev_attr.attr, + &sensor_dev_attr_in402_label.dev_attr.attr, + &sensor_dev_attr_in403_label.dev_attr.attr, + &sensor_dev_attr_in404_label.dev_attr.attr, + + + &sensor_dev_attr_in1_alarm.dev_attr.attr, + &sensor_dev_attr_in2_alarm.dev_attr.attr, + &sensor_dev_attr_in3_alarm.dev_attr.attr, + &sensor_dev_attr_in4_alarm.dev_attr.attr, + &sensor_dev_attr_in5_alarm.dev_attr.attr, + &sensor_dev_attr_in6_alarm.dev_attr.attr, + &sensor_dev_attr_in7_alarm.dev_attr.attr, + &sensor_dev_attr_in8_alarm.dev_attr.attr, + &sensor_dev_attr_in9_alarm.dev_attr.attr, + &sensor_dev_attr_in10_alarm.dev_attr.attr, + &sensor_dev_attr_in11_alarm.dev_attr.attr, + &sensor_dev_attr_in12_alarm.dev_attr.attr, + &sensor_dev_attr_in13_alarm.dev_attr.attr, + &sensor_dev_attr_in14_alarm.dev_attr.attr, + &sensor_dev_attr_in15_alarm.dev_attr.attr, + &sensor_dev_attr_in16_alarm.dev_attr.attr, + &sensor_dev_attr_in17_alarm.dev_attr.attr, + &sensor_dev_attr_in18_alarm.dev_attr.attr, + &sensor_dev_attr_in19_alarm.dev_attr.attr, + &sensor_dev_attr_in20_alarm.dev_attr.attr, + &sensor_dev_attr_in21_alarm.dev_attr.attr, + &sensor_dev_attr_in22_alarm.dev_attr.attr, + &sensor_dev_attr_in23_alarm.dev_attr.attr, + &sensor_dev_attr_in24_alarm.dev_attr.attr, + &sensor_dev_attr_in25_alarm.dev_attr.attr, + &sensor_dev_attr_in26_alarm.dev_attr.attr, + &sensor_dev_attr_in27_alarm.dev_attr.attr, + &sensor_dev_attr_in28_alarm.dev_attr.attr, + + + NULL +}; + +static const struct attribute_group smf_vsen_group = { + .attrs = smf_vsen_attrs, + .is_visible = smf_vsen_is_visible, +}; + +/* CURRENT ATTR */ +static ssize_t +show_current_label(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct smf_data *data = dev_get_drvdata(dev); + int nr = to_sensor_dev_attr(attr)->index; + return sprintf(buf, "%s\n", data->curr_label[nr]); +} + +static ssize_t show_current(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct smf_data *data = dev_get_drvdata(dev); + int ret=0; + int curr; + + if (index < CURR22_INPUT) + if (data->kind == s6100smf) + ret = smf_read_reg16(data, SWITCH_CURRENT_S6100 + index * 2); + else + ret = smf_read_reg16(data, SWITCH_CURRENT_Z9100 + index * 2); + else if (index < CURR602_INPUT) + curr = smf_read_reg16(data, PSU_1_INPUT_CURRENT + (index % 4) * 2); + else + curr = smf_read_reg16(data, PSU_2_INPUT_CURRENT + (index % 4) * 2); + + + if (ret < 0) + return ret; + + /* TODO: docs say 10mA, value look like A? */ + if(index < 2) + curr = ret*1000; + + return sprintf(buf, "%d\n", curr); +} + + +static umode_t smf_curr_is_visible(struct kobject *kobj, + struct attribute *a, int n) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct smf_data *data = dev_get_drvdata(dev); + + if (data->curr_mask & (1 << (n % CURR_MAX))) + return a->mode; + return 0; +} + + +static SENSOR_DEVICE_ATTR(curr21_input, S_IRUGO, show_current, NULL, 0); +static SENSOR_DEVICE_ATTR(curr22_input, S_IRUGO, show_current, NULL, 1); + +static SENSOR_DEVICE_ATTR(curr601_input, S_IRUGO, show_current, NULL, 2); +static SENSOR_DEVICE_ATTR(curr602_input, S_IRUGO, show_current, NULL, 3); + +static SENSOR_DEVICE_ATTR(curr701_input, S_IRUGO, show_current, NULL, 4); +static SENSOR_DEVICE_ATTR(curr702_input, S_IRUGO, show_current, NULL, 5); + +static SENSOR_DEVICE_ATTR(curr21_label, S_IRUGO, show_current_label, NULL, 0); +static SENSOR_DEVICE_ATTR(curr22_label, S_IRUGO, show_current_label, NULL, 1); + +static SENSOR_DEVICE_ATTR(curr601_label, S_IRUGO, show_current_label, NULL, 2); +static SENSOR_DEVICE_ATTR(curr602_label, S_IRUGO, show_current_label, NULL, 3); + +static SENSOR_DEVICE_ATTR(curr701_label, S_IRUGO, show_current_label, NULL, 4); +static SENSOR_DEVICE_ATTR(curr702_label, S_IRUGO, show_current_label, NULL, 5); + + +static struct attribute *smf_curr_attrs[] = { + &sensor_dev_attr_curr21_input.dev_attr.attr, + &sensor_dev_attr_curr22_input.dev_attr.attr, + + &sensor_dev_attr_curr601_input.dev_attr.attr, + &sensor_dev_attr_curr602_input.dev_attr.attr, + + &sensor_dev_attr_curr701_input.dev_attr.attr, + &sensor_dev_attr_curr702_input.dev_attr.attr, + + &sensor_dev_attr_curr21_label.dev_attr.attr, + &sensor_dev_attr_curr22_label.dev_attr.attr, + + &sensor_dev_attr_curr601_label.dev_attr.attr, + &sensor_dev_attr_curr602_label.dev_attr.attr, + + &sensor_dev_attr_curr701_label.dev_attr.attr, + &sensor_dev_attr_curr702_label.dev_attr.attr, + + NULL +}; + + +static const struct attribute_group smf_curr_group = { + .attrs = smf_curr_attrs, + .is_visible = smf_curr_is_visible, +}; + + +/* CPU_TEMP ATTR */ +static ssize_t +show_temp_label(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct smf_data *data = dev_get_drvdata(dev); + int nr = to_sensor_dev_attr(attr)->index; + return sprintf(buf, "%s\n", data->temp_label[nr]); +} + + +static ssize_t show_tcpu(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct smf_data *data = dev_get_drvdata(dev); + int ret; + int temp; + + if (index < TEMP13_INPUT) /* Temp sensors */ + ret = smf_read_reg16(data, TEMP_SENSOR_1 + index * 2); + else if(index < TEMP601_INPUT) + ret = smf_read_reg16(data, PSU_1_TEMPERATURE); + else + ret = smf_read_reg16(data, PSU_2_TEMPERATURE); + + if (ret < 0) + return ret; + + if (ret > 65500) + ret = 0; + + if (ret & 0x8000) + ret = - (ret & 0x7fff); + + temp = ret*100; + + return sprintf(buf, "%d\n", temp); +} + + +static ssize_t show_temp_crit(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct smf_data *data = dev_get_drvdata(dev); + int ret; + int temp; + + ret = smf_read_reg16(data, TEMP_SENSOR_1_HW_LIMIT + index * 2); + if (ret < 0) + return ret; + + if (ret == 65535) + ret = 0; + + if (ret & 0x8000) + ret = - (ret & 0x7fff); + + temp = ret*100; + + return sprintf(buf, "%d\n", temp); +} + + +/*static ssize_t show_temp_alarm(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct smf_data *data = dev_get_drvdata(dev); + int ret; + int temp; + + ret = smf_read_reg16(data, TEMP_SENSOR_1_STATUS + index * 2); + + if (ret < 0) + return ret; + + temp = ret; + + return sprintf(buf, "%d\n", temp); +}*/ + + +static umode_t smf_tcpu_is_visible(struct kobject *kobj, + struct attribute *a, int n) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct smf_data *data = dev_get_drvdata(dev); + + if (data->tcpu_mask & (1 << (n % TCPU_MAX))) + return a->mode; + + return 0; +} + + +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_tcpu, NULL, 0); +static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_tcpu, NULL, 1); +static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_tcpu, NULL, 2); +static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_tcpu, NULL, 3); +static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, show_tcpu, NULL, 4); +static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO, show_tcpu, NULL, 5); +static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO, show_tcpu, NULL, 6); +static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO, show_tcpu, NULL, 7); +static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO, show_tcpu, NULL, 8); +static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO, show_tcpu, NULL, 9); +static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO, show_tcpu, NULL, 10); +static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO, show_tcpu, NULL, 11); +static SENSOR_DEVICE_ATTR(temp13_input, S_IRUGO, show_tcpu, NULL, 12); + +/* PSU1 Fan Temp */ +static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO, show_tcpu, NULL, 13); + +/* PSU2 Fan Temp */ +static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO, show_tcpu, NULL, 14); + +static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_temp_label, NULL, 0); +static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, show_temp_label, NULL, 1); +static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO, show_temp_label, NULL, 2); +static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO, show_temp_label, NULL, 3); +static SENSOR_DEVICE_ATTR(temp5_label, S_IRUGO, show_temp_label, NULL, 4); +static SENSOR_DEVICE_ATTR(temp6_label, S_IRUGO, show_temp_label, NULL, 5); +static SENSOR_DEVICE_ATTR(temp7_label, S_IRUGO, show_temp_label, NULL, 6); +static SENSOR_DEVICE_ATTR(temp8_label, S_IRUGO, show_temp_label, NULL, 7); +static SENSOR_DEVICE_ATTR(temp9_label, S_IRUGO, show_temp_label, NULL, 8); +static SENSOR_DEVICE_ATTR(temp10_label, S_IRUGO, show_temp_label, NULL, 9); +static SENSOR_DEVICE_ATTR(temp11_label, S_IRUGO, show_temp_label, NULL, 10); +static SENSOR_DEVICE_ATTR(temp12_label, S_IRUGO, show_temp_label, NULL, 11); +static SENSOR_DEVICE_ATTR(temp13_label, S_IRUGO, show_temp_label, NULL, 12); + +static SENSOR_DEVICE_ATTR(temp14_label, S_IRUGO, show_temp_label, NULL, 14); +static SENSOR_DEVICE_ATTR(temp15_label, S_IRUGO, show_temp_label, NULL, 15); + + +static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp_crit, NULL, 1); +static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp_crit, NULL, 5); +static SENSOR_DEVICE_ATTR(temp3_crit, S_IRUGO, show_temp_crit, NULL, 9); +static SENSOR_DEVICE_ATTR(temp4_crit, S_IRUGO, show_temp_crit, NULL, 13); +static SENSOR_DEVICE_ATTR(temp5_crit, S_IRUGO, show_temp_crit, NULL, 17); +static SENSOR_DEVICE_ATTR(temp6_crit, S_IRUGO, show_temp_crit, NULL, 21); +static SENSOR_DEVICE_ATTR(temp7_crit, S_IRUGO, show_temp_crit, NULL, 25); +static SENSOR_DEVICE_ATTR(temp8_crit, S_IRUGO, show_temp_crit, NULL, 29); +static SENSOR_DEVICE_ATTR(temp9_crit, S_IRUGO, show_temp_crit, NULL, 33); +static SENSOR_DEVICE_ATTR(temp10_crit, S_IRUGO, show_temp_crit, NULL, 37); +static SENSOR_DEVICE_ATTR(temp11_crit, S_IRUGO, show_temp_crit, NULL, 41); +static SENSOR_DEVICE_ATTR(temp12_crit, S_IRUGO, show_temp_crit, NULL, 45); +static SENSOR_DEVICE_ATTR(temp13_crit, S_IRUGO, show_temp_crit, NULL, 49); + +static SENSOR_DEVICE_ATTR(temp14_crit, S_IRUGO, show_temp_crit, NULL, 11); +static SENSOR_DEVICE_ATTR(temp15_crit, S_IRUGO, show_temp_crit, NULL, 11); + + +static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp_crit, NULL, 2); +static SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO, show_temp_crit, NULL, 6); +static SENSOR_DEVICE_ATTR(temp3_max, S_IRUGO, show_temp_crit, NULL, 10); +static SENSOR_DEVICE_ATTR(temp4_max, S_IRUGO, show_temp_crit, NULL, 14); +static SENSOR_DEVICE_ATTR(temp5_max, S_IRUGO, show_temp_crit, NULL, 18); +static SENSOR_DEVICE_ATTR(temp6_max, S_IRUGO, show_temp_crit, NULL, 22); +static SENSOR_DEVICE_ATTR(temp7_max, S_IRUGO, show_temp_crit, NULL, 26); +static SENSOR_DEVICE_ATTR(temp8_max, S_IRUGO, show_temp_crit, NULL, 30); +static SENSOR_DEVICE_ATTR(temp9_max, S_IRUGO, show_temp_crit, NULL, 34); +static SENSOR_DEVICE_ATTR(temp10_max, S_IRUGO, show_temp_crit, NULL, 38); +static SENSOR_DEVICE_ATTR(temp11_max, S_IRUGO, show_temp_crit, NULL, 42); +static SENSOR_DEVICE_ATTR(temp12_max, S_IRUGO, show_temp_crit, NULL, 46); +static SENSOR_DEVICE_ATTR(temp13_max, S_IRUGO, show_temp_crit, NULL, 50); + +static SENSOR_DEVICE_ATTR(temp14_max, S_IRUGO, show_temp_crit, NULL, 46); +static SENSOR_DEVICE_ATTR(temp15_max, S_IRUGO, show_temp_crit, NULL, 50); + + +static struct attribute *smf_tcpu_attrs[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp4_input.dev_attr.attr, + &sensor_dev_attr_temp5_input.dev_attr.attr, + &sensor_dev_attr_temp6_input.dev_attr.attr, + &sensor_dev_attr_temp7_input.dev_attr.attr, + &sensor_dev_attr_temp8_input.dev_attr.attr, + &sensor_dev_attr_temp9_input.dev_attr.attr, + &sensor_dev_attr_temp10_input.dev_attr.attr, + &sensor_dev_attr_temp11_input.dev_attr.attr, + &sensor_dev_attr_temp12_input.dev_attr.attr, + &sensor_dev_attr_temp13_input.dev_attr.attr, + &sensor_dev_attr_temp14_input.dev_attr.attr, + &sensor_dev_attr_temp15_input.dev_attr.attr, + + &sensor_dev_attr_temp1_label.dev_attr.attr, + &sensor_dev_attr_temp2_label.dev_attr.attr, + &sensor_dev_attr_temp3_label.dev_attr.attr, + &sensor_dev_attr_temp4_label.dev_attr.attr, + &sensor_dev_attr_temp5_label.dev_attr.attr, + &sensor_dev_attr_temp6_label.dev_attr.attr, + &sensor_dev_attr_temp7_label.dev_attr.attr, + &sensor_dev_attr_temp8_label.dev_attr.attr, + &sensor_dev_attr_temp9_label.dev_attr.attr, + &sensor_dev_attr_temp10_label.dev_attr.attr, + &sensor_dev_attr_temp11_label.dev_attr.attr, + &sensor_dev_attr_temp12_label.dev_attr.attr, + &sensor_dev_attr_temp13_label.dev_attr.attr, + &sensor_dev_attr_temp14_label.dev_attr.attr, + &sensor_dev_attr_temp15_label.dev_attr.attr, + + &sensor_dev_attr_temp1_crit.dev_attr.attr, + &sensor_dev_attr_temp2_crit.dev_attr.attr, + &sensor_dev_attr_temp3_crit.dev_attr.attr, + &sensor_dev_attr_temp4_crit.dev_attr.attr, + &sensor_dev_attr_temp5_crit.dev_attr.attr, + &sensor_dev_attr_temp6_crit.dev_attr.attr, + &sensor_dev_attr_temp7_crit.dev_attr.attr, + &sensor_dev_attr_temp8_crit.dev_attr.attr, + &sensor_dev_attr_temp9_crit.dev_attr.attr, + &sensor_dev_attr_temp10_crit.dev_attr.attr, + &sensor_dev_attr_temp11_crit.dev_attr.attr, + &sensor_dev_attr_temp12_crit.dev_attr.attr, + &sensor_dev_attr_temp13_crit.dev_attr.attr, + &sensor_dev_attr_temp14_crit.dev_attr.attr, + &sensor_dev_attr_temp15_crit.dev_attr.attr, + + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp3_max.dev_attr.attr, + &sensor_dev_attr_temp4_max.dev_attr.attr, + &sensor_dev_attr_temp5_max.dev_attr.attr, + &sensor_dev_attr_temp6_max.dev_attr.attr, + &sensor_dev_attr_temp7_max.dev_attr.attr, + &sensor_dev_attr_temp8_max.dev_attr.attr, + &sensor_dev_attr_temp9_max.dev_attr.attr, + &sensor_dev_attr_temp10_max.dev_attr.attr, + &sensor_dev_attr_temp11_max.dev_attr.attr, + &sensor_dev_attr_temp12_max.dev_attr.attr, + &sensor_dev_attr_temp13_max.dev_attr.attr, + &sensor_dev_attr_temp14_max.dev_attr.attr, + &sensor_dev_attr_temp15_max.dev_attr.attr, + + NULL +}; + + +static const struct attribute_group smf_tcpu_group = { + .attrs = smf_tcpu_attrs, + .is_visible = smf_tcpu_is_visible, +}; + + +/* PSU ATTR */ +static ssize_t +show_psu_label(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct smf_data *data = dev_get_drvdata(dev); + int nr = to_sensor_dev_attr(attr)->index; + return sprintf(buf, "%s\n", data->psu_label[nr]); +} + + +static ssize_t show_psu(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + struct smf_data *data = dev_get_drvdata(dev); + int ret=0, export_hex=0; + int psu_status=0, pow; + + switch (index) { + + case 0: + pow = smf_read_reg16(data, PSU_1_MAX_POWER); + /* TODO Fix */ + if (data->kind == s6100smf) + ret = 1000000 * 1100; + else + ret = 1000000 * 750; + break; + case 1: + ret = smf_read_reg(data, PSU_1_STATUS); + export_hex=1; + break; + case 2: + ret = 100000 * smf_read_reg16(data, PSU_1_INPUT_POWER); + break; + case 3: + ret = 100000 * smf_read_reg16(data, PSU_1_OUTPUT_POWER); + break; + case 4: + psu_status = smf_read_reg(data, PSU_1_STATUS); + if (psu_status &(1)) + ret=1; + break; + case 5: + pow = smf_read_reg16(data, PSU_2_MAX_POWER); + ret = 1000000 * pow; + /* TODO Fix */ + if (data->kind == s6100smf) + ret = 1000000 * 1100; + else + ret = 1000000 * 750; + break; + case 6: + ret = smf_read_reg(data, PSU_2_STATUS); + export_hex=1; + break; + case 7: + ret = 100000 * smf_read_reg16(data, PSU_2_INPUT_POWER); + break; + case 8: + ret = 100000 * smf_read_reg16(data, PSU_2_OUTPUT_POWER); + break; + case 9: + psu_status = smf_read_reg(data, PSU_2_STATUS); + if (psu_status &(1)) + ret=1; + break; + case 10: + pow = smf_read_reg16(data, CURRENT_TOTAL_POWER); + ret = pow/10; + break; + default: + return ret; + } + + if (ret < 0) + return ret; + + pow = ret; + + if(export_hex) + return sprintf(buf, "%x\n", pow); + else + return sprintf(buf, "%u\n", pow); +} + + +static umode_t smf_psu_is_visible(struct kobject *kobj, + struct attribute *a, int n) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct smf_data *data = dev_get_drvdata(dev); + + if (data->psu_mask & (1 << (n % PSU_MAX))) + return a->mode; + return 0; +} + +/* PSU */ +static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, show_psu, NULL, 2); +static SENSOR_DEVICE_ATTR(power2_input, S_IRUGO, show_psu, NULL, 3); +static SENSOR_DEVICE_ATTR(power3_input, S_IRUGO, show_psu, NULL, 7); +static SENSOR_DEVICE_ATTR(power4_input, S_IRUGO, show_psu, NULL, 8); + +static SENSOR_DEVICE_ATTR(power1_label, S_IRUGO, show_psu_label, NULL, 0); +static SENSOR_DEVICE_ATTR(power2_label, S_IRUGO, show_psu_label, NULL, 1); +static SENSOR_DEVICE_ATTR(power3_label, S_IRUGO, show_psu_label, NULL, 2); +static SENSOR_DEVICE_ATTR(power4_label, S_IRUGO, show_psu_label, NULL, 3); + +static SENSOR_DEVICE_ATTR(power1_max, S_IRUGO, show_psu, NULL, 0); +static SENSOR_DEVICE_ATTR(power2_max, S_IRUGO, show_psu, NULL, 0); +static SENSOR_DEVICE_ATTR(power3_max, S_IRUGO, show_psu, NULL, 5); +static SENSOR_DEVICE_ATTR(power4_max, S_IRUGO, show_psu, NULL, 5); + + +/* PSU2 */ +//static SENSOR_DEVICE_ATTR(power602_alarm, S_IRUGO, show_psu, NULL, 4); +//static SENSOR_DEVICE_ATTR(power702_alarm, S_IRUGO, show_psu, NULL, 9); + + + +static struct attribute *smf_psu_attrs[] = { + + &sensor_dev_attr_power1_input.dev_attr.attr, + &sensor_dev_attr_power2_input.dev_attr.attr, + &sensor_dev_attr_power3_input.dev_attr.attr, + &sensor_dev_attr_power4_input.dev_attr.attr, + + &sensor_dev_attr_power1_label.dev_attr.attr, + &sensor_dev_attr_power2_label.dev_attr.attr, + &sensor_dev_attr_power3_label.dev_attr.attr, + &sensor_dev_attr_power4_label.dev_attr.attr, + + &sensor_dev_attr_power1_max.dev_attr.attr, + &sensor_dev_attr_power2_max.dev_attr.attr, + &sensor_dev_attr_power3_max.dev_attr.attr, + &sensor_dev_attr_power4_max.dev_attr.attr, + + NULL +}; + + +static const struct attribute_group smf_psu_group = { + .attrs = smf_psu_attrs, + .is_visible = smf_psu_is_visible, +}; + + +static const struct attribute_group smf_fanin_group = { + .attrs = smf_fanin_attrs, + .is_visible = smf_fanin_is_visible, +}; + + +static SENSOR_DEVICE_ATTR(fan_tray_presence, S_IRUGO, show_fan, NULL, 12); +static SENSOR_DEVICE_ATTR(fan1_airflow, S_IRUGO, show_fan_airflow, NULL, 0); +static SENSOR_DEVICE_ATTR(fan3_airflow, S_IRUGO, show_fan_airflow, NULL, 1); +static SENSOR_DEVICE_ATTR(fan5_airflow, S_IRUGO, show_fan_airflow, NULL, 2); +static SENSOR_DEVICE_ATTR(fan7_airflow, S_IRUGO, show_fan_airflow, NULL, 3); +static SENSOR_DEVICE_ATTR(fan9_airflow, S_IRUGO, show_fan_airflow, NULL, 4); +static SENSOR_DEVICE_ATTR(fan11_airflow, S_IRUGO, show_psu_fan, NULL, 0); +static SENSOR_DEVICE_ATTR(fan12_airflow, S_IRUGO, show_psu_fan, NULL, 3); +/* IOM status */ +static SENSOR_DEVICE_ATTR(iom_status, S_IRUGO, show_voltage, NULL, 44); +static SENSOR_DEVICE_ATTR(iom_presence, S_IRUGO, show_voltage, NULL, 45); + +static SENSOR_DEVICE_ATTR(psu1_presence, S_IRUGO, show_psu, NULL, 1); +static SENSOR_DEVICE_ATTR(psu2_presence, S_IRUGO, show_psu, NULL, 6); +static SENSOR_DEVICE_ATTR(current_total_power, S_IRUGO, show_psu, NULL, 10); + +static struct attribute *smf_dell_attrs[] = { + &sensor_dev_attr_fan_tray_presence.dev_attr.attr, + &sensor_dev_attr_fan1_airflow.dev_attr.attr, + &sensor_dev_attr_fan3_airflow.dev_attr.attr, + &sensor_dev_attr_fan5_airflow.dev_attr.attr, + &sensor_dev_attr_fan7_airflow.dev_attr.attr, + &sensor_dev_attr_fan9_airflow.dev_attr.attr, + &sensor_dev_attr_fan11_airflow.dev_attr.attr, + &sensor_dev_attr_fan12_airflow.dev_attr.attr, + &sensor_dev_attr_iom_status.dev_attr.attr, + &sensor_dev_attr_iom_presence.dev_attr.attr, + &sensor_dev_attr_psu1_presence.dev_attr.attr, + &sensor_dev_attr_psu2_presence.dev_attr.attr, + &sensor_dev_attr_current_total_power.dev_attr.attr, + NULL +}; + +static const struct attribute_group smf_dell_group = { + .attrs = smf_dell_attrs, + .is_visible = smf_dell_is_visible, +}; + + +static const struct attribute_group *smf_groups[] = { + &smf_psu_group, + &smf_fanin_group, + &smf_vsen_group, + &smf_curr_group, + &smf_tcpu_group, + &smf_dell_group, + NULL +}; + + + +static int smf_probe(struct platform_device *pdev) +{ + struct smf_data *data; + struct device *dev = &pdev->dev; + struct smf_sio_data *sio_data = dev_get_platdata(dev); + struct resource *res; + int err = 0; + + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + if (!request_region(res->start, IOREGION_LENGTH, + smf_devices[sio_data->kind].name)) { + err = -EBUSY; + dev_err(dev, "Failed to request region 0x%lx-0x%lx\n", + (unsigned long)res->start, + (unsigned long)res->start + IOREGION_LENGTH - 1); + return err; + } + + data = devm_kzalloc(dev, sizeof(struct smf_data), GFP_KERNEL); + /* TODO Use probe address value */ + data->addr = SMF_PROBE_ADDR; + data->kind = sio_data->kind; + + if (!data) + return -ENOMEM; + + mutex_init(&data->lock); + + /* PSU attributes */ + data->psu_mask = smf_devices[data->kind].psu_mask; + data->psu_label = smf_devices[data->kind].psu_label; + + /* FANIN attributes */ + data->fanin_mask = smf_devices[data->kind].fanin_mask; + data->fan_label = smf_devices[data->kind].fan_label; + + /* VSEN attributes */ + data->vsen_mask = smf_devices[data->kind].vsen_mask; + data->vsen_label = smf_devices[data->kind].vsen_label; + + /* CURR attributes */ + data->curr_mask = smf_devices[data->kind].curr_mask; + data->curr_label = smf_devices[data->kind].curr_label; + + /* CPU_TEMP attributes */ + data->tcpu_mask = smf_devices[data->kind].tcpu_mask; + data->temp_label = smf_devices[data->kind].temp_label; + + data->hwmon_dev = devm_hwmon_device_register_with_groups(dev, + smf_devices[data->kind].name, + data, smf_groups); + + return PTR_ERR_OR_ZERO(data->hwmon_dev); +} + + +static int smf_remove(struct platform_device *pdev) +{ + struct resource *res; + + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + release_region(res->start, IOREGION_LENGTH); + return 0; +} + + +static struct platform_driver smf_driver = { + .driver = { + .name = "SMF", + }, + .probe = smf_probe, + .remove = smf_remove +}; + +int __init +smf_find(int sioaddr, unsigned short *addr, struct smf_sio_data *sio_data) +{ + + int val; + + if (force_id) + val = force_id; + else + val = inb(sioaddr + SIO_REG_DEVID); + + switch (val) { + case SIO_Z9100_ID: + sio_data->kind = z9100smf; + break; + case SIO_S6100_ID: + sio_data->kind = s6100smf; + break; + + default: + if (val != 0xffff) + pr_debug("unsupported chip ID: 0x%04x\n", val); + return -ENODEV; + } + + /* TODO Use define, should this be 0x200 or 0x210??? */ + *addr = sioaddr; + + pr_info("Found %s chip at %#x\n", smf_devices[sio_data->kind].name, *addr); + sio_data->sioreg = sioaddr; + + return (0); +} + + +/* + * when Super-I/O functions move to a separate file, the Super-I/O + * bus will manage the lifetime of the device and this module will only keep + * track of the smf driver. But since we platform_device_alloc(), we + * must keep track of the device + */ +static struct platform_device *pdev; + +static int __init sensors_smf_init(void) +{ + int err; + unsigned short address; + struct resource res; + struct smf_sio_data sio_data; + + /* + * initialize sio_data->kind and sio_data->sioreg. + * when Super-I/O functions move to a separate file, the Super-I/O + * driver will probe and auto-detect the presence of a + * smf hardware monitor, and call probe() + */ + + if (smf_find(SMF_REG_ADDR, &address, &sio_data)) + return -ENODEV; + + err = platform_driver_register(&smf_driver); + if (err) + goto exit; + + pdev = platform_device_alloc(SIO_DRVNAME, address); + if (!pdev) { + err = -ENOMEM; + pr_err("Device allocation failed\n"); + goto exit_unregister; + } + + err = platform_device_add_data(pdev, &sio_data, + sizeof(struct smf_sio_data)); + if (err) { + pr_err("Platform data allocation failed\n"); + goto exit_device_put; + } + + memset(&res, 0, sizeof(res)); + res.name = SIO_DRVNAME; + res.start = address + IOREGION_OFFSET; + res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1; + res.flags = IORESOURCE_IO; + + err = acpi_check_resource_conflict(&res); + if (err) + goto exit_device_put; + + err = platform_device_add_resources(pdev, &res, 1); + if (err) { + pr_err("Device resource addition failed (%d)\n", err); + goto exit_device_put; + } + + /* platform_device_add calls probe() */ + err = platform_device_add(pdev); + if (err) { + pr_err("Device addition failed (%d)\n", err); + goto exit_device_put; + } + + return 0; + +exit_device_put: + platform_device_put(pdev); +exit_unregister: + platform_driver_unregister(&smf_driver); +exit: + return err; +} + + +static void __exit sensors_smf_exit(void) +{ + platform_device_unregister(pdev); + platform_driver_unregister(&smf_driver); + + /*Remove sysfs dell_kobj*/ + kobject_put(dell_kobj); +} + + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("SMF driver"); +MODULE_PARM_DESC(force_id, "Override the detected device ID"); +MODULE_AUTHOR("Per Fremrot "); +MODULE_AUTHOR("Paavaanan "); + +module_init(sensors_smf_init); +module_exit(sensors_smf_exit); diff --git a/platform/broadcom/sonic-platform-modules-dell/common/fstrim.service b/platform/broadcom/sonic-platform-modules-dell/common/fstrim.service new file mode 100644 index 000000000000..cf740d3af34d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/common/fstrim.service @@ -0,0 +1,6 @@ +[Unit] +Description=Discard unused blocks + +[Service] +Type=oneshot +ExecStart=/sbin/fstrim -av diff --git a/platform/broadcom/sonic-platform-modules-dell/common/fstrim.timer b/platform/broadcom/sonic-platform-modules-dell/common/fstrim.timer new file mode 100644 index 000000000000..c6142dd94826 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/common/fstrim.timer @@ -0,0 +1,12 @@ +[Unit] +Description=Discard unused blocks once a week +Documentation=man:fstrim + +[Timer] +OnCalendar=weekly +OnBootSec=10min +AccuracySec=1h +Persistent=true + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/changelog b/platform/broadcom/sonic-platform-modules-dell/debian/changelog new file mode 100644 index 000000000000..90fed6f6d847 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/debian/changelog @@ -0,0 +1,11 @@ +sonic-dell-platform-modules (1.1) unstable; urgency=low + + * Add support for Dell S6100 + + -- Dell Team Wed, 08 Feb 2017 15:57:40 -0800 + +sonic-dell-platform-modules (1.0) unstable; urgency=low + + * Initial release + + -- Dell Team Mon, 6 Feb 2017 10:10:10 -0800 diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/compat b/platform/broadcom/sonic-platform-modules-dell/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/debian/compat @@ -0,0 +1 @@ +9 diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/control b/platform/broadcom/sonic-platform-modules-dell/debian/control new file mode 100644 index 000000000000..45f94e04b9eb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/debian/control @@ -0,0 +1,17 @@ +Source: sonic-dell-platform-modules +Section: main +Priority: extra +Maintainer: Dell Team +Build-Depends: debhelper (>= 8.0.0), bzip2 +Standards-Version: 3.9.3 + +Package: platform-modules-z9100 +Architecture: amd64 +Depends: linux-image-3.16.0-5-amd64 +Description: kernel modules for platform devices such as fan, led, sfp + +Package: platform-modules-s6100 +Architecture: amd64 +Depends: linux-image-3.16.0-5-amd64 +Description: kernel modules for platform devices such as fan, led, sfp + diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.init b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.init new file mode 100755 index 000000000000..c798b24ef235 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.init @@ -0,0 +1,40 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup S6100 board. +### END INIT INFO + +case "$1" in +start) + echo -n "Setting up board... " + + /usr/local/bin/iom_power_on.sh + /usr/local/bin/s6100_platform.sh init + + echo "done." + ;; + +stop) + /usr/local/bin/s6100_platform.sh deinit + echo "done." + + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/platform-modules-s6100.init {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install new file mode 100644 index 000000000000..f456acb9d812 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install @@ -0,0 +1,9 @@ +s6100/scripts/io_rd_wr.py usr/local/bin +s6100/scripts/iom_power_*.sh usr/local/bin +s6100/scripts/s6100_platform.sh usr/local/bin +common/dell_i2c_utils.sh usr/local/bin +common/fstrim.timer etc/systemd/system +common/fstrim.service etc/systemd/system +s6100/scripts/platform_sensors.py usr/local/bin +s6100/scripts/sensors usr/bin + diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.postinst b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.postinst new file mode 100644 index 000000000000..aeabe1abd27c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.postinst @@ -0,0 +1,7 @@ +# postinst script for S6100 + +# Enable fstrim +systemctl enable fstrim.timer +systemctl start fstrim.timer + +#DEBHELPER# diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.init b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.init new file mode 100755 index 000000000000..aefecf1d8158 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.init @@ -0,0 +1,40 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup Z9100 board. +### END INIT INFO + +case "$1" in +start) + echo -n "Setting up board... " + + # /usr/local/bin/iom_power_on.sh + /usr/local/bin/z9100_platform.sh init + + echo "done." + ;; + +stop) + /usr/local/bin/z9100_platform.sh deinit + echo "done." + + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/platform-modules-z9100.init {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install new file mode 100644 index 000000000000..66d24e98e89c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install @@ -0,0 +1,8 @@ +z9100/scripts/check_qsfp.sh usr/local/bin +z9100/scripts/z9100_platform.sh usr/local/bin +common/dell_i2c_utils.sh usr/local/bin +common/fstrim.timer etc/systemd/system +common/fstrim.service etc/systemd/system +z9100/scripts/platform_sensors.py usr/local/bin +z9100/scripts/sensors usr/bin +z9100/cfg/z9100-modules.conf etc/modules-load.d diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.postinst b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.postinst new file mode 100644 index 000000000000..b11ae1f274c4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.postinst @@ -0,0 +1,7 @@ +# postinst script for Z9100 + +# Enable fstrim +systemctl enable fstrim.timer +systemctl start fstrim.timer + +#DEBHELPER# diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/rules b/platform/broadcom/sonic-platform-modules-dell/debian/rules new file mode 100755 index 000000000000..12c3dffb1d4b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/debian/rules @@ -0,0 +1,45 @@ +#!/usr/bin/make -f + +export INSTALL_MOD_DIR:=extra + +KVERSION ?= $(shell uname -r) +KERNEL_SRC := /lib/modules/$(KVERSION) +MOD_SRC_DIR:= $(shell pwd) +MODULE_DIRS:= s6100 z9100 +COMMON_DIR := common + +%: + dh $@ + +override_dh_auto_build: + (for mod in $(MODULE_DIRS); do \ + if [ $$mod = "s6100" ]; then \ + cp $(COMMON_DIR)/*.c $(MOD_SRC_DIR)/$${mod}/modules/dell_s6100_lpc.c; \ + else \ + cp $(COMMON_DIR)/*.c $(MOD_SRC_DIR)/$${mod}/modules/dell_mailbox.c; \ + fi; \ + echo "making man page alias $$mod -> $$mod APIs";\ + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ + done) + +override_dh_auto_install: + (for mod in $(MODULE_DIRS); do \ + dh_installdirs -pplatform-modules-$${mod} \ + $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp $(MOD_SRC_DIR)/$${mod}/modules/*.ko \ + debian/platform-modules-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + done) + +override_dh_usrlocal: + +override_dh_clean: + dh_clean + (for mod in $(MODULE_DIRS); do \ + if [ $$mod = "s6100" ]; then \ + rm -f $(MOD_SRC_DIR)/$${mod}/modules/dell_s6100_lpc.c; \ + else \ + rm -f $(MOD_SRC_DIR)/$${mod}/modules/dell_mailbox.c; \ + fi; \ + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules clean; \ + done) + diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/modules/Makefile b/platform/broadcom/sonic-platform-modules-dell/s6100/modules/Makefile new file mode 100644 index 000000000000..0cdfbf5e67b8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/modules/Makefile @@ -0,0 +1,2 @@ +obj-m := dell_s6100_iom_cpld.o dell_s6100_lpc.o + diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/modules/dell_s6100_iom_cpld.c b/platform/broadcom/sonic-platform-modules-dell/s6100/modules/dell_s6100_iom_cpld.c new file mode 100644 index 000000000000..6cc28f707a1f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/modules/dell_s6100_iom_cpld.c @@ -0,0 +1,266 @@ + +#include // included for all kernel modules +#include // included for KERN_INFO +#include // included for __init and __exit macros +#include +#include +#include +#include + + +//iom cpld slave address +#define IOM_CPLD_SLAVE_ADD 0x3e + +//iom cpld ver register +#define IOM_CPLD_SLAVE_VER 0x00 + +//qsfp reset cntrl reg on each iom +#define QSFP_RST_CRTL_REG0 0x10 +#define QSFP_RST_CRTL_REG1 0x11 + +//qsfp lp mode reg on each iom +#define QSFP_LPMODE_REG0 0x12 +#define QSFP_LPMODE_REG1 0x13 + +//qsfp mod presence reg on each iom +#define QSFP_MOD_PRS_REG0 0x16 +#define QSFP_MOD_PRS_REG1 0x17 + + +struct cpld_data { + struct i2c_client *client; + struct mutex update_lock; +}; + + +static void dell_s6100_iom_cpld_add_client(struct i2c_client *client) +{ + struct cpld_data *data = kzalloc(sizeof(struct cpld_data), GFP_KERNEL); + + if (!data) { + dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", client->addr); + return; + } + + data->client = client; + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); +} + +static void dell_s6100_iom_cpld_remove_client(struct i2c_client *client) +{ + struct cpld_data *data = i2c_get_clientdata(client); + kfree(data); + return; +} + +int dell_s6100_iom_cpld_read(struct cpld_data *data,unsigned short cpld_addr, u8 reg) +{ + int ret = -EPERM; + u8 high_reg =0x00; + + mutex_lock(&data->update_lock); + ret = i2c_smbus_write_byte_data(data->client, high_reg,reg); + ret = i2c_smbus_read_byte(data->client); + mutex_unlock(&data->update_lock); + + return ret; +} + +int dell_s6100_iom_cpld_write(struct cpld_data *data,unsigned short cpld_addr, u8 reg, u8 value) +{ + int ret = -EIO; + u16 devdata=0; + u8 high_reg =0x00; + + mutex_lock(&data->update_lock); + devdata = (value << 8) | reg; + i2c_smbus_write_word_data(data->client,high_reg,devdata); + mutex_unlock(&data->update_lock); + + return ret; +} +static ssize_t get_cpldver(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + u8 devdata=0; + struct cpld_data *data = dev_get_drvdata(dev); + + ret = dell_s6100_iom_cpld_read(data,IOM_CPLD_SLAVE_ADD,IOM_CPLD_SLAVE_VER); + if(ret < 0) + return sprintf(buf, "read error"); + devdata = (u8)ret & 0xff; + return sprintf(buf,"IOM CPLD Version:0x%02x\n",devdata); +} + +static ssize_t get_modprs(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + u16 devdata=0; + struct cpld_data *data = dev_get_drvdata(dev); + + ret = dell_s6100_iom_cpld_read(data,IOM_CPLD_SLAVE_ADD,QSFP_MOD_PRS_REG0); + if(ret < 0) + return sprintf(buf, "read error"); + devdata = (u16)ret & 0xff; + + ret = dell_s6100_iom_cpld_read(data,IOM_CPLD_SLAVE_ADD,QSFP_MOD_PRS_REG1); + if(ret < 0) + return sprintf(buf, "read error"); + devdata |= (u16)(ret & 0xff) << 8; + + return sprintf(buf,"0x%04x\n",devdata); +} + +static ssize_t get_lpmode(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + u16 devdata=0; + struct cpld_data *data = dev_get_drvdata(dev); + + ret = dell_s6100_iom_cpld_read(data,IOM_CPLD_SLAVE_ADD,QSFP_LPMODE_REG0); + if(ret < 0) + return sprintf(buf, "read error"); + devdata = (u16)ret & 0xff; + + ret = dell_s6100_iom_cpld_read(data,IOM_CPLD_SLAVE_ADD,QSFP_LPMODE_REG1); + if(ret < 0) + return sprintf(buf, "read error"); + devdata |= (u16)(ret & 0xff) << 8; + + return sprintf(buf,"0x%04x\n",devdata); +} + +static ssize_t get_reset(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + u16 devdata=0; + struct cpld_data *data = dev_get_drvdata(dev); + + ret = dell_s6100_iom_cpld_read(data,IOM_CPLD_SLAVE_ADD,QSFP_RST_CRTL_REG0); + if(ret < 0) + return sprintf(buf, "read error"); + devdata = (u16)ret & 0xff; + + ret = dell_s6100_iom_cpld_read(data,IOM_CPLD_SLAVE_ADD,QSFP_RST_CRTL_REG1); + if(ret < 0) + return sprintf(buf, "read error"); + devdata |= (u16)(ret & 0xff) << 8; + + return sprintf(buf,"0x%04x\n",devdata); +} + +static ssize_t set_lpmode(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + unsigned long devdata; + int err; + struct cpld_data *data = dev_get_drvdata(dev); + + err = kstrtoul(buf, 16, &devdata); + if (err) + return err; + + dell_s6100_iom_cpld_write(data,IOM_CPLD_SLAVE_ADD,QSFP_LPMODE_REG0,(u8)(devdata & 0xff)); + dell_s6100_iom_cpld_write(data,IOM_CPLD_SLAVE_ADD,QSFP_LPMODE_REG1,(u8)((devdata >> 8) & 0xff)); + + return count; +} + +static ssize_t set_reset(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + unsigned long devdata; + int err; + struct cpld_data *data = dev_get_drvdata(dev); + + err = kstrtoul(buf, 16, &devdata); + if (err) + return err; + + dell_s6100_iom_cpld_write(data,IOM_CPLD_SLAVE_ADD,QSFP_RST_CRTL_REG0,(u8)(devdata & 0xff)); + dell_s6100_iom_cpld_write(data,IOM_CPLD_SLAVE_ADD,QSFP_RST_CRTL_REG1,(u8)((devdata >> 8) & 0xff)); + + return count; +} + +static DEVICE_ATTR(iom_cpld_vers,S_IRUGO,get_cpldver, NULL); +static DEVICE_ATTR(qsfp_modprs, S_IRUGO,get_modprs, NULL); +static DEVICE_ATTR(qsfp_lpmode, S_IRUGO | S_IWUSR,get_lpmode,set_lpmode); +static DEVICE_ATTR(qsfp_reset, S_IRUGO | S_IWUSR,get_reset, set_reset); + +static struct attribute *i2c_cpld_attrs[] = { + &dev_attr_qsfp_lpmode.attr, + &dev_attr_qsfp_reset.attr, + &dev_attr_qsfp_modprs.attr, + &dev_attr_iom_cpld_vers.attr, + NULL, +}; + +static struct attribute_group i2c_cpld_attr_grp = { + .attrs = i2c_cpld_attrs, +}; + +static int dell_s6100_iom_cpld_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_dbg(&client->dev, "i2c_check_functionality failed (0x%x)\n", client->addr); + status = -EIO; + goto exit; + } + + dev_info(&client->dev, "chip found\n"); + dell_s6100_iom_cpld_add_client(client); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &i2c_cpld_attr_grp); + if (status) { + printk(KERN_INFO "Cannot create sysfs\n"); + } + return 0; + +exit: + return status; +} + +static int dell_s6100_iom_cpld_remove(struct i2c_client *client) +{ + dell_s6100_iom_cpld_remove_client(client); + return 0; +} + + +static const struct i2c_device_id dell_s6100_iom_cpld_id[] = { + { "dell_s6100_iom_cpld", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, dell_s6100_iom_cpld_id); + +static struct i2c_driver dell_s6100_iom_cpld_driver = { + .driver = { + .name = "dell_s6100_iom_cpld", + }, + .probe = dell_s6100_iom_cpld_probe, + .remove = dell_s6100_iom_cpld_remove, + .id_table = dell_s6100_iom_cpld_id, +}; + + + +static int __init dell_s6100_iom_cpld_init(void) +{ + return i2c_add_driver(&dell_s6100_iom_cpld_driver); +} + +static void __exit dell_s6100_iom_cpld_exit(void) +{ + i2c_del_driver(&dell_s6100_iom_cpld_driver); +} + +MODULE_AUTHOR("Srideep Devireddy "); +MODULE_DESCRIPTION("dell_s6100_iom_cpld driver"); +MODULE_LICENSE("GPL"); + +module_init(dell_s6100_iom_cpld_init); +module_exit(dell_s6100_iom_cpld_exit); diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/README b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/README new file mode 100644 index 000000000000..b141bb05e2e4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/README @@ -0,0 +1,146 @@ +Dell S6100 64x40G support +------------------------ + +summary:- +S6100 has 64 x 40G port capacity +S6100 supports 4 IO Modules which are pluggable. Below section covers how to power on IO modules +and initialize the device drivers and configure necessary mux to send traffic. + + +Necessary drivers and scripts to package + +1) Users are expected to build necessary drivers for kernel and package to acess it on the target + + a) Mgmt phy driver + This supports BCM 54616 phy driver ( enable CONFIG_IGB in kernel config) + b) driver-support-sff-8436-eeprom.patch + c) driver-support-sff-8436-eeprom-update.patch + This driver supports QSFP EEPROM + d) dell_s6100_iom_cpld.ko + This driver provides support for cpld on 4 x 40Gig-IOM modules + e) i2c_mux_pca954x.ko + This driver provides support for i2c mux/switch (pca954x) + f) dell_s6100_lpc.ko + This driver porivide support for reading all the platform info from SMF. + + +2) Users are also expected to package below scripts for platform initialization and i2c tree creation + + a) iom_power.sh + This script is used to power on IO modules on S6100 + b) io_rd_wr.py +This script is generic LPC/io read/write utility (can also access system cpld) + +steps to platform initialization (Tested with 3.16) + +1) After power up of S6100 + + a) power up the io modules by executing (./iom_power.sh) + b) insert i2c_mux_pca954x.ko,dell_s6100_iom_cpld.ko,dell_s6100_lpc.ko + + Above 2 steps can be called by including them in below 2 step + +2) Build i2c device tree/device initialization by calling below script + + ./s6100_platform_init.sh + +3) IOM cpld devices are created under "/sys/bus/i2c/drivers/dell_s6100_iom_cpld/" + QSFP handles via sysfs i2c bus #( 15,16,17,18-003e) + iom_cpld_vers -- Displays CPLD version(RO) + qsfp_lpmode -- lpmode settings(RW) + qsfp_modprs -- modules presence (RO) + qsfp_reset -- reset settings (RW) + + ls /sys/bus/i2c/drivers/dell_s6100_iom_cpld/15-003e/ + driver/ iom_cpld_vers modalias name power/ qsfp_lpmode qsfp_modprs qsfp_reset subsystem/ uevent + +4) step 2 script also builds/attach sfp device tress in sysfs + + Example for reading EEPROM data + + cat /sys/bus/i2c/devices/19-0050/eeprom | hexdump -C + 00000000 0d 00 00 0f 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000010 00 00 00 00 00 00 18 1b 00 00 82 20 00 00 00 00 |........... ....| + 00000020 00 00 00 00 00 00 00 00 00 00 16 4d 16 4d 16 4d |...........M.M.M| + 00000030 16 4d 34 bf 44 bf 54 bf 64 bf 00 00 00 00 00 00 |.M4.D.T.d.......| + 00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + * + 00000070 00 00 00 00 00 00 00 ff ff ff ff ff ff ff ff 00 |................| + 00000080 0d 00 0c 04 00 00 00 40 40 02 d5 05 69 00 00 32 |.......@@...i..2| + 00000090 00 00 00 00 46 49 4e 49 53 41 52 20 43 4f 52 50 |....FINISAR CORP| + 000000a0 20 20 20 20 07 00 90 65 46 54 4c 34 31 30 51 45 | ...eFTL410QE| + 000000b0 31 43 20 20 20 20 20 20 41 33 42 68 07 d0 46 70 |1C A3Bh..Fp| + 000000c0 00 01 04 d0 4d 4c 54 30 30 51 33 20 20 20 20 20 |....MLT00Q3 | + 000000d0 20 20 20 20 31 32 30 31 31 35 20 20 08 00 00 38 | 120115 ...8| + 000000e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | | + 000000f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + * + 00000200 4b 00 fb 00 46 00 00 00 00 00 00 00 00 00 00 00 |K...F...........| + 00000210 94 70 6e f0 86 c4 7b 0c 00 00 00 00 00 00 00 00 |.pn...{.........| + 00000220 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + * + 00000260 00 00 11 11 00 00 00 00 00 00 00 00 00 00 22 22 |..............""| + 00000270 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + 00000280 + +5)SMF driver details/Readme are as below + + S6100 SMF + --------- + + S6100 has one SMF soc on CPU board. This is via LPC interface, provide access to all the below functionality + + a) Read sensors details on the system + b) Read PSU details on the system + c) Read fans/Fan tray details on the system + d) Read/Write to system led + + dell_s6100_lpc create entry for all the above necessary platform components as attributes in below path. + + /sys/devices/platform/dell_s6100_lpc/ + + + LED:- + ---- + + Get /set operations on sys_led + + Get operation + cat /sys/devices/platform/dell_s6100_lpc/sys_led + 0x80 + + Set operation + echo 83 > sys/devices/platform/dell_s6100_lpc/sys_led + + Sensors:- + -------- + + Max no of sensors on the system ( 11 sensors are available on fully loaded system) + + cat /sys/devices/platform/dell_s6100_lpc/max_num_temp_sensors + b + + cat /sys/devices/platform/dell_s6100_lpc/temp_sensor_1 ( temp_sensor_1 <85>.temp_sensor_11) + + Fan tray speed:- + -------------- + + /sys/devices/platform/dell_s6100_lpc/fan_tray_1_speed (fan_tray_1_speed - fan_tray_4_speed) + 13700 + + cat /sys/devices/platform/dell_s6100_lpc/psu1_max_pwr + 110 + cat /sys/devices/platform/dell_s6100_lpc/psu2_max_pwr + 110 + + cat /sys/devices/platform/dell_s6100_lpc/psu_total_pwr + 232 + + + + + + + + + diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/io_rd_wr.py b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/io_rd_wr.py new file mode 100755 index 000000000000..dc9dd09807c2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/io_rd_wr.py @@ -0,0 +1,93 @@ +#!/usr/bin/python +#Script to read/write the io based registers + +import sys +import os +import getopt +import struct + +io_resource='/dev/port' + +def usage(): + ''' This is the Usage Method ''' + + print 'Utility for IO read/write' + print '\t\t io_rd_wr.py --get --offset ' + print '\t\t io_rd_wr.py --set --val --offset ' + sys.exit(1) + +def io_reg_read(io_resource,offset): + fd=os.open(io_resource, os.O_RDONLY) + if(fd<0): + print 'file open failed %s"%io_resource' + return + if(os.lseek(fd, offset, os.SEEK_SET) != offset): + print 'lseek failed on %s'%io_resource + return + buf=os.read(fd,1) + reg_val1=ord(buf) + print 'reg value %x'%reg_val1 + os.close(fd) + +def io_reg_write(io_resource,offset,val): + fd=os.open(io_resource,os.O_RDWR) + if(fd<0): + print 'file open failed %s"%io_resource' + return + if(os.lseek(fd, offset, os.SEEK_SET) != offset): + print 'lseek failed on %s'%io_resource + return + ret=os.write(fd,struct.pack('B',val)) + if(ret != 1): + print 'write failed %d'%ret + return + os.close(fd) + +def main(argv): + + ''' The main function will read the user input from the + command line argument and process the request ''' + + opts = '' + val = '' + choice = '' + resouce = '' + offset = '' + + try: + opts, args = getopt.getopt(argv, "hgs:" , \ + ["val=","offset=","help", "get", "set"]) + + except getopt.GetoptError: + usage() + + for opt,arg in opts: + + if opt in ('-h','--help'): + choice = 'help' + + elif opt in ('-g', '--get'): + choice = 'get' + + elif opt in ('-s', '--set'): + choice = 'set' + + elif opt == '--offset': + offset = int(arg,16) + + elif opt == '--val': + val = int(arg,16) + + if choice == 'get' and offset != '': + io_reg_read(io_resource,offset) + + elif choice == 'set' and offset != '' and val != '': + io_reg_write(io_resource,offset,val) + + else: + usage() + +#Calling the main method +if __name__ == "__main__": + main(sys.argv[1:]) + diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_off.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_off.sh new file mode 100755 index 000000000000..a7671cfe589c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_off.sh @@ -0,0 +1,16 @@ +#!/bin/bash +#This script is used to power off IO modules +# IOM can be controlled via SMF using mailbox registers +# write 0x2 to 0x04D9 to power off IOM 1 +./io_rd_wr.py --set --val 0x04 --offset 0x210 +./io_rd_wr.py --set --val 0xd9 --offset 0x211 +./io_rd_wr.py --set --val 0x2 --offset 0x213 +# write 0x2 to 0x04DA to power off IOM 2 +./io_rd_wr.py --set --val 0xda --offset 0x211 +./io_rd_wr.py --set --val 0x2 --offset 0x213 +# write 0x2 to 0x04DB to power off IOM 3 +./io_rd_wr.py --set --val 0xdb --offset 0x211 +./io_rd_wr.py --set --val 0x2 --offset 0x213 +# write 0x2 to 0x04DC to power off IOM 4 +./io_rd_wr.py --set --val 0xdc --offset 0x211 +./io_rd_wr.py --set --val 0x2 --offset 0x213 diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_on.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_on.sh new file mode 100755 index 000000000000..3d31170803e1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/iom_power_on.sh @@ -0,0 +1,17 @@ +#!/bin/bash +# This script is used to power on IO modules +# IOM can be controlled via SMF using mailbox registers + +# write 0x1 to 0x04D9 to power up IOM 1 +/usr/local/bin/io_rd_wr.py --set --val 0x04 --offset 0x210 +/usr/local/bin/io_rd_wr.py --set --val 0xd9 --offset 0x211 +/usr/local/bin/io_rd_wr.py --set --val 0x1 --offset 0x213 +# write 0x1 to 0x04DA to power up IOM 2 +/usr/local/bin/io_rd_wr.py --set --val 0xda --offset 0x211 +/usr/local/bin/io_rd_wr.py --set --val 0x1 --offset 0x213 +# write 0x1 to 0x04DB to power up IOM 3 +/usr/local/bin/io_rd_wr.py --set --val 0xdb --offset 0x211 +/usr/local/bin/io_rd_wr.py --set --val 0x1 --offset 0x213 +# write 0x1 to 0x04DC to power up IOM 4 +/usr/local/bin/io_rd_wr.py --set --val 0xdc --offset 0x211 +/usr/local/bin/io_rd_wr.py --set --val 0x1 --offset 0x213 diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_sensors.py new file mode 100755 index 000000000000..fb59df1ee7f3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_sensors.py @@ -0,0 +1,322 @@ +#!/usr/bin/python + +# On S6100, the Platform Management Controller runs the +# thermal algorithm. It provides a mailbox for the Host +# to query relevant thermals. The dell_mailbox module +# provides the sysfs support for the following objects: +# * onboard temperature sensors +# * FAN trays +# * PSU +# +import os +import sys +import logging + +S6100_MAX_FAN_TRAYS = 4 +S6100_MAX_PSUS = 2 +S6100_MAX_IOMS = 4 + +MAILBOX_DIR = "/sys/devices/platform/SMF.512/hwmon/hwmon1" +iom_status_list = [] + +# Get a mailbox register + + +def get_pmc_register(reg_name): + retval = 'ERR' + mb_reg_file = MAILBOX_DIR+'/'+reg_name + + if (not os.path.isfile(mb_reg_file)): + print mb_reg_file, 'not found !' + return retval + + try: + with open(mb_reg_file, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", mb_reg_file, "file !") + + retval = retval.rstrip('\r\n') + retval = retval.lstrip(" ") + return retval + +logging.basicConfig(level=logging.DEBUG) + +if (os.path.isdir(MAILBOX_DIR)): + print 'dell-s6100-lpc' + print 'Adapter: S6100 Platform Management Controller' +else: + logging.error('S6100 Platform Management Controller module not loaded !') + # sys.exit(0) + +# Print the information for temperature sensors + + +def print_temperature_sensors(): + print("\nOnboard Temperature Sensors:") + print ' CPU: ',\ + int(get_pmc_register('temp1_input'))/1000, 'C' + print ' BCM56960 (PSU side): ',\ + int(get_pmc_register('temp2_input'))/1000, 'C' + print ' System Outlet 1 (switch board): ',\ + int(get_pmc_register('temp3_input'))/1000, 'C' + print ' BCM56960 (IO side): ',\ + int(get_pmc_register('temp4_input'))/1000, 'C' + print ' System Outlet 2 (CPU board): ',\ + int(get_pmc_register('temp9_input'))/1000, 'C' + print ' System Inlet Left (IO side): ',\ + int(get_pmc_register('temp10_input'))/1000, 'C' + print ' System Inlet Right (IO side): ',\ + int(get_pmc_register('temp11_input'))/1000, 'C' + + iom_status = get_pmc_register('iom_presence') + iom_status = int(iom_status, 16) + + iom_presence = get_pmc_register('iom_status') + + if (iom_presence != 'ERR'): + iom_presence = int(iom_presence, 16) + + # IOM presence : 0 => IOM present + # Temperature sensors 5..8 correspond to IOM 1..4 + for iom in range(0, S6100_MAX_IOMS): + if (~iom_presence & (1 << iom)): + iom_sensor_indx = iom + 5 + print ' IOM ' + str(iom + 1) + ':\t\t\t ',\ + int(get_pmc_register('temp'+str(iom_sensor_indx) + + '_input'))/1000, 'C' + + # Save the IOM Status for later use + if (~iom_status & (1 << iom)): + iom_status_list.append('ON') + else: + iom_status_list.append('OFF') + else: + iom_status_list.append('Not present') + print ' IOM ' + str(iom + 1) + ':\t\t\t ', 'Not present' + else: + logging.error('Unable to check IOM presence') + +print_temperature_sensors() + + +# Print the information for voltage sensors + + +def print_voltage_sensors(): + print("\nOnboard Voltage Sensors:") + + print ' CPU XP3R3V_EARLY ',\ + float(get_pmc_register('in1_input'))/1000, 'V' + print ' CPU XP5R0V_CP ',\ + float(get_pmc_register('in2_input'))/1000, 'V' + print ' CPU XP3R3V_STD ',\ + float(get_pmc_register('in3_input'))/1000, 'V' + print ' CPU XP3R3V_CP ',\ + float(get_pmc_register('in4_input'))/1000, 'V' + print ' CPU XP0R75V_VTT_A ',\ + float(get_pmc_register('in5_input'))/1000, 'V' + print ' CPU XPPR75V_VTT_B ',\ + float(get_pmc_register('in6_input'))/1000, 'V' + print ' CPU XP1R07V_CPU ',\ + float(get_pmc_register('in7_input'))/1000, 'V' + print ' CPU XP1R0V_CPU ',\ + float(get_pmc_register('in8_input'))/1000, 'V' + print ' CPU XP12R0V ',\ + float(get_pmc_register('in9_input'))/1000, 'V' + print ' CPU VDDR_CPU_2 ',\ + float(get_pmc_register('in10_input'))/1000, 'V' + print ' CPU VDDR_CPU_1 ',\ + float(get_pmc_register('in11_input'))/1000, 'V' + print ' CPU XP1R5V_CLK ',\ + float(get_pmc_register('in12_input'))/1000, 'V' + print ' CPU XP1R8V_CPU ',\ + float(get_pmc_register('in13_input'))/1000, 'V' + print ' CPU XP1R0V_CPU_VNN ',\ + float(get_pmc_register('in14_input'))/1000, 'V' + print ' CPU XP1R0V_CPU_VCC ',\ + float(get_pmc_register('in15_input'))/1000, 'V' + print ' CPU XP1R5V_EARLY ',\ + float(get_pmc_register('in16_input'))/1000, 'V' + print ' SW XP3R3V_MON ',\ + float(get_pmc_register('in17_input'))/1000, 'V' + print ' SW XP1R25V_MON ',\ + float(get_pmc_register('in19_input'))/1000, 'V' + print ' SW XP1R2V_MON ',\ + float(get_pmc_register('in20_input'))/1000, 'V' + print ' SW XP1R0V_SW_MON ',\ + float(get_pmc_register('in21_input'))/1000, 'V' + print ' SW XP1R0V_ROV_SW_MON ',\ + float(get_pmc_register('in22_input'))/1000, 'V' + print ' SW XR1R0V_BCM84752_MON ',\ + float(get_pmc_register('in23_input'))/1000, 'V' + print ' SW XP5V_MB_MON ',\ + float(get_pmc_register('in24_input'))/1000, 'V' + print ' SW XP3R3V_FPGA_MON ',\ + float(get_pmc_register('in26_input'))/1000, 'V' + print ' SW XP3R3V_EARLY_MON ',\ + float(get_pmc_register('in27_input'))/1000, 'V' + +print_voltage_sensors() + +# Print the information for 1 Fan Tray + + +def print_fan_tray(tray): + + Fan_Status = ['Normal', 'Abnormal'] + Airflow_Direction = ['B2F', 'F2B'] + + print ' Fan Tray ' + str(tray) + ':' + + if (tray == 1): + fan1_speed = get_pmc_register('fan1_input') + air_flow_reg = int(get_pmc_register('fan1_airflow'), 16) + fan1_status = 0 if fan1_speed >= 1000 else 1 + + print ' Fan Speed: ', fan1_speed, 'RPM' + print ' Fan State: ', Fan_Status[fan1_status] + print ' Air Flow: ', Airflow_Direction[air_flow_reg] + elif (tray == 2): + fan1_speed = get_pmc_register('fan3_input') + air_flow_reg = int(get_pmc_register('fan3_airflow'), 16) + fan1_status = 0 if fan1_speed >= 1000 else 1 + + print ' Fan Speed: ', fan1_speed, 'RPM' + print ' Fan State: ', Fan_Status[fan1_status] + print ' Air Flow: ', Airflow_Direction[air_flow_reg] + elif (tray == 3): + fan1_speed = get_pmc_register('fan5_input') + air_flow_reg = int(get_pmc_register('fan5_airflow'), 16) + fan1_status = 0 if fan1_speed >= 1000 else 1 + + print ' Fan Speed: ', fan1_speed, 'RPM' + print ' Fan State: ', Fan_Status[fan1_status] + print ' Air Flow: ', Airflow_Direction[air_flow_reg] + elif (tray == 4): + fan1_speed = get_pmc_register('fan7_input') + air_flow_reg = int(get_pmc_register('fan7_airflow'), 16) + fan1_status = 0 if fan1_speed >= 1000 else 1 + + print ' Fan Speed: ', fan1_speed, 'RPM' + print ' Fan State: ', Fan_Status[fan1_status] + print ' Air Flow: ', Airflow_Direction[air_flow_reg] + +print('\nFan Trays:') +fan_tray_presence = get_pmc_register('fan_tray_presence') + +if (fan_tray_presence != 'ERR'): + fan_tray_presence = int(fan_tray_presence, 16) + + for tray in range(0, S6100_MAX_FAN_TRAYS): + if (fan_tray_presence & (1 << tray)): + print_fan_tray(tray + 1) + else: + print '\n Fan Tray ' + str(tray + 1) + ': Not present' +else: + logging.error('Unable to read FAN presence') + +# Print the information for PSU1, PSU2 + + +def print_psu(psu): + Psu_Type = ['Mismatch', 'Normal'] + Psu_Input_Type = ['AC', 'DC'] + PSU_STATUS_TYPE_BIT = 4 + PSU_STATUS_INPUT_TYPE_BIT = 1 + PSU_FAN_PRESENT_BIT = 2 + PSU_FAN_STATUS_BIT = 1 + PSU_FAN_AIR_FLOW_BIT = 0 + Psu_Fan_Presence = ['Present', 'Absent'] + Psu_Fan_Status = ['Normal', 'Abnormal'] + Psu_Fan_Airflow = ['B2F', 'F2B'] + + print ' PSU ' + str(psu) + ':' + if (psu == 1): + psu_status = int(get_pmc_register('psu1_presence'), 16) + else: + psu_status = int(get_pmc_register('psu2_presence'), 16) + + psu_input_type = (psu_status & (1 << PSU_STATUS_INPUT_TYPE_BIT)) >>\ + PSU_STATUS_INPUT_TYPE_BIT + psu_type = (psu_status & (1 << PSU_STATUS_TYPE_BIT)) >>\ + PSU_STATUS_TYPE_BIT + + print ' Input: ', Psu_Input_Type[psu_input_type] + print ' Type: ', Psu_Type[psu_type] + + # PSU FAN details + if (psu == 1): + print ' FAN Speed: ', get_pmc_register('fan11_input'), 'RPM' + psu_fan_airflow = int(get_pmc_register('fan11_airflow')) + psu_fan_status = int(get_pmc_register('fan11_alarm')) + psu_fan_present = int(get_pmc_register('fan11_fault')) + input_voltage = float(get_pmc_register('in29_input')) / 1000 + output_voltage = float(get_pmc_register('in30_input')) / 1000 + input_current = float(get_pmc_register('curr601_input')) / 100 + output_current = float(get_pmc_register('curr602_input')) / 100 + input_power = float(get_pmc_register('power1_input')) / 1000000 + output_power = float(get_pmc_register('power2_input')) / 1000000 + if (input_power != 0): + psu_fan_temp = int(get_pmc_register('temp14_input'))/1000 + else: + print ' FAN Speed: ', get_pmc_register('fan12_input'), 'RPM' + psu_fan_airflow = int(get_pmc_register('fan12_airflow')) + psu_fan_status = int(get_pmc_register('fan12_alarm')) + psu_fan_present = int(get_pmc_register('fan12_fault')) + input_voltage = float(get_pmc_register('in31_input')) / 1000 + output_voltage = float(get_pmc_register('in32_input')) / 1000 + input_current = float(get_pmc_register('curr701_input')) / 100 + output_current = float(get_pmc_register('curr702_input')) / 100 + input_power = float(get_pmc_register('power3_input')) / 1000000 + output_power = float(get_pmc_register('power4_input')) / 1000000 + if (input_power != 0): + psu_fan_temp = int(get_pmc_register('temp15_input'))/1000 + print ' FAN: ', Psu_Fan_Presence[psu_fan_present] + print ' FAN Status: ', Psu_Fan_Status[psu_fan_status] + print ' FAN AIRFLOW: ', Psu_Fan_Airflow[psu_fan_airflow] + + # PSU input & output monitors + print ' Input Voltage: %6.2f' % (input_voltage), 'V' + + print ' Output Voltage: %6.2f' % (output_voltage), 'V' + + print ' Input Current: %6.2f' % (input_current), 'A' + + print ' Output Current: %6.2f' % (output_current), 'A' + + print ' Input Power: %6.2f' % (input_power), 'W' + + print ' Output Power: %6.2f' % (output_power), 'W' + + # PSU firmware gives spurious temperature reading without input power + if (input_power != 0): + print ' Temperature: ', psu_fan_temp, 'C' + else: + print ' Temperature: ', 'NA' + +print('\nPSUs:') +for psu in range(1, S6100_MAX_PSUS + 1): + + if (psu == 1): + psu_status = get_pmc_register('psu1_presence') + else: + psu_status = get_pmc_register('psu2_presence') + + if (psu_status != 'ERR'): + psu_status = int(psu_status, 16) + if (~psu_status & 0b1): + print_psu(psu) + else: + print '\n PSU ', psu, 'Not present' + else: + logging.error('Unable to check PSU presence') + +print '\n Total Power: ', get_pmc_register('current_total_power'), 'W' + +print('\nIO Modules:') + +for iom in range(1, S6100_MAX_IOMS+1): + print ' IOM ' + str(iom) + ' :' + iom_status_list[iom - 1] + +print '\n' diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh new file mode 100755 index 000000000000..be143cb9efe7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh @@ -0,0 +1,205 @@ +#!/bin/bash + +#platform init script for Dell S6100 + +source dell_i2c_utils.sh + +init_devnum() { + found=0 + for devnum in 0 1; do + devname=`cat /sys/bus/i2c/devices/i2c-${devnum}/name` + # iSMT adapter can be at either dffd0000 or dfff0000 + if [[ $devname == 'SMBus iSMT adapter at '* ]]; then + found=1 + break + fi + done + + [[ $found -eq 0 ]] && echo "cannot find iSMT" && exit 1 +} + +# Attach/Detach CPU board mux @ 0x70 +cpu_board_mux() { + case $1 in + "new_device") i2c_config "echo pca9547 0x70 > /sys/bus/i2c/devices/i2c-${devnum}/$1" + ;; + "delete_device") i2c_config "echo 0x70 > /sys/bus/i2c/devices/i2c-${devnum}/$1" + ;; + *) echo "s6100_platform: cpu_board_mux: invalid command !" + ;; + esac +} + +# Attach/Detach Switchboard MUX @ 0x71 +switch_board_mux() { + case $1 in + "new_device") i2c_config "echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-4/$1" + ;; + "delete_device") i2c_config "echo 0x71 > /sys/bus/i2c/devices/i2c-4/$1" + ;; + *) echo "s6100_platform: switch_board_mux : invalid command !" + ;; + esac +} + +# Attach/Detach syseeprom on CPU board +sys_eeprom() { + case $1 in + "new_device") i2c_config "echo 24c02 0x50 > /sys/bus/i2c/devices/i2c-2/$1" + ;; + "delete_device") i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-2/$1" + ;; + *) echo "s6100_platform: sys_eeprom : invalid command !" + ;; + esac +} + +#Attach/Detach CPLD devices to drivers for each IOM +switch_board_cpld() { + case $1 in + "new_device") + for ((i=14;i<=17;i++)); + do + i2c_config "echo dell_s6100_iom_cpld 0x3e > /sys/bus/i2c/devices/i2c-$i/$1" + done + ;; + "delete_device") + for ((i=14;i<=17;i++)); + do + i2c_config "echo 0x3e > /sys/bus/i2c/devices/i2c-$i/$1" + done + ;; + *) echo "s6100_platform: switch_board_cpld : invalid command !" + ;; + esac +} + +#Attach/Detach the MUX connecting all QSFPs on each IOM @0x71 and 0x72 +switch_board_qsfp_mux() { + case $1 in + "new_device") + for ((i=9;i>=6;i--)); + do + # 0x71 mux on the IOM 1 + mux_index=$(expr $i - 5) + echo "Attaching PCA9548 $mux_index" + i2c_config "echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-$i/$1" + i2c_config "echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-$i/$1" + done + ;; + "delete_device") + for ((i=9;i>=6;i--)); + do + # 0x71 mux on the IOM 1 + mux_index=$(expr $i - 5) + echo "Detaching PCA9548 $mux_index" + i2c_config "echo 0x71 > /sys/bus/i2c/devices/i2c-$devnum/i2c-$i/$1" + i2c_config "echo 0x72 > /sys/bus/i2c/devices/i2c-$devnum/i2c-$i/$1" + done + ;; + *) echo "s6100_platform: switch_board_qsfp_mux: invalid command !" + ;; + esac +} + +#Attach/Detach the SFP modules on PCA9548_2 +switch_board_sfp() { + case $1 in + "new_device") i2c_config "echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-11/$1" + i2c_config "echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-12/$1" + ;; + "delete_device") i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-11/$1" + i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-12/$1" + ;; + *) echo "s6100_platform: switch_board_sfp: invalid command !" + ;; + esac +} + +#Add/Delete ($1) a range ($2..$3) of QSFPs +qsfp_device_mod() { + case $1 in + "new_device") for ((i=$2;i<=$3;i++)); + do + i2c_config "echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-$i/$1" + done + ;; + "delete_device") for ((i=$2;i<=$3;i++)); + do + i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-$i/$1" + done + ;; + *) echo "s6100_platform: qsfp_device_mod: invalid command $1:$2,$3!" + ;; + esac +} + +# Attach/Detach 16 instances of QSFP ports on each IO modules +# eeprom can dump data using below command +switch_board_qsfp() { + if i2c_poll_bus_exists "/sys/bus/i2c/devices/i2c-18"; then + qsfp_device_mod $1 18 33 + fi + + if i2c_poll_bus_exists "/sys/bus/i2c/devices/i2c-34"; then + qsfp_device_mod $1 34 49 + fi + + if i2c_poll_bus_exists "/sys/bus/i2c/devices/i2c-50"; then + qsfp_device_mod $1 50 65 + fi + + if i2c_poll_bus_exists "/sys/bus/i2c/devices/i2c-66"; then + qsfp_device_mod $1 66 81 + fi +} + +# Enable/Disable low power mode on all QSFP ports +switch_board_qsfp_lpmode() { + case $1 in + "enable") value=0xffff + ;; + "disable") value=0x0 + ;; + *) echo "s6100_platform: switch_board_qsfp_lpmode: invalid command $1!" + return + ;; + esac + echo $value > /sys/class/i2c-adapter/i2c-14/14-003e/qsfp_lpmode + echo $value > /sys/class/i2c-adapter/i2c-15/15-003e/qsfp_lpmode + echo $value > /sys/class/i2c-adapter/i2c-16/16-003e/qsfp_lpmode + echo $value > /sys/class/i2c-adapter/i2c-17/17-003e/qsfp_lpmode +} + +init_devnum + +if [[ "$1" == "init" ]]; then + modprobe i2c-dev + modprobe i2c-mux-pca954x force_deselect_on_exit=1 + modprobe dell_s6100_iom_cpld + modprobe dell_s6100_lpc + + cpu_board_mux "new_device" + switch_board_mux "new_device" + sys_eeprom "new_device" + switch_board_cpld "new_device" + switch_board_qsfp_mux "new_device" + switch_board_sfp "new_device" + switch_board_qsfp "new_device" + switch_board_qsfp_lpmode "disable" +elif [[ "$1" == "deinit" ]]; then + switch_board_sfp "delete_device" + switch_board_cpld "delete_device" + switch_board_mux "delete_device" + sys_eeprom "delete_device" + switch_board_qsfp "delete_device" + switch_board_qsfp_mux "delete_device" + cpu_board_mux "delete_device" + + modprobe -r dell_s6100_lpc + modprobe -r dell_s6100_iom_cpld + modprobe -r i2c-mux-pca954x + modprobe -r i2c-dev +else + echo "s6100_platform : Invalid option !" +fi diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/sensors b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/sensors new file mode 100755 index 000000000000..030d636a1565 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/sensors @@ -0,0 +1,7 @@ +#!/bin/bash +docker exec -i pmon sensors "$@" + +#To probe sensors not part of lm-sensors +if [ -r /usr/local/bin/platform_sensors.py ]; then + python /usr/local/bin/platform_sensors.py +fi diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/cfg/z9100-modules.conf b/platform/broadcom/sonic-platform-modules-dell/z9100/cfg/z9100-modules.conf new file mode 100644 index 000000000000..66f002a5fc94 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/cfg/z9100-modules.conf @@ -0,0 +1,15 @@ +# /etc/modules: kernel modules to load at boot time. +# +# This file contains the names of kernel modules that should be loaded +# at boot time, one per line. Lines beginning with "#" are ignored. + +i2c-i801 +i2c-isch +i2c-ismt +i2c-dev +i2c-mux +i2c-smbus + +i2c-mux-gpio +i2c-mux-pca954x + diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/modules/Makefile b/platform/broadcom/sonic-platform-modules-dell/z9100/modules/Makefile new file mode 100644 index 000000000000..46da5beec391 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/modules/Makefile @@ -0,0 +1,2 @@ +obj-m := dell_mailbox.o dell_z9100_cpld.o + diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/modules/dell_z9100_cpld.c b/platform/broadcom/sonic-platform-modules-dell/z9100/modules/dell_z9100_cpld.c new file mode 100644 index 000000000000..01c3133354b1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/modules/dell_z9100_cpld.c @@ -0,0 +1,273 @@ + + +/* Includes only 3 things. + * a. QSFP Reset control + * b. LP Mode + * c. Module Presence + */ +#include // included for all kernel modules +#include // included for KERN_INFO +#include // included for __init and __exit macros +#include +#include +#include +#include + + +//iom cpld slave address +#define IOM_CPLD_SLAVE_ADD 0x3e + +//iom cpld ver register +#define IOM_CPLD_SLAVE_VER 0x00 + +//qsfp reset cntrl reg on each iom +#define QSFP_RST_CRTL_REG0 0x10 +#define QSFP_RST_CRTL_REG1 0x11 + +//qsfp lp mode reg on each iom +#define QSFP_LPMODE_REG0 0x12 +#define QSFP_LPMODE_REG1 0x13 + +//qsfp mod presence reg on each iom +#define QSFP_MOD_PRS_REG0 0x16 +#define QSFP_MOD_PRS_REG1 0x17 + + +struct cpld_data { + struct i2c_client *client; + struct mutex update_lock; +}; + + +static void dell_z9100_iom_cpld_add_client(struct i2c_client *client) +{ + struct cpld_data *data = kzalloc(sizeof(struct cpld_data), GFP_KERNEL); + + if (!data) { + dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", client->addr); + return; + } + + data->client = client; + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); +} + +static void dell_z9100_iom_cpld_remove_client(struct i2c_client *client) +{ + struct cpld_data *data = i2c_get_clientdata(client); + kfree(data); + return ; +} + +int dell_z9100_iom_cpld_read(struct cpld_data *data, u8 reg) +{ + int ret = -EPERM; + u8 high_reg =0x00; + + mutex_lock(&data->update_lock); + + ret = i2c_smbus_write_byte_data(data->client, high_reg,reg); + ret = i2c_smbus_read_byte(data->client); + mutex_unlock(&data->update_lock); + + return ret; +} + +int dell_z9100_iom_cpld_write(struct cpld_data *data,u8 reg, u8 value) +{ + int ret = -EIO; + u16 devdata=0; + u8 high_reg =0x00; + + mutex_lock(&data->update_lock); + devdata = (value << 8) | reg; + i2c_smbus_write_word_data(data->client,high_reg,devdata); + mutex_unlock(&data->update_lock); + + return ret; +} +static ssize_t get_cpldver(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + u8 devdata=0; + struct cpld_data *data = dev_get_drvdata(dev); + + ret = dell_z9100_iom_cpld_read(data,IOM_CPLD_SLAVE_VER); + if(ret < 0) + return sprintf(buf, "read error"); + devdata = (u8)ret & 0xff; + return sprintf(buf,"IOM CPLD Version:0x%02x\n",devdata); +} + +static ssize_t get_modprs(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + u16 devdata=0; + struct cpld_data *data = dev_get_drvdata(dev); + + ret = dell_z9100_iom_cpld_read(data,QSFP_MOD_PRS_REG0); + if(ret < 0) + return sprintf(buf, "read error"); + devdata = (u16)ret & 0xff; + + ret = dell_z9100_iom_cpld_read(data,QSFP_MOD_PRS_REG1); + if(ret < 0) + return sprintf(buf, "read error"); + devdata |= (u16)(ret & 0xff) << 8; + + return sprintf(buf,"0x%04x\n",devdata); +} + +static ssize_t get_lpmode(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + u16 devdata=0; + struct cpld_data *data = dev_get_drvdata(dev); + + ret = dell_z9100_iom_cpld_read(data,QSFP_LPMODE_REG0); + if(ret < 0) + return sprintf(buf, "read error"); + devdata = (u16)ret & 0xff; + + ret = dell_z9100_iom_cpld_read(data,QSFP_LPMODE_REG1); + if(ret < 0) + return sprintf(buf, "read error"); + devdata |= (u16)(ret & 0xff) << 8; + + return sprintf(buf,"0x%04x\n",devdata); +} + +static ssize_t get_reset(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + u16 devdata=0; + struct cpld_data *data = dev_get_drvdata(dev); + + ret = dell_z9100_iom_cpld_read(data,QSFP_RST_CRTL_REG0); + if(ret < 0) + return sprintf(buf, "read error"); + devdata = (u16)ret & 0xff; + + ret = dell_z9100_iom_cpld_read(data,QSFP_RST_CRTL_REG1); + if(ret < 0) + return sprintf(buf, "read error"); + devdata |= (u16)(ret & 0xff) << 8; + + return sprintf(buf,"0x%04x\n",devdata); +} + +static ssize_t set_lpmode(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + unsigned long devdata; + int err; + struct cpld_data *data = dev_get_drvdata(dev); + + err = kstrtoul(buf, 16, &devdata); + if (err) + return err; + + dell_z9100_iom_cpld_write(data,QSFP_LPMODE_REG0,(u8)(devdata & 0xff)); + dell_z9100_iom_cpld_write(data,QSFP_LPMODE_REG1,(u8)((devdata >> 8) & 0xff)); + + return count; +} + +static ssize_t set_reset(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + unsigned long devdata; + int err; + struct cpld_data *data = dev_get_drvdata(dev); + + err = kstrtoul(buf, 16, &devdata); + if (err) + return err; + + dell_z9100_iom_cpld_write(data,QSFP_RST_CRTL_REG0,(u8)(devdata & 0xff)); + dell_z9100_iom_cpld_write(data,QSFP_RST_CRTL_REG1,(u8)((devdata >> 8) & 0xff)); + + return count; +} + +static DEVICE_ATTR(iom_cpld_vers,S_IRUGO,get_cpldver, NULL); +static DEVICE_ATTR(qsfp_modprs, S_IRUGO,get_modprs, NULL); +static DEVICE_ATTR(qsfp_lpmode, S_IRUGO | S_IWUSR,get_lpmode,set_lpmode); +static DEVICE_ATTR(qsfp_reset, S_IRUGO | S_IWUSR,get_reset, set_reset); + +static struct attribute *i2c_cpld_attrs[] = { + &dev_attr_qsfp_lpmode.attr, + &dev_attr_qsfp_reset.attr, + &dev_attr_qsfp_modprs.attr, + &dev_attr_iom_cpld_vers.attr, + NULL, +}; + +static struct attribute_group i2c_cpld_attr_grp = { + .attrs = i2c_cpld_attrs, +}; + +static int dell_z9100_iom_cpld_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_dbg(&client->dev, "i2c_check_functionality failed (0x%x)\n", client->addr); + status = -EIO; + goto exit; + } + + dev_info(&client->dev, "chip found- New\n"); + dell_z9100_iom_cpld_add_client(client); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &i2c_cpld_attr_grp); + if (status) { + printk(KERN_INFO "Cannot create sysfs\n"); + } + return 0; + +exit: + return status; +} + +static int dell_z9100_iom_cpld_remove(struct i2c_client *client) +{ + dell_z9100_iom_cpld_remove_client(client); + return 0; +} + + +static const struct i2c_device_id dell_z9100_iom_cpld_id[] = { + { "dell_z9100_iom_cpld", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, dell_z9100_iom_cpld_id); + +static struct i2c_driver dell_z9100_iom_cpld_driver = { + .driver = { + .name = "dell_z9100_iom_cpld", + }, + .probe = dell_z9100_iom_cpld_probe, + .remove = dell_z9100_iom_cpld_remove, + .id_table = dell_z9100_iom_cpld_id, +}; + + + +static int __init dell_z9100_iom_cpld_init(void) +{ + return i2c_add_driver(&dell_z9100_iom_cpld_driver); +} + +static void __exit dell_z9100_iom_cpld_exit(void) +{ + i2c_del_driver(&dell_z9100_iom_cpld_driver); +} + +MODULE_AUTHOR("Srideep Devireddy "); +MODULE_DESCRIPTION("dell_z9100_iom_cpld driver"); +MODULE_LICENSE("GPL"); + +module_init(dell_z9100_iom_cpld_init); +module_exit(dell_z9100_iom_cpld_exit); diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/check_qsfp.sh b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/check_qsfp.sh new file mode 100755 index 000000000000..38f62013e46b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/check_qsfp.sh @@ -0,0 +1,60 @@ +#!/bin/bash + +#Usage: +# check_qsfp.sh qsfp10 +# check_qsfp.sh sffp2 + +# There are 34 optics ports. 32 QSFP28, 2 SFP+ +# QSFP28 is orgainized is 3 banks +# CPLD-2 QSFP-1-12 +# CPLD-3 QSFP-13-22 +# CPLD-4 QSFP-23-32 +# SFF+ 2 ports on CPLD-4 + +optics=$1 +cpld_addr="003e" + +if [ `expr match $optics qsfp` -ne 0 ] +then + type=qsfp + id=${optics:4} + + if [ $id -le 0 -o $id -gt 32 ] + then + echo "Invalid QSFP id" + return -1 + fi + if [ $id -le 12 ] + then + #cpld=2 + cpld_bus=15 + elif [ $id -le 22 ] + then + #cpld=3 + cpld_bus=16 + else + #cpld=4 + cpld_bus=17 + fi + + if [ $id -le 8 ] + then + let qsfp_bus=42+$id + elif [ $id -le 16 ] + then + let qsfp_bus=34+${id}-8 + elif [ $id -le 24 ] + then + let qsfp_bus=26+${id}-16 + else + let qsfp_bus=18+${id}-24 + fi +else + type=sff + id=${optics:3} + cpld=4 +fi + +echo "Preence:`cat /sys/class/i2c-dev/i2c-${cpld_bus}/device/${cpld_bus}-${cpld_addr}/qsfp_modprs`" +echo "Hexdump:" +cat /sys/bus/i2c/devices/${qsfp_bus}-0050/eeprom | hexdump -C diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/platform_sensors.py new file mode 100755 index 000000000000..763e65772282 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/platform_sensors.py @@ -0,0 +1,324 @@ +#!/usr/bin/python +# +# On Z9100, the Platform Management Controller runs the +# thermal algorithm. It provides a mailbox for the Host +# to query relevant thermals. The dell_mailbox module +# provides the sysfs support for the following objects: +# * onboard temperature sensors +# * FAN trays +# * PSU + +import os +import sys +import logging + +Z9100_MAX_FAN_TRAYS = 5 +Z9100_MAX_PSUS = 2 +S6100_MAX_IOMS = 4 + +MAILBOX_DIR = "/sys/devices/platform/SMF.512/hwmon/hwmon1" + +# Get a mailbox register + + +def get_pmc_register(reg_name): + retval = 'ERR' + mb_reg_file = MAILBOX_DIR+'/'+reg_name + + if (not os.path.isfile(mb_reg_file)): + print mb_reg_file, 'not found !' + return retval + + try: + with open(mb_reg_file, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", mb_reg_file, "file !") + + retval = retval.rstrip('\r\n') + retval = retval.lstrip(" ") + return retval + +logging.basicConfig(level=logging.DEBUG) + +if (os.path.isdir(MAILBOX_DIR)): + print 'dell-s6100-lpc' + print 'Adapter: S6100 Platform Management Controller' +else: + logging.error('S6100 Platform Management Controller module not loaded !') + # sys.exit(0) + +# Print the information for temperature sensors + + +def print_temperature_sensors(): + print("\nOnboard Temperature Sensors:") + print ' CPU: ',\ + int(get_pmc_register('temp1_input'))/1000, 'C' + print ' BCM56960 (PSU side): ',\ + int(get_pmc_register('temp2_input'))/1000, 'C' + print ' System Outlet 1 (switch board): ',\ + int(get_pmc_register('temp3_input'))/1000, 'C' + print ' BCM56960 (IO side): ',\ + int(get_pmc_register('temp4_input'))/1000, 'C' + print ' System Outlet 2 (CPU board): ',\ + int(get_pmc_register('temp9_input'))/1000, 'C' + print ' System Inlet Left (IO side): ',\ + int(get_pmc_register('temp6_input'))/1000, 'C' + +print_temperature_sensors() + + +# Print the information for voltage sensors + + +def print_voltage_sensors(): + print("\nOnboard Voltage Sensors:") + + print ' CPU XP3R3V_EARLY ',\ + float(get_pmc_register('in1_input'))/1000, 'V' + print '\n CPU XP5R0V_CP ',\ + float(get_pmc_register('in2_input'))/1000, 'V' + print ' CPU XP3R3V_STD ',\ + float(get_pmc_register('in3_input'))/1000, 'V' + print ' CPU XP3R3V_CP ',\ + float(get_pmc_register('in4_input'))/1000, 'V' + print ' CPU XP0R75V_VTT_A ',\ + float(get_pmc_register('in5_input'))/1000, 'V' + print ' CPU XPPR75V_VTT_B ',\ + float(get_pmc_register('in6_input'))/1000, 'V' + print ' CPU XP1R07V_CPU ',\ + float(get_pmc_register('in7_input'))/1000, 'V' + print ' CPU XP1R0V_CPU ',\ + float(get_pmc_register('in8_input'))/1000, 'V' + print ' CPU XP12R0V ',\ + float(get_pmc_register('in9_input'))/1000, 'V' + print ' CPU VDDR_CPU_2 ',\ + float(get_pmc_register('in10_input'))/1000, 'V' + print ' CPU VDDR_CPU_1 ',\ + float(get_pmc_register('in11_input'))/1000, 'V' + print ' CPU XP1R5V_CLK ',\ + float(get_pmc_register('in12_input'))/1000, 'V' + print ' CPU XP1R8V_CPU ',\ + float(get_pmc_register('in13_input'))/1000, 'V' + print ' CPU XP1R0V_CPU_VNN ',\ + float(get_pmc_register('in14_input'))/1000, 'V' + print ' CPU XP1R0V_CPU_VCC ',\ + float(get_pmc_register('in15_input'))/1000, 'V' + print ' CPU XP1R5V_EARLY ',\ + float(get_pmc_register('in16_input'))/1000, 'V' + print ' SW XP3R3V_MON ',\ + float(get_pmc_register('in17_input'))/1000, 'V' + print ' SW XP1R8V_MON ',\ + float(get_pmc_register('in19_input'))/1000, 'V' + print ' SW XP1R2V_MON ',\ + float(get_pmc_register('in20_input'))/1000, 'V' + print ' SW XP1R0V_SW_MON ',\ + float(get_pmc_register('in21_input'))/1000, 'V' + print ' SW XP1R0V_ROV_SW_MON ',\ + float(get_pmc_register('in22_input'))/1000, 'V' + print ' SW XR1R0V_BCM84752_MON ',\ + float(get_pmc_register('in23_input'))/1000, 'V' + print ' SW XP5V_MB_MON ',\ + float(get_pmc_register('in24_input'))/1000, 'V' + print ' SW XP1R8V_FPGA_MON ',\ + float(get_pmc_register('in25_input'))/1000, 'V' + print ' SW XP3R3V_FPGA_MON ',\ + float(get_pmc_register('in26_input'))/1000, 'V' + print ' SW XP3R3V_EARLY_MON ',\ + float(get_pmc_register('in27_input'))/1000, 'V' + print ' SW XP1R0V_ ',\ + float(get_pmc_register('curr21_input'))/10000, 'A' + print ' SW XP1R0V_ROV ',\ + float(get_pmc_register('curr22_input'))/10000, 'A' + + + +print_voltage_sensors() + +# Print the information for 1 Fan Tray + + +def print_fan_tray(tray): + + Fan_Status = ['Normal', 'Abnormal'] + Airflow_Direction = ['B2F', 'F2B'] + + print ' Fan Tray ' + str(tray) + ':' + + if (tray == 1): + fan1_speed = get_pmc_register('fan1_input') + fan2_speed = get_pmc_register('fan2_input') + air_flow_reg = int(get_pmc_register('fan1_airflow'), 16) + fan1_status = 0 if fan1_speed >= 1000 else 1 + fan2_status = 0 if fan2_speed >= 1000 else 1 + + print ' Fan1 Speed: ', fan1_speed, 'RPM' + print ' Fan2 Speed: ', fan2_speed, 'RPM' + print ' Fan1 State: ', Fan_Status[fan1_status] + print ' Fan2 State: ', Fan_Status[fan2_status] + print ' Air Flow: ', Airflow_Direction[air_flow_reg] + elif (tray == 2): + fan1_speed = get_pmc_register('fan3_input') + fan2_speed = get_pmc_register('fan4_input') + air_flow_reg = int(get_pmc_register('fan3_airflow'), 16) + fan1_status = 0 if fan1_speed >= 1000 else 1 + fan2_status = 0 if fan2_speed >= 1000 else 1 + + print ' Fan1 Speed: ', fan1_speed, 'RPM' + print ' Fan2 Speed: ', fan2_speed, 'RPM' + print ' Fan1 State: ', Fan_Status[fan1_status] + print ' Fan2 State: ', Fan_Status[fan2_status] + print ' Air Flow: ', Airflow_Direction[air_flow_reg] + elif (tray == 3): + fan1_speed = get_pmc_register('fan5_input') + fan2_speed = get_pmc_register('fan6_input') + air_flow_reg = int(get_pmc_register('fan5_airflow'), 16) + fan1_status = 0 if fan1_speed >= 1000 else 1 + fan2_status = 0 if fan2_speed >= 1000 else 1 + + print ' Fan1 Speed: ', fan1_speed, 'RPM' + print ' Fan2 Speed: ', fan2_speed, 'RPM' + print ' Fan1 State: ', Fan_Status[fan1_status] + print ' Fan2 State: ', Fan_Status[fan2_status] + print ' Air Flow: ', Airflow_Direction[air_flow_reg] + elif (tray == 4): + fan1_speed = get_pmc_register('fan7_input') + fan2_speed = get_pmc_register('fan8_input') + air_flow_reg = int(get_pmc_register('fan7_airflow'), 16) + fan1_status = 0 if fan1_speed >= 1000 else 1 + fan2_status = 0 if fan2_speed >= 1000 else 1 + + print ' Fan1 Speed: ', fan1_speed, 'RPM' + print ' Fan2 Speed: ', fan2_speed, 'RPM' + print ' Fan1 State: ', Fan_Status[fan1_status] + print ' Fan2 State: ', Fan_Status[fan2_status] + print ' Air Flow: ', Airflow_Direction[air_flow_reg] + elif (tray == 5): + fan1_speed = get_pmc_register('fan9_input') + fan2_speed = get_pmc_register('fan10_input') + air_flow_reg = int(get_pmc_register('fan9_airflow'), 16) + fan1_status = 0 if fan1_speed >= 1000 else 1 + fan2_status = 0 if fan2_speed >= 1000 else 1 + + print ' Fan1 Speed: ', fan1_speed, 'RPM' + print ' Fan2 Speed: ', fan2_speed, 'RPM' + print ' Fan1 State: ', Fan_Status[fan1_status] + print ' Fan2 State: ', Fan_Status[fan2_status] + print ' Air Flow: ', Airflow_Direction[air_flow_reg] + + +print('\nFan Trays:') +fan_tray_presence = get_pmc_register('fan_tray_presence') + +if (fan_tray_presence != 'ERR'): + fan_tray_presence = int(fan_tray_presence, 16) + + for tray in range(0, Z9100_MAX_FAN_TRAYS): + if (fan_tray_presence & (1 << tray)): + print_fan_tray(tray + 1) + else: + print '\n Fan Tray ' + str(tray + 1) + ': Not present' +else: + logging.error('Unable to read FAN presence') + +# Print the information for PSU1, PSU2 + + +def print_psu(psu): + Psu_Type = ['Normal', 'Mismatch'] + Psu_Input_Type = ['AC', 'DC'] + PSU_STATUS_TYPE_BIT = 4 + PSU_STATUS_INPUT_TYPE_BIT = 1 + PSU_FAN_PRESENT_BIT = 2 + PSU_FAN_STATUS_BIT = 1 + PSU_FAN_AIR_FLOW_BIT = 0 + Psu_Fan_Presence = ['Present', 'Absent'] + Psu_Fan_Status = ['Normal', 'Abnormal'] + Psu_Fan_Airflow = ['B2F', 'F2B'] + + + print ' PSU ' + str(psu) + ':' + if (psu == 1): + psu_status = int(get_pmc_register('psu1_presence'), 16) + else: + psu_status = int(get_pmc_register('psu2_presence'), 16) + + psu_input_type = (psu_status & (1 << PSU_STATUS_INPUT_TYPE_BIT)) >>\ + PSU_STATUS_INPUT_TYPE_BIT + psu_type = (psu_status & (1 << PSU_STATUS_TYPE_BIT)) >>\ + PSU_STATUS_TYPE_BIT + + print ' Input: ', Psu_Input_Type[psu_input_type] + print ' Type: ', Psu_Type[psu_type] + + # PSU FAN details + if (psu == 1): + print ' FAN Speed: ', get_pmc_register('fan11_input'), 'RPM' + psu_fan_airflow = int(get_pmc_register('fan11_airflow')) + psu_fan_status = int(get_pmc_register('fan11_alarm')) + psu_fan_present = int(get_pmc_register('fan11_fault')) + input_voltage = float(get_pmc_register('in29_input')) / 1000 + output_voltage = float(get_pmc_register('in30_input')) / 1000 + input_current = float(get_pmc_register('curr601_input')) / 100 + output_current = float(get_pmc_register('curr602_input')) /100 + input_power = float(get_pmc_register('power1_input')) / 1000000 + output_power = float(get_pmc_register('power2_input')) / 1000000 + if (input_power != 0): + psu_fan_temp = int(get_pmc_register('temp14_input'))/1000 + else: + print ' FAN Speed: ', get_pmc_register('fan12_input'), 'RPM' + psu_fan_airflow = int(get_pmc_register('fan12_airflow')) + psu_fan_status = int(get_pmc_register('fan12_alarm')) + psu_fan_present = int(get_pmc_register('fan12_fault')) + input_voltage = float(get_pmc_register('in31_input')) / 1000 + output_voltage = float(get_pmc_register('in32_input')) / 1000 + input_current = float(get_pmc_register('curr701_input')) / 100 + output_current = float(get_pmc_register('curr702_input')) / 100 + input_power = float(get_pmc_register('power3_input')) / 1000000 + output_power = float(get_pmc_register('power4_input')) / 1000000 + if (input_power != 0): + psu_fan_temp = int(get_pmc_register('temp15_input'))/1000 + + print ' FAN: ', Psu_Fan_Presence[psu_fan_present] + print ' FAN Status: ', Psu_Fan_Status[psu_fan_status] + print ' FAN AIRFLOW: ', Psu_Fan_Airflow[psu_fan_airflow] + + # PSU input & output monitors + print ' Input Voltage: %6.2f' % (input_voltage), 'V' + + print ' Output Voltage: %6.2f' % (output_voltage), 'V' + + print ' Input Current: %6.2f' % (input_current), 'A' + + print ' Output Current: %6.2f' % (output_current), 'A' + + print ' Input Power: %6.2f' % (input_power), 'W' + + print ' Output Power: %6.2f' % (output_power), 'W' + + # PSU firmware gives spurious temperature reading without input power + if (input_power != 0): + print ' Temperature: ', psu_fan_temp, 'C' + else: + print ' Temperature: ', 'NA' + +print('\nPSUs:') +for psu in range(1, Z9100_MAX_PSUS + 1): + + if (psu == 1): + psu_status = get_pmc_register('psu1_presence') + else: + psu_status = get_pmc_register('psu2_presence') + + if (psu_status != 'ERR'): + psu_status = int(psu_status, 16) + + if (~psu_status & 0b1): + print_psu(psu) + else: + print '\n PSU ', psu, 'Not present' + else: + logging.error('Unable to check PSU presence') + +print '\n Total Power: ', get_pmc_register('current_total_power'), 'W' diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/sensors b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/sensors new file mode 100755 index 000000000000..030d636a1565 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/sensors @@ -0,0 +1,7 @@ +#!/bin/bash +docker exec -i pmon sensors "$@" + +#To probe sensors not part of lm-sensors +if [ -r /usr/local/bin/platform_sensors.py ]; then + python /usr/local/bin/platform_sensors.py +fi diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh new file mode 100755 index 000000000000..6b62144eedac --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh @@ -0,0 +1,169 @@ +#!/bin/bash + +#platform init script for Dell Z9100 + +source dell_i2c_utils.sh + +init_devnum() { + found=0 + for devnum in 0 1; do + devname=`cat /sys/bus/i2c/devices/i2c-${devnum}/name` + # iSMT adapter can be at either dffd0000 or dfff0000 + if [[ $devname == 'SMBus iSMT adapter at '* ]]; then + found=1 + break + fi + done + + [[ $found -eq 0 ]] && echo "cannot find iSMT" && exit 1 +} + +# Attach/Detach CPU board mux @ 0x70 +cpu_board_mux() { + case $1 in + "new_device") i2c_config "echo pca9547 0x70 > /sys/bus/i2c/devices/i2c-${devnum}/$1" + ;; + "delete_device") i2c_config "echo 0x70 > /sys/bus/i2c/devices/i2c-${devnum}/$1" + ;; + *) echo "z9100_platform: cpu_board_mux: invalid command !" + ;; + esac +} + +# Attach/Detach switch board MUX to IOM CPLDs @ 0x71 +switch_board_mux() { + case $1 in + "new_device") i2c_config "echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-4/$1" + ;; + "delete_device") i2c_config "echo 0x71 > /sys/bus/i2c/devices/i2c-4/$1" + ;; + *) echo "z9100_platform: switch_board_mux : invalid command !" + ;; + esac +} + +# Attach/Detach syseeprom on CPU board +sys_eeprom() { + case $1 in + "new_device") i2c_config "echo 24c02 0x50 > /sys/bus/i2c/devices/i2c-2/$1" + ;; + "delete_device") i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-2/$1" + ;; + *) echo "z9100_platform: sys_eeprom : invalid command !" + ;; + esac +} + +#Attach/Detach cpld devices to drivers for each iom +switch_board_cpld() { + case $1 in + "new_device") + for ((i=14;i<=17;i++)); + do + i2c_config "echo dell_z9100_iom_cpld 0x3e > /sys/bus/i2c/devices/i2c-$i/$1" + done + ;; + "delete_device") + for ((i=14;i<=17;i++)); + do + i2c_config "echo 0x3e > /sys/bus/i2c/devices/i2c-$i/$1" + done + ;; + *) echo "z9100_platform: switch_board_cpld : invalid command !" + ;; + esac +} + +#Attach/Detach the MUX connecting all QSFPs +switch_board_qsfp_mux() { + case $1 in + "new_device") + for ((i=9;i>=6;i--)); + do + # 0x71 mux on the IOM 1 + mux_index=$(expr $i - 5) + echo "Attaching PCA9548 $mux_index" + i2c_config "echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-$i/$1" + done + ;; + "delete_device") + for ((i=9;i>=6;i--)); + do + # 0x71 mux on the IOM 1 + mux_index=$(expr $i - 5) + echo "Detaching PCA9548 $mux_index" + i2c_config "echo 0x71 > /sys/bus/i2c/devices/i2c-$devnum/i2c-$i/$1" + done + ;; + *) echo "z9100_platform: switch_board_qsfp_mux: invalid command !" + ;; + esac +} + +#Attach/Detach the SFP modules on PCA9548_2 +switch_board_sfp() { + case $1 in + "new_device") i2c_config "echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-11/$1" + i2c_config "echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-12/$1" + ;; + "delete_device") i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-11/$1" + i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-12/$1" + ;; + *) echo "z9100_platform: switch_board_sfp: invalid command !" + ;; + esac +} + +# Attach/Detach 32 instances of EEPROM driver QSFP ports on IO module 1 +#eeprom can dump data using below command +switch_board_qsfp() { + case $1 in + "new_device") + for ((i=18;i<=49;i++)); + do + i2c_config "echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-$i/$1" + done + ;; + "delete_device") + for ((i=18;i<=49;i++)); + do + i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-$i/$1" + done + ;; + + *) echo "z9100_platform: switch_board_qsfp: invalid command !" + ;; + esac +} + +init_devnum + +if [[ "$1" == "init" ]]; then + modprobe i2c-dev + modprobe i2c-mux-pca954x force_deselect_on_exit=1 + modprobe dell_mailbox + modprobe dell_z9100_cpld + + cpu_board_mux "new_device" + switch_board_mux "new_device" + sys_eeprom "new_device" + switch_board_cpld "new_device" + switch_board_qsfp_mux "new_device" + switch_board_sfp "new_device" + switch_board_qsfp "new_device" +elif [[ "$1" == "deinit" ]]; then + switch_board_sfp "delete_device" + switch_board_cpld "delete_device" + switch_board_mux "delete_device" + sys_eeprom "delete_device" + switch_board_qsfp "delete_device" + switch_board_qsfp_mux "delete_device" + cpu_board_mux "delete_device" + + modprobe -r dell_z9100_cpld + modprobe -r dell_mailbox + modprobe -r i2c-mux-pca954x + modprobe -r i2c-dev +else + echo "z9100_platform : Invalid option !" +fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys b/platform/broadcom/sonic-platform-modules-ingrasys deleted file mode 160000 index f6e0fa9860c6..000000000000 --- a/platform/broadcom/sonic-platform-modules-ingrasys +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f6e0fa9860c6d1bd9274b091147d4fc06a0597c3 diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/.gitignore b/platform/broadcom/sonic-platform-modules-ingrasys/.gitignore new file mode 100644 index 000000000000..f805e810e5c6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/.gitignore @@ -0,0 +1,33 @@ +# Object files +*.o +*.ko +*.obj +*.elf + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/LICENSE b/platform/broadcom/sonic-platform-modules-ingrasys/LICENSE new file mode 100644 index 000000000000..9cecc1d4669e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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 3 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, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/changelog b/platform/broadcom/sonic-platform-modules-ingrasys/debian/changelog new file mode 100644 index 000000000000..338234f97c45 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/changelog @@ -0,0 +1,22 @@ +platform-driver (1.1.0) unstable; urgency=low + + * Add support for s9200-64x + + -- developer Fri, 26 May 2017 11:00:00 +0800 + +platform-driver (1.1.0) unstable; urgency=low + + * Add support for s8810-32q + + -- developer Fri, 26 May 2017 11:00:00 +0800 +platform-driver (1.1.0) unstable; urgency=low + + * Add support for s8900 series + + -- developer Wed, 29 Mar 2017 11:00:00 +0800 + +platform-driver (1.0.0) unstable; urgency=low + + * Initial release (Closes: #nnnn) + + -- developer Wed, 05 Oct 2016 16:30:45 +0800 diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/compat b/platform/broadcom/sonic-platform-modules-ingrasys/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/compat @@ -0,0 +1 @@ +9 diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/control b/platform/broadcom/sonic-platform-modules-ingrasys/debian/control new file mode 100644 index 000000000000..99c87f772ed5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/control @@ -0,0 +1,26 @@ +Source: platform-driver +Section: unknown +Priority: optional +Maintainer: Wade He +Build-Depends: debhelper (>= 9), dh-systemd +Standards-Version: 1.0.0 + +Package: sonic-platform-ingrasys-s9100 +Architecture: amd64 +Description: This package contains S9100 platform driver utility for SONiC project. + +Package: sonic-platform-ingrasys-s8900-64xc +Architecture: amd64 +Description: This package contains S8900-64XC platform driver utility for SONiC project. + +Package: sonic-platform-ingrasys-s8900-54xc +Architecture: amd64 +Description: This package contains S8900-54XC platform driver utility for SONiC project. + +Package: sonic-platform-ingrasys-s8810-32q +Architecture: amd64 +Description: This package contains S8810-32Q platform driver utility for SONiC project. + +Package: sonic-platform-ingrasys-s9200-64x +Architecture: amd64 +Description: This package contains S9200-64X platform driver utility for SONiC project. diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/rules b/platform/broadcom/sonic-platform-modules-ingrasys/debian/rules new file mode 100644 index 000000000000..352dd55afbd7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/rules @@ -0,0 +1,80 @@ +#!/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. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +export INSTALL_MOD_DIR:=extra + +PACKAGE_PRE_NAME := sonic-platform-ingrasys +KVERSION ?= $(shell uname -r) +KERNEL_SRC := /lib/modules/$(KVERSION) +MOD_SRC_DIR:= $(shell pwd) +MODULE_DIRS:= s9100 s8900-64xc s8900-54xc s8810-32q s9200-64x +MODULE_DIR := modules +UTILS_DIR := utils +SERVICE_DIR := service +CONF_DIR := conf + +%: + dh $@ --with systemd + +clean: + dh_testdir + dh_testroot + dh_clean + +build: + #make modules -C $(KERNEL_SRC)/build M=$(MODULE_SRC) + (for mod in $(MODULE_DIRS); do \ + make modules -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ + 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 \ + mkdir debian/tmp/usr/sbin -p; \ + mkdir debian/tmp/lib/systemd/system -p; \ + mkdir debian/tmp/etc -p; \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp $(MOD_SRC_DIR)/$${mod}/$(MODULE_DIR)/*.ko debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/*.sh debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/sbin/; \ + cp $(MOD_SRC_DIR)/$${mod}/$(SERVICE_DIR)/*.service debian/$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system/; \ + done) + # 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 diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8810-32q.dirs b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8810-32q.dirs new file mode 100644 index 000000000000..bec29f195770 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8810-32q.dirs @@ -0,0 +1,3 @@ +usr/sbin +lib/systemd/system +etc/ \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8810-32q.install b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8810-32q.install new file mode 100644 index 000000000000..38efbef5d864 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8810-32q.install @@ -0,0 +1,3 @@ +lib/systemd/ +usr/sbin/ +etc/ \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8810-32q.postinst b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8810-32q.postinst new file mode 100644 index 000000000000..6a94f8327559 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8810-32q.postinst @@ -0,0 +1,43 @@ +# Automatically added by dh_systemd_enable +# This will only remove masks created by d-s-h on package removal. +deb-systemd-helper unmask s8810-32q-monitor.service >/dev/null || true +deb-systemd-helper unmask qsfp-monitor.service >/dev/null || true +# Generate kernel modules.dep and map files for add eeprom_mb. +depmod -a || true +# was-enabled defaults to true, so new installations run enable. +if deb-systemd-helper --quiet was-enabled s8810-32q-monitor.service; then + # Enables the unit on first installation, creates new + # symlinks on upgrades if the unit file has changed. + deb-systemd-helper enable s8810-32q-monitor.service >/dev/null || true +else + # Update the statefile to add new symlinks (if any), which need to be + # cleaned up on purge. Also remove old symlinks. + deb-systemd-helper update-state s8810-32q-monitor.service >/dev/null || true +fi +if deb-systemd-helper --quiet was-enabled qsfp-monitor.service; then + # Enables the unit on first installation, creates new + # symlinks on upgrades if the unit file has changed. + deb-systemd-helper enable qsfp-monitor.service >/dev/null || true +else + # Update the statefile to add new symlinks (if any), which need to be + # cleaned up on purge. Also remove old symlinks. + deb-systemd-helper update-state qsfp-monitor.service >/dev/null || true +fi +# End automatically added section +# Automatically added by dh_installinit +if [ -x "/etc/init.d/s8810-32q-monitor" ]; then + update-rc.d s8810-32q-monitor defaults >/dev/null + invoke-rc.d s8810-32q-monitor start || exit $? +fi +if [ -x "/etc/init.d/qsfp-monitor" ]; then + update-rc.d qsfp-monitor defaults >/dev/null + invoke-rc.d qsfp-monitor start || exit $? +fi +# End automatically added section +# Automatically added by dh_systemd_start +if [ -d /run/systemd/system ]; then + systemctl --system daemon-reload >/dev/null || true + deb-systemd-invoke start s8810-32q-monitor.service >/dev/null || true + deb-systemd-invoke start qsfp-monitor.service >/dev/null || true +fi +# End automatically added section diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8810-32q.postrm b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8810-32q.postrm new file mode 100644 index 000000000000..a1049b153eef --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8810-32q.postrm @@ -0,0 +1,38 @@ +# Automatically added by dh_systemd_start +if [ -d /run/systemd/system ]; then + systemctl --system daemon-reload >/dev/null || true + fi +# End automatically added section +# Automatically added by dh_installinit +if [ "$1" = "purge" ] ; then + update-rc.d s8810-32q-monitor remove >/dev/null + update-rc.d qsfp-monitor remove >/dev/null +fi + + +# In case this system is running systemd, we make systemd reload the unit files +# to pick up changes. +if [ -d /run/systemd/system ] ; then + systemctl --system daemon-reload >/dev/null || true +fi +# End automatically added section +# Automatically added by dh_systemd_enable +if [ "$1" = "remove" ]; then + if [ -x "/usr/bin/deb-systemd-helper" ]; then + deb-systemd-helper mask s8810-32q-monitor.service >/dev/null + deb-systemd-helper mask qsfp-monitor.service >/dev/null + fi +fi + +if [ "$1" = "purge" ]; then + if [ -x "/usr/bin/deb-systemd-helper" ]; then + deb-systemd-helper purge s8810-32q-monitor.service >/dev/null + deb-systemd-helper unmask s8810-32q-monitor.service >/dev/null + deb-systemd-helper purge qsfp-monitor.service >/dev/null + deb-systemd-helper unmask qsfp-monitor.service >/dev/null + fi +fi +# Generate kernel modules.dep and map files for remove eeprom_mb. +depmod -a || true +# End automatically added section + diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8810-32q.prerm b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8810-32q.prerm new file mode 100644 index 000000000000..5a6581e5f410 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8810-32q.prerm @@ -0,0 +1,17 @@ +# Automatically added by dh_systemd_start +if [ -d /run/systemd/system ]; then + deb-systemd-invoke stop s8810-32q-monitor.service >/dev/null + deb-systemd-invoke stop qsfp-monitor.service >/dev/null +fi +# End automatically added section +# Automatically added by dh_installinit +if [ -x "/etc/init.d/s8810-32q-monitor" ]; then + invoke-rc.d s8810-32q-monitor stop || exit $? +fi +if [ -x "/etc/init.d/qsfp-monitor" ]; then + invoke-rc.d qsfp-monitor stop || exit $? +fi +# Driver deinit +/usr/sbin/i2c_utils.sh i2c_deinit +# End automatically added section + diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8810-32q.upstart b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8810-32q.upstart new file mode 100644 index 000000000000..f907d1bb51e5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8810-32q.upstart @@ -0,0 +1,6 @@ +description "SONiC platform service" + +respawn + +exec /usr/sbin/s8810_32q_monitor.sh +exec /usr/sbin/qsfp_monitor.sh diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-54xc.dirs b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-54xc.dirs new file mode 100644 index 000000000000..bec29f195770 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-54xc.dirs @@ -0,0 +1,3 @@ +usr/sbin +lib/systemd/system +etc/ \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-54xc.install b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-54xc.install new file mode 100644 index 000000000000..38efbef5d864 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-54xc.install @@ -0,0 +1,3 @@ +lib/systemd/ +usr/sbin/ +etc/ \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-54xc.postinst b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-54xc.postinst new file mode 100644 index 000000000000..d2dc4ea518fb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-54xc.postinst @@ -0,0 +1,43 @@ +# Automatically added by dh_systemd_enable +# This will only remove masks created by d-s-h on package removal. +deb-systemd-helper unmask s8900-54xc-monitor.service >/dev/null || true +# Generate kernel modules.dep and map files for add eeprom_mb. +depmod -a || true +# was-enabled defaults to true, so new installations run enable. +if deb-systemd-helper --quiet was-enabled s8900-54xc-monitor.service; then + # Enables the unit on first installation, creates new + # symlinks on upgrades if the unit file has changed. + deb-systemd-helper enable s8900-54xc-monitor.service >/dev/null || true +else + # Update the statefile to add new symlinks (if any), which need to be + # cleaned up on purge. Also remove old symlinks. + deb-systemd-helper update-state s8900-54xc-monitor.service >/dev/null || true +fi +if deb-systemd-helper --quiet was-enabled qsfp-monitor.service; then + # Enables the unit on first installation, creates new + # symlinks on upgrades if the unit file has changed. + deb-systemd-helper enable qsfp-monitor.service >/dev/null || true +else + # Update the statefile to add new symlinks (if any), which need to be + # cleaned up on purge. Also remove old symlinks. + deb-systemd-helper update-state qsfp-monitor.service >/dev/null || true +fi + +# End automatically added section +# Automatically added by dh_installinit +if [ -x "/etc/init.d/s8900-54xc-monitor" ]; then + update-rc.d s8900-54xc-monitor defaults >/dev/null + invoke-rc.d s8900-54xc-monitor start || exit $? +fi +if [ -x "/etc/init.d/qsfp-monitor" ]; then + update-rc.d qsfp-monitor defaults >/dev/null + invoke-rc.d qsfp-monitor start || exit $? +fi +# End automatically added section +# Automatically added by dh_systemd_start +if [ -d /run/systemd/system ]; then + systemctl --system daemon-reload >/dev/null || true + deb-systemd-invoke start s8900-54xc-monitor.service >/dev/null || true + deb-systemd-invoke start qsfp-monitor.service >/dev/null || true +fi +# End automatically added section diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-54xc.postrm b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-54xc.postrm new file mode 100644 index 000000000000..b4e4ede5d88d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-54xc.postrm @@ -0,0 +1,38 @@ +# Automatically added by dh_systemd_start +if [ -d /run/systemd/system ]; then + systemctl --system daemon-reload >/dev/null || true + fi +# End automatically added section +# Automatically added by dh_installinit +if [ "$1" = "purge" ] ; then + update-rc.d s8900-54xc-monitor remove >/dev/null + update-rc.d qsfp-monitor remove >/dev/null +fi + + +# In case this system is running systemd, we make systemd reload the unit files +# to pick up changes. +if [ -d /run/systemd/system ] ; then + systemctl --system daemon-reload >/dev/null || true +fi +# End automatically added section +# Automatically added by dh_systemd_enable +if [ "$1" = "remove" ]; then + if [ -x "/usr/bin/deb-systemd-helper" ]; then + deb-systemd-helper mask s8900-54xc-monitor.service >/dev/null + deb-systemd-helper mask qsfp-monitor.service >/dev/null + fi +fi + +if [ "$1" = "purge" ]; then + if [ -x "/usr/bin/deb-systemd-helper" ]; then + deb-systemd-helper purge s8900-54xc-monitor.service >/dev/null + deb-systemd-helper unmask s8900-54xc-monitor.service >/dev/null + deb-systemd-helper purge qsfp-monitor.service >/dev/null + deb-systemd-helper unmask qsfp-monitor.service >/dev/null + fi +fi +# Generate kernel modules.dep and map files for remove eeprom_mb. +depmod -a || true +# End automatically added section + diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-54xc.prerm b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-54xc.prerm new file mode 100644 index 000000000000..b35262b16cf8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-54xc.prerm @@ -0,0 +1,17 @@ +# Automatically added by dh_systemd_start +if [ -d /run/systemd/system ]; then + deb-systemd-invoke stop s8900-54xc-monitor.service >/dev/null + deb-systemd-invoke stop qsfp-monitor.service >/dev/null +fi +# End automatically added section +# Automatically added by dh_installinit +if [ -x "/etc/init.d/s8900-54xc-monitor" ]; then + invoke-rc.d s8900-54xc-monitor stop || exit $? +fi +if [ -x "/etc/init.d/qsfp-monitor" ]; then + invoke-rc.d qsfp-monitor stop || exit $? +fi +# Driver deinit +/usr/sbin/i2c_utils.sh i2c_deinit +# End automatically added section + diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-54xc.upstart b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-54xc.upstart new file mode 100644 index 000000000000..cfdfc490fcc7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-54xc.upstart @@ -0,0 +1,6 @@ +description "SONiC platform service" + +respawn + +exec /usr/sbin/s8900_54xc_monitor.sh +exec /usr/sbin/qsfp_monitor.sh diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-64xc.dirs b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-64xc.dirs new file mode 100644 index 000000000000..be337bc5ea1f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-64xc.dirs @@ -0,0 +1,3 @@ +usr/sbin +lib/systemd/system +etc/ diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-64xc.install b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-64xc.install new file mode 100644 index 000000000000..1cf6f97b306f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-64xc.install @@ -0,0 +1,3 @@ +lib/systemd/ +usr/sbin/ +etc/ diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-64xc.postinst b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-64xc.postinst new file mode 100644 index 000000000000..dfc789e964bd --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-64xc.postinst @@ -0,0 +1,42 @@ +# Automatically added by dh_systemd_enable +# This will only remove masks created by d-s-h on package removal. +deb-systemd-helper unmask s8900-64xc-monitor.service >/dev/null || true +# Generate kernel modules.dep and map files for add eeprom_mb. +depmod -a || true +# was-enabled defaults to true, so new installations run enable. +if deb-systemd-helper --quiet was-enabled s8900-64xc-monitor.service; then + # Enables the unit on first installation, creates new + # symlinks on upgrades if the unit file has changed. + deb-systemd-helper enable s8900-64xc-monitor.service >/dev/null || true +else + # Update the statefile to add new symlinks (if any), which need to be + # cleaned up on purge. Also remove old symlinks. + deb-systemd-helper update-state s8900-64xc-monitor.service >/dev/null || true +fi +if deb-systemd-helper --quiet was-enabled qsfp-monitor.service; then + # Enables the unit on first installation, creates new + # symlinks on upgrades if the unit file has changed. + deb-systemd-helper enable qsfp-monitor.service >/dev/null || true +else + # Update the statefile to add new symlinks (if any), which need to be + # cleaned up on purge. Also remove old symlinks. + deb-systemd-helper update-state qsfp-monitor.service >/dev/null || true +fi +# End automatically added section +# Automatically added by dh_installinit +if [ -x "/etc/init.d/s8900-64xc-monitor" ]; then + update-rc.d s8900-64xc-monitor defaults >/dev/null + invoke-rc.d s8900-64xc-monitor start || exit $? +fi +if [ -x "/etc/init.d/qsfp-monitor" ]; then + update-rc.d qsfp-monitor defaults >/dev/null + invoke-rc.d qsfp-monitor start || exit $? +fi +# End automatically added section +# Automatically added by dh_systemd_start +if [ -d /run/systemd/system ]; then + systemctl --system daemon-reload >/dev/null || true + deb-systemd-invoke start s8900-64xc-monitor.service >/dev/null || true + deb-systemd-invoke start qsfp-monitor.service >/dev/null || true +fi +# End automatically added section diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-64xc.postrm b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-64xc.postrm new file mode 100644 index 000000000000..e3dddecc088b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-64xc.postrm @@ -0,0 +1,38 @@ +# Automatically added by dh_systemd_start +if [ -d /run/systemd/system ]; then + systemctl --system daemon-reload >/dev/null || true + fi +# End automatically added section +# Automatically added by dh_installinit +if [ "$1" = "purge" ] ; then + update-rc.d s8900-64xc-monitor remove >/dev/null + update-rc.d qsfp-monitor remove >/dev/null +fi + + +# In case this system is running systemd, we make systemd reload the unit files +# to pick up changes. +if [ -d /run/systemd/system ] ; then + systemctl --system daemon-reload >/dev/null || true +fi +# End automatically added section +# Automatically added by dh_systemd_enable +if [ "$1" = "remove" ]; then + if [ -x "/usr/bin/deb-systemd-helper" ]; then + deb-systemd-helper mask s8900-64xc-monitor.service >/dev/null + deb-systemd-helper mask qsfp-monitor.service >/dev/null + fi +fi + +if [ "$1" = "purge" ]; then + if [ -x "/usr/bin/deb-systemd-helper" ]; then + deb-systemd-helper purge s8900-64xc-monitor.service >/dev/null + deb-systemd-helper unmask s8900-64xc-monitor.service >/dev/null + deb-systemd-helper purge qsfp-monitor.service >/dev/null + deb-systemd-helper unmask qsfp-monitor.service >/dev/null + fi +fi +# Generate kernel modules.dep and map files for remove eeprom_mb. +depmod -a || true +# End automatically added section + diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-64xc.prerm b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-64xc.prerm new file mode 100644 index 000000000000..2168a6c76245 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-64xc.prerm @@ -0,0 +1,15 @@ +# Automatically added by dh_systemd_start +if [ -d /run/systemd/system ]; then + deb-systemd-invoke stop s8900-64xc-monitor.service >/dev/null + deb-systemd-invoke stop qsfp-monitor.service >/dev/null +fi +# End automatically added section +# Automatically added by dh_installinit +if [ -x "/etc/init.d/s8900-64xc-monitor" ]; then + invoke-rc.d s8900-64xc-monitor stop || exit $? + invoke-rc.d qsfp-monitor stop || exit $? +fi +# Driver deinit +/usr/sbin/i2c_utils.sh i2c_deinit +# End automatically added section + diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-64xc.upstart b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-64xc.upstart new file mode 100644 index 000000000000..25510457ecd8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s8900-64xc.upstart @@ -0,0 +1,6 @@ +description "SONiC platform service" + +respawn + +exec /usr/sbin/s8900_64xc_monitor.sh +exec /usr/sbin/qsfp-monitor.sh diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9100.dirs b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9100.dirs new file mode 100644 index 000000000000..bec29f195770 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9100.dirs @@ -0,0 +1,3 @@ +usr/sbin +lib/systemd/system +etc/ \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9100.install b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9100.install new file mode 100644 index 000000000000..38efbef5d864 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9100.install @@ -0,0 +1,3 @@ +lib/systemd/ +usr/sbin/ +etc/ \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9100.postinst b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9100.postinst new file mode 100644 index 000000000000..a9bc64e26c05 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9100.postinst @@ -0,0 +1,43 @@ +# Automatically added by dh_systemd_enable +# This will only remove masks created by d-s-h on package removal. +deb-systemd-helper unmask s9100-monitor.service >/dev/null || true +deb-systemd-helper unmask qsfp-monitor.service >/dev/null || true +# Generate kernel modules.dep and map files for add eeprom_mb. +depmod -a || true +# was-enabled defaults to true, so new installations run enable. +if deb-systemd-helper --quiet was-enabled s9100-monitor.service; then + # Enables the unit on first installation, creates new + # symlinks on upgrades if the unit file has changed. + deb-systemd-helper enable s9100-monitor.service >/dev/null || true +else + # Update the statefile to add new symlinks (if any), which need to be + # cleaned up on purge. Also remove old symlinks. + deb-systemd-helper update-state s9100-monitor.service >/dev/null || true +fi +if deb-systemd-helper --quiet was-enabled qsfp-monitor.service; then + # Enables the unit on first installation, creates new + # symlinks on upgrades if the unit file has changed. + deb-systemd-helper enable qsfp-monitor.service >/dev/null || true +else + # Update the statefile to add new symlinks (if any), which need to be + # cleaned up on purge. Also remove old symlinks. + deb-systemd-helper update-state qsfp-monitor.service >/dev/null || true +fi +# End automatically added section +# Automatically added by dh_installinit +if [ -x "/etc/init.d/s9100-monitor" ]; then + update-rc.d s9100-monitor defaults >/dev/null + invoke-rc.d s9100-monitor start || exit $? +fi +if [ -x "/etc/init.d/qsfp-monitor" ]; then + update-rc.d qsfp-monitor defaults >/dev/null + invoke-rc.d qsfp-monitor start || exit $? +fi +# End automatically added section +# Automatically added by dh_systemd_start +if [ -d /run/systemd/system ]; then + systemctl --system daemon-reload >/dev/null || true + deb-systemd-invoke start s9100-monitor.service >/dev/null || true + deb-systemd-invoke start qsfp-monitor.service >/dev/null || true +fi +# End automatically added section diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9100.postrm b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9100.postrm new file mode 100644 index 000000000000..669179b11e50 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9100.postrm @@ -0,0 +1,38 @@ +# Automatically added by dh_systemd_start +if [ -d /run/systemd/system ]; then + systemctl --system daemon-reload >/dev/null || true + fi +# End automatically added section +# Automatically added by dh_installinit +if [ "$1" = "purge" ] ; then + update-rc.d s9100-monitor remove >/dev/null + update-rc.d qsfp-monitor remove >/dev/null +fi + + +# In case this system is running systemd, we make systemd reload the unit files +# to pick up changes. +if [ -d /run/systemd/system ] ; then + systemctl --system daemon-reload >/dev/null || true +fi +# End automatically added section +# Automatically added by dh_systemd_enable +if [ "$1" = "remove" ]; then + if [ -x "/usr/bin/deb-systemd-helper" ]; then + deb-systemd-helper mask s9100-monitor.service >/dev/null + deb-systemd-helper mask qsfp-monitor.service >/dev/null + fi +fi + +if [ "$1" = "purge" ]; then + if [ -x "/usr/bin/deb-systemd-helper" ]; then + deb-systemd-helper purge s9100-monitor.service >/dev/null + deb-systemd-helper unmask s9100-monitor.service >/dev/null + deb-systemd-helper purge qsfp-monitor.service >/dev/null + deb-systemd-helper unmask qsfp-monitor.service >/dev/null + fi +fi +# Generate kernel modules.dep and map files for remove eeprom_mb. +depmod -a || true +# End automatically added section + diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9100.prerm b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9100.prerm new file mode 100644 index 000000000000..2ca8a83b273f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9100.prerm @@ -0,0 +1,17 @@ +# Automatically added by dh_systemd_start +if [ -d /run/systemd/system ]; then + deb-systemd-invoke stop s9100-monitor.service >/dev/null + deb-systemd-invoke stop qsfp-monitor.service >/dev/null +fi +# End automatically added section +# Automatically added by dh_installinit +if [ -x "/etc/init.d/s9100-monitor" ]; then + invoke-rc.d s9100-monitor stop || exit $? +fi +if [ -x "/etc/init.d/qsfp-monitor" ]; then + invoke-rc.d qsfp-monitor stop || exit $? +fi +# Driver deinit +/usr/sbin/i2c_utils.sh i2c_deinit +# End automatically added section + diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9100.upstart b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9100.upstart new file mode 100644 index 000000000000..5d0ba7080129 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9100.upstart @@ -0,0 +1,6 @@ +description "SONiC platform service" + +respawn + +exec /usr/sbin/s9100_monitor.sh +exec /usr/sbin/qsfp_monitor.sh diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9200-64x.dirs b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9200-64x.dirs new file mode 100644 index 000000000000..bec29f195770 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9200-64x.dirs @@ -0,0 +1,3 @@ +usr/sbin +lib/systemd/system +etc/ \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9200-64x.install b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9200-64x.install new file mode 100644 index 000000000000..38efbef5d864 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9200-64x.install @@ -0,0 +1,3 @@ +lib/systemd/ +usr/sbin/ +etc/ \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9200-64x.postinst b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9200-64x.postinst new file mode 100644 index 000000000000..0605612a1190 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9200-64x.postinst @@ -0,0 +1,43 @@ +# Automatically added by dh_systemd_enable +# This will only remove masks created by d-s-h on package removal. +deb-systemd-helper unmask s9200-64x-monitor.service >/dev/null || true +deb-systemd-helper unmask qsfp-monitor.service >/dev/null || true +# Generate kernel modules.dep and map files for add eeprom_mb. +depmod -a || true +# was-enabled defaults to true, so new installations run enable. +if deb-systemd-helper --quiet was-enabled s9200-64x-monitor.service; then + # Enables the unit on first installation, creates new + # symlinks on upgrades if the unit file has changed. + deb-systemd-helper enable s9200-64x-monitor.service >/dev/null || true +else + # Update the statefile to add new symlinks (if any), which need to be + # cleaned up on purge. Also remove old symlinks. + deb-systemd-helper update-state s9200-64x-monitor.service >/dev/null || true +fi +if deb-systemd-helper --quiet was-enabled qsfp-monitor.service; then + # Enables the unit on first installation, creates new + # symlinks on upgrades if the unit file has changed. + deb-systemd-helper enable qsfp-monitor.service >/dev/null || true +else + # Update the statefile to add new symlinks (if any), which need to be + # cleaned up on purge. Also remove old symlinks. + deb-systemd-helper update-state qsfp-monitor.service >/dev/null || true +fi +# End automatically added section +# Automatically added by dh_installinit +if [ -x "/etc/init.d/s9200-64x-monitor" ]; then + update-rc.d s9200-64x-monitor defaults >/dev/null + invoke-rc.d s9200-64x-monitor start || exit $? +fi +if [ -x "/etc/init.d/qsfp-monitor" ]; then + update-rc.d qsfp-monitor defaults >/dev/null + invoke-rc.d qsfp-monitor start || exit $? +fi +# End automatically added section +# Automatically added by dh_systemd_start +if [ -d /run/systemd/system ]; then + systemctl --system daemon-reload >/dev/null || true + deb-systemd-invoke start s9200-64x-monitor.service >/dev/null || true + deb-systemd-invoke start qsfp-monitor.service >/dev/null || true +fi +# End automatically added section diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9200-64x.postrm b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9200-64x.postrm new file mode 100644 index 000000000000..3e9494097556 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9200-64x.postrm @@ -0,0 +1,38 @@ +# Automatically added by dh_systemd_start +if [ -d /run/systemd/system ]; then + systemctl --system daemon-reload >/dev/null || true + fi +# End automatically added section +# Automatically added by dh_installinit +if [ "$1" = "purge" ] ; then + update-rc.d s9200-64x-monitor remove >/dev/null + update-rc.d qsfp-monitor remove >/dev/null +fi + + +# In case this system is running systemd, we make systemd reload the unit files +# to pick up changes. +if [ -d /run/systemd/system ] ; then + systemctl --system daemon-reload >/dev/null || true +fi +# End automatically added section +# Automatically added by dh_systemd_enable +if [ "$1" = "remove" ]; then + if [ -x "/usr/bin/deb-systemd-helper" ]; then + deb-systemd-helper mask s9200-64x-monitor.service >/dev/null + deb-systemd-helper mask qsfp-monitor.service >/dev/null + fi +fi + +if [ "$1" = "purge" ]; then + if [ -x "/usr/bin/deb-systemd-helper" ]; then + deb-systemd-helper purge s9200-64x-monitor.service >/dev/null + deb-systemd-helper unmask s9200-64x-monitor.service >/dev/null + deb-systemd-helper purge qsfp-monitor.service >/dev/null + deb-systemd-helper unmask qsfp-monitor.service >/dev/null + fi +fi +# Generate kernel modules.dep and map files for remove eeprom_mb. +depmod -a || true +# End automatically added section + diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9200-64x.prerm b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9200-64x.prerm new file mode 100644 index 000000000000..6238dcad7886 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9200-64x.prerm @@ -0,0 +1,17 @@ +# Automatically added by dh_systemd_start +if [ -d /run/systemd/system ]; then + deb-systemd-invoke stop s9200-64x-monitor.service >/dev/null + deb-systemd-invoke stop qsfp-monitor.service >/dev/null +fi +# End automatically added section +# Automatically added by dh_installinit +if [ -x "/etc/init.d/s9200-64x-monitor" ]; then + invoke-rc.d s9200-64x-monitor stop || exit $? +fi +if [ -x "/etc/init.d/qsfp-monitor" ]; then + invoke-rc.d qsfp-monitor stop || exit $? +fi +# Driver deinit +/usr/sbin/i2c_utils.sh i2c_deinit +# End automatically added section + diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9200-64x.upstart b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9200-64x.upstart new file mode 100644 index 000000000000..00803ff5e3b9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9200-64x.upstart @@ -0,0 +1,6 @@ +description "SONiC platform service" + +respawn + +exec /usr/sbin/s9200_64x_monitor.sh +exec /usr/sbin/qsfp_monitor.sh diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/README.md b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/README.md new file mode 100644 index 000000000000..dec38cb33393 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/README.md @@ -0,0 +1,185 @@ +# Ingrasys S8810-32Q Platform Driver for SONiC + +Copyright (C) 2016 Ingrasys, 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 3 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, see . + + +## Licensing terms + +The Licensing terms of the files within this project is split 2 parts. +The Linux kernel is released under the GNU General Public License version 2. +All other code is released under the GNU General Public License version 3. +Please see the LICENSE file for copies of both licenses. + +## Contents of this package + + - service/ + > Service config files for platform initialization and monitoring + - utils/ + > Scripts useful during platform bringup and sysfs function + - conf/ + > Platform configure files. + +## Kernel modules and drivers + +The driver for interacting with Ingrasys S8810-32Q is contained in the I2C +kernel module and initialization script. The initialization script loads +the modules in the correct order. It has been built and tested against +the Linux 3.16 kernel. + +The initialization script will modprobe the needed modules, navigate to the +module's device directory in sysfs, and write configuration data to +the kernel module. + +### IGB + +This is OOB Ports on front panel for management plane. + +The IGB module must be loaded first on Ingrasys S8810-32Q platform. + +### I2C i801 + +The I2C i801 on Ingrasys S8810-32Q can be found in +`/sys/bus/i2c/devices/i2c-0/` + +This is I2C bus for Clock Gen, DIMM channel and digital potentiometers. + +The i801 module must be loaded second on Ingrasys S8810-32Q. + +### I2C iSMT + +The I2C iSMT module on S8810-32Q can be found in +`/sys/bus/i2c/devices/i2c-1/` + +This is I2C bus for CPLD, HWM, power controller and I2C Switches. + +The i801 module must be loaded third on Ingrasys S8810-32Q. + +### I2C PCA9548 +The PCA9548 module on S8810-32Q can be found in +`/sys/bus/i2c/devices/i2c-2/` , `/sys/bus/i2c/devices/i2c-3/`, +`/sys/bus/i2c/devices/i2c-4/`, `/sys/bus/i2c/devices/i2c-5/`, +`/sys/bus/i2c/devices/i2c-6/`, `/sys/bus/i2c/devices/i2c-7/`, +`/sys/bus/i2c/devices/i2c-8/`, `/sys/bus/i2c/devices/i2c-9/`. + +The pca9548 module for zQSFP module get/set functions, PSU information, +fan status and EEPROM. + +## Hardware components + +The hardware components are initialized in the init script on S8810-32Q. +The following describes manual initialization as well as interaction. +The examples below are just for Ingrasys S8810-32Q platform. + +### Hardware initialization + +When the sonic-platform-ingrasys-s8810-32q package is installed on the S8810-32Q, +it is automatically initialized. If you want to manual initialization, the +utility command usage as follows: +``` + i2c_utils.sh i2c_init +``` + +### EEPROM + +The EEPROM is including the board SKU, model name, vendor name, serial number, +and other information can be accessed with the specific eeprom kernel module. +After using `modprobe eeprom_mb` to detect the eeprom, it will show up in sysfs. + +The hexdump utility can be used to decode the raw output of the EEPROM. +For example, +``` + bash# echo "mb_eeprom 0x54" > /sys/bus/i2c/devices/i2c-9/new_device + bash# cat /sys/bus/i2c/drivers/mb_eeprom/9-0054/eeprom | hexdump -C +``` + +### Front panel LEDs + +LEDs can be setup on/off by using i2c utility `/usr/sbin/i2c_utils.sh`. +Utility function command usage as follows: + +``` +Status LED: + i2c_utils.sh i2c_sys_led green|amber on|off + +Fan status LED: + i2c_utils.sh i2c_fan_led green|amber on|off + +PSU1 status LED: + i2c_utils.sh i2c_psu1_led green|amber on|off + +PSU2 status LED: + i2c_utils.sh i2c_psu2_led green|amber on|off + +``` +QSFP Module Port LEDs control by ASIC library. + + +### Fan speed + +Fan speed are controlled by the w83795 kernel module. +It can be found in `/sys/class/hwmon/hwmon1/device/`. +If they were compiled as modules, you will need to modprobe w83795 for +their sysfs entries to show up. Each fan has an `fan_input` file +for reading the fan speed. And `pwm1` setting fan1 to fan4, +`pwm2` setting fan5 to fan8. + +There is docker-platform-monitor container installed fancontrol package that can +automatic control platform fan speed. + + +### Temperature sensors + +Temperature sensors are controlled by the w83795 kernel +module. It can be found in `/sys/class/hwmon/hwmon1/device/`. +If they were compiled as modules, then you will need to modprobe w83795 for +their sysfs entries to show up. +`temp1_input` is front MAC temperature sensor. `temp2_input` is rear MAC +temperature sensor. + +There is docker-platform-monitor container installed lm-sensors package that can +monitor platform temperature. And `sensors` command can show each +temperature sensors status. + +### Power supplies + +Power supplies status and its EEPROM info can be used i2c utility +`/usr/sbin/i2c_utils.sh` to get. +The usage as follows: +``` +PSU EEPROM: + i2c_utils.sh i2c_psu_eeprom_get + hexdump -C psu0.rom + hexdump -C psu1.rom + +PSU Status: + i2c_utils.sh i2c_psu_status +``` + +### QSFPs +QSFP modules are managed by the pca9548 kernel driver. +The i2c utility `/usr/sbin/i2c_utils.sh` can be used to get status and +module EEPROM informations. +The usage as follows: +``` +QSFP EEPROM: + i2c_utils.sh i2c_qsfp_eeprom_get [1-32] + +QSFP Insert Event: + i2c_utils.sh i2c_qsfp_eeprom_get [1-32] + 0 => not insert + 1 => inserted +``` + diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/modules/Makefile b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/modules/Makefile new file mode 100755 index 000000000000..7c782163f402 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/modules/Makefile @@ -0,0 +1,2 @@ +obj-m := eeprom_mb.o +obj-m += ingrasys_s8810_32q_psu.o diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/modules/eeprom_mb.c b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/modules/eeprom_mb.c new file mode 100755 index 000000000000..2040e3cfc5db --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/modules/eeprom_mb.c @@ -0,0 +1,212 @@ +/* + * Copyright (C) 1998, 1999 Frodo Looijaard and + * Philip Edelbrock + * Copyright (C) 2003 Greg Kroah-Hartman + * Copyright (C) 2003 IBM Corp. + * Copyright (C) 2004 Jean Delvare + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Addresses to scan */ +static const unsigned short normal_i2c[] = { 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, I2C_CLIENT_END }; + + +/* Size of EEPROM in bytes */ +#define EEPROM_SIZE 256 + +#define SLICE_BITS (6) +#define SLICE_SIZE (1 << SLICE_BITS) +#define SLICE_NUM (EEPROM_SIZE/SLICE_SIZE) + +/* Each client has this additional data */ +struct eeprom_data { + struct mutex update_lock; + u8 valid; /* bitfield, bit!=0 if slice is valid */ + unsigned long last_updated[SLICE_NUM]; /* In jiffies, 8 slices */ + u8 data[EEPROM_SIZE]; /* Register values */ +}; + + +static void mb_eeprom_update_client(struct i2c_client *client, u8 slice) +{ + struct eeprom_data *data = i2c_get_clientdata(client); + int i, j; + int ret; + int addr; + + mutex_lock(&data->update_lock); + + if (!(data->valid & (1 << slice)) || + time_after(jiffies, data->last_updated[slice] + 300 * HZ)) { + dev_dbg(&client->dev, "Starting eeprom update, slice %u\n", slice); + + addr = slice << SLICE_BITS; + + ret = i2c_smbus_write_byte_data(client, (u8)((addr >> 8) & 0xFF), (u8)(addr & 0xFF)); + /* select the eeprom address */ + if (ret < 0) { + dev_err(&client->dev, "address set failed\n"); + goto exit; + } + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BYTE)) { + goto exit; + } + + for (i = slice << SLICE_BITS; i < (slice + 1) << SLICE_BITS; i+= SLICE_SIZE) { + for (j = i; j < (i+SLICE_SIZE); j++) { + int res; + + res = i2c_smbus_read_byte(client); + if (res < 0) { + goto exit; + } + + data->data[j] = res & 0xFF; + } + } + + data->last_updated[slice] = jiffies; + data->valid |= (1 << slice); + } +exit: + mutex_unlock(&data->update_lock); +} + +static ssize_t mb_eeprom_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj)); + struct eeprom_data *data = i2c_get_clientdata(client); + u8 slice; + + if (off > EEPROM_SIZE) { + return 0; + } + if (off + count > EEPROM_SIZE) { + count = EEPROM_SIZE - off; + } + if (count == 0) { + return 0; + } + + /* Only refresh slices which contain requested bytes */ + for (slice = off >> SLICE_BITS; slice <= (off + count - 1) >> SLICE_BITS; slice++) { + mb_eeprom_update_client(client, slice); + } + + memcpy(buf, &data->data[off], count); + + return count; +} + +static struct bin_attribute mb_eeprom_attr = { + .attr = { + .name = "eeprom", + .mode = S_IRUGO, + }, + .size = EEPROM_SIZE, + .read = mb_eeprom_read, +}; + +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int mb_eeprom_detect(struct i2c_client *client, struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = client->adapter; + + /* EDID EEPROMs are often 24C00 EEPROMs, which answer to all + addresses 0x50-0x57, but we only care about 0x50. So decline + attaching to addresses >= 0x51 on DDC buses */ + if (!(adapter->class & I2C_CLASS_SPD) && client->addr >= 0x56) { + return -ENODEV; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE) + && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { + return -ENODEV; + } + + strlcpy(info->type, "eeprom", I2C_NAME_SIZE); + + return 0; +} + +static int mb_eeprom_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct eeprom_data *data; + int err; + + if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) { + err = -ENOMEM; + goto exit; + } + + memset(data->data, 0xff, EEPROM_SIZE); + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + /* create the sysfs eeprom file */ + err = sysfs_create_bin_file(&client->dev.kobj, &mb_eeprom_attr); + if (err) { + goto exit_kfree; + } + + return 0; + +exit_kfree: + kfree(data); +exit: + return err; +} + +static int mb_eeprom_remove(struct i2c_client *client) +{ + sysfs_remove_bin_file(&client->dev.kobj, &mb_eeprom_attr); + kfree(i2c_get_clientdata(client)); + + return 0; +} + +static const struct i2c_device_id mb_eeprom_id[] = { + { "mb_eeprom", 0 }, + { } +}; + +static struct i2c_driver mb_eeprom_driver = { + .driver = { + .name = "mb_eeprom", + }, + .probe = mb_eeprom_probe, + .remove = mb_eeprom_remove, + .id_table = mb_eeprom_id, + + .class = I2C_CLASS_DDC | I2C_CLASS_SPD, + .detect = mb_eeprom_detect, + .address_list = normal_i2c, +}; + +module_i2c_driver(mb_eeprom_driver); + +MODULE_AUTHOR("Wade "); +MODULE_DESCRIPTION("Ingrasys S8810-32Q Mother Board EEPROM driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/modules/ingrasys_s8810_32q_platform.h b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/modules/ingrasys_s8810_32q_platform.h new file mode 100644 index 000000000000..a88755946e9a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/modules/ingrasys_s8810_32q_platform.h @@ -0,0 +1,148 @@ +#ifndef _S8810_32Q_PLATFORM_H +#define _S8810_32Q_PLATFORM_H + +#include + +// remove debug before release +#define DEBUG + +enum bus_order { + I2C_BUS_MAIN, + MUX_9548_0_CH0, + MUX_9548_0_CH1, + MUX_9548_0_CH2, + MUX_9548_0_CH3, + MUX_9548_0_CH4, + MUX_9548_0_CH5, + MUX_9548_0_CH6, + MUX_9548_0_CH7, + MUX_9548_1_CH0, + MUX_9548_1_CH1, + MUX_9548_1_CH2, + MUX_9548_1_CH3, + MUX_9548_1_CH4, + MUX_9548_1_CH5, + MUX_9548_1_CH6, + MUX_9548_1_CH7, + MUX_9546_0_CH0, + MUX_9546_0_CH1, + MUX_9546_0_CH2, + MUX_9546_0_CH3, + MUX_9546_1_CH0, + MUX_9546_1_CH1, + MUX_9546_1_CH2, + MUX_9546_1_CH3, + MUX_9548_2_CH0, + MUX_9548_2_CH1, + MUX_9548_2_CH2, + MUX_9548_2_CH3, + MUX_9548_2_CH4, + MUX_9548_2_CH5, + MUX_9548_2_CH6, + MUX_9548_2_CH7, + MUX_9548_3_CH0, + MUX_9548_3_CH1, + MUX_9548_3_CH2, + MUX_9548_3_CH3, + MUX_9548_3_CH4, + MUX_9548_3_CH5, + MUX_9548_3_CH6, + MUX_9548_3_CH7, + MUX_9548_4_CH0, + MUX_9548_4_CH1, + MUX_9548_4_CH2, + MUX_9548_4_CH3, + MUX_9548_4_CH4, + MUX_9548_4_CH5, + MUX_9548_4_CH6, + MUX_9548_4_CH7, + MUX_9548_5_CH0, + MUX_9548_5_CH1, + MUX_9548_5_CH2, + MUX_9548_5_CH3, + MUX_9548_5_CH4, + MUX_9548_5_CH5, + MUX_9548_5_CH6, + MUX_9548_5_CH7, + MUX_9548_6_CH0, + MUX_9548_6_CH1, + MUX_9548_6_CH2, + MUX_9548_6_CH3, + MUX_9548_6_CH4, + MUX_9548_6_CH5, + MUX_9548_6_CH6, + MUX_9548_6_CH7, + MUX_9548_7_CH0, + MUX_9548_7_CH1, + MUX_9548_7_CH2, + MUX_9548_7_CH3, + MUX_9548_7_CH4, + MUX_9548_7_CH5, + MUX_9548_7_CH6, + MUX_9548_7_CH7, + MUX_9548_8_CH0, + MUX_9548_8_CH1, + MUX_9548_8_CH2, + MUX_9548_8_CH3, + MUX_9548_8_CH4, + MUX_9548_8_CH5, + MUX_9548_8_CH6, + MUX_9548_8_CH7, + MUX_9548_9_CH0, + MUX_9548_9_CH1, + MUX_9548_9_CH2, + MUX_9548_9_CH3, + MUX_9548_9_CH4, + MUX_9548_9_CH5, + MUX_9548_9_CH6, + MUX_9548_9_CH7, + MUX_9548_10_CH0, + MUX_9548_10_CH1, + MUX_9548_10_CH2, + MUX_9548_10_CH3, + MUX_9548_10_CH4, + MUX_9548_10_CH5, + MUX_9548_10_CH6, + MUX_9548_10_CH7, +}; + +#define I2C_ADDR_MUX_9555_0 (0x20) +#define I2C_ADDR_MUX_9555_1 (0x24) +#define I2C_ADDR_MUX_9555_2 (0x25) +#define I2C_ADDR_MUX_9555_3 (0x26) +#define I2C_ADDR_MUX_9539_0 (0x76) +#define I2C_ADDR_MUX_9539_1 (0x76) +#define I2C_BUS_FAN_STATUS (I2C_BUS_MAIN) +#define I2C_BUS_SYS_LED (MUX_9548_1_CH1) + +#define NUM_OF_I2C_MUX (11) +#define NUM_OF_CPLD (5) +#define NUM_OF_QSFP_PORT (64) +#define NUM_OF_SFP_PORT (2) +#define QSFP_EEPROM_I2C_ADDR (0x50) + +enum gpio_reg { + REG_PORT0_IN, + REG_PORT1_IN, + REG_PORT0_OUT, + REG_PORT1_OUT, + REG_PORT0_POL, + REG_PORT1_POL, + REG_PORT0_DIR, + REG_PORT1_DIR, +}; + +struct ing_i2c_board_info { + int ch; + int size; + struct i2c_board_info *board_info; +}; + +struct i2c_init_data { + __u16 ch; + __u16 addr; + __u8 reg; + __u8 value; +}; + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/modules/ingrasys_s8810_32q_psu.c b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/modules/ingrasys_s8810_32q_psu.c new file mode 100644 index 000000000000..ae34c8eb33ed --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/modules/ingrasys_s8810_32q_psu.c @@ -0,0 +1,393 @@ +/* + * S8810-32Q PSU driver + * + * Copyright (C) 2017 Ingrasys, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ingrasys_s8810_32q_platform.h" + +static ssize_t show_psu_eeprom(struct device *dev, + struct device_attribute *da, + char *buf); +static struct s8810_psu_data *s8810_psu_update_status(struct device *dev); +static struct s8810_psu_data *s8810_psu_update_eeprom(struct device *dev); +static int s8810_psu_read_block(struct i2c_client *client, + u8 command, + u8 *data, + int data_len); + + +#define DRIVER_NAME "psu" + +// Addresses scanned +static const unsigned short normal_i2c[] = { 0x51, I2C_CLIENT_END }; + +/* PSU EEPROM SIZE */ +#define EEPROM_SZ 256 +#define READ_EEPROM 1 +#define NREAD_EEPROM 0 + +static struct i2c_client cpld_client; + +/* CPLD Registers */ +#define REG_PSU_PG 0x02 +#define REG_PSU_PRSNT 0x03 + +/* CPLD Pins */ +#define PSU1_PRSNT_L 0 +#define PSU2_PRSNT_L 1 +#define PSU1_PWROK 3 +#define PSU2_PWROK 4 + + +/* Driver Private Data */ +struct s8810_psu_data { + struct mutex lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 index; /* PSU index */ + char eeprom[EEPROM_SZ]; /* psu eeprom data */ + char psuABS; /* PSU absent */ + char psuPG; /* PSU power good */ +}; + +enum psu_index +{ + s8810_psu1, + s8810_psu2 +}; + +/* + * display power good attribute + */ +static ssize_t +show_psu_pg(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct s8810_psu_data *data = s8810_psu_update_status(dev); + unsigned int value; + + mutex_lock(&data->lock); + value = data->psuPG; + mutex_unlock(&data->lock); + + return sprintf(buf, "%d\n", value); +} + +/* + * display power absent attribute + */ +static ssize_t +show_psu_abs(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct s8810_psu_data *data = s8810_psu_update_status(dev); + unsigned int value; + + mutex_lock(&data->lock); + value = data->psuABS; + mutex_unlock(&data->lock); + + return sprintf(buf, "%d\n", value); +} + + +/* + * sysfs attributes for psu + */ +static DEVICE_ATTR(psu_pg, S_IRUGO, show_psu_pg, NULL); +static DEVICE_ATTR(psu_abs, S_IRUGO, show_psu_abs, NULL); +static DEVICE_ATTR(psu_eeprom, S_IRUGO, show_psu_eeprom, NULL); + +static struct attribute *s8810_psu_attributes[] = { + &dev_attr_psu_pg.attr, + &dev_attr_psu_abs.attr, + &dev_attr_psu_eeprom.attr, + NULL +}; + +/* + * display psu eeprom content + */ +static ssize_t +show_psu_eeprom(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct s8810_psu_data *data = s8810_psu_update_eeprom(dev); + + memcpy(buf, (char *)data->eeprom, EEPROM_SZ); + return EEPROM_SZ; +} + +static const struct attribute_group s8810_psu_group = { + .attrs = s8810_psu_attributes, +}; + +/* + * check gpio expander is accessible + */ +static int +cpld_detect(struct i2c_client *client) +{ + if (i2c_smbus_read_byte_data(client, REG_PSU_PG) < 0) { + return -ENODEV; + } + + return 0; +} + +/* + * client address init + */ +static void +i2c_devices_client_address_init(struct i2c_client *client) +{ + cpld_client = *client; + cpld_client.addr = 0x33; +} + +static int +s8810_psu_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct s8810_psu_data *data; + int status, err; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct s8810_psu_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + memset(data, 0, sizeof(struct s8810_psu_data)); + i2c_set_clientdata(client, data); + data->valid = 0; + data->index = dev_id->driver_data; + mutex_init(&data->lock); + + i2c_devices_client_address_init(client); + + err = cpld_detect(&cpld_client); + if (err) { + dev_info(&client->dev, "cpld detect failure\n"); + return err; + } + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &s8810_psu_group); + if (status) { + goto exit_free; + } + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &s8810_psu_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int +s8810_psu_remove(struct i2c_client *client) +{ + struct s8810_psu_data *data = i2c_get_clientdata(client); + + sysfs_remove_group(&client->dev.kobj, &s8810_psu_group); + kfree(data); + + return 0; +} + + +/* + * psu eeprom read utility + */ +static int +s8810_psu_read_block(struct i2c_client *client, + u8 command, + u8 *data, + int data_len) +{ + int i=0, ret=0; + int blk_max = 32; //max block read size + + /* read eeprom, 32 * 8 = 256 bytes */ + for (i=0; i < EEPROM_SZ/blk_max; i++) { + ret = i2c_smbus_read_i2c_block_data(client, (i*blk_max), blk_max, + data + (i*blk_max)); + if (ret < 0) { + return ret; + } + } + return ret; +} + +/* + * update eeprom content + */ +static struct s8810_psu_data +*s8810_psu_update_eeprom(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct s8810_psu_data *data = i2c_get_clientdata(client); + s32 status = 0; + char psu_pg = 0; + char psu_prsnt = 0; + int psu_pwrok = 0; + int psu_prsnt_l = 0; + + mutex_lock(&data->lock); + + if (time_after(jiffies, data->last_updated + 300 * HZ) + || !data->valid) { + + /* Read psu status */ + + psu_pg = i2c_smbus_read_byte_data(&(cpld_client), REG_PSU_PG); + psu_prsnt = i2c_smbus_read_byte_data(&(cpld_client), REG_PSU_PRSNT); + + /*read psu status from io expander*/ + + if (data->index == s8810_psu1) { + psu_pwrok = PSU1_PWROK; + psu_prsnt_l = PSU1_PRSNT_L; + } else { + psu_pwrok = PSU2_PWROK; + psu_prsnt_l = PSU2_PRSNT_L; + } + data->psuPG = (psu_pg >> psu_pwrok) & 0x1; + data->psuABS = (psu_prsnt >> psu_prsnt_l) & 0x1; + + /* Read eeprom */ + if (!data->psuABS) { + //clear local eeprom data + memset(data->eeprom, 0, EEPROM_SZ); + + //read eeprom + status = s8810_psu_read_block(client, 0, data->eeprom, + ARRAY_SIZE(data->eeprom)); + + if (status < 0) { + memset(data->eeprom, 0, EEPROM_SZ); + dev_err(&client->dev, "Read eeprom failed, status=(%d)\n", status); + } else { + data->valid = 1; + } + } else { + memset(data->eeprom, 0, EEPROM_SZ); + } + data->last_updated = jiffies; + } + + mutex_unlock(&data->lock); + + return data; +} + +/* + * update psu status + */ +static struct s8810_psu_data +*s8810_psu_update_status(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct s8810_psu_data *data = i2c_get_clientdata(client); + char psu_pg = 0; + char psu_prsnt = 0; + int psu_pwrok = 0; + int psu_prsnt_l = 0; + + mutex_lock(&data->lock); + + /* Read psu status */ + + psu_pg = i2c_smbus_read_byte_data(&(cpld_client), REG_PSU_PG); + psu_prsnt = i2c_smbus_read_byte_data(&(cpld_client), REG_PSU_PRSNT); + + /*read psu status from io expander*/ + + if (data->index == s8810_psu1) { + psu_pwrok = PSU1_PWROK; + psu_prsnt_l = PSU1_PRSNT_L; + } else { + psu_pwrok = PSU2_PWROK; + psu_prsnt_l = PSU2_PRSNT_L; + } + data->psuPG = (psu_pg >> psu_pwrok) & 0x1; + data->psuABS = (psu_prsnt >> psu_prsnt_l) & 0x1; + + mutex_unlock(&data->lock); + + return data; +} + +static const struct i2c_device_id s8810_psu_id[] = { + { "psu1", s8810_psu1 }, + { "psu2", s8810_psu2 }, + {} +}; + +MODULE_DEVICE_TABLE(i2c, s8810_psu_id); + +static struct i2c_driver s8810_psu_driver = { + .driver = { + .name = DRIVER_NAME, + }, + .probe = s8810_psu_probe, + .remove = s8810_psu_remove, + .id_table = s8810_psu_id, + .address_list = normal_i2c, +}; + +static int __init s8810_psu_init(void) +{ + return i2c_add_driver(&s8810_psu_driver); +} + +static void __exit s8810_psu_exit(void) +{ + i2c_del_driver(&s8810_psu_driver); +} + +module_init(s8810_psu_init); +module_exit(s8810_psu_exit); + +MODULE_AUTHOR("Jason Tsai "); +MODULE_DESCRIPTION("S8810-32Q psu driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/service/qsfp-monitor.service b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/service/qsfp-monitor.service new file mode 100644 index 000000000000..3d69fdae0f87 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/service/qsfp-monitor.service @@ -0,0 +1,15 @@ +[Unit] +Description= This QSFP Monitor service is to setup QSFP SI. +Requires=s8810-32q-monitor.service +After=s8810-32q-monitor.service + +[Service] +ExecStart=/usr/sbin/qsfp_monitor.sh +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/service/s8810-32q-monitor.service b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/service/s8810-32q-monitor.service new file mode 100644 index 000000000000..644efe443256 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/service/s8810-32q-monitor.service @@ -0,0 +1,19 @@ +[Unit] +Description= This Platform Monitor service is to initialize platform and monitor platform. +Before=platform-monitor.service +After=sysinit.target +Wants=fancontrol.service +Wants=qsfp-monitor.service +DefaultDependencies=no + +[Service] +ExecStartPre=/usr/sbin/i2c_utils.sh i2c_init +ExecStart=/usr/sbin/s8810_32q_monitor.sh +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/i2c_utils.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/i2c_utils.sh new file mode 100644 index 000000000000..98ffb9d8d2f4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/i2c_utils.sh @@ -0,0 +1,1452 @@ +#!/bin/bash + +# Copyright (C) 2016 Ingrasys, 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 3 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, see . + +VERSION="1.0.0" +TRUE=200 +FALSE=404 + +EXEC_FUNC=${1} +COLOR_LED=${2} +QSFP_PORT=${2} +QSFP_ACTION=${2} +MB_EEPROM_ACTION=${2} +ONOFF_LED=${3} +FAN_TRAY=${4} + +############################################################ +# Distributor ID: Debian +# Description: Debian GNU/Linux 8.6 (jessie) +# Release: 8.6 +# Codename: jessie +# Linux debian 3.16.0-4-amd64 #1 +# SMP Debian 3.16.36-1+deb8u1 (2016-09-03) x86_64 GNU/Linux +############################################################ + +# Color Definition +COLOR_TITLE="\e[1;32m" ### Green ### +COLOR_WARNING="\e[1;33m" ### Yellow ### +COLOR_ERROR="\e[1;31m" ### Red ### +COLOR_END="\e[0m" ### END ### + +NUM_I801_DEVICE=0 +NUM_ISMT_DEVICE=$(( ${NUM_I801_DEVICE} + 1 )) + +#MUX PCA9548#0 +NUM_MUX_9548_0_CHAN0=$(( ${NUM_I801_DEVICE} + 2 )) +NUM_MUX_9548_0_CHAN1=$(( ${NUM_I801_DEVICE} + 3 )) +NUM_MUX_9548_0_CHAN2=$(( ${NUM_I801_DEVICE} + 4 )) +#NUM_MUX_9548_0_CHAN3=$(( ${NUM_I801_DEVICE} + 5 )) +#NUM_MUX_9548_0_CHAN4=$(( ${NUM_I801_DEVICE} + 6 )) +#NUM_MUX_9548_0_CHAN5=$(( ${NUM_I801_DEVICE} + 7 )) +#NUM_MUX_9548_0_CHAN6=$(( ${NUM_I801_DEVICE} + 8 )) +#NUM_MUX_9548_0_CHAN7=$(( ${NUM_I801_DEVICE} + 9 )) + +#MUX PCA9548#1 +NUM_MUX_9548_1_CHAN0=$(( ${NUM_I801_DEVICE} + 10 )) +NUM_MUX_9548_1_CHAN1=$(( ${NUM_I801_DEVICE} + 11 )) +NUM_MUX_9548_1_CHAN2=$(( ${NUM_I801_DEVICE} + 12 )) +NUM_MUX_9548_1_CHAN3=$(( ${NUM_I801_DEVICE} + 13 )) +NUM_MUX_9548_1_CHAN4=$(( ${NUM_I801_DEVICE} + 14 )) +NUM_MUX_9548_1_CHAN5=$(( ${NUM_I801_DEVICE} + 15 )) +NUM_MUX_9548_1_CHAN6=$(( ${NUM_I801_DEVICE} + 16 )) +NUM_MUX_9548_1_CHAN7=$(( ${NUM_I801_DEVICE} + 17 )) + +NUM_MUX_9548_2_CHAN0=$(( ${NUM_I801_DEVICE} + 18 )) +NUM_MUX_9548_3_CHAN0=$(( ${NUM_I801_DEVICE} + 26 )) +NUM_MUX_9548_4_CHAN0=$(( ${NUM_I801_DEVICE} + 34 )) +NUM_MUX_9548_5_CHAN0=$(( ${NUM_I801_DEVICE} + 42 )) + +#MUX Alias +I2C_BUS_PSU1_EEPROM=${NUM_MUX_9548_0_CHAN1} +I2C_BUS_PSU2_EEPROM=${NUM_MUX_9548_0_CHAN2} +I2C_BUS_FAN_STATUS=${NUM_MUX_9548_1_CHAN0} +I2C_BUS_LED_BOARD=${NUM_MUX_9548_1_CHAN0} +I2C_BUS_MB_EEPROM=${NUM_MUX_9548_1_CHAN2} + +PATH_SYS_I2C_DEVICES="/sys/bus/i2c/devices" +PATH_SYS_GPIO="/sys/class/gpio" +PATH_HWMON_ROOT_DEVICES="/sys/class/hwmon" +PATH_HWMON_W83795_DEVICE="${PATH_HWMON_ROOT_DEVICES}/hwmon1" +PATH_I801_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_I801_DEVICE}" +PATH_ISMT_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_ISMT_DEVICE}" +#PATH for MUX PCA9548#0 +PATH_MUX_9548_0_CHAN0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_0_CHAN0}" +PATH_MUX_9548_0_CHAN1="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_0_CHAN1}" +PATH_MUX_9548_0_CHAN2="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_0_CHAN2}" +#PATH for MUX PCA9548#1 +PATH_MUX_9548_1_CHAN0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CHAN0}" +PATH_MUX_9548_1_CHAN1="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CHAN1}" +PATH_MUX_9548_1_CHAN2="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CHAN2}" +PATH_MUX_9548_1_CHAN3="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CHAN3}" +PATH_MUX_9548_1_CHAN4="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CHAN4}" +PATH_MUX_9548_1_CHAN5="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CHAN5}" +PATH_MUX_9548_1_CHAN6="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CHAN6}" +PATH_MUX_9548_1_CHAN7="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CHAN7}" + +#i2cmap and gpiomap path +PATH_GPIOMAP=/tmp/gpiomap +PATH_I2CMAP=/tmp/i2cmap + +I2C_ADDR_MUX_9548_0=0x70 +I2C_ADDR_MUX_9548_1=0x70 +I2C_ADDR_MUX_9548_2=0x71 +I2C_ADDR_MUX_9548_3=0x71 +I2C_ADDR_MUX_9548_4=0x71 +I2C_ADDR_MUX_9548_5=0x71 +I2C_ADDR_DDR3=0x50 +I2C_ADDR_RTC=0x68 +I2C_ADDR_CPLD=0x33 +I2C_ADDR_HWM=0x2F +I2C_ADDR_MUX_9535_FAN=0x20 +I2C_ADDR_MUX_9535_LED=0x22 +I2C_ADDR_MUX_9535_0=0x20 +I2C_ADDR_MUX_9535_1=0x21 +I2C_ADDR_MUX_9535_2=0x22 +I2C_ADDR_MUX_9535_3=0x23 +I2C_ADDR_MUX_9535_4=0x20 +I2C_ADDR_MUX_9535_5=0x21 +I2C_ADDR_MUX_9535_6=0x22 +I2C_ADDR_MUX_9535_7=0x23 +I2C_ADDR_MUX_9535_8=0x20 +I2C_ADDR_MUX_9535_9=0x21 +I2C_ADDR_MUX_9535_10=0x22 +I2C_ADDR_MB_EEPROM=0x56 +I2C_ADDR_QSFP_EEPROM=0x50 +I2C_ADDR_PSU_EEPROM=0x51 + +#sysfs +PATH_SYSFS_PSU1="${PATH_SYS_I2C_DEVICES}/${I2C_BUS_PSU1_EEPROM}-$(printf "%04x" $I2C_ADDR_PSU_EEPROM)" +PATH_SYSFS_PSU2="${PATH_SYS_I2C_DEVICES}/${I2C_BUS_PSU2_EEPROM}-$(printf "%04x" $I2C_ADDR_PSU_EEPROM)" + +#Active High/Low +ACTIVE_LOW=1 +ACTIVE_HIGH=0 +#GPIO Direction In/Out +DIR_IN=in +DIR_OUT=out + +#Power Supply Status +PSU_DC_ON=1 +PSU_DC_OFF=0 +PSU_EXIST=1 +PSU_NOT_EXIST=0 + +#W83795 Registers +REG_BANK_SEL=0x00 +REG_VOLT_CTRL1=0x02 +REG_VOLT_CTRL2=0x03 +REG_TEMP_CTRL1=0x04 +REG_TEMP_CTRL2=0x05 + +#PCA9535 Registers +REG_IN_0=0 +REG_IN_1=1 +REG_OUT_0=2 +REG_OUT_1=3 +REG_POLARITY_0=4 +REG_POLARITY_1=5 +REG_CFG_0=6 +REG_CFG_1=7 + +#Bit Mask +BIT_MASK=(1 2 4 8 16 32 64 128) + + +# Help usage function +function _help { + echo "=========================================================" + echo "# Description: Help Function" + echo "=========================================================" + echo "----------------------------------------------------" + echo "EX : ${0} help" + echo " : ${0} i2c_init" + echo " : ${0} i2c_deinit" + echo " : ${0} i2c_temp_init" + echo " : ${0} i2c_fan_init" + echo " : ${0} i2c_volmon_init" + echo " : ${0} i2c_io_exp_init" + echo " : ${0} i2c_gpio_init" + echo " : ${0} i2c_gpio_deinit" + echo " : ${0} i2c_psu_eeprom_get" + echo " : ${0} i2c_mb_eeprom_get" + echo " : ${0} i2c_qsfp_eeprom_get [1-32]" + echo " : ${0} i2c_qsfp_eeprom_init new|delete" + echo " : ${0} i2c_mb_eeprom_init new|delete" + echo " : ${0} i2c_qsfp_status_get [1-32]" + echo " : ${0} i2c_qsfp_type_get [1-32]" + echo " : ${0} i2c_board_type_get" + echo " : ${0} i2c_psu_status" + echo " : ${0} i2c_led_psu_status_set" + echo " : ${0} i2c_led_fan_status_set" + echo " : ${0} i2c_led_fan_tray_status_set" + echo " : ${0} i2c_led_fan_tray_test" + echo " : ${0} i2c_cpld_version" + echo " : ${0} i2c_test_all" + echo " : ${0} i2c_led_test" + echo " : ${0} i2c_sys_led green|amber on|off" + echo " : ${0} i2c_fan_led green|amber on|off" + echo " : ${0} i2c_psu1_led green|amber on|off" + echo " : ${0} i2c_psu2_led green|amber on|off" + echo " : ${0} i2c_fan_tray_led green|amber on|off [1-4]" + echo "----------------------------------------------------" +} + +#Pause function +function _pause { + read -p "$*" +} + +#Retry command function +function _retry { + local i + for i in {1..5}; + do + eval "${*}" && break || echo "retry"; sleep 1; + done +} + +#set i2cmap +function _set_i2cmap { + local i2c_n=$1 + local alias=$2 + + #create i2cmap dir if not exist + mkdir -p $PATH_I2CMAP + + #check i2c_n exists in sysfs + if [ ! -L ${PATH_SYS_I2C_DEVICES}/i2c-${i2c_n} ]; then + echo "${PATH_SYS_I2C_DEVICES}/i2c-${i2c_n} does not exist." + return + fi + + #create or update link + ln -sf ${PATH_SYS_I2C_DEVICES}/i2c-${i2c_n} ${PATH_I2CMAP}/${alias} +} + +#clear i2cmap +function _clear_i2cmap { + #delete i2cmap dir + rm -rf ${PATH_I2CMAP}/ +} + + +#I2C Init +function _i2c_init { + echo "=========================================================" + echo "# Description: I2C Init" + echo "=========================================================" + + rmmod i2c_ismt + rmmod i2c_i801 + modprobe i2c_i801 + modprobe i2c_ismt + modprobe i2c_dev + modprobe i2c_mux_pca954x force_deselect_on_exit=1 + + #add MUX PCA9548#0 on I801 + if [ ! -e "${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_0_CHAN0}" ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_0}' > ${PATH_I801_DEVICE}/new_device" + _set_i2cmap ${NUM_MUX_9548_0_CHAN0} "PCA9548_0" + else + echo "pca9548#0 ${I2C_ADDR_MUX_9548_0} already init." + fi + #add MUX PCA9548#1 on ISMT + if [ ! -e "${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CHAN0}" ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_1}' > ${PATH_ISMT_DEVICE}/new_device" + _set_i2cmap ${NUM_MUX_9548_1_CHAN0} "PCA9548_1" + else + echo "pca9548#1 ${I2C_ADDR_MUX_9548_1} already init." + fi + #add MUX PCA9548#2 on PCA9548#1 + if [ ! -e "${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_2_CHAN0}" ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_2}' > ${PATH_MUX_9548_1_CHAN4}/new_device" + _set_i2cmap ${NUM_MUX_9548_2_CHAN0} "PCA9548_2" + else + echo "pca9548#2 ${I2C_ADDR_MUX_9548_2} already init." + fi + #add MUX PCA9548#3 on PCA9548#1 + if [ ! -e "${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_3_CHAN0}" ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_3}' > ${PATH_MUX_9548_1_CHAN5}/new_device" + _set_i2cmap ${NUM_MUX_9548_3_CHAN0} "PCA9548_3" + else + echo "pca9548#3 ${I2C_ADDR_MUX_9548_3} already init." + fi + #add MUX PCA9548#4 on PCA9548#1 + if [ ! -e "${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_4_CHAN0}" ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_4}' > ${PATH_MUX_9548_1_CHAN6}/new_device" + _set_i2cmap ${NUM_MUX_9548_4_CHAN0} "PCA9548_4" + else + echo "pca9548#4 ${I2C_ADDR_MUX_9548_4} already init." + fi + #add MUX PCA9548#5 on PCA9548#1 + if [ ! -e "${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_5_CHAN0}" ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_5}' > ${PATH_MUX_9548_1_CHAN7}/new_device" + _set_i2cmap ${NUM_MUX_9548_5_CHAN0} "PCA9548_5" + else + echo "pca9548#5 ${I2C_ADDR_MUX_9548_5} already init." + fi + #Init CPLD LED_CLR Register (Front Port LED) + i2cset -y ${NUM_I801_DEVICE} ${I2C_ADDR_CPLD} 0x34 0x10 + + rmmod coretemp + rmmod jc42 + rmmod w83795 + _i2c_temp_init + _i2c_volmon_init + modprobe coretemp + modprobe w83795 + modprobe jc42 + modprobe eeprom + modprobe eeprom_mb + modprobe gpio-pca953x + _i2c_fan_init + _i2c_io_exp_init + _i2c_gpio_init + _i2c_psu_init + _i2c_qsfp_eeprom_init "new" + _i2c_mb_eeprom_init "new" + _i2c_led_psu_status_set + _i2c_led_fan_status_set + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_sys_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_sys_led + _config_rmem +} + +#I2C Deinit +function _i2c_deinit { + _i2c_gpio_deinit + for mod in coretemp jc42 w83795 eeprom_mb gpio-pca953x i2c_mux_pca954x i2c_ismt i2c_i801 ingrasys_s8810_32q_psu; + do + [ "$(lsmod | grep "^$mod ")" != "" ] && rmmod $mod + done + _clear_i2cmap +} + +#Temperature sensor Init +function _i2c_temp_init { + echo -n "TEMP INIT..." + #select bank0 + i2cset -y -r ${NUM_I801_DEVICE} ${I2C_ADDR_HWM} ${REG_BANK_SEL} 0x80 + #enable TR1, TR2, TR3 temperature monitoring + i2cset -y -r ${NUM_I801_DEVICE} ${I2C_ADDR_HWM} ${REG_TEMP_CTRL2} 0x7F + + # CLKIN clock frequency set as 48Mhz + i2cset -y -r ${NUM_I801_DEVICE} ${I2C_ADDR_HWM} 0x01 0x1C +} + +#FAN Init +function _i2c_fan_init { + + local init_fan_speed=120 + echo -n "FAN INIT..." + if [ -e "${PATH_HWMON_W83795_DEVICE}" ]; then + #Init Fan Speed + echo $init_fan_speed > ${PATH_HWMON_W83795_DEVICE}/device/pwm1 + echo $init_fan_speed > ${PATH_HWMON_W83795_DEVICE}/device/pwm2 + echo "SUCCESS" + else + echo "FAIL, W83795 not found in path ${PATH_HWMON_W83795_DEVICE}" + fi +} + +#VOLMON Init +function _i2c_volmon_init { + #3.3V 3VDD + #VSEN1 ROV + #VSEN4 1V + #VSEN5 1.8V + #VSEN7 5V + echo -n "VOLMON INIT..." + #select bank0 + i2cset -y -r ${NUM_I801_DEVICE} ${I2C_ADDR_HWM} ${REG_BANK_SEL} 0x80 + #enable voltage monitoring VSEN1-8 + i2cset -y -r ${NUM_I801_DEVICE} ${I2C_ADDR_HWM} ${REG_VOLT_CTRL1} 0xFF + #enable voltage monitoring 3VDD and 3VBAT + i2cset -y -r ${NUM_I801_DEVICE} ${I2C_ADDR_HWM} ${REG_VOLT_CTRL2} 0x50 + #disable voltage monitoring VSEN12 and VSEN13 + i2cset -y -r ${NUM_I801_DEVICE} ${I2C_ADDR_HWM} ${REG_TEMP_CTRL1} 0x00 + echo "Done" +} + +#IO Expander Init +function _i2c_io_exp_init { + echo "=========================================================" + echo "# Description: I2C IO Expander Init" + echo "=========================================================" + + #SMBUS1 + + echo "Init FAN Status IO Expander" + #PCA9535_FAN FAN_STATUS + #command byte 2/3, output logic level is 0 + #command byte 4/5, polarity is not inverted + #command byte 6/7, direction is input + i2cset -y -r ${I2C_BUS_FAN_STATUS} ${I2C_ADDR_MUX_9535_FAN} ${REG_OUT_0} 0x11 + i2cset -y -r ${I2C_BUS_FAN_STATUS} ${I2C_ADDR_MUX_9535_FAN} ${REG_OUT_1} 0x11 + i2cset -y -r ${I2C_BUS_FAN_STATUS} ${I2C_ADDR_MUX_9535_FAN} ${REG_POLARITY_0} 0x00 + i2cset -y -r ${I2C_BUS_FAN_STATUS} ${I2C_ADDR_MUX_9535_FAN} ${REG_POLARITY_1} 0x00 + i2cset -y -r ${I2C_BUS_FAN_STATUS} ${I2C_ADDR_MUX_9535_FAN} ${REG_CFG_0} 0xCC + i2cset -y -r ${I2C_BUS_FAN_STATUS} ${I2C_ADDR_MUX_9535_FAN} ${REG_CFG_1} 0xCC + + echo "Init LED Status IO Expander" + #PCA9535_LED LED_BOARD + #command byte 2/3, output logic level is 0 + #command byte 4/5, polarity is not inverted + #command byte 6/7, direction is output + i2cset -y -r ${I2C_BUS_LED_BOARD} ${I2C_ADDR_MUX_9535_LED} ${REG_OUT_0} 0xFF #active low + i2cset -y -r ${I2C_BUS_LED_BOARD} ${I2C_ADDR_MUX_9535_LED} ${REG_OUT_1} 0xFF #active low + i2cset -y -r ${I2C_BUS_LED_BOARD} ${I2C_ADDR_MUX_9535_LED} ${REG_POLARITY_0} 0x00 + i2cset -y -r ${I2C_BUS_LED_BOARD} ${I2C_ADDR_MUX_9535_LED} ${REG_POLARITY_1} 0x00 + i2cset -y -r ${I2C_BUS_LED_BOARD} ${I2C_ADDR_MUX_9535_LED} ${REG_CFG_0} 0x00 + i2cset -y -r ${I2C_BUS_LED_BOARD} ${I2C_ADDR_MUX_9535_LED} ${REG_CFG_1} 0x00 + + #PCA9535#0-10 zQSFP + + echo "Init ZQSFP IO Expander" + + echo "set ZQSFP ABS" + #zQSFP 0-31 ABS + #command byte 4/5, polarity is not inverted + #command byte 6/7, direction is input + i2cset -y -r ${NUM_MUX_9548_1_CHAN1} ${I2C_ADDR_MUX_9535_0} ${REG_POLARITY_0} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN1} ${I2C_ADDR_MUX_9535_0} ${REG_POLARITY_1} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN1} ${I2C_ADDR_MUX_9535_0} ${REG_CFG_0} 0xFF + i2cset -y -r ${NUM_MUX_9548_1_CHAN1} ${I2C_ADDR_MUX_9535_0} ${REG_CFG_1} 0xFF + + i2cset -y -r ${NUM_MUX_9548_1_CHAN1} ${I2C_ADDR_MUX_9535_1} ${REG_POLARITY_0} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN1} ${I2C_ADDR_MUX_9535_1} ${REG_POLARITY_1} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN1} ${I2C_ADDR_MUX_9535_1} ${REG_CFG_0} 0xFF + i2cset -y -r ${NUM_MUX_9548_1_CHAN1} ${I2C_ADDR_MUX_9535_1} ${REG_CFG_1} 0xFF + + echo "set ZQSFP INT" + #zQSFP 0-31 INT + #command byte 4/5, polarity is not inverted + #command byte 6/7, direction is input + i2cset -y -r ${NUM_MUX_9548_1_CHAN1} ${I2C_ADDR_MUX_9535_2} ${REG_POLARITY_0} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN1} ${I2C_ADDR_MUX_9535_2} ${REG_POLARITY_1} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN1} ${I2C_ADDR_MUX_9535_2} ${REG_CFG_0} 0xFF + i2cset -y -r ${NUM_MUX_9548_1_CHAN1} ${I2C_ADDR_MUX_9535_2} ${REG_CFG_1} 0xFF + + i2cset -y -r ${NUM_MUX_9548_1_CHAN1} ${I2C_ADDR_MUX_9535_3} ${REG_POLARITY_0} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN1} ${I2C_ADDR_MUX_9535_3} ${REG_POLARITY_1} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN1} ${I2C_ADDR_MUX_9535_3} ${REG_CFG_0} 0xFF + i2cset -y -r ${NUM_MUX_9548_1_CHAN1} ${I2C_ADDR_MUX_9535_3} ${REG_CFG_1} 0xFF + + echo "set ZQSFP LP_MODE" + #zQSFP 0-31 LP_MODE + #command byte 2/3, output logic level is 0 + #command byte 4/5, polarity is not inverted + #command byte 6/7, direction is output + i2cset -y -r ${NUM_MUX_9548_1_CHAN2} ${I2C_ADDR_MUX_9535_4} ${REG_OUT_0} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN2} ${I2C_ADDR_MUX_9535_4} ${REG_OUT_1} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN2} ${I2C_ADDR_MUX_9535_4} ${REG_POLARITY_0} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN2} ${I2C_ADDR_MUX_9535_4} ${REG_POLARITY_1} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN2} ${I2C_ADDR_MUX_9535_4} ${REG_CFG_0} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN2} ${I2C_ADDR_MUX_9535_4} ${REG_CFG_1} 0x00 + + i2cset -y -r ${NUM_MUX_9548_1_CHAN2} ${I2C_ADDR_MUX_9535_5} ${REG_OUT_0} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN2} ${I2C_ADDR_MUX_9535_5} ${REG_OUT_1} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN2} ${I2C_ADDR_MUX_9535_5} ${REG_POLARITY_0} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN2} ${I2C_ADDR_MUX_9535_5} ${REG_POLARITY_1} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN2} ${I2C_ADDR_MUX_9535_5} ${REG_CFG_0} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN2} ${I2C_ADDR_MUX_9535_5} ${REG_CFG_1} 0x00 + + echo "set ZQSFP RST" + #zQSFP 0-31 RST + #command byte 2/3, output logic level is 0 + #command byte 4/5, polarity is not inverted + #command byte 6/7, direction is output + i2cset -y -r ${NUM_MUX_9548_1_CHAN2} ${I2C_ADDR_MUX_9535_6} ${REG_OUT_0} 0xFF + i2cset -y -r ${NUM_MUX_9548_1_CHAN2} ${I2C_ADDR_MUX_9535_6} ${REG_OUT_1} 0xFF + i2cset -y -r ${NUM_MUX_9548_1_CHAN2} ${I2C_ADDR_MUX_9535_6} ${REG_POLARITY_0} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN2} ${I2C_ADDR_MUX_9535_6} ${REG_POLARITY_1} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN2} ${I2C_ADDR_MUX_9535_6} ${REG_CFG_0} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN2} ${I2C_ADDR_MUX_9535_6} ${REG_CFG_1} 0x00 + + i2cset -y -r ${NUM_MUX_9548_1_CHAN2} ${I2C_ADDR_MUX_9535_7} ${REG_OUT_0} 0xFF + i2cset -y -r ${NUM_MUX_9548_1_CHAN2} ${I2C_ADDR_MUX_9535_7} ${REG_OUT_1} 0xFF + i2cset -y -r ${NUM_MUX_9548_1_CHAN2} ${I2C_ADDR_MUX_9535_7} ${REG_POLARITY_0} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN2} ${I2C_ADDR_MUX_9535_7} ${REG_POLARITY_1} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN2} ${I2C_ADDR_MUX_9535_7} ${REG_CFG_0} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN2} ${I2C_ADDR_MUX_9535_7} ${REG_CFG_1} 0x00 + + echo "set ZQSFP Mode Select" + #zQSFP 0-31 Mode Select + #command byte 2/3, output logic level is 0 + #command byte 4/5, polarity is not inverted + #command byte 6/7, direction is output + i2cset -y -r ${NUM_MUX_9548_1_CHAN3} ${I2C_ADDR_MUX_9535_8} ${REG_OUT_0} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN3} ${I2C_ADDR_MUX_9535_8} ${REG_OUT_1} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN3} ${I2C_ADDR_MUX_9535_8} ${REG_POLARITY_0} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN3} ${I2C_ADDR_MUX_9535_8} ${REG_POLARITY_1} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN3} ${I2C_ADDR_MUX_9535_8} ${REG_CFG_0} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN3} ${I2C_ADDR_MUX_9535_8} ${REG_CFG_1} 0x00 + + i2cset -y -r ${NUM_MUX_9548_1_CHAN3} ${I2C_ADDR_MUX_9535_9} ${REG_OUT_0} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN3} ${I2C_ADDR_MUX_9535_9} ${REG_OUT_1} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN3} ${I2C_ADDR_MUX_9535_9} ${REG_POLARITY_0} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN3} ${I2C_ADDR_MUX_9535_9} ${REG_POLARITY_1} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN3} ${I2C_ADDR_MUX_9535_9} ${REG_CFG_0} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN3} ${I2C_ADDR_MUX_9535_9} ${REG_CFG_1} 0x00 + + #ZQSFP ABS0_15, ABS16_31, INT0_15, INT16_31, PSU1_PWROFF, PSU2_PWROFF + #command byte 2/3, output logic level is 0 + #command byte 4/5, polarity is not inverted + #command byte 6/7, I/O 1.0 and I/O 1.1 are output, others are input + i2cset -y -r ${NUM_MUX_9548_1_CHAN3} ${I2C_ADDR_MUX_9535_10} ${REG_OUT_0} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN3} ${I2C_ADDR_MUX_9535_10} ${REG_OUT_1} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN3} ${I2C_ADDR_MUX_9535_10} ${REG_POLARITY_0} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN3} ${I2C_ADDR_MUX_9535_10} ${REG_POLARITY_1} 0x00 + i2cset -y -r ${NUM_MUX_9548_1_CHAN3} ${I2C_ADDR_MUX_9535_10} ${REG_CFG_0} 0xFF + i2cset -y -r ${NUM_MUX_9548_1_CHAN3} ${I2C_ADDR_MUX_9535_10} ${REG_CFG_1} 0xFC +} + +#GPIO Init Utility Function +function _gpio_export { + local gpio_n=$1 + local direction=$2 + local active_low=$3 + local value=$4 + + if [ -z "${gpio_n}" ]; then + echo "[_gpio_init] gpio_n(${gpio_n}) is not provided" + return + fi + if [ "${gpio_n}" -lt "0" ] || [ "${gpio_n}" -gt "255" ]; then + echo "[_gpio_init] gpio_n(${gpio_n}) is invalid value" + return + fi + + #export gpio + echo ${gpio_n} > ${PATH_SYS_GPIO}/export + + #set gpio direction + echo ${direction} > ${PATH_SYS_GPIO}/gpio${gpio_n}/direction + + #set gpio active_low + echo ${active_low} > ${PATH_SYS_GPIO}/gpio${gpio_n}/active_low + + #set value + if [ ! -z "${value}" ]; then + echo ${value} > ${PATH_SYS_GPIO}/gpio${gpio_n}/value + fi +} + +#set gpiomap +function _set_gpiomap { + local gpio_n=$1 + local alias=$2 + + #create gpiomap dir if not exist + mkdir -p $PATH_GPIOMAP + + #check gpio_n exists in sysfs + if [ ! -L ${PATH_SYS_GPIO}/gpio${gpio_n} ]; then + echo "${PATH_SYS_GPIO}/gpio${gpio_n} does not exist." + return + fi + + #create or update link + ln -sf ${PATH_SYS_GPIO}/gpio${gpio_n} ${PATH_GPIOMAP}/${alias} +} + +#clear gpiomap +function _clear_gpiomap { + #delete gpiomap dir + rm -rf ${PATH_GPIOMAP} +} + +#GPIO Init +function _i2c_gpio_init { + local i=0 + + #ABS Port 0-31 + echo "pca9535 ${I2C_ADDR_MUX_9535_1}" > ${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CHAN1}/new_device + echo "pca9535 ${I2C_ADDR_MUX_9535_0}" > ${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CHAN1}/new_device + for i in {224..255} + do + _gpio_export ${i} ${DIR_IN} ${ACTIVE_LOW} + _set_gpiomap ${i} "QSFP$(( i - 223 ))_ABS" + done + + #INT Port 0-31 + echo "pca9535 ${I2C_ADDR_MUX_9535_3}" > ${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CHAN1}/new_device + echo "pca9535 ${I2C_ADDR_MUX_9535_2}" > ${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CHAN1}/new_device + for i in {192..223} + do + _gpio_export ${i} ${DIR_IN} ${ACTIVE_LOW} + _set_gpiomap ${i} "QSFP$(( i - 191 ))_INT" + done + + #LP Mode Port 0-31 + echo "pca9535 ${I2C_ADDR_MUX_9535_5}" > ${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CHAN2}/new_device + echo "pca9535 ${I2C_ADDR_MUX_9535_4}" > ${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CHAN2}/new_device + for i in {160..191} + do + _gpio_export ${i} ${DIR_OUT} ${ACTIVE_HIGH} + _set_gpiomap ${i} "QSFP$(( i - 159 ))_LPMODE" + done + + #RST Port 0-31 + echo "pca9535 ${I2C_ADDR_MUX_9535_7}" > ${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CHAN2}/new_device + echo "pca9535 ${I2C_ADDR_MUX_9535_6}" > ${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CHAN2}/new_device + for i in {128..159} + do + _gpio_export ${i} ${DIR_OUT} ${ACTIVE_LOW} + _set_gpiomap ${i} "QSFP$(( i - 127 ))_RST" + #Reset QSFP + echo "${ACTIVE_LOW}" > ${PATH_SYS_GPIO}/gpio${i}/value + echo "${ACTIVE_HIGH}" > ${PATH_SYS_GPIO}/gpio${i}/value + done + + #MODSEL Port 0-31 + echo "pca9535 ${I2C_ADDR_MUX_9535_9}" > ${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CHAN3}/new_device + echo "pca9535 ${I2C_ADDR_MUX_9535_8}" > ${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CHAN3}/new_device + for i in {96..127} + do + _gpio_export ${i} ${DIR_OUT} ${ACTIVE_LOW} + _set_gpiomap ${i} "QSFP$(( i - 95 ))_MODSEL" + done +} + +#GPIO DeInit +function _i2c_gpio_deinit { + echo ${I2C_ADDR_MUX_9535_0} > ${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CHAN1}/delete_device + echo ${I2C_ADDR_MUX_9535_1} > ${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CHAN1}/delete_device + echo ${I2C_ADDR_MUX_9535_2} > ${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CHAN1}/delete_device + echo ${I2C_ADDR_MUX_9535_3} > ${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CHAN1}/delete_device + echo ${I2C_ADDR_MUX_9535_4} > ${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CHAN2}/delete_device + echo ${I2C_ADDR_MUX_9535_5} > ${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CHAN2}/delete_device + _clear_gpiomap +} + +#Set FAN Tray LED +function _i2c_led_fan_tray_status_set { + echo "FAN Tray Status Setup" + + #check W83795 exists in hwmon2 + if [ ! -e "${PATH_HWMON_W83795_DEVICE}" ]; then + echo "FAIL, W83795 not found in path ${PATH_HWMON_W83795_DEVICE}" + return + fi + #FAN Status get + FAN1_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan1_alarm` + FAN2_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan2_alarm` + FAN3_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan3_alarm` + FAN4_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan4_alarm` + FAN5_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan5_alarm` + FAN6_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan6_alarm` + FAN7_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan7_alarm` + FAN8_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan8_alarm` + + FAN_TRAY=1 + if [ "${FAN1_ALARM}" == "0" ] && [ "${FAN2_ALARM}" == "0" ]; then + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + else + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + fi + + FAN_TRAY=2 + if [ "${FAN3_ALARM}" == "0" ] && [ "${FAN4_ALARM}" == "0" ]; then + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + else + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + fi + + FAN_TRAY=3 + if [ "${FAN5_ALARM}" == "0" ] && [ "${FAN6_ALARM}" == "0" ]; then + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + else + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + fi + + FAN_TRAY=4 + if [ "${FAN7_ALARM}" == "0" ] && [ "${FAN8_ALARM}" == "0" ]; then + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + else + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + fi +} + +#Test FAN Tray LED +function _i2c_led_fan_tray_test { + echo "FAN Tray LED Test" + + for i in {1..4} + do + FAN_TRAY=$i + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + _pause 'Check Fan Tray ${FAN_TRAY} LED green light and Press [Enter] key to continue...' + + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + _pause 'Check Fan Tray ${FAN_TRAY} LED amber light and Press [Enter] key to continue...' + done +} +#Set FAN LED +function _i2c_led_fan_status_set { + echo "FAN Status Setup" + + #check W83795 exists in hwmon2 + if [ ! -e "${PATH_HWMON_W83795_DEVICE}" ]; then + echo "FAIL, W83795 not found in path ${PATH_HWMON_W83795_DEVICE}" + return + fi + + #PSU Status set + FAN1_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan1_alarm` + FAN2_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan2_alarm` + FAN3_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan3_alarm` + FAN4_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan4_alarm` + FAN5_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan5_alarm` + FAN6_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan6_alarm` + FAN7_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan7_alarm` + FAN8_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan8_alarm` + + if [ "${FAN1_ALARM}" == "0" ] && [ "${FAN2_ALARM}" == "0" ] \ + && [ "${FAN3_ALARM}" == "0" ] && [ "${FAN4_ALARM}" == "0" ] \ + && [ "${FAN5_ALARM}" == "0" ] && [ "${FAN6_ALARM}" == "0" ] \ + && [ "${FAN7_ALARM}" == "0" ] && [ "${FAN8_ALARM}" == "0" ]; then + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_led + else + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_led + fi +} + +#Set Power Supply LED +function _i2c_led_psu_status_set { + echo "PSU LED Status Setup" + + #PSU Status set + _i2c_psu_status + + #PSU1 Status + if [ "${psu1Exist}" == ${PSU_EXIST} ]; then + if [ "${psu1PwGood}" == ${PSU_DC_ON} ]; then + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu1_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu1_led + else + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu1_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu1_led + fi + else + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu1_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu1_led + fi + + #PSU2 Status + if [ "${psu2Exist}" == ${PSU_EXIST} ]; then + if [ "${psu2PwGood}" == ${PSU_DC_ON} ]; then + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu2_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu2_led + else + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu2_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu2_led + fi + else + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu2_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu2_led + fi +} + +#LED Test +function _i2c_led_test { + echo "=========================================================" + echo "# Description: I2C LED TEST..." + echo "=========================================================" + #sys led (green) + _i2c_reset_led + COLOR_LED="green" + ONOFF_LED="on" + _i2c_sys_led + _pause 'Check SYS LED green light and Press [Enter] key to continue...' + #sys led (amber) + _i2c_reset_led + COLOR_LED="amber" + ONOFF_LED="on" + _i2c_sys_led + _pause 'Check SYS LED amber light and Press [Enter] key to continue...' + + #FAN led (green) + _i2c_reset_led + COLOR_LED="green" + ONOFF_LED="on" + _i2c_fan_led + _pause 'Check FAN LED green light and Press [Enter] key to continue...' + #FAN led (amber) + _i2c_reset_led + COLOR_LED="amber" + ONOFF_LED="on" + _i2c_fan_led + _pause 'Check FAN LED amber light and Press [Enter] key to continue...' + + #PSU2 led (green) + _i2c_reset_led + COLOR_LED="green" + ONOFF_LED="on" + _i2c_psu2_led + _pause 'Check PSU2 LED green light and Press [Enter] key to continue...' + #PSU2 led (amber) + _i2c_reset_led + COLOR_LED="amber" + ONOFF_LED="on" + _i2c_psu2_led + _pause 'Check PSU2 LED amber light and Press [Enter] key to continue...' + + #PSU1 led (green) + _i2c_reset_led + COLOR_LED="green" + ONOFF_LED="on" + _i2c_psu1_led + _pause 'Check PSU1 LED green light and Press [Enter] key to continue...' + #PSU1 led (amber) + _i2c_reset_led + COLOR_LED="amber" + ONOFF_LED="on" + _i2c_psu1_led + _pause 'Check PSU1 LED amber light and Press [Enter] key to continue...' + + #Turn OFF All LED + _i2c_reset_led + _pause 'Check turn off all LEDs and Press [Enter] key to continue...' + echo "done..." + + #sys led (green) + COLOR_LED="green" + ONOFF_LED="on" + _i2c_sys_led +} + +#Set QSFP Port variable +function _qsfp_port_i2c_var_set { + local port=$1 + case ${port} in + 1|2|3|4|5|6|7|8) + i2cbus=${NUM_MUX_9548_1_CHAN1} + regAddr=0x20 + dataAddr=0 + eeprombusbase=${NUM_MUX_9548_2_CHAN0} + gpioBase=224 + ;; + 9|10|11|12|13|14|15|16) + i2cbus=${NUM_MUX_9548_1_CHAN1} + regAddr=0x20 + dataAddr=1 + eeprombusbase=${NUM_MUX_9548_3_CHAN0} + gpioBase=224 + ;; + 17|18|19|20|21|22|23|24) + i2cbus=${NUM_MUX_9548_1_CHAN1} + regAddr=0x21 + dataAddr=0 + eeprombusbase=${NUM_MUX_9548_4_CHAN0} + gpioBase=240 + ;; + 25|26|27|28|29|30|31|32) + i2cbus=${NUM_MUX_9548_1_CHAN1} + regAddr=0x21 + dataAddr=1 + eeprombusbase=${NUM_MUX_9548_5_CHAN0} + gpioBase=240 + ;; + *) + echo "Please input 1~32" + ;; + esac +} + +#Set QSFP Port variable +function _qsfp_eeprom_var_set { + local port=$1 + eeprombusidx=$(( ${port} % 8)) + case $eeprombusidx in + 1) + eeprombus=$(( $eeprombusbase + 0 )) + ;; + 2) + eeprombus=$(( $eeprombusbase + 1 )) + ;; + 3) + eeprombus=$(( $eeprombusbase + 2 )) + ;; + 4) + eeprombus=$(( $eeprombusbase + 3 )) + ;; + 5) + eeprombus=$(( $eeprombusbase + 4 )) + ;; + 6) + eeprombus=$(( $eeprombusbase + 5 )) + ;; + 7) + eeprombus=$(( $eeprombusbase + 6 )) + ;; + 0) + eeprombus=$(( $eeprombusbase + 7 )) + ;; + esac + eepromAddr=${I2C_ADDR_QSFP_EEPROM} +} + +#Get QSFP EEPROM Information +function _i2c_qsfp_eeprom_get { + + _qsfp_port_i2c_var_set ${QSFP_PORT} + + #status: 0 -> Down, 1 -> Up + status=`cat ${PATH_SYS_GPIO}/gpio$(( gpioBase + (QSFP_PORT-1)%16 ))/value` + echo $status + + if [ $status = 0 ]; then + exit + fi + + _qsfp_eeprom_var_set ${QSFP_PORT} + + cat ${PATH_SYS_I2C_DEVICES}/$eeprombus-$(printf "%04x" $eepromAddr)/eeprom | hexdump -C +} + +#Init QSFP EEPROM +function _i2c_qsfp_eeprom_init { + echo -n "QSFP EEPROM INIT..." + + #Action check + action=$1 + if [ -z "${action}" ]; then + echo "No action, skip" + return + elif [ "${action}" != "new" ] && [ "${action}" != "delete" ]; then + echo "Error action, skip" + return + fi + + #Init 1-32 ports EEPROM + local i + for i in {1..32}; + do + _qsfp_port_i2c_var_set ${i} + + _qsfp_eeprom_var_set ${i} + + if [ "${action}" == "new" ] && \ + ! [ -L ${PATH_SYS_I2C_DEVICES}/$eeprombus-$(printf "%04x" $eepromAddr) ]; then + echo "sff8436 $eepromAddr" > ${PATH_SYS_I2C_DEVICES}/i2c-$eeprombus/new_device + elif [ "${action}" == "delete" ] && \ + [ -L ${PATH_SYS_I2C_DEVICES}/$eeprombus-$(printf "%04x" $eepromAddr) ]; then + echo "$eepromAddr" > ${PATH_SYS_I2C_DEVICES}/i2c-$eeprombus/delete_device + fi + done + echo "DONE" +} + +#Init Main Board EEPROM +function _i2c_mb_eeprom_init { + echo -n "Main Board EEPROM INIT..." + + #Action check + action=$1 + if [ -z "${action}" ]; then + echo "No action, skip" + return + elif [ "${action}" != "new" ] && [ "${action}" != "delete" ]; then + echo "Error action, skip" + return + fi + + #Init MB EEPROM + if [ "${action}" == "new" ] && \ + ! [ -L ${PATH_SYS_I2C_DEVICES}/${I2C_BUS_MB_EEPROM}-$(printf "%04x" $I2C_ADDR_MB_EEPROM) ]; then + echo "mb_eeprom ${I2C_ADDR_MB_EEPROM}" > ${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_MB_EEPROM}/new_device + elif [ "${action}" == "delete" ] && \ + [ -L ${PATH_SYS_I2C_DEVICES}/${I2C_BUS_MB_EEPROM}-$(printf "%04x" $I2C_ADDR_MB_EEPROM) ]; then + echo "${I2C_ADDR_MB_EEPROM}" > ${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_MB_EEPROM}/delete_device + fi + echo "DONE" +} + +#get QSFP Status +function _i2c_qsfp_status_get { + + _qsfp_port_i2c_var_set ${QSFP_PORT} + + #status: 0 -> Down, 1 -> Up + + status=`cat ${PATH_SYS_GPIO}/gpio$(( gpioBase + (QSFP_PORT-1)%16 ))/value` + echo "status=$status" +} + +#get QSFP Type +function _i2c_qsfp_type_get { + + _qsfp_port_i2c_var_set ${QSFP_PORT} + + _qsfp_eeprom_var_set ${QSFP_PORT} + + #Get QSFP EEPROM info + qsfp_info=$(base64 ${PATH_SYS_I2C_DEVICES}/$eeprombus-$(printf "%04x" $eepromAddr)/eeprom) + + identifier=$(echo $qsfp_info | base64 -d -i | hexdump -s 128 -n 1 -e '"%x"') + connector=$(echo $qsfp_info | base64 -d -i | hexdump -s 130 -n 1 -e '"%x"') + transceiver=$(echo $qsfp_info | base64 -d -i | hexdump -s 131 -n 1 -e '"%x"') + + echo "identifier=$identifier" + echo "connector=$connector" + echo "transceiver=$transceiver" +} + +#Init PSU Kernel Module +function _i2c_psu_init { + echo "=========================================================" + echo "# Description: I2C PSU Init" + echo "=========================================================" + modprobe ingrasys_s8810_32q_psu + + echo "psu1 ${I2C_ADDR_PSU_EEPROM}" > ${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_PSU1_EEPROM}/new_device + echo "psu2 ${I2C_ADDR_PSU_EEPROM}" > ${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_PSU2_EEPROM}/new_device +} + +#Get PSU EEPROM Information +function _i2c_psu_eeprom_get { + local eeprom_psu1="" + local eeprom_psu2="" + + echo "=========================================================" + echo "# Description: I2C PSU EEPROM Get..." + echo "=========================================================" + + eeprom_psu1="${PATH_SYSFS_PSU1}/psu_eeprom" + cat ${eeprom_psu1} | hexdump -C + + eeprom_psu2="${PATH_SYSFS_PSU2}/psu_eeprom" + cat ${eeprom_psu2} | hexdump -C +} + +#Get MotherBoard EEPROM Information +function _i2c_mb_eeprom_get { + echo "=========================================================" + echo "# Description: I2C MB EEPROM Get..." + echo "=========================================================" + + ## MB EEPROM + cat ${PATH_SYS_I2C_DEVICES}/${I2C_BUS_MB_EEPROM}-$(printf "%04x" $I2C_ADDR_MB_EEPROM)/eeprom | hexdump -C + echo "done..." +} + +#Set FAN Tray LED +function _i2c_fan_tray_led { + local value=0 + case ${FAN_TRAY} in + 1) + ioPort=$REG_OUT_0 + if [ "${COLOR_LED}" == "green" ]; then + mask=0x01 + elif [ "${COLOR_LED}" == "amber" ]; then + mask=0x02 + fi + ;; + 2) + ioPort=$REG_OUT_0 + if [ "${COLOR_LED}" == "green" ]; then + mask=0x10 + elif [ "${COLOR_LED}" == "amber" ]; then + mask=0x20 + fi + ;; + 3) + ioPort=$REG_OUT_1 + if [ "${COLOR_LED}" == "green" ]; then + mask=0x01 + elif [ "${COLOR_LED}" == "amber" ]; then + mask=0x02 + fi + ;; + 4) + ioPort=$REG_OUT_1 + if [ "${COLOR_LED}" == "green" ]; then + mask=0x10 + elif [ "${COLOR_LED}" == "amber" ]; then + mask=0x20 + fi + ;; + *) + echo "Please input 1~4" + exit + ;; + esac + + if [ "${ONOFF_LED}" == "on" ]; then + value=0xFF + elif [ "${ONOFF_LED}" == "off" ]; then + value=0x00 + else + echo "Invalid Parameters ${ONOFF_LED}, Exit!!!" + _help + exit ${FALSE} + fi + i2cset -m $mask -y -r ${I2C_BUS_FAN_STATUS} ${I2C_ADDR_MUX_9535_FAN} $ioPort $value + + #echo "done..." +} + +#Set System Status LED +function _i2c_sys_led { + local green_mask=${BIT_MASK[7]} + local amber_mask=${BIT_MASK[6]} + + _i2c_set_led $green_mask $amber_mask +} + +#Set FAN LED +function _i2c_fan_led { + local green_mask=${BIT_MASK[3]} + local amber_mask=${BIT_MASK[2]} + + _i2c_set_led $green_mask $amber_mask +} + +#Set PSU1 LED +function _i2c_psu1_led { + local green_mask=${BIT_MASK[1]} + local amber_mask=${BIT_MASK[0]} + + _i2c_set_led $green_mask $amber_mask +} + +#Set PSU2 LED +function _i2c_psu2_led { + local green_mask=${BIT_MASK[5]} + local amber_mask=${BIT_MASK[4]} + + _i2c_set_led $green_mask $amber_mask +} + +#Set LEDs in LED Board +function _i2c_set_led { + local green_mask=$1 + local amber_mask=$2 + local mask=0 + local value=0 + + + if [ "${COLOR_LED}" == "green" ]; then + mask=$green_mask + elif [ "${COLOR_LED}" == "amber" ]; then + mask=$amber_mask + else + echo "Invalid Parameters ${COLOR_LED}, Exit!!!" + _help + exit ${FALSE} + fi + + # Singals are active_low + if [ "${ONOFF_LED}" == "on" ]; then + value=0x00 + elif [ "${ONOFF_LED}" == "off" ]; then + value=0xFF + else + echo "Invalid Parameters ${ONOFF_LED}, Exit!!!" + _help + exit ${FALSE} + fi + + i2cset -m $mask -y -r ${I2C_BUS_LED_BOARD} ${I2C_ADDR_MUX_9535_LED} ${REG_OUT_0} $value +} + +#Reset all system leds +function _i2c_reset_led { + i2cset -y ${I2C_BUS_LED_BOARD} ${I2C_ADDR_MUX_9535_LED} ${REG_OUT_0} 0xFF +} + +#Get Board Version and Type +function _i2c_board_type_get { + local reg_board=0x00 + local reg_ext_board=0x07 + local boardType=0 + local boardBuildRev=0 + local boardHwRev=0 + local boardId=0 + local extBoardType=0 + + boardType=`i2cget -y ${NUM_I801_DEVICE} ${I2C_ADDR_CPLD} ${reg_board}` + #Bit 0-1 + boardBuildRev=$((($boardType) & 0x03)) + #Bit 2-3 + boardHwRev=$((($boardType) >> 2 & 0x03)) + #Bit 4-7 + boardId=$((($boardType) >> 4)) + + extBoardType=`i2cget -y ${NUM_I801_DEVICE} ${I2C_ADDR_CPLD} ${reg_ext_board}` + #Bit 0-3 + extBoardType=$((($extBoardType) & 0x0F)) + + printf "BOARD_ID=0x%02x, HW Rev=%d, Build Rev=%d, Ext_BOARD_ID=0x%02x\n" $boardId $boardHwRev $boardBuildRev $extBoardType + +} + +#Get CPLD Version +function _i2c_cpld_version { + local reg_cpld_rev=0x01 + cpldRev=`i2cget -y ${NUM_I801_DEVICE} ${I2C_ADDR_CPLD} ${reg_cpld_rev}` + cpldRelease=$((($cpldRev) >> 6 & 0x01)) + cpldVersion=$((($cpldRev) & 0x3F)) + printf "CPLD is %s version(0:RD 1:Release), Revision is 0x%02x\n" $cpldRelease $cpldVersion + +} + +#Get PSU Status +function _i2c_psu_status { + local psu_abs="" + + psu1PwGood=`cat ${PATH_SYSFS_PSU1}/psu_pg` + psu_abs=`cat ${PATH_SYSFS_PSU1}/psu_abs` + if [ "$psu_abs" == "0" ]; then + psu1Exist=1 + else + psu1Exist=0 + fi + + psu2PwGood=`cat ${PATH_SYSFS_PSU2}/psu_pg` + psu_abs=`cat ${PATH_SYSFS_PSU2}/psu_abs` + if [ "$psu_abs" == "0" ]; then + psu2Exist=1 + else + psu2Exist=0 + fi + + printf "PSU1 Exist:%x PSU1 PW Good:%d\n" $psu1Exist $psu1PwGood + printf "PSU2 Exist:%d PSU2 PW Good:%d\n" $psu2Exist $psu2PwGood +} + +#Increase read socket buffer for CoPP Test +function _config_rmem { + echo "109430400" > /proc/sys/net/core/rmem_max +} + +#Main Function +function _main { + start_time_str=`date` + start_time_sec=$(date +%s) + + if [ "${EXEC_FUNC}" == "help" ]; then + _help + elif [ "${EXEC_FUNC}" == "i2c_init" ]; then + _i2c_init + elif [ "${EXEC_FUNC}" == "i2c_deinit" ]; then + _i2c_deinit + elif [ "${EXEC_FUNC}" == "i2c_temp_init" ]; then + _i2c_temp_init + elif [ "${EXEC_FUNC}" == "i2c_fan_init" ]; then + _i2c_fan_init + elif [ "${EXEC_FUNC}" == "i2c_volmon_init" ]; then + _i2c_volmon_init + elif [ "${EXEC_FUNC}" == "i2c_io_exp_init" ]; then + _i2c_io_exp_init + elif [ "${EXEC_FUNC}" == "i2c_gpio_init" ]; then + _i2c_gpio_init + elif [ "${EXEC_FUNC}" == "i2c_gpio_deinit" ]; then + _i2c_gpio_deinit + elif [ "${EXEC_FUNC}" == "i2c_led_test" ]; then + _i2c_led_test + elif [ "${EXEC_FUNC}" == "i2c_mb_eeprom_get" ]; then + _i2c_mb_eeprom_get + elif [ "${EXEC_FUNC}" == "i2c_psu_eeprom_get" ]; then + _i2c_psu_eeprom_get + elif [ "${EXEC_FUNC}" == "i2c_qsfp_eeprom_get" ]; then + _i2c_qsfp_eeprom_get + elif [ "${EXEC_FUNC}" == "i2c_qsfp_eeprom_init" ]; then + _i2c_qsfp_eeprom_init ${QSFP_ACTION} + elif [ "${EXEC_FUNC}" == "i2c_mb_eeprom_init" ]; then + _i2c_mb_eeprom_init ${MB_EEPROM_ACTION} + elif [ "${EXEC_FUNC}" == "i2c_qsfp_status_get" ]; then + _i2c_qsfp_status_get + elif [ "${EXEC_FUNC}" == "i2c_qsfp_type_get" ]; then + _i2c_qsfp_type_get + elif [ "${EXEC_FUNC}" == "i2c_led_psu_status_set" ]; then + _i2c_led_psu_status_set + elif [ "${EXEC_FUNC}" == "i2c_led_fan_status_set" ]; then + _i2c_led_fan_status_set + elif [ "${EXEC_FUNC}" == "i2c_led_fan_tray_status_set" ]; then + _i2c_led_fan_tray_status_set + elif [ "${EXEC_FUNC}" == "i2c_led_fan_tray_test" ]; then + _i2c_led_fan_tray_test + elif [ "${EXEC_FUNC}" == "i2c_sys_led" ]; then + _i2c_sys_led + elif [ "${EXEC_FUNC}" == "i2c_fan_led" ]; then + _i2c_fan_led + elif [ "${EXEC_FUNC}" == "i2c_fan_tray_led" ]; then + _i2c_fan_tray_led + elif [ "${EXEC_FUNC}" == "i2c_psu1_led" ]; then + _i2c_psu1_led + elif [ "${EXEC_FUNC}" == "i2c_psu2_led" ]; then + _i2c_psu2_led + elif [ "${EXEC_FUNC}" == "i2c_board_type_get" ]; then + _i2c_board_type_get + elif [ "${EXEC_FUNC}" == "i2c_cpld_version" ]; then + _i2c_cpld_version + elif [ "${EXEC_FUNC}" == "i2c_psu_status" ]; then + _i2c_psu_status + elif [ "${EXEC_FUNC}" == "i2c_test_all" ]; then + _i2c_deinit + _i2c_init + _i2c_led_test + _i2c_psu_eeprom_get + _i2c_mb_eeprom_get + _i2c_board_type_get + _i2c_cpld_version + _i2c_psu_status + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + end_time_str=`date` + end_time_sec=$(date +%s) + diff_time=$[ ${end_time_sec} - ${start_time_sec} ] + echo "Start Time: ${start_time_str} (${start_time_sec})" + echo "End Time : ${end_time_str} (${end_time_sec})" + echo "Total Execution Time: ${diff_time} sec" + + echo "done!!!" +} + +_main diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/qsfp_monitor.sh new file mode 100755 index 000000000000..249f179216a6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/qsfp_monitor.sh @@ -0,0 +1,104 @@ +#!/bin/bash +# Copyright (C) 2017 Ingrasys, 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 3 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, see . + +INTERVAL=3 +I2C_UTILS="/usr/sbin/i2c_utils.sh" +QSFP_SI_SCRIPT="/usr/sbin/qsfp_si_cfg.sh" +QSFP_ARRAY=(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) + +#QSFP SI monitor +function _qsfp_si_monitor { + local i + local status + for i in {0..31}; + do + status=`${I2C_UTILS} i2c_qsfp_status_get $(expr $i + 1) | egrep '^status=.*$' | sed -e 's/status=//g'` + if [ "${status}" == "1" ]; then + _qsfp_type_check $i + fi + done +} + +#QSFP type +function _qsfp_type_check { + local port=$1 + local qsfp_type=`${I2C_UTILS} i2c_qsfp_type_get $(expr $port + 1)` + local identifier=`echo "$qsfp_type" | grep '^identifier=.*$' | sed -e 's/identifier=//g'` + if [ "${identifier}" == "11" ]; then + connector=`echo "$qsfp_type" | grep '^connector=.*$' | sed -e 's/connector=//g'` + case ${connector} in + 21|23) + #DAC + if [ "${QSFP_ARRAY[$port]}" != "${connector}" ]; then + echo "Change Port $(expr $port + 1) to DAC" + QSFP_ARRAY[$port]=${connector} + ${QSFP_SI_SCRIPT} dac $port >/dev/null + fi + ;; + *) + #Optical + if [ "${QSFP_ARRAY[$port]}" != "${connector}" ]; then + echo "Change Port $(expr $port + 1) to Optical" + QSFP_ARRAY[$port]=${connector} + ${QSFP_SI_SCRIPT} optical $port >/dev/null + fi + ;; + esac + fi +} + +#Docker exist check +function _docker_swss_check { + while true + do + # Check if syncd starts + result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + if [ "$result" == "3" ]; then + return + fi + sleep $INTERVAL + done +} + +#Docker exist check +function _qsfp_si_cfg_script_check { + + if [ -f ${QSFP_SI_SCRIPT} ] && [ -x ${QSFP_SI_SCRIPT} ]; then + echo "SI Script exists. Start monitor." + return + else + echo "SI Script not exist. Exit monitor." + exit + fi +} + +# main function +function _main { + #Check SI Script + _qsfp_si_cfg_script_check + #Check docker swss is running + _docker_swss_check + while true + do + _qsfp_si_monitor + # Sleep while still handling signals + sleep $INTERVAL & + wait $! + done +} + +_main + diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/s8810_32q_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/s8810_32q_monitor.sh new file mode 100755 index 000000000000..974da6d5001f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/s8810_32q_monitor.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# Copyright (C) 2016 Ingrasys, 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 3 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, see . + +INTERVAL=5 +I2C_UTILS="/usr/sbin/i2c_utils.sh" + + +# LED status monitor +function _led_monitor { + ${I2C_UTILS} i2c_led_fan_status_set >/dev/null + ${I2C_UTILS} i2c_led_psu_status_set >/dev/null + ${I2C_UTILS} i2c_led_fan_tray_status_set >/dev/null +} + +# main function +function _main { + while true + do + _led_monitor + # Sleep while still handling signals + sleep $INTERVAL & + wait $! + done +} + +_main \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/README.md b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/README.md new file mode 100644 index 000000000000..2042625f631c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/README.md @@ -0,0 +1,185 @@ +# Ingrasys S8900-54XC Platform Driver for SONiC + +Copyright (C) 2016 Ingrasys, 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 3 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, see . + + +## Licensing terms + +The Licensing terms of the files within this project is split 2 parts. +The Linux kernel is released under the GNU General Public License version 2. +All other code is released under the GNU General Public License version 3. +Please see the LICENSE file for copies of both licenses. + +## Contents of this package + + - service/ + > Service config files for platform initialization and monitoring + - utils/ + > Scripts useful during platform bringup and sysfs function + - conf/ + > Platform configure files. + +## Kernel modules and drivers + +The driver for interacting with Ingrasys S8900-54XC is contained in the I2C +kernel module and initialization script. The initialization script loads +the modules in the correct order. It has been built and tested against +the Linux 3.16 kernel. + +The initialization script will modprobe the needed modules, navigate to the +module's device directory in sysfs, and write configuration data to +the kernel module. + +### IGB + +This is OOB Ports on front panel for management plane. + +The IGB module must be loaded first on Ingrasys S8900-54XC platform. + +### I2C i801 + +The I2C i801 on Ingrasys S8900-54XC can be found in +`/sys/bus/i2c/devices/i2c-0/` + +This is I2C bus for Clock Gen, DIMM channel and digital potentiometers. + +The i801 module must be loaded second on Ingrasys S8900-54XC. + +### I2C iSMT + +The I2C iSMT module on S8900-54XC can be found in +`/sys/bus/i2c/devices/i2c-1/` + +This is I2C bus for CPLD, HWM, power controller and I2C Switches. + +The i801 module must be loaded third on Ingrasys S8900-54XC. + +### I2C PCA9548 +The PCA9548 module on S8900-54XC can be found in +`/sys/bus/i2c/devices/i2c-2/` , `/sys/bus/i2c/devices/i2c-3/`, +`/sys/bus/i2c/devices/i2c-4/`, `/sys/bus/i2c/devices/i2c-5/`, +`/sys/bus/i2c/devices/i2c-6/`, `/sys/bus/i2c/devices/i2c-7/`, +`/sys/bus/i2c/devices/i2c-8/`, `/sys/bus/i2c/devices/i2c-9/`. + +The pca9548 module for zQSFP module get/set functions, PSU information, +fan status and EEPROM. + +## Hardware components + +The hardware components are initialized in the init script on S8900-54XC. +The following describes manual initialization as well as interaction. +The examples below are just for Ingrasys S8900-54XC platform. + +### Hardware initialization + +When the sonic-platform-ingrasys-s8900-54xc package is installed on the S8900-54XC, +it is automatically initialized. If you want to manual initialization, the +utility command usage as follows: +``` + i2c_utils.sh i2c_init +``` + +### EEPROM + +The EEPROM is including the board SKU, model name, vendor name, serial number, +and other information can be accessed with the specific eeprom kernel module. +After using `modprobe eeprom_mb` to detect the eeprom, it will show up in sysfs. + +The hexdump utility can be used to decode the raw output of the EEPROM. +For example, +``` + bash# echo "mb_eeprom 0x54" > /sys/bus/i2c/devices/i2c-9/new_device + bash# cat /sys/bus/i2c/drivers/mb_eeprom/9-0054/eeprom | hexdump -C +``` + +### Front panel LEDs + +LEDs can be setup on/off by using i2c utility `/usr/sbin/i2c_utils.sh`. +Utility function command usage as follows: + +``` +Status LED: + i2c_utils.sh i2c_sys_led green|amber on|off + +Fan status LED: + i2c_utils.sh i2c_fan_led green|amber on|off + +PSU1 status LED: + i2c_utils.sh i2c_psu1_led green|amber on|off + +PSU2 status LED: + i2c_utils.sh i2c_psu2_led green|amber on|off + +``` +QSFP Module Port LEDs control by ASIC library. + + +### Fan speed + +Fan speed are controlled by the w83795 kernel module. +It can be found in `/sys/class/hwmon/hwmon1/device/`. +If they were compiled as modules, you will need to modprobe w83795 for +their sysfs entries to show up. Each fan has an `fan_input` file +for reading the fan speed. And `pwm1` setting fan1 to fan4, +`pwm2` setting fan5 to fan8. + +There is docker-platform-monitor container installed fancontrol package that can +automatic control platform fan speed. + + +### Temperature sensors + +Temperature sensors are controlled by the w83795 kernel +module. It can be found in `/sys/class/hwmon/hwmon1/device/`. +If they were compiled as modules, then you will need to modprobe w83795 for +their sysfs entries to show up. +`temp1_input` is front MAC temperature sensor. `temp2_input` is rear MAC +temperature sensor. + +There is docker-platform-monitor container installed lm-sensors package that can +monitor platform temperature. And `sensors` command can show each +temperature sensors status. + +### Power supplies + +Power supplies status and its EEPROM info can be used i2c utility +`/usr/sbin/i2c_utils.sh` to get. +The usage as follows: +``` +PSU EEPROM: + i2c_utils.sh i2c_psu_eeprom_get + hexdump -C psu0.rom + hexdump -C psu1.rom + +PSU Status: + i2c_utils.sh i2c_psu_status +``` + +### QSFPs +QSFP modules are managed by the pca9548 kernel driver. +The i2c utility `/usr/sbin/i2c_utils.sh` can be used to get status and +module EEPROM informations. +The usage as follows: +``` +QSFP EEPROM: + i2c_utils.sh i2c_qsfp_eeprom_get [1-32] + +QSFP Insert Event: + i2c_utils.sh i2c_qsfp_eeprom_get [1-32] + 0 => not insert + 1 => inserted +``` + diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/modules/Makefile b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/modules/Makefile new file mode 100644 index 000000000000..a0042543dff5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/modules/Makefile @@ -0,0 +1,2 @@ +obj-m := eeprom_mb.o +obj-m+= i2c_cpld.o diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/modules/eeprom_mb.c b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/modules/eeprom_mb.c new file mode 100644 index 000000000000..0886cad58eb3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/modules/eeprom_mb.c @@ -0,0 +1,212 @@ +/* + * Copyright (C) 1998, 1999 Frodo Looijaard and + * Philip Edelbrock + * Copyright (C) 2003 Greg Kroah-Hartman + * Copyright (C) 2003 IBM Corp. + * Copyright (C) 2004 Jean Delvare + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Addresses to scan */ +static const unsigned short normal_i2c[] = { 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, I2C_CLIENT_END }; + + +/* Size of EEPROM in bytes */ +#define EEPROM_SIZE 256 + +#define SLICE_BITS (6) +#define SLICE_SIZE (1 << SLICE_BITS) +#define SLICE_NUM (EEPROM_SIZE/SLICE_SIZE) + +/* Each client has this additional data */ +struct eeprom_data { + struct mutex update_lock; + u8 valid; /* bitfield, bit!=0 if slice is valid */ + unsigned long last_updated[SLICE_NUM]; /* In jiffies, 8 slices */ + u8 data[EEPROM_SIZE]; /* Register values */ +}; + + +static void mb_eeprom_update_client(struct i2c_client *client, u8 slice) +{ + struct eeprom_data *data = i2c_get_clientdata(client); + int i, j; + int ret; + int addr; + + mutex_lock(&data->update_lock); + + if (!(data->valid & (1 << slice)) || + time_after(jiffies, data->last_updated[slice] + 300 * HZ)) { + dev_dbg(&client->dev, "Starting eeprom update, slice %u\n", slice); + + addr = slice << SLICE_BITS; + + ret = i2c_smbus_write_byte_data(client, ((u8)addr >> 8) & 0xFF, (u8)addr & 0xFF); + /* select the eeprom address */ + if (ret < 0) { + dev_err(&client->dev, "address set failed\n"); + goto exit; + } + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BYTE)) { + goto exit; + } + + for (i = slice << SLICE_BITS; i < (slice + 1) << SLICE_BITS; i+= SLICE_SIZE) { + for (j = i; j < (i+SLICE_SIZE); j++) { + int res; + + res = i2c_smbus_read_byte(client); + if (res < 0) { + goto exit; + } + + data->data[j] = res & 0xFF; + } + } + + data->last_updated[slice] = jiffies; + data->valid |= (1 << slice); + } +exit: + mutex_unlock(&data->update_lock); +} + +static ssize_t mb_eeprom_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj)); + struct eeprom_data *data = i2c_get_clientdata(client); + u8 slice; + + if (off > EEPROM_SIZE) { + return 0; + } + if (off + count > EEPROM_SIZE) { + count = EEPROM_SIZE - off; + } + if (count == 0) { + return 0; + } + + /* Only refresh slices which contain requested bytes */ + for (slice = off >> SLICE_BITS; slice <= (off + count - 1) >> SLICE_BITS; slice++) { + mb_eeprom_update_client(client, slice); + } + + memcpy(buf, &data->data[off], count); + + return count; +} + +static struct bin_attribute mb_eeprom_attr = { + .attr = { + .name = "eeprom", + .mode = S_IRUGO, + }, + .size = EEPROM_SIZE, + .read = mb_eeprom_read, +}; + +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int mb_eeprom_detect(struct i2c_client *client, struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = client->adapter; + + /* EDID EEPROMs are often 24C00 EEPROMs, which answer to all + addresses 0x50-0x57, but we only care about 0x50. So decline + attaching to addresses >= 0x51 on DDC buses */ + if (!(adapter->class & I2C_CLASS_SPD) && client->addr >= 0x51) { + return -ENODEV; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE) + && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { + return -ENODEV; + } + + strlcpy(info->type, "eeprom", I2C_NAME_SIZE); + + return 0; +} + +static int mb_eeprom_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct eeprom_data *data; + int err; + + if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) { + err = -ENOMEM; + goto exit; + } + + memset(data->data, 0xff, EEPROM_SIZE); + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + /* create the sysfs eeprom file */ + err = sysfs_create_bin_file(&client->dev.kobj, &mb_eeprom_attr); + if (err) { + goto exit_kfree; + } + + return 0; + +exit_kfree: + kfree(data); +exit: + return err; +} + +static int mb_eeprom_remove(struct i2c_client *client) +{ + sysfs_remove_bin_file(&client->dev.kobj, &mb_eeprom_attr); + kfree(i2c_get_clientdata(client)); + + return 0; +} + +static const struct i2c_device_id mb_eeprom_id[] = { + { "mb_eeprom", 0 }, + { } +}; + +static struct i2c_driver mb_eeprom_driver = { + .driver = { + .name = "mb_eeprom", + }, + .probe = mb_eeprom_probe, + .remove = mb_eeprom_remove, + .id_table = mb_eeprom_id, + + .class = I2C_CLASS_DDC | I2C_CLASS_SPD, + .detect = mb_eeprom_detect, + .address_list = normal_i2c, +}; + +module_i2c_driver(mb_eeprom_driver); + +MODULE_AUTHOR("Wade "); +MODULE_DESCRIPTION("Ingrasys S8900 Mother Borad EEPROM driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/modules/i2c_cpld.c b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/modules/i2c_cpld.c new file mode 100644 index 000000000000..626c63177b50 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/modules/i2c_cpld.c @@ -0,0 +1,448 @@ +/* + * S9100-32X I2C CPLD driver + * + * Copyright (C) 2017 Ingrasys, Inc. + * Wade He + * + * 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, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "i2c_cpld.h" + +#ifdef DEBUG + #define DEBUG_PRINT(fmt, args...) \ + printk(KERN_INFO "%s[%d]: " fmt "\r\n", \ + __FUNCTION__, __LINE__, ##args) +#else + #define DEBUG_PRINT(fmt, args...) +#endif + +#define I2C_READ_BYTE_DATA(ret, lock, i2c_client, reg) \ +{ \ + mutex_lock(lock); \ + ret = i2c_smbus_read_byte_data(i2c_client, reg); \ + mutex_unlock(lock); \ +} +#define I2C_WRITE_BYTE_DATA(ret, lock, i2c_client, reg, val) \ +{ \ + mutex_lock(lock); \ + ret = i2c_smbus_write_byte_data(i2c_client, reg, val); \ + mutex_unlock(lock); \ +} + +/* CPLD sysfs attributes index */ +enum i2c_cpld_sysfs_attributes { + CPLD_ACCESS_REG, + CPLD_REGISTER_VAL, + CPLD_PORT_START, + CPLD_PORTS, + CPLD_VERSION, + CPLD_ID, + CPLD_BOARD_TYPE, + CPLD_EXT_BOARD_TYPE, + CPLD_PW_GOOD, + CPLD_PW_ABS, +}; + +/* CPLD sysfs attributes hook functions */ +static ssize_t read_access_register(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t write_access_register(struct device *dev, + struct device_attribute *da, const char *buf, size_t count); +static ssize_t read_register_value(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t write_register_value(struct device *dev, + struct device_attribute *da, const char *buf, size_t count); +static ssize_t read_cpld_version(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_board_type(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_ext_board_type(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_pw_good(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_pw_abs(struct device *dev, + struct device_attribute *da, char *buf); + +static LIST_HEAD(cpld_client_list); /* client list for cpld */ +static struct mutex list_lock; /* mutex for client list */ + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; + +struct cpld_data { + int index; /* CPLD index */ + struct mutex access_lock; /* mutex for cpld access */ + u8 access_reg; /* register to access */ +}; + +/* CPLD device id and data */ +static const struct i2c_device_id i2c_cpld_id[] = { + { "i2c_cpld", i2c_cpld }, + {} +}; + +/* Addresses scanned for i2c_cpld */ +static const unsigned short cpld_i2c_addr[] = { 0x33, I2C_CLIENT_END }; +/* platform sysfs object */ +extern struct kobject *s9230_64x_kobj; + + +/* define all support register access of cpld in attribute */ +static SENSOR_DEVICE_ATTR(cpld_access_register, S_IWUSR | S_IRUGO, + read_access_register, write_access_register, CPLD_ACCESS_REG); +static SENSOR_DEVICE_ATTR(cpld_register_value, S_IWUSR | S_IRUGO, + read_register_value, write_register_value, CPLD_REGISTER_VAL); +static SENSOR_DEVICE_ATTR(cpld_version, S_IRUGO, + read_cpld_version, NULL, CPLD_VERSION); +static SENSOR_DEVICE_ATTR(cpld_board_type, S_IRUGO, + read_board_type, NULL, CPLD_BOARD_TYPE); +static SENSOR_DEVICE_ATTR(cpld_ext_board_type, S_IRUGO, + read_ext_board_type, NULL, CPLD_EXT_BOARD_TYPE); +static SENSOR_DEVICE_ATTR(cpld_pw_good, S_IRUGO, + read_pw_good, NULL, CPLD_PW_GOOD); +static SENSOR_DEVICE_ATTR(cpld_pw_abs, S_IRUGO, + read_pw_abs, NULL, CPLD_PW_ABS); + + +/* define support attributes of cpldx , total 5 */ +/* cpld 1 */ +static struct attribute *i2c_cpld_attributes[] = { + &sensor_dev_attr_cpld_access_register.dev_attr.attr, + &sensor_dev_attr_cpld_register_value.dev_attr.attr, + &sensor_dev_attr_cpld_version.dev_attr.attr, + &sensor_dev_attr_cpld_board_type.dev_attr.attr, + &sensor_dev_attr_cpld_ext_board_type.dev_attr.attr, + &sensor_dev_attr_cpld_pw_good.dev_attr.attr, + &sensor_dev_attr_cpld_pw_abs.dev_attr.attr, + NULL +}; + +/* cpld 1 attributes group */ +static const struct attribute_group i2c_cpld_group = { + .attrs = i2c_cpld_attributes, +}; + +/* read access register from cpld data */ +static ssize_t read_access_register(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg = data->access_reg; + + return sprintf(buf, "0x%x\n", reg); +} + +/* write access register to cpld data */ +static ssize_t write_access_register(struct device *dev, + struct device_attribute *da, + const char *buf, + size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + + if (kstrtou8(buf, 0, ®) < 0) + return -EINVAL; + + data->access_reg = reg; + return count; +} + +/* read the value of access register in cpld data */ +static ssize_t read_register_value(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg = data->access_reg; + int reg_val; + + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + + if (reg_val < 0) + return -1; + + return sprintf(buf, "0x%x\n", reg_val); +} + +/* wrtie the value to access register in cpld data */ +static ssize_t write_register_value(struct device *dev, + struct device_attribute *da, + const char *buf, + size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + int ret = -EIO; + u8 reg = data->access_reg; + u8 reg_val; + + if (kstrtou8(buf, 0, ®_val) < 0) + return -EINVAL; + + I2C_WRITE_BYTE_DATA(ret, &data->access_lock, client, reg, reg_val); + + return count; +} + +/* get cpdl version register value */ +static ssize_t read_cpld_version(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_VERSION) { + reg = CPLD_VERSION_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* get board type register value */ +static ssize_t read_board_type(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_BOARD_TYPE) { + reg = CPLD_BOARD_TYPE_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* get extend board type register value */ +static ssize_t read_ext_board_type(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_EXT_BOARD_TYPE) { + reg = CPLD_EXT_BOARD_TYPE_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* get extend board type register value */ +static ssize_t read_pw_good(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_PW_GOOD) { + reg = CPLD_PW_GOOD_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* get extend board type register value */ +static ssize_t read_pw_abs(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_PW_ABS) { + reg = CPLD_PW_ABS_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* add valid cpld client to list */ +static void i2c_cpld_add_client(struct i2c_client *client) +{ + struct cpld_client_node *node = NULL; + + node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); + if (!node) { + dev_info(&client->dev, + "Can't allocate cpld_client_node for index %d\n", + client->addr); + return; + } + + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &cpld_client_list); + mutex_unlock(&list_lock); +} + +/* remove exist cpld client in list */ +static void i2c_cpld_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + list_for_each(list_node, &cpld_client_list) { + cpld_node = list_entry(list_node, + struct cpld_client_node, list); + + if (cpld_node->client == client) { + found = 1; + break; + } + } + + if (found) { + list_del(list_node); + kfree(cpld_node); + } + mutex_unlock(&list_lock); +} + +/* cpld drvier probe */ +static int i2c_cpld_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int status; + struct cpld_data *data = NULL; + + data = kzalloc(sizeof(struct cpld_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + /* init cpld data for client */ + i2c_set_clientdata(client, data); + mutex_init(&data->access_lock); + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_info(&client->dev, + "i2c_check_functionality failed (0x%x)\n", + client->addr); + status = -EIO; + goto exit; + } + + + status = sysfs_create_group(&client->dev.kobj,&i2c_cpld_group); + + if (status) + goto exit; + + dev_info(&client->dev, "chip found\n"); + + /* add probe chip to client list */ + i2c_cpld_add_client(client); + + return 0; +exit: + sysfs_remove_group(&client->dev.kobj, &i2c_cpld_group); + return status; +} + +/* cpld drvier remove */ +static int i2c_cpld_remove(struct i2c_client *client) +{ + + sysfs_remove_group(&client->dev.kobj, &i2c_cpld_group); + + i2c_cpld_remove_client(client); + return 0; +} + +MODULE_DEVICE_TABLE(i2c, i2c_cpld_id); + +static struct i2c_driver i2c_cpld_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "i2c_cpld", + }, + .probe = i2c_cpld_probe, + .remove = i2c_cpld_remove, + .id_table = i2c_cpld_id, + .address_list = cpld_i2c_addr, +}; + +static int __init i2c_cpld_init(void) +{ + mutex_init(&list_lock); + return i2c_add_driver(&i2c_cpld_driver); +} + +static void __exit i2c_cpld_exit(void) +{ + i2c_del_driver(&i2c_cpld_driver); +} + +MODULE_AUTHOR("Wade He "); +MODULE_DESCRIPTION("Ingrasys S9100-32X Platform i2c cpld driver"); +MODULE_LICENSE("GPL"); + +module_init(i2c_cpld_init); +module_exit(i2c_cpld_exit); + + + diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/modules/i2c_cpld.h b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/modules/i2c_cpld.h new file mode 100644 index 000000000000..e103b05c717a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/modules/i2c_cpld.h @@ -0,0 +1,197 @@ +/* + * + * S9100-32X I2C CPLD driver header file + * + * Copyright (C) 2017 Ingrasys, Inc. + * Wade He + * + * 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, see . + */ + +#ifndef I2C_CPLD_H +#define I2C_CPLD_H + +// remove debug before release +#define DEBUG + +/* CPLD device index value */ +enum cpld_id { + i2c_cpld +}; + +/* port number on CPLD */ +#define CPLD_1_PORT_NUM 12 +#define CPLD_2_PORT_NUM 13 + +/* QSFP port number */ +#define QSFP_MAX_PORT_NUM 64 +#define QSFP_MIN_PORT_NUM 1 + +/* SFP+ port number */ +#define SFP_MAX_PORT_NUM 2 +#define SFP_MIN_PORT_NUM 1 + + +/* CPLD registers */ +#define CPLD_BOARD_TYPE_REG 0x0 +#define CPLD_EXT_BOARD_TYPE_REG 0x7 +#define CPLD_VERSION_REG 0x1 +#define CPLD_PW_GOOD_REG 0x2 +#define CPLD_PW_ABS_REG 0x3 + + +/* bit definition for register value */ + +enum CPLD_RESET_CONTROL_BITS { + CPLD_RESET_CONTROL_SWRST_BIT, + CPLD_RESET_CONTROL_CP2104RST_BIT, + CPLD_RESET_CONTROL_82P33814RST_BIT, + CPLD_RESET_CONTROL_BMCRST_BIT, +}; + +/* bit field structure for register value */ +struct cpld_reg_board_type_t { + u8 build_rev:2; + u8 hw_rev:2; + u8 board_id:4; +}; + +struct cpld_reg_version_t { + u8 revision:6; + u8 release:1; + u8 reserve:1; +}; + +struct cpld_reg_pw_good_t { + u8 reserve1:3; + u8 psu1:1; + u8 psu2:1; + u8 reserve2:3; +}; + +struct cpld_reg_pw_abs_t { + u8 psu1:1; + u8 psu2:1; + u8 reserve:6; +}; + +/* common manipulation */ +#define INVALID(i, min, max) ((i < min) || (i > max) ? 1u : 0u) +#define READ_BIT(val, bit) ((0u == (val & (1<bf_name) +#define READ_BF_1(bf_struct, val, bf_name, bf_value) \ + bf_struct bf; \ + bf.data = val; \ + bf_value = bf.bf_name +#define BOARD_TYPE_BUILD_REV_GET(val, res) \ + READ_BF(cpld_reg_board_type_t, val, build_rev, res) +#define BOARD_TYPE_HW_REV_GET(val, res) \ + READ_BF(cpld_reg_board_type_t, val, hw_rev, res) +#define BOARD_TYPE_BOARD_ID_GET(val, res) \ + READ_BF(cpld_reg_board_type_t, val, board_id, res) +#define CPLD_VERSION_REV_GET(val, res) \ + READ_BF(cpld_reg_version_t, val, revision, res) +#define CPLD_VERSION_REL_GET(val, res) \ + READ_BF(cpld_reg_version_t, val, release, res) +#define CPLD_PSU1_PW_GOOD_GET(val, res) \ + READ_BF(cpld_reg_pw_good_t, val, psu1, res) +#define CPLD_PSU2_PW_GOOD_GET(val, res) \ + READ_BF(cpld_reg_pw_good_t, val, psu2, res) +#define CPLD_PSU1_PW_ABS_GET(val, res) \ + READ_BF(cpld_reg_pw_abs_t, val, psu1, res) +#define CPLD_PSU2_PW_ABS_GET(val, res) \ + READ_BF(cpld_reg_pw_abs_t, val, psu2, res) +/* QSFP/SFP registers manipulation */ +#define QSFP_TO_CPLD_IDX(qsfp_port, cpld_index, cpld_port) \ +{ \ + if (QSFP_MIN_PORT_NUM <= qsfp_port && qsfp_port <= CPLD_1_PORT_NUM) { \ + cpld_index = cpld1; \ + cpld_port = qsfp_port - 1; \ + } else if (CPLD_1_PORT_NUM < qsfp_port \ + && qsfp_port <= QSFP_MAX_PORT_NUM) { \ + cpld_index = cpld2 + (qsfp_port - 1 - CPLD_1_PORT_NUM) \ + / CPLD_2_PORT_NUM; \ + cpld_port = (qsfp_port - 1 - CPLD_1_PORT_NUM) % \ + CPLD_2_PORT_NUM; \ + } else { \ + cpld_index = 0; \ + cpld_port = 0; \ + } \ +} +#define SFP_TO_CPLD_IDX(sfp_port, cpld_index) \ + (cpld_index = sfp_port - SFP_MIN_PORT_NUM) +#define QSFP_PORT_STATUS_REG(cpld_port) \ + (CPLD_QSFP_PORT_STATUS_BASE_REG + cpld_port) +#define QSFP_PORT_CONFIG_REG(cpld_port) \ + (CPLD_QSFP_PORT_CONFIG_BASE_REG + cpld_port) +#define QSFP_PORT_INT_BIT_GET(port_status_value) \ + READ_BIT(port_status_value, CPLD_QSFP_PORT_STATUS_INT_BIT) +#define QSFP_PORT_ABS_BIT_GET(port_status_value) \ + READ_BIT(port_status_value, CPLD_QSFP_PORT_STATUS_ABS_BIT) +#define QSFP_PORT_RESET_BIT_GET(port_config_value) \ + READ_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_RESET_BIT) +#define QSFP_PORT_LPMODE_BIT_GET(port_config_value) \ + READ_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_LPMODE_BIT) +#define QSFP_PORT_RESET_BIT_SET(port_config_value) \ + SET_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_RESET_BIT) +#define QSFP_PORT_RESET_BIT_CLEAR(port_config_value) \ + CLEAR_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_RESET_BIT) +#define QSFP_PORT_LPMODE_BIT_SET(port_config_value) \ + SET_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_LPMODE_BIT) +#define QSFP_PORT_LPMODE_BIT_CLEAR(port_config_value) \ + CLEAR_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_LPMODE_BIT) +#define SFP_PORT_PRESENT_BIT_GET(port_status_value) \ + READ_BIT(port_status_value, CPLD_SFP_PORT_STATUS_PRESENT_BIT) + + #define SFP_PORT_TXFAULT_BIT_GET(port_status_value) \ + READ_BIT(port_status_value, CPLD_SFP_PORT_STATUS_TXFAULT_BIT) + #define SFP_PORT_RXLOS_BIT_GET(port_status_value) \ + READ_BIT(port_status_value, CPLD_SFP_PORT_STATUS_RXLOS_BIT) + #define SFP_PORT_TXDIS_BIT_GET(port_status_value) \ + READ_BIT(port_status_value, CPLD_SFP_PORT_CONFIG_TXDIS_BIT) +#define SFP_PORT_RS_BIT_GET(port_config_value) \ + READ_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_RS_BIT) +#define SFP_PORT_TS_BIT_GET(port_config_value) \ + READ_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_TS_BIT) +#define SFP_PORT_TXDIS_BIT_SET(port_config_value) \ + SET_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_TXDIS_BIT) +#define SFP_PORT_TXDIS_BIT_CLEAR(port_config_value) \ + CLEAR_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_TXDIS_BIT) +#define SFP_PORT_RS_BIT_SET(port_config_value) \ + SET_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_RS_BIT) +#define SFP_PORT_RS_BIT_CLEAR(port_config_value) \ + CLEAR_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_RS_BIT) +#define SFP_PORT_TS_BIT_SET(port_config_value) \ + SET_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_TS_BIT) +#define SFP_PORT_TS_BIT_CLEAR(port_config_value) \ + CLEAR_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_TS_BIT) + +/* CPLD access functions */ +extern int i2c_cpld_get_qsfp_port_status_val(u8 port_num); +extern int i2c_cpld_get_qsfp_port_config_val(u8 port_num); +extern int i2c_cpld_set_qsfp_port_config_val(u8 port_num, u8 reg_val); +extern int i2c_cpld_get_sfp_port_status_val(u8 port_num); +extern int i2c_cpld_get_sfp_port_config_val(u8 port_num); +extern int i2c_cpld_set_sfp_port_config_val(u8 port_num, u8 reg_val); +extern u8 fp_port_to_phy_port(u8 fp_port); +#endif + diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/service/qsfp-monitor.service b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/service/qsfp-monitor.service new file mode 100644 index 000000000000..e33c2fdae122 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/service/qsfp-monitor.service @@ -0,0 +1,15 @@ +[Unit] +Description= This QSFP Monitor service is to setup QSFP SI. +Requires=s8900-54xc-monitor.service +After=s8900-54xc-monitor.service + +[Service] +ExecStart=/usr/sbin/qsfp_monitor.sh +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/service/s8900-54xc-monitor.service b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/service/s8900-54xc-monitor.service new file mode 100644 index 000000000000..e43fddc9b857 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/service/s8900-54xc-monitor.service @@ -0,0 +1,18 @@ +[Unit] +Description= This Platform Monitor service is to initialize platform and monitor platform. +Before=platform-monitor.service +After=sysinit.target +Wants=fancontrol.service +DefaultDependencies=no + +[Service] +ExecStartPre=/usr/sbin/i2c_utils.sh i2c_init +ExecStart=/usr/sbin/s8900_54xc_monitor.sh +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/i2c_utils.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/i2c_utils.sh new file mode 100644 index 000000000000..eea7b9ba8fe9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/i2c_utils.sh @@ -0,0 +1,1485 @@ +#!/bin/bash + +# Copyright (C) 2016 Ingrasys, 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 3 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, see . + +VERSION="1.0.0" +TRUE=200 +FALSE=404 +PORT_START=1 +PORT_END=54 + +EXEC_FUNC=${1} +COLOR_LED=${2} +QSFP_PORT=${2} +ONOFF_LED=${3} +FAN_TRAY=${4} + +############################################################ +# Distributor ID: Debian +# Description: Debian GNU/Linux 8.6 (jessie) +# Release: 8.6 +# Codename: jessie +# Linux debian 3.16.0-4-amd64 #1 +# SMP Debian 3.16.36-1+deb8u1 (2016-09-03) x86_64 GNU/Linux +############################################################ + +# Color Definition +COLOR_TITLE="\e[1;32m" ### Green ### +COLOR_WARNING="\e[1;33m" ### Yellow ### +COLOR_ERROR="\e[1;31m" ### Red ### +COLOR_END="\e[0m" ### END ### + +NUM_IGB_DEVICE=0 +NUM_I801_DEVICE=0 +NUM_ISMT_DEVICE=$(( ${NUM_I801_DEVICE} + 1 )) +NUM_MUX1_CHAN0_DEVICE=$(( ${NUM_I801_DEVICE} + 2 )) +NUM_MUX1_CHAN1_DEVICE=$(( ${NUM_I801_DEVICE} + 3 )) +NUM_MUX1_CHAN2_DEVICE=$(( ${NUM_I801_DEVICE} + 4 )) +NUM_MUX1_CHAN3_DEVICE=$(( ${NUM_I801_DEVICE} + 5 )) +NUM_MUX1_CHAN4_DEVICE=$(( ${NUM_I801_DEVICE} + 6 )) +NUM_MUX1_CHAN5_DEVICE=$(( ${NUM_I801_DEVICE} + 7 )) +NUM_MUX1_CHAN6_DEVICE=$(( ${NUM_I801_DEVICE} + 8 )) +NUM_MUX1_CHAN7_DEVICE=$(( ${NUM_I801_DEVICE} + 9 )) +NUM_MUX2_CHAN0_DEVICE=$(( ${NUM_I801_DEVICE} + 10 )) +NUM_MUX2_CHAN1_DEVICE=$(( ${NUM_I801_DEVICE} + 11 )) +NUM_MUX2_CHAN2_DEVICE=$(( ${NUM_I801_DEVICE} + 12 )) +NUM_MUX2_CHAN3_DEVICE=$(( ${NUM_I801_DEVICE} + 13 )) +NUM_MUX2_CHAN4_DEVICE=$(( ${NUM_I801_DEVICE} + 14 )) +NUM_MUX2_CHAN5_DEVICE=$(( ${NUM_I801_DEVICE} + 15 )) +NUM_MUX2_CHAN6_DEVICE=$(( ${NUM_I801_DEVICE} + 16 )) +NUM_MUX2_CHAN7_DEVICE=$(( ${NUM_I801_DEVICE} + 17 )) +NUM_MUX3_CHAN0_DEVICE=$(( ${NUM_I801_DEVICE} + 18 )) +NUM_MUX4_CHAN0_DEVICE=$(( ${NUM_I801_DEVICE} + 26 )) +NUM_MUX5_CHAN0_DEVICE=$(( ${NUM_I801_DEVICE} + 34 )) +NUM_MUX6_CHAN0_DEVICE=$(( ${NUM_I801_DEVICE} + 42 )) +NUM_MUX7_CHAN0_DEVICE=$(( ${NUM_I801_DEVICE} + 50 )) +NUM_MUX8_CHAN0_DEVICE=$(( ${NUM_I801_DEVICE} + 58 )) +NUM_MUX9_CHAN0_DEVICE=$(( ${NUM_I801_DEVICE} + 66 )) + +PATH_SYS_I2C_DEVICES="/sys/bus/i2c/devices" +PATH_HWMON_ROOT_DEVICES="/sys/class/hwmon" +PATH_HWMON_W83795_DEVICE="${PATH_HWMON_ROOT_DEVICES}/hwmon1" +PATH_I801_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_I801_DEVICE}" +PATH_ISMT_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_ISMT_DEVICE}" +PATH_MUX_CHAN0_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN0_DEVICE}" +PATH_MUX_CHAN1_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN1_DEVICE}" +PATH_MUX_CHAN2_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN2_DEVICE}" +PATH_MUX_CHAN3_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN3_DEVICE}" +PATH_MUX_CHAN4_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN4_DEVICE}" +PATH_MUX_CHAN5_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN5_DEVICE}" +PATH_MUX_CHAN6_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN6_DEVICE}" +PATH_MUX_CHAN7_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN7_DEVICE}" + +#SFP/QSFP EEPROM i2c bus index +SFP_EEPROM_BUS_IDX=0 + +#Power Supply Status +PSU_DC_ON=1 +PSU_DC_OFF=0 +PSU_EXIST=1 +PSU_NOT_EXIST=0 + +#GPIO Index for QSFP +ZQSFP_PORT0_15_ABS_GPIO_IDX=192 +ZQSFP_PORT16_31_ABS_GPIO_IDX=176 +ZQSFP_PORT32_47_ABS_GPIO_IDX=160 + + +# Help usage function +function _help { + echo "=========================================================" + echo "# Description: Help Function" + echo "=========================================================" + echo "----------------------------------------------------" + echo "EX : ${0} help" + echo " : ${0} i2c_init" + echo " : ${0} i2c_deinit" + echo " : ${0} i2c_temp_init" + echo " : ${0} i2c_fan_init" + echo " : ${0} i2c_volmon_init" + echo " : ${0} i2c_io_exp_init" + echo " : ${0} i2c_gpio_init" + echo " : ${0} i2c_gpio_deinit" + echo " : ${0} i2c_led_test" + echo " : ${0} i2c_psu_eeprom_get" + echo " : ${0} i2c_mb_eeprom_get" + echo " : ${0} i2c_qsfp_eeprom_get [1-54]" + echo " : ${0} i2c_qsfp_status_get [1-54]" + echo " : ${0} i2c_qsfp_type_get [1-54]" + echo " : ${0} i2c_board_type_get" + echo " : ${0} i2c_psu_status" + echo " : ${0} i2c_led_psu_status_set" + echo " : ${0} i2c_led_fan_status_set" + echo " : ${0} i2c_led_fan_tray_status_set" + echo " : ${0} i2c_cpld_version" + echo " : ${0} i2c_front_temp" + echo " : ${0} i2c_rear_temp" + echo " : ${0} i2c_test_all" + echo " : ${0} i2c_sys_led green|amber on|off" + echo " : ${0} i2c_fan_led green|amber on|off" + echo " : ${0} i2c_psu1_led green|amber on|off" + echo " : ${0} i2c_psu2_led green|amber on|off" + echo " : ${0} i2c_fan_tray_led green|amber on|off [1-4]" + echo "----------------------------------------------------" +} + +#Pause function +function _pause { + read -p "$*" +} + +#Retry command function +function _retry { + for i in {1..5}; + do + eval "${*}" && break || echo "retry"; sleep 1; + done +} + + +#I2C Init +function _i2c_init { + echo "=========================================================" + echo "# Description: I2C Init" + echo "=========================================================" + + rmmod i2c_ismt + rmmod i2c_i801 + modprobe i2c_i801 + modprobe i2c_ismt + modprobe i2c_dev + modprobe i2c_mux_pca954x force_deselect_on_exit=1 + + if [ ! -e "${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN0_DEVICE}" ]; then + _retry "echo 'pca9548 0x70' > ${PATH_ISMT_DEVICE}/new_device" + else + echo "pca9548 0x70 already init." + fi + if [ ! -e "${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX2_CHAN0_DEVICE}" ]; then + _retry "echo 'pca9548 0x72' > ${PATH_ISMT_DEVICE}/new_device" + else + echo "pca9548 0x72 already init." + fi + if [ ! -e "${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX3_CHAN0_DEVICE}" ]; then + _retry "echo 'pca9548 0x71' > ${PATH_MUX_CHAN0_DEVICE}/new_device" + else + echo "pca9548 0x71 already init." + fi + if [ ! -e "${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX4_CHAN0_DEVICE}" ]; then + _retry "echo 'pca9548 0x71' > ${PATH_MUX_CHAN1_DEVICE}/new_device" + else + echo "pca9548 0x71 already init." + fi + if [ ! -e "${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX5_CHAN0_DEVICE}" ]; then + _retry "echo 'pca9548 0x71' > ${PATH_MUX_CHAN2_DEVICE}/new_device" + else + echo "pca9548 0x71 already init." + fi + if [ ! -e "${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX6_CHAN0_DEVICE}" ]; then + _retry "echo 'pca9548 0x71' > ${PATH_MUX_CHAN3_DEVICE}/new_device" + else + echo "pca9548 0x71 already init." + fi + if [ ! -e "${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX7_CHAN0_DEVICE}" ]; then + _retry "echo 'pca9548 0x71' > ${PATH_MUX_CHAN4_DEVICE}/new_device" + else + echo "pca9548 0x71 already init." + fi + if [ ! -e "${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX8_CHAN0_DEVICE}" ]; then + _retry "echo 'pca9548 0x71' > ${PATH_MUX_CHAN5_DEVICE}/new_device" + else + echo "pca9548 0x71 already init." + fi + if [ ! -e "${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX9_CHAN0_DEVICE}" ]; then + _retry "echo 'pca9548 0x71' > ${PATH_MUX_CHAN6_DEVICE}/new_device" + else + echo "pca9548 0x71 already init." + fi + + #Init CPLD LED_CLR Register (Front Port LED) + i2cset -y ${NUM_I801_DEVICE} 0x33 0x34 0x10 + + rmmod coretemp + rmmod jc42 + rmmod w83795 + _i2c_temp_init + _i2c_volmon_init + _i2c_hwmon_init + modprobe coretemp + modprobe w83795 + modprobe jc42 + modprobe sff_8436_eeprom + modprobe eeprom + modprobe eeprom_mb + _i2c_fan_init + _i2c_io_exp_init + _i2c_gpio_init + _i2c_cpld_init + _i2c_psu_eeprom_init + _i2c_led_psu_status_set + _i2c_led_fan_status_set + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_sys_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_sys_led + echo "Mount Main Board EEPROM" + echo "mb_eeprom 0x54" > /sys/bus/i2c/devices/i2c-17/new_device + for (( i=$PORT_START; i<=$PORT_END; i++ )) + do + _i2c_mount_sfp_eeprom $i + done + _config_rmem +} + +#I2C Deinit +function _i2c_deinit { + _i2c_gpio_deinit + for mod in coretemp jc42 w83795 eeprom_mb gpio-pca953x i2c_mux_pca954x i2c_ismt i2c_i801; + do + [ "$(lsmod | grep "^$mod ")" != "" ] && rmmod $mod + done +} + +#Temperature sensor Init +function _i2c_temp_init { + i2cset -y -r ${NUM_I801_DEVICE} 0x2F 0x00 0x80 + i2cset -y -r ${NUM_I801_DEVICE} 0x2F 0x05 0x7F + i2cset -y -r ${NUM_I801_DEVICE} 0x2F 0x04 0x0A + echo "TEMP INIT Done" +} + +#FAN Init +function _i2c_fan_init { + echo -n "FAN INIT..." + if [ -e "${PATH_HWMON_W83795_DEVICE}" ]; then + echo 120 > ${PATH_HWMON_W83795_DEVICE}/device/pwm1 + echo 120 > ${PATH_HWMON_W83795_DEVICE}/device/pwm2 + echo "SUCCESS" + else + echo "FAIL" + fi + +} + +#VOLMON Init +function _i2c_volmon_init { + echo -n "VOLMON INIT..." + i2cset -y -r ${NUM_I801_DEVICE} 0x2F 0x00 0x80 + i2cset -y -r ${NUM_I801_DEVICE} 0x2F 0x02 0xFF + i2cset -y -r ${NUM_I801_DEVICE} 0x2F 0x03 0x50 + i2cset -y -r ${NUM_I801_DEVICE} 0x2F 0x04 0x0A + echo "Done" +} + +#HWMON Init +function _i2c_hwmon_init { + echo -n "HWMON INIT..." + i2cset -y ${NUM_I801_DEVICE} 0x2F 0x00 0x80 + i2cset -y ${NUM_I801_DEVICE} 0x2F 0x06 0xFF + echo "Done" +} + +#IO Expander Init +function _i2c_io_exp_init { + echo "=========================================================" + echo "# Description: I2C IO Expender Init" + echo "=========================================================" + #SMBUS0 IO_EXPENDER + i2cset -y -r ${NUM_I801_DEVICE} 0x27 4 0x00 + i2cset -y -r ${NUM_I801_DEVICE} 0x27 5 0x00 + i2cset -y -r ${NUM_I801_DEVICE} 0x27 6 0xFF + i2cset -y -r ${NUM_I801_DEVICE} 0x27 7 0xFF + + #SMBUS1 + #SFP+ ABS + i2cset -y -r ${NUM_MUX2_CHAN0_DEVICE} 0x20 4 0x00 + i2cset -y -r ${NUM_MUX2_CHAN0_DEVICE} 0x20 5 0x00 + i2cset -y -r ${NUM_MUX2_CHAN0_DEVICE} 0x21 4 0x00 + i2cset -y -r ${NUM_MUX2_CHAN0_DEVICE} 0x21 5 0x00 + i2cset -y -r ${NUM_MUX2_CHAN0_DEVICE} 0x22 4 0x00 + i2cset -y -r ${NUM_MUX2_CHAN0_DEVICE} 0x22 5 0x00 + + i2cset -y -r ${NUM_MUX2_CHAN0_DEVICE} 0x20 6 0xFF + i2cset -y -r ${NUM_MUX2_CHAN0_DEVICE} 0x20 7 0xFF + i2cset -y -r ${NUM_MUX2_CHAN0_DEVICE} 0x21 6 0xFF + i2cset -y -r ${NUM_MUX2_CHAN0_DEVICE} 0x21 7 0xFF + i2cset -y -r ${NUM_MUX2_CHAN0_DEVICE} 0x22 6 0xFF + i2cset -y -r ${NUM_MUX2_CHAN0_DEVICE} 0x22 7 0xFF + + #QSFP/ZQSFP ABS + i2cset -y -r ${NUM_MUX2_CHAN0_DEVICE} 0x23 4 0x00 + i2cset -y -r ${NUM_MUX2_CHAN0_DEVICE} 0x23 6 0xFF + + #QSFP/ZQSFP INT + i2cset -y -r ${NUM_MUX2_CHAN0_DEVICE} 0x23 5 0x00 + i2cset -y -r ${NUM_MUX2_CHAN0_DEVICE} 0x23 7 0xFF + + #SFP+ RX_LOS + i2cset -y -r ${NUM_MUX2_CHAN1_DEVICE} 0x20 4 0x00 + i2cset -y -r ${NUM_MUX2_CHAN1_DEVICE} 0x20 5 0x00 + i2cset -y -r ${NUM_MUX2_CHAN1_DEVICE} 0x21 4 0x00 + i2cset -y -r ${NUM_MUX2_CHAN1_DEVICE} 0x21 5 0x00 + i2cset -y -r ${NUM_MUX2_CHAN1_DEVICE} 0x22 4 0x00 + i2cset -y -r ${NUM_MUX2_CHAN1_DEVICE} 0x22 5 0x00 + + i2cset -y -r ${NUM_MUX2_CHAN1_DEVICE} 0x20 6 0xFF + i2cset -y -r ${NUM_MUX2_CHAN1_DEVICE} 0x20 7 0xFF + i2cset -y -r ${NUM_MUX2_CHAN1_DEVICE} 0x21 6 0xFF + i2cset -y -r ${NUM_MUX2_CHAN1_DEVICE} 0x21 7 0xFF + i2cset -y -r ${NUM_MUX2_CHAN1_DEVICE} 0x22 6 0xFF + i2cset -y -r ${NUM_MUX2_CHAN1_DEVICE} 0x22 7 0xFF + + #SFP+ TX_FAULT + i2cset -y -r ${NUM_MUX2_CHAN2_DEVICE} 0x20 4 0x00 + i2cset -y -r ${NUM_MUX2_CHAN2_DEVICE} 0x20 5 0x00 + i2cset -y -r ${NUM_MUX2_CHAN2_DEVICE} 0x21 4 0x00 + i2cset -y -r ${NUM_MUX2_CHAN2_DEVICE} 0x21 5 0x00 + i2cset -y -r ${NUM_MUX2_CHAN2_DEVICE} 0x22 4 0x00 + i2cset -y -r ${NUM_MUX2_CHAN2_DEVICE} 0x22 5 0x00 + + i2cset -y -r ${NUM_MUX2_CHAN2_DEVICE} 0x20 6 0xFF + i2cset -y -r ${NUM_MUX2_CHAN2_DEVICE} 0x20 7 0xFF + i2cset -y -r ${NUM_MUX2_CHAN2_DEVICE} 0x21 6 0xFF + i2cset -y -r ${NUM_MUX2_CHAN2_DEVICE} 0x21 7 0xFF + i2cset -y -r ${NUM_MUX2_CHAN2_DEVICE} 0x22 6 0xFF + i2cset -y -r ${NUM_MUX2_CHAN2_DEVICE} 0x22 7 0xFF + + #SFP+ TX_RS + i2cset -y -r ${NUM_MUX2_CHAN3_DEVICE} 0x20 4 0x00 + i2cset -y -r ${NUM_MUX2_CHAN3_DEVICE} 0x20 5 0x00 + i2cset -y -r ${NUM_MUX2_CHAN3_DEVICE} 0x21 4 0x00 + i2cset -y -r ${NUM_MUX2_CHAN3_DEVICE} 0x21 5 0x00 + i2cset -y -r ${NUM_MUX2_CHAN3_DEVICE} 0x22 4 0x00 + i2cset -y -r ${NUM_MUX2_CHAN3_DEVICE} 0x22 5 0x00 + + i2cset -y -r ${NUM_MUX2_CHAN3_DEVICE} 0x20 2 0xFF + i2cset -y -r ${NUM_MUX2_CHAN3_DEVICE} 0x20 3 0xFF + i2cset -y -r ${NUM_MUX2_CHAN3_DEVICE} 0x21 2 0xFF + i2cset -y -r ${NUM_MUX2_CHAN3_DEVICE} 0x21 3 0xFF + i2cset -y -r ${NUM_MUX2_CHAN3_DEVICE} 0x22 2 0xFF + i2cset -y -r ${NUM_MUX2_CHAN3_DEVICE} 0x22 3 0xFF + + i2cset -y -r ${NUM_MUX2_CHAN3_DEVICE} 0x20 6 0xFF + i2cset -y -r ${NUM_MUX2_CHAN3_DEVICE} 0x20 7 0xFF + i2cset -y -r ${NUM_MUX2_CHAN3_DEVICE} 0x21 6 0xFF + i2cset -y -r ${NUM_MUX2_CHAN3_DEVICE} 0x21 7 0xFF + i2cset -y -r ${NUM_MUX2_CHAN3_DEVICE} 0x22 6 0xFF + i2cset -y -r ${NUM_MUX2_CHAN3_DEVICE} 0x22 7 0xFF + + #QSFP/zQSFP LPMODE + i2cset -y -r ${NUM_MUX2_CHAN3_DEVICE} 0x23 4 0x00 + i2cset -y -r ${NUM_MUX2_CHAN3_DEVICE} 0x23 2 0x00 + i2cset -y -r ${NUM_MUX2_CHAN3_DEVICE} 0x23 6 0x00 + + #QSFP/zQSFP MODSEL + i2cset -y -r ${NUM_MUX2_CHAN3_DEVICE} 0x23 5 0x00 + i2cset -y -r ${NUM_MUX2_CHAN3_DEVICE} 0x23 3 0x00 + i2cset -y -r ${NUM_MUX2_CHAN3_DEVICE} 0x23 7 0x00 + + #SFP+ RX_RS + i2cset -y -r ${NUM_MUX2_CHAN4_DEVICE} 0x20 4 0x00 + i2cset -y -r ${NUM_MUX2_CHAN4_DEVICE} 0x20 5 0x00 + i2cset -y -r ${NUM_MUX2_CHAN4_DEVICE} 0x21 4 0x00 + i2cset -y -r ${NUM_MUX2_CHAN4_DEVICE} 0x21 5 0x00 + i2cset -y -r ${NUM_MUX2_CHAN4_DEVICE} 0x22 4 0x00 + i2cset -y -r ${NUM_MUX2_CHAN4_DEVICE} 0x22 5 0x00 + + i2cset -y -r ${NUM_MUX2_CHAN4_DEVICE} 0x20 2 0xFF + i2cset -y -r ${NUM_MUX2_CHAN4_DEVICE} 0x20 3 0xFF + i2cset -y -r ${NUM_MUX2_CHAN4_DEVICE} 0x21 2 0xFF + i2cset -y -r ${NUM_MUX2_CHAN4_DEVICE} 0x21 3 0xFF + i2cset -y -r ${NUM_MUX2_CHAN4_DEVICE} 0x22 2 0xFF + i2cset -y -r ${NUM_MUX2_CHAN4_DEVICE} 0x22 3 0xFF + + i2cset -y -r ${NUM_MUX2_CHAN4_DEVICE} 0x20 6 0x00 + i2cset -y -r ${NUM_MUX2_CHAN4_DEVICE} 0x20 7 0x00 + i2cset -y -r ${NUM_MUX2_CHAN4_DEVICE} 0x21 6 0x00 + i2cset -y -r ${NUM_MUX2_CHAN4_DEVICE} 0x21 7 0x00 + i2cset -y -r ${NUM_MUX2_CHAN4_DEVICE} 0x22 6 0x00 + i2cset -y -r ${NUM_MUX2_CHAN4_DEVICE} 0x22 7 0x00 + + #SFP+ TX_DIS + i2cset -y -r ${NUM_MUX2_CHAN5_DEVICE} 0x20 4 0x00 + i2cset -y -r ${NUM_MUX2_CHAN5_DEVICE} 0x20 5 0x00 + i2cset -y -r ${NUM_MUX2_CHAN5_DEVICE} 0x21 4 0x00 + i2cset -y -r ${NUM_MUX2_CHAN5_DEVICE} 0x21 5 0x00 + i2cset -y -r ${NUM_MUX2_CHAN5_DEVICE} 0x22 4 0x00 + i2cset -y -r ${NUM_MUX2_CHAN5_DEVICE} 0x22 5 0x00 + + i2cset -y -r ${NUM_MUX2_CHAN5_DEVICE} 0x20 2 0x00 + i2cset -y -r ${NUM_MUX2_CHAN5_DEVICE} 0x20 3 0x00 + i2cset -y -r ${NUM_MUX2_CHAN5_DEVICE} 0x21 2 0x00 + i2cset -y -r ${NUM_MUX2_CHAN5_DEVICE} 0x21 3 0x00 + i2cset -y -r ${NUM_MUX2_CHAN5_DEVICE} 0x22 2 0x00 + i2cset -y -r ${NUM_MUX2_CHAN5_DEVICE} 0x22 3 0x00 + + i2cset -y -r ${NUM_MUX2_CHAN5_DEVICE} 0x20 6 0x00 + i2cset -y -r ${NUM_MUX2_CHAN5_DEVICE} 0x20 7 0x00 + i2cset -y -r ${NUM_MUX2_CHAN5_DEVICE} 0x21 6 0x00 + i2cset -y -r ${NUM_MUX2_CHAN5_DEVICE} 0x21 7 0x00 + i2cset -y -r ${NUM_MUX2_CHAN5_DEVICE} 0x22 6 0x00 + i2cset -y -r ${NUM_MUX2_CHAN5_DEVICE} 0x22 7 0x00 + + #QSFP/zQSFP RST + i2cset -y -r ${NUM_MUX2_CHAN5_DEVICE} 0x23 4 0x00 + i2cset -y -r ${NUM_MUX2_CHAN5_DEVICE} 0x23 2 0xFF + i2cset -y -r ${NUM_MUX2_CHAN5_DEVICE} 0x23 6 0x00 + + #SFP/QSFP/zQSFP I/O + i2cset -y -r ${NUM_MUX2_CHAN5_DEVICE} 0x24 4 0x00 + i2cset -y -r ${NUM_MUX2_CHAN5_DEVICE} 0x24 5 0x00 + i2cset -y -r ${NUM_MUX2_CHAN5_DEVICE} 0x24 6 0xFF + i2cset -y -r ${NUM_MUX2_CHAN5_DEVICE} 0x24 7 0xFF + + #ZQSFP/SFP+/E-Card General + i2cset -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x21 4 0x00 + i2cset -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x21 5 0x00 + i2cset -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x21 2 0x00 + i2cset -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x21 3 0x00 + i2cset -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x21 6 0xF4 + i2cset -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x21 7 0xF4 + + #LED board after PVT (S8900_IO_EXP_LED_ID) + echo "Init LED IO Expender" + i2cset -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 4 0x00 + i2cset -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 5 0x00 + i2cset -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 6 0x00 + i2cset -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 7 0x00 + + #PSU I/O (S8900_IO_EXP_PSU_ID) + echo "Init PSU IO Expender" + i2cset -y -r ${NUM_MUX2_CHAN6_DEVICE} 0x20 4 0x00 + i2cset -y -r ${NUM_MUX2_CHAN6_DEVICE} 0x20 5 0x00 + i2cset -y -r ${NUM_MUX2_CHAN6_DEVICE} 0x20 2 0x00 + i2cset -y -r ${NUM_MUX2_CHAN6_DEVICE} 0x20 3 0x00 + i2cset -y -r ${NUM_MUX2_CHAN6_DEVICE} 0x20 6 0xFF + i2cset -y -r ${NUM_MUX2_CHAN6_DEVICE} 0x20 7 0xFF + + #FAN I/O (S8900_IO_EXP_FAN_ID) + echo "Init FAN IO Expender" + i2cset -y -r ${NUM_MUX2_CHAN7_DEVICE} 0x20 4 0x00 + i2cset -y -r ${NUM_MUX2_CHAN7_DEVICE} 0x20 5 0x00 + i2cset -y -r ${NUM_MUX2_CHAN7_DEVICE} 0x20 2 0x11 + i2cset -y -r ${NUM_MUX2_CHAN7_DEVICE} 0x20 3 0x11 + i2cset -y -r ${NUM_MUX2_CHAN7_DEVICE} 0x20 6 0xCC + i2cset -y -r ${NUM_MUX2_CHAN7_DEVICE} 0x20 7 0xCC +} + +function _get_sfp_eeprom_bus_idx { + case $1 in + 1|2|3|4|5|6|7|8) + SFP_EEPROM_BUS_IDX=$(( (${NUM_MUX3_CHAN0_DEVICE} + $1 - 1) )) + ;; + 9|10|11|12|13|14|15|16) + SFP_EEPROM_BUS_IDX=$(( (${NUM_MUX4_CHAN0_DEVICE} + $1 - 9) )) + ;; + 17|18|19|20|21|22|23|24) + SFP_EEPROM_BUS_IDX=$(( (${NUM_MUX5_CHAN0_DEVICE} + $1 - 17) )) + ;; + 25|26|27|28|29|30|31|32) + SFP_EEPROM_BUS_IDX=$(( (${NUM_MUX6_CHAN0_DEVICE} + $1 - 25) )) + ;; + 33|34|35|36|37|38|39|40) + SFP_EEPROM_BUS_IDX=$(( (${NUM_MUX7_CHAN0_DEVICE} + $1 - 33) )) + ;; + 41|42|43|44|45|46|47|48) + SFP_EEPROM_BUS_IDX=$(( (${NUM_MUX8_CHAN0_DEVICE} + $1 - 41) )) + ;; + 49|50|51|52|53|54) + SFP_EEPROM_BUS_IDX=$(( (${NUM_MUX9_CHAN0_DEVICE} + $1 - 49) )) + ;; + *) + SFP_EEPROM_BUS_IDX=-1 + ;; + esac +} + +#Mount SFP/QSFP EEPROM +function _i2c_mount_sfp_eeprom { + _get_sfp_eeprom_bus_idx $1 + eeprombus=${SFP_EEPROM_BUS_IDX} + eepromAddr=0x50 + echo "sff8436 $eepromAddr" > /sys/bus/i2c/devices/i2c-$eeprombus/new_device + echo "Mount Port $1 EEPROM" +} + +#Unmount SFP/QSFP EEPROM +function _i2c_unmount_sfp_eeprom { + _get_sfp_eeprom_bus_idx $1 + eeprombus=${SFP_EEPROM_BUS_IDX} + eepromAddr=0x50 + echo "$eepromAddr" > /sys/bus/i2c/devices/i2c-$eeprombus/new_device + echo "Unmount Port $1 EEPROM" +} + +#GPIO Init +function _i2c_gpio_init { + + #QSFP/ZQSFP ABS+INT + echo "pca9535 0x23" > /sys/bus/i2c/devices/i2c-${NUM_MUX2_CHAN0_DEVICE}/new_device + + _retry "echo 240 > /sys/class/gpio/export" + echo 241 > /sys/class/gpio/export + echo 242 > /sys/class/gpio/export + echo 243 > /sys/class/gpio/export + echo 244 > /sys/class/gpio/export + echo 245 > /sys/class/gpio/export + echo 246 > /sys/class/gpio/export + echo 247 > /sys/class/gpio/export + echo 248 > /sys/class/gpio/export + echo 249 > /sys/class/gpio/export + echo 250 > /sys/class/gpio/export + echo 251 > /sys/class/gpio/export + echo 252 > /sys/class/gpio/export + echo 253 > /sys/class/gpio/export + echo 254 > /sys/class/gpio/export + echo 255 > /sys/class/gpio/export + + echo 1 > /sys/class/gpio/gpio241/active_low #QSFP49 ABS + echo 1 > /sys/class/gpio/gpio240/active_low #QSFP48 ABS + echo 1 > /sys/class/gpio/gpio243/active_low #QSFP51 ABS + echo 1 > /sys/class/gpio/gpio242/active_low #QSFP50 ABS + echo 1 > /sys/class/gpio/gpio245/active_low #QSFP53 ABS + echo 1 > /sys/class/gpio/gpio244/active_low #QSFP52 ABS + echo 1 > /sys/class/gpio/gpio247/active_low #NA + echo 1 > /sys/class/gpio/gpio246/active_low #NA + echo 1 > /sys/class/gpio/gpio249/active_low #QSFP49 INT + echo 1 > /sys/class/gpio/gpio248/active_low #QSFP48 INT + echo 1 > /sys/class/gpio/gpio251/active_low #QSFP51 INT + echo 1 > /sys/class/gpio/gpio250/active_low #QSFP50 INT + echo 1 > /sys/class/gpio/gpio253/active_low #QSFP53 INT + echo 1 > /sys/class/gpio/gpio252/active_low #QSFP52 INT + echo 1 > /sys/class/gpio/gpio255/active_low #NA + echo 1 > /sys/class/gpio/gpio254/active_low #NA + + #QSFP/zQSFP LPMODE+MODSEL + echo "pca9535 0x23" > /sys/bus/i2c/devices/i2c-${NUM_MUX2_CHAN3_DEVICE}/new_device + echo 224 > /sys/class/gpio/export #QSFP0 LPMODE + echo 225 > /sys/class/gpio/export #QSFP1 LPMODE + echo 226 > /sys/class/gpio/export #QSFP2 LPMODE + echo 227 > /sys/class/gpio/export #QSFP3 LPMODE + echo 228 > /sys/class/gpio/export #QSFP4 LPMODE + echo 229 > /sys/class/gpio/export #QSFP5 LPMODE + echo 230 > /sys/class/gpio/export #NA + echo 231 > /sys/class/gpio/export #NA + echo 232 > /sys/class/gpio/export #QSFP0 MODSEL + echo 233 > /sys/class/gpio/export #QSFP1 MODSEL + echo 234 > /sys/class/gpio/export #QSFP2 MODSEL + echo 235 > /sys/class/gpio/export #QSFP3 MODSEL + echo 236 > /sys/class/gpio/export #QSFP4 MODSEL + echo 237 > /sys/class/gpio/export #QSFP5 MODSEL + echo 238 > /sys/class/gpio/export #NA + echo 239 > /sys/class/gpio/export #NA + echo out > /sys/class/gpio/gpio224/direction + echo out > /sys/class/gpio/gpio225/direction + echo out > /sys/class/gpio/gpio226/direction + echo out > /sys/class/gpio/gpio227/direction + echo out > /sys/class/gpio/gpio228/direction + echo out > /sys/class/gpio/gpio229/direction + echo out > /sys/class/gpio/gpio230/direction + echo out > /sys/class/gpio/gpio231/direction + echo out > /sys/class/gpio/gpio232/direction + echo out > /sys/class/gpio/gpio233/direction + echo out > /sys/class/gpio/gpio234/direction + echo out > /sys/class/gpio/gpio235/direction + echo out > /sys/class/gpio/gpio236/direction + echo out > /sys/class/gpio/gpio237/direction + echo out > /sys/class/gpio/gpio238/direction + echo out > /sys/class/gpio/gpio239/direction + + #QSFP RST + echo "pca9535 0x23" > /sys/bus/i2c/devices/i2c-${NUM_MUX2_CHAN5_DEVICE}/new_device + echo 208 > /sys/class/gpio/export #QSFP0 RST + echo 209 > /sys/class/gpio/export #QSFP1 RST + echo 210 > /sys/class/gpio/export #QSFP2 RST + echo 211 > /sys/class/gpio/export #QSFP3 RST + echo 212 > /sys/class/gpio/export #QSFP4 RST + echo 213 > /sys/class/gpio/export #QSFP5 RST + echo 214 > /sys/class/gpio/export #NA + echo 215 > /sys/class/gpio/export #NA + echo 216 > /sys/class/gpio/export #NA + echo 217 > /sys/class/gpio/export #NA + echo 218 > /sys/class/gpio/export #NA + echo 219 > /sys/class/gpio/export #NA + echo 220 > /sys/class/gpio/export #NA + echo 221 > /sys/class/gpio/export #NA + echo 222 > /sys/class/gpio/export #NA + echo 223 > /sys/class/gpio/export #NA + echo out > /sys/class/gpio/gpio208/direction + echo out > /sys/class/gpio/gpio209/direction + echo out > /sys/class/gpio/gpio210/direction + echo out > /sys/class/gpio/gpio211/direction + echo out > /sys/class/gpio/gpio212/direction + echo out > /sys/class/gpio/gpio213/direction + echo 1 > /sys/class/gpio/gpio208/active_low + echo 1 > /sys/class/gpio/gpio209/active_low + echo 1 > /sys/class/gpio/gpio210/active_low + echo 1 > /sys/class/gpio/gpio211/active_low + echo 1 > /sys/class/gpio/gpio212/active_low + echo 1 > /sys/class/gpio/gpio213/active_low + echo 0 > /sys/class/gpio/gpio208/value + echo 0 > /sys/class/gpio/gpio209/value + echo 0 > /sys/class/gpio/gpio210/value + echo 0 > /sys/class/gpio/gpio211/value + echo 0 > /sys/class/gpio/gpio212/value + echo 0 > /sys/class/gpio/gpio213/value + + #SFP+ ABS 0-15 + echo "pca9535 0x20" > /sys/bus/i2c/devices/i2c-${NUM_MUX2_CHAN0_DEVICE}/new_device + echo 192 > /sys/class/gpio/export + echo 193 > /sys/class/gpio/export + echo 194 > /sys/class/gpio/export + echo 195 > /sys/class/gpio/export + echo 196 > /sys/class/gpio/export + echo 197 > /sys/class/gpio/export + echo 198 > /sys/class/gpio/export + echo 199 > /sys/class/gpio/export + echo 200 > /sys/class/gpio/export + echo 201 > /sys/class/gpio/export + echo 202 > /sys/class/gpio/export + echo 203 > /sys/class/gpio/export + echo 204 > /sys/class/gpio/export + echo 205 > /sys/class/gpio/export + echo 206 > /sys/class/gpio/export + echo 207 > /sys/class/gpio/export + echo 1 > /sys/class/gpio/gpio192/active_low #SFP+00 + echo 1 > /sys/class/gpio/gpio193/active_low #SFP+01 + echo 1 > /sys/class/gpio/gpio194/active_low #SFP+02 + echo 1 > /sys/class/gpio/gpio195/active_low #SFP+03 + echo 1 > /sys/class/gpio/gpio196/active_low #SFP+04 + echo 1 > /sys/class/gpio/gpio197/active_low #SFP+05 + echo 1 > /sys/class/gpio/gpio198/active_low #SFP+06 + echo 1 > /sys/class/gpio/gpio199/active_low #SFP+07 + echo 1 > /sys/class/gpio/gpio200/active_low #SFP+08 + echo 1 > /sys/class/gpio/gpio201/active_low #SFP+09 + echo 1 > /sys/class/gpio/gpio202/active_low #SFP+10 + echo 1 > /sys/class/gpio/gpio203/active_low #SFP+11 + echo 1 > /sys/class/gpio/gpio204/active_low #SFP+12 + echo 1 > /sys/class/gpio/gpio205/active_low #SFP+13 + echo 1 > /sys/class/gpio/gpio206/active_low #SFP+14 + echo 1 > /sys/class/gpio/gpio207/active_low #SFP+15 + + #SFP+ ABS 16-31 + echo "pca9535 0x21" > /sys/bus/i2c/devices/i2c-${NUM_MUX2_CHAN0_DEVICE}/new_device + echo 176 > /sys/class/gpio/export + echo 177 > /sys/class/gpio/export + echo 178 > /sys/class/gpio/export + echo 179 > /sys/class/gpio/export + echo 180 > /sys/class/gpio/export + echo 181 > /sys/class/gpio/export + echo 182 > /sys/class/gpio/export + echo 183 > /sys/class/gpio/export + echo 184 > /sys/class/gpio/export + echo 185 > /sys/class/gpio/export + echo 186 > /sys/class/gpio/export + echo 187 > /sys/class/gpio/export + echo 188 > /sys/class/gpio/export + echo 189 > /sys/class/gpio/export + echo 190 > /sys/class/gpio/export + echo 191 > /sys/class/gpio/export + echo 1 > /sys/class/gpio/gpio176/active_low #SFP+16 + echo 1 > /sys/class/gpio/gpio177/active_low #SFP+17 + echo 1 > /sys/class/gpio/gpio178/active_low #SFP+18 + echo 1 > /sys/class/gpio/gpio179/active_low #SFP+19 + echo 1 > /sys/class/gpio/gpio180/active_low #SFP+20 + echo 1 > /sys/class/gpio/gpio181/active_low #SFP+21 + echo 1 > /sys/class/gpio/gpio182/active_low #SFP+22 + echo 1 > /sys/class/gpio/gpio183/active_low #SFP+23 + echo 1 > /sys/class/gpio/gpio184/active_low #SFP+24 + echo 1 > /sys/class/gpio/gpio185/active_low #SFP+25 + echo 1 > /sys/class/gpio/gpio186/active_low #SFP+26 + echo 1 > /sys/class/gpio/gpio187/active_low #SFP+27 + echo 1 > /sys/class/gpio/gpio188/active_low #SFP+28 + echo 1 > /sys/class/gpio/gpio189/active_low #SFP+29 + echo 1 > /sys/class/gpio/gpio190/active_low #SFP+30 + echo 1 > /sys/class/gpio/gpio191/active_low #SFP+31 + + #SFP+ ABS 32-47 + echo "pca9535 0x22" > /sys/bus/i2c/devices/i2c-${NUM_MUX2_CHAN0_DEVICE}/new_device + echo 160 > /sys/class/gpio/export + echo 161 > /sys/class/gpio/export + echo 162 > /sys/class/gpio/export + echo 163 > /sys/class/gpio/export + echo 164 > /sys/class/gpio/export + echo 165 > /sys/class/gpio/export + echo 166 > /sys/class/gpio/export + echo 167 > /sys/class/gpio/export + echo 168 > /sys/class/gpio/export + echo 169 > /sys/class/gpio/export + echo 170 > /sys/class/gpio/export + echo 171 > /sys/class/gpio/export + echo 172 > /sys/class/gpio/export + echo 173 > /sys/class/gpio/export + echo 174 > /sys/class/gpio/export + echo 175 > /sys/class/gpio/export + echo 1 > /sys/class/gpio/gpio160/active_low #SFP+32 + echo 1 > /sys/class/gpio/gpio161/active_low #SFP+33 + echo 1 > /sys/class/gpio/gpio162/active_low #SFP+34 + echo 1 > /sys/class/gpio/gpio163/active_low #SFP+35 + echo 1 > /sys/class/gpio/gpio164/active_low #SFP+36 + echo 1 > /sys/class/gpio/gpio165/active_low #SFP+37 + echo 1 > /sys/class/gpio/gpio166/active_low #SFP+38 + echo 1 > /sys/class/gpio/gpio167/active_low #SFP+39 + echo 1 > /sys/class/gpio/gpio168/active_low #SFP+40 + echo 1 > /sys/class/gpio/gpio169/active_low #SFP+41 + echo 1 > /sys/class/gpio/gpio170/active_low #SFP+42 + echo 1 > /sys/class/gpio/gpio171/active_low #SFP+43 + echo 1 > /sys/class/gpio/gpio172/active_low #SFP+44 + echo 1 > /sys/class/gpio/gpio173/active_low #SFP+45 + echo 1 > /sys/class/gpio/gpio174/active_low #SFP+46 + echo 1 > /sys/class/gpio/gpio175/active_low #SFP+47 + +} + +#GPIO DeInit +function _i2c_gpio_deinit { + echo "0x23" > /sys/bus/i2c/devices/i2c-${NUM_MUX2_CHAN0_DEVICE}/delete_device + echo "0x23" > /sys/bus/i2c/devices/i2c-${NUM_MUX2_CHAN3_DEVICE}/delete_device + echo "0x23" > /sys/bus/i2c/devices/i2c-${NUM_MUX2_CHAN5_DEVICE}/delete_device + echo "0x20" > /sys/bus/i2c/devices/i2c-${NUM_MUX2_CHAN0_DEVICE}/delete_device + echo "0x21" > /sys/bus/i2c/devices/i2c-${NUM_MUX2_CHAN0_DEVICE}/delete_device + echo "0x22" > /sys/bus/i2c/devices/i2c-${NUM_MUX2_CHAN0_DEVICE}/delete_device +} + +#I2C CPLD init +function _i2c_cpld_init { + echo "=========================================================" + echo "# Description: I2C CPLD Init..." + echo "=========================================================" + + ## modprobe i2c_cpld + modprobe i2c_cpld + ## Add CPLD device + echo "i2c_cpld 0x33" > ${PATH_SYS_I2C_DEVICES}/i2c-${NUM_I801_DEVICE}/new_device + + echo "done..." +} + +#Set FAN Tray LED +function _i2c_led_fan_tray_status_set { + echo "FAN Tray Status Setup" + #FAN Status get + FAN1_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan1_alarm` + FAN2_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan2_alarm` + FAN3_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan3_alarm` + FAN4_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan4_alarm` + FAN5_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan5_alarm` + FAN6_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan6_alarm` + FAN7_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan7_alarm` + FAN8_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan8_alarm` + + if [ "${FAN1_ALARM}" == "0" ] && [ "${FAN2_ALARM}" == "0" ]; then + FAN_TRAY=1 + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + else + FAN_TRAY=1 + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + fi + + if [ "${FAN3_ALARM}" == "0" ] && [ "${FAN4_ALARM}" == "0" ]; then + FAN_TRAY=2 + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + else + FAN_TRAY=2 + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + fi + + if [ "${FAN5_ALARM}" == "0" ] && [ "${FAN6_ALARM}" == "0" ]; then + FAN_TRAY=3 + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + else + FAN_TRAY=3 + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + fi + + if [ "${FAN7_ALARM}" == "0" ] && [ "${FAN8_ALARM}" == "0" ]; then + FAN_TRAY=4 + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + else + FAN_TRAY=4 + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + fi +} + +#Set FAN LED +function _i2c_led_fan_status_set { + echo "FAN Status Setup" + #PSU Status set + FAN1_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan1_alarm` + FAN2_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan2_alarm` + FAN3_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan3_alarm` + FAN4_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan4_alarm` + FAN5_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan5_alarm` + FAN6_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan6_alarm` + FAN7_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan7_alarm` + FAN8_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan8_alarm` + + if [ "${FAN1_ALARM}" == "0" ] && [ "${FAN2_ALARM}" == "0" ] \ + && [ "${FAN3_ALARM}" == "0" ] && [ "${FAN4_ALARM}" == "0" ] \ + && [ "${FAN5_ALARM}" == "0" ] && [ "${FAN6_ALARM}" == "0" ] \ + && [ "${FAN7_ALARM}" == "0" ] && [ "${FAN8_ALARM}" == "0" ]; then + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_led + else + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_led + fi +} + +#Set Power Supply LED +function _i2c_led_psu_status_set { + echo "PSU LED Status Setup" + + #PSU Status set + _i2c_psu_status + + #PSU1 Status + if [ "${psu1Exist}" == ${PSU_EXIST} ]; then + if [ "${psu1PwGood}" == ${PSU_DC_ON} ]; then + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu1_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu1_led + else + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu1_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu1_led + fi + else + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu1_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu1_led + fi + + #PSU2 Status + if [ "${psu2Exist}" == ${PSU_EXIST} ]; then + if [ "${psu2PwGood}" == ${PSU_DC_ON} ]; then + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu2_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu2_led + else + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu2_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu2_led + fi + else + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu2_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu2_led + fi +} + +#LED Test +function _i2c_led_test { + echo "=========================================================" + echo "# Description: I2C LED TEST..." + echo "=========================================================" + #sys led (green) + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0x7F + _pause 'Check SYS LED green light and Press [Enter] key to continue...' + #sys led (amber) + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xBF + _pause 'Check SYS LED amber light and Press [Enter] key to continue...' + + #FAN led (green) + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xF7 + _pause 'Check FAN LED green light and Press [Enter] key to continue...' + #FAN led (amber) + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFB + _pause 'Check FAN LED amber light and Press [Enter] key to continue...' + + #PSU2 led (green) + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xDF + _pause 'Check PSU2 LED green light and Press [Enter] key to continue...' + #PSU2 led (amber) + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xEF + _pause 'Check PSU2 LED amber light and Press [Enter] key to continue...' + + #PSU1 led (green) + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFD + _pause 'Check PSU1 LED green light and Press [Enter] key to continue...' + #PSU1 led (amber) + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFE + _pause 'Check PSU1 LED amber light and Press [Enter] key to continue...' + + #Turn OFF All LED + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + _pause 'Check turn off all LEDs and Press [Enter] key to continue...' + echo "done..." +} + +#Set QSFP Port variable +function _qsfp_port_i2c_var_set { + local port=$1 + case ${port} in + 1|2|3|4|5|6|7|8) + i2cbus=${NUM_MUX2_CHAN0_DEVICE} + regAddr=0x20 + dataAddr=0 + gpioBase=${ZQSFP_PORT0_15_ABS_GPIO_IDX} + ;; + 9|10|11|12|13|14|15|16) + i2cbus=${NUM_MUX2_CHAN0_DEVICE} + regAddr=0x20 + dataAddr=1 + gpioBase=${ZQSFP_PORT0_15_ABS_GPIO_IDX} + ;; + 17|18|19|20|21|22|23|24) + i2cbus=${NUM_MUX2_CHAN0_DEVICE} + regAddr=0x21 + dataAddr=0 + gpioBase=${ZQSFP_PORT16_31_ABS_GPIO_IDX} + ;; + 25|26|27|28|29|30|31|32) + i2cbus=${NUM_MUX2_CHAN0_DEVICE} + regAddr=0x21 + dataAddr=1 + gpioBase=${ZQSFP_PORT16_31_ABS_GPIO_IDX} + ;; + 33|34|35|36|37|38|39|40) + i2cbus=${NUM_MUX2_CHAN0_DEVICE} + regAddr=0x22 + dataAddr=0 + gpioBase=${ZQSFP_PORT32_47_ABS_GPIO_IDX} + ;; + 41|42|43|44|45|46|47|48) + i2cbus=${NUM_MUX2_CHAN0_DEVICE} + regAddr=0x22 + dataAddr=1 + gpioBase=${ZQSFP_PORT32_47_ABS_GPIO_IDX} + ;; + 49|50|51|52|53|54) + i2cbus=${NUM_MUX2_CHAN0_DEVICE} + regAddr=0x23 + dataAddr=0 + gpioBase=$((240 - 48)) + ;; + *) + echo "Please input 1~54" + exit ${FALSE} + ;; + esac +} + +#Get QSFP present +function _i2c_qsfp_status_get { + local status + _qsfp_port_i2c_var_set ${QSFP_PORT} + if [ ${QSFP_PORT} -lt 49 ] && [ ${QSFP_PORT} -gt 0 ]; then + status=`cat /sys/class/gpio/gpio$(( $(($gpioBase + (${QSFP_PORT} - 1) % 16 )) ))/value` + elif [ ${QSFP_PORT} -ge 49 ] && [ ${QSFP_PORT} -le 54 ]; then + status=`cat /sys/class/gpio/gpio$(( $(($gpioBase + (${QSFP_PORT} - 1))) ))/value` + fi + + echo "status=$status" +} + +#Get QSFP type +function _i2c_qsfp_type_get { + _get_sfp_eeprom_bus_idx ${QSFP_PORT} + eeprombus=${SFP_EEPROM_BUS_IDX} + eepromAddr=0x50 + qsfp_info=$(base64 ${PATH_SYS_I2C_DEVICES}/$eeprombus-$(printf "%04x" $eepromAddr)/eeprom) + + if [ ${QSFP_PORT} -ge 1 ] && [ ${QSFP_PORT} -le 48 ]; then + echo "sfp" + # 1~48 port is sfp port + identifier=$(echo $qsfp_info | base64 -d -i | hexdump -s 0 -n 1 -e '"%x"') + connector=$(echo $qsfp_info | base64 -d -i | hexdump -s 2 -n 1 -e '"%x"') + transceiver=$(echo $qsfp_info | base64 -d -i | hexdump -s 3 -n 1 -e '"%x"') + else + echo "qsfp" + # 49~54 port is qsfp port + identifier=$(echo $qsfp_info | base64 -d -i | hexdump -s 128 -n 1 -e '"%x"') + connector=$(echo $qsfp_info | base64 -d -i | hexdump -s 130 -n 1 -e '"%x"') + transceiver=$(echo $qsfp_info | base64 -d -i | hexdump -s 131 -n 1 -e '"%x"') + fi + + echo "identifier=$identifier" + echo "connector=$connector" + echo "transceiver=$transceiver" +} + +#Get QSFP EEPROM Information +function _i2c_qsfp_eeprom_get { + + _qsfp_port_i2c_var_set ${QSFP_PORT} + + if [ ${QSFP_PORT} -lt 49 ] && [ ${QSFP_PORT} -gt 0 ]; then + + #status: 0 -> Down, 1 -> Up + status=`cat /sys/class/gpio/gpio$(( $(($gpioBase + (${QSFP_PORT} - 1) % 16 )) ))/value` + echo $status + + if [ $status = 0 ]; then + exit + fi + + _get_sfp_eeprom_bus_idx ${QSFP_PORT} + eeprombus=${SFP_EEPROM_BUS_IDX} + eepromAddr=0x50 + cat ${PATH_SYS_I2C_DEVICES}/$eeprombus-$(printf "%04x" $eepromAddr)/eeprom | hexdump -C + elif [ ${QSFP_PORT} -ge 49 ] && [ ${QSFP_PORT} -le 54 ]; then + #status: 0 -> Down, 1 -> Up + status=`cat /sys/class/gpio/gpio$(( $(($gpioBase + (${QSFP_PORT} - 1))) ))/value` + echo $status + + if [ $status = 0 ]; then + exit + fi + _get_sfp_eeprom_bus_idx ${QSFP_PORT} + eeprombus=${SFP_EEPROM_BUS_IDX} + eepromAddr=0x50 + cat ${PATH_SYS_I2C_DEVICES}/$eeprombus-$(printf "%04x" $eepromAddr)/eeprom | hexdump -C + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi +} + +#PSU EEPROM init +function _i2c_psu_eeprom_init { + echo "=========================================================" + echo "# Description: I2C PSU EEPROM Init..." + echo "=========================================================" + + ## modprobe eeprom + modprobe eeprom + ## PUS(0) EEPROM + echo "eeprom 0x50" > ${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX2_CHAN6_DEVICE}/new_device + + ## PUS(1) EEPROM + echo "eeprom 0x50" > ${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX2_CHAN7_DEVICE}/new_device + + echo "done..." +} + +#Get PSU EEPROM Information +function _i2c_psu_eeprom_get { + echo "=========================================================" + echo "# Description: I2C PSU EEPROM Get..." + echo "=========================================================" + + ## modprobe eeprom + modprobe eeprom + ## PUS(0) EEPROM + cat ${PATH_SYS_I2C_DEVICES}/${NUM_MUX2_CHAN6_DEVICE}-0050/eeprom | hexdump -C + + ## PUS(1) EEPROM + cat ${PATH_SYS_I2C_DEVICES}/${NUM_MUX2_CHAN7_DEVICE}-0050/eeprom | hexdump -C + + echo "done..." +} + +#Get MotherBoard EEPROM Information +function _i2c_mb_eeprom_get { + echo "=========================================================" + echo "# Description: I2C MB EEPROM Get..." + echo "=========================================================" + + ## modprobe eeprom + modprobe eeprom_mb + + ## MB EEPROM + cat ${PATH_SYS_I2C_DEVICES}/${NUM_MUX2_CHAN7_DEVICE}-0054/eeprom | hexdump -C + echo "done..." +} + +#Set System Status LED +function _i2c_sys_led { + if [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "on" ]; then + i2cset -m 0x80 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0x00 + elif [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "off" ]; then + i2cset -m 0x80 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "on" ]; then + i2cset -m 0x40 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0x00 + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "off" ]; then + i2cset -m 0x40 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + echo "done..." +} + +#Set PSU2 LED +function _i2c_psu2_led { + if [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "on" ]; then + i2cset -m 0x20 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0x00 + elif [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "off" ]; then + i2cset -m 0x20 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "on" ]; then + i2cset -m 0x10 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0x00 + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "off" ]; then + i2cset -m 0x10 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + echo "done..." +} + +#Set FAN Tray LED +function _i2c_fan_tray_led { + case ${FAN_TRAY} in + 1) + i2cAddr=0x20 + ioPort=2 + if [ "${COLOR_LED}" == "green" ]; then + mask=0x01 + elif [ "${COLOR_LED}" == "amber" ]; then + mask=0x02 + fi + ;; + 2) + i2cAddr=0x20 + ioPort=2 + if [ "${COLOR_LED}" == "green" ]; then + mask=0x10 + elif [ "${COLOR_LED}" == "amber" ]; then + mask=0x20 + fi + ;; + 3) + i2cAddr=0x20 + ioPort=3 + if [ "${COLOR_LED}" == "green" ]; then + mask=0x01 + elif [ "${COLOR_LED}" == "amber" ]; then + mask=0x02 + fi + ;; + 4) + i2cAddr=0x20 + ioPort=3 + if [ "${COLOR_LED}" == "green" ]; then + mask=0x10 + elif [ "${COLOR_LED}" == "amber" ]; then + mask=0x20 + fi + ;; + *) + echo "Please input 1~4" + exit + ;; + esac + + if [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "on" ]; then + i2cset -m $mask -y -r ${NUM_MUX2_CHAN7_DEVICE} $i2cAddr $ioPort 0x33 + elif [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "off" ]; then + i2cset -m $mask -y -r ${NUM_MUX2_CHAN7_DEVICE} $i2cAddr $ioPort 0x00 + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "on" ]; then + i2cset -m $mask -y -r ${NUM_MUX2_CHAN7_DEVICE} $i2cAddr $ioPort 0x33 + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "off" ]; then + i2cset -m $mask -y -r ${NUM_MUX2_CHAN7_DEVICE} $i2cAddr $ioPort 0x00 + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + echo "done..." +} + +#Set FAN LED +function _i2c_fan_led { + if [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "on" ]; then + i2cset -m 0x08 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0x00 + elif [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "off" ]; then + i2cset -m 0x08 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "on" ]; then + i2cset -m 0x04 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0x00 + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "off" ]; then + i2cset -m 0x04 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + echo "done..." +} + +#Set PSU1 LED +function _i2c_psu1_led { + if [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "on" ]; then + i2cset -m 0x02 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0x00 + elif [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "off" ]; then + i2cset -m 0x02 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "on" ]; then + i2cset -m 0x01 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0x00 + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "off" ]; then + i2cset -m 0x01 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + echo "done..." +} + +#Get Board Version and Type +function _i2c_board_type_get { + boardType=`cat ${PATH_SYS_I2C_DEVICES}/0-0033/cpld_board_type` + boardBuildRev=$((($boardType) & 0x03)) + boardHwRev=$((($boardType) >> 2 & 0x03)) + boardId=$((($boardType) >> 4)) + printf "BOARD_ID is 0x%02x, HW Rev %d, Build Rev %d\n" $boardId $boardHwRev $boardBuildRev + +} + +#Get CPLD Version +function _i2c_cpld_version { + cpldRev=`cat ${PATH_SYS_I2C_DEVICES}/0-0033/cpld_version` + cpldRelease=$((($cpldRev) >> 6 & 0x01)) + cpldVersion=$((($cpldRev) & 0x3F)) + printf "CPLD is %s version(0:RD 1:Release), Revision is 0x%02x\n" $cpldRelease $cpldVersion + +} + +#Get PSU Status +function _i2c_psu_status { + psuPresent=`cat ${PATH_SYS_I2C_DEVICES}/0-0033/cpld_pw_abs` + psu1Exist=$(($((($psuPresent) & 0x01))?0:1)) + psu2Exist=$(($((($psuPresent) & 0x02))?0:1)) + psuPwGood=`cat ${PATH_SYS_I2C_DEVICES}/0-0033/cpld_pw_good` + psu1PwGood=$(($((($psuPwGood) >> 3 & 0x01))?1:0)) + psu2PwGood=$(($((($psuPwGood) >> 3 & 0x02))?1:0)) + printf "PSU1 Exist:%d PSU1 PW Good:%d\n" $psu1Exist $psu1PwGood + printf "PSU2 Exist:%d PSU2 PW Good:%d\n" $psu2Exist $psu2PwGood +} + +#Get Front Sensor Temperature +function _i2c_front_temp { + #Front MAC + sensors | grep 'Front MAC Temp' -A 1 +} + +#Get Rear Sensor Temperature +function _i2c_rear_temp { + #Rear MAC + sensors | grep 'Rear MAC Temp' -A 1 +} + +#Increase read socket buffer for CoPP Test +function _config_rmem { + echo "109430400" > /proc/sys/net/core/rmem_max +} + +#Main Function +function _main { + tart_time_str=`date` + start_time_sec=$(date +%s) + + if [ "${EXEC_FUNC}" == "help" ]; then + _help + elif [ "${EXEC_FUNC}" == "i2c_init" ]; then + _i2c_init + elif [ "${EXEC_FUNC}" == "i2c_deinit" ]; then + _i2c_deinit + elif [ "${EXEC_FUNC}" == "i2c_temp_init" ]; then + _i2c_temp_init + elif [ "${EXEC_FUNC}" == "i2c_fan_init" ]; then + _i2c_fan_init + elif [ "${EXEC_FUNC}" == "i2c_volmon_init" ]; then + _i2c_volmon_init + elif [ "${EXEC_FUNC}" == "i2c_io_exp_init" ]; then + _i2c_io_exp_init + elif [ "${EXEC_FUNC}" == "i2c_gpio_init" ]; then + _i2c_gpio_init + elif [ "${EXEC_FUNC}" == "i2c_gpio_deinit" ]; then + _i2c_gpio_deinit + elif [ "${EXEC_FUNC}" == "i2c_led_test" ]; then + _i2c_led_test + elif [ "${EXEC_FUNC}" == "i2c_mb_eeprom_get" ]; then + _i2c_mb_eeprom_get + elif [ "${EXEC_FUNC}" == "i2c_psu_eeprom_get" ]; then + _i2c_psu_eeprom_get + elif [ "${EXEC_FUNC}" == "i2c_qsfp_eeprom_get" ]; then + _i2c_qsfp_eeprom_get + elif [ "${EXEC_FUNC}" == "i2c_qsfp_status_get" ]; then + _i2c_qsfp_status_get + elif [ "${EXEC_FUNC}" == "i2c_qsfp_type_get" ]; then + _i2c_qsfp_type_get + elif [ "${EXEC_FUNC}" == "i2c_led_psu_status_set" ]; then + _i2c_led_psu_status_set + elif [ "${EXEC_FUNC}" == "i2c_led_fan_status_set" ]; then + _i2c_led_fan_status_set + elif [ "${EXEC_FUNC}" == "i2c_led_fan_tray_status_set" ]; then + _i2c_led_fan_tray_status_set + elif [ "${EXEC_FUNC}" == "i2c_sys_led" ]; then + _i2c_sys_led + elif [ "${EXEC_FUNC}" == "i2c_fan_led" ]; then + _i2c_fan_led + elif [ "${EXEC_FUNC}" == "i2c_fan_tray_led" ]; then + _i2c_fan_tray_led + elif [ "${EXEC_FUNC}" == "i2c_psu1_led" ]; then + _i2c_psu1_led + elif [ "${EXEC_FUNC}" == "i2c_psu2_led" ]; then + _i2c_psu2_led + elif [ "${EXEC_FUNC}" == "i2c_board_type_get" ]; then + _i2c_board_type_get + elif [ "${EXEC_FUNC}" == "i2c_cpld_version" ]; then + _i2c_cpld_version + elif [ "${EXEC_FUNC}" == "i2c_psu_status" ]; then + _i2c_psu_status + elif [ "${EXEC_FUNC}" == "i2c_front_temp" ]; then + _i2c_front_temp + elif [ "${EXEC_FUNC}" == "i2c_rear_temp" ]; then + _i2c_rear_temp + elif [ "${EXEC_FUNC}" == "i2c_test_all" ]; then + _i2c_init + _i2c_temp_init + _i2c_fan_init + _i2c_io_exp_init + _i2c_led_test + _i2c_psu_eeprom_get + _i2c_mb_eeprom_get + _i2c_board_type_get + _i2c_cpld_version + _i2c_psu_status + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + end_time_str=`date` + end_time_sec=$(date +%s) + diff_time=$[ ${end_time_sec} - ${start_time_sec} ] + echo "Start Time: ${start_time_str} (${start_time_sec})" + echo "End Time : ${end_time_str} (${end_time_sec})" + echo "Total Execution Time: ${diff_time} sec" + + echo "done!!!" +} + +_main diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_monitor.sh new file mode 100644 index 000000000000..7f50d137bcb7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_monitor.sh @@ -0,0 +1,106 @@ +#!/bin/bash +# Copyright (C) 2017 Ingrasys, 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 3 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, see . + +INTERVAL=3 +I2C_UTILS="/usr/sbin/i2c_utils.sh" +QSFP_SI_SCRIPT="/usr/sbin/qsfp_si_cfg.sh" +QSFP_ARRAY=(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \ + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + +#QSFP SI monitor +function _qsfp_si_monitor { + local i + local status + for i in {0..53}; + do + status=`${I2C_UTILS} i2c_qsfp_status_get $(expr $i + 1) | egrep '^status=.*$' | sed -e 's/status=//g'` + if [ "${status}" == "1" ]; then + _qsfp_type_check $i + fi + done +} + +#QSFP type +function _qsfp_type_check { + local port=$1 + local qsfp_type=`${I2C_UTILS} i2c_qsfp_type_get $(expr $port + 1)` + local identifier=`echo "$qsfp_type" | grep '^identifier=.*$' | sed -e 's/identifier=//g'` + # identifier 11 for qsfp, 3 for sfp + if [ "${identifier}" == "11" ] || [ "${identifier}" == "3" ]; then + connector=`echo "$qsfp_type" | grep '^connector=.*$' | sed -e 's/connector=//g'` + case ${connector} in + 21|23) + #DAC + if [ "${QSFP_ARRAY[$port]}" != "${connector}" ]; then + echo "Change Port $(expr $port + 1) to DAC" + QSFP_ARRAY[$port]=${connector} + ${QSFP_SI_SCRIPT} dac $port >/dev/null + fi + ;; + *) + #AOC + if [ "${QSFP_ARRAY[$port]}" != "${connector}" ]; then + echo "Change Port $(expr $port + 1) to AOC" + QSFP_ARRAY[$port]=${connector} + ${QSFP_SI_SCRIPT} aoc $port >/dev/null + fi + ;; + esac + fi +} + +#Docker exist check +function _docker_swss_check { + while true + do + # Check if syncd starts + result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + if [ "$result" == "3" ]; then + return + fi + sleep $INTERVAL + done +} + +#Docker exist check +function _qsfp_si_cfg_script_check { + + if [ -f ${QSFP_SI_SCRIPT} ] && [ -x ${QSFP_SI_SCRIPT} ]; then + echo "SI Script exists. Start monitor." + return + else + echo "SI Script not exist. Exit monitor." + exit + fi +} + +# main function +function _main { + #Check SI Script + _qsfp_si_cfg_script_check + #Check docker swss is running + _docker_swss_check + while true + do + _qsfp_si_monitor + # Sleep while still handling signals + sleep $INTERVAL & + wait $! + done +} + +_main + diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_si_cfg.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_si_cfg.sh new file mode 100644 index 000000000000..6ded3e522bce --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_si_cfg.sh @@ -0,0 +1,331 @@ +#!/bin/bash +# Copyright (C) 2017 Ingrasys, 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 3 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, see . + +VERSION="1.0.0" +TRUE=200 +FALSE=404 + +TYPE=${1} +PORT=${2} + +# port number +MIN_PORT=0 +MAX_PORT=53 + +# INDEX of value field in array +SI_PRE_IDX=1 +SI_POST_IDX=2 +SI_MAIN_IDX=3 +SI_AMP_IDX=4 +SI_DRI_IDX=5 + +# type string +AOC_TYPE="aoc" +DAC_TYPE="dac" + +# si value for bcm command +SI_VAL="" + +# "PRE POST MAIN AMP DRIVERMODE" for each port in array +# TODO: need to change aoc si value when available +xe_aoc_si_value=( + "0x00 0x3e 0x32 0xf 0x0" #port 0 + "0x00 0x3a 0x36 0xf 0x0" #port 1 + "0x00 0x3a 0x36 0xf 0x0" #port 2 + "0x00 0x38 0x38 0xf 0x0" #port 3 + "0x00 0x37 0x39 0xf 0x0" #port 4 + "0x00 0x2e 0x42 0xf 0x0" #port 5 + "0x00 0x33 0x3d 0xf 0x0" #port 6 + "0x00 0x30 0x40 0xc 0x0" #port 7 + "0x00 0x2f 0x43 0xe 0x0" #port 8 + "0x00 0x2d 0x43 0xc 0x0" #port 9 + "0x00 0x2c 0x44 0xc 0x0" #port 10 + "0x00 0x2d 0x43 0xc 0x0" #port 11 + "0x00 0x29 0x47 0xc 0x0" #port 12 + "0x00 0x28 0x48 0xc 0x0" #port 13 + "0x00 0x29 0x47 0xa 0x0" #port 14 + "0x00 0x29 0x47 0xf 0x0" #port 15 + "0x00 0x18 0x58 0x9 0x0" #port 16 + "0x00 0x1d 0x53 0x9 0x0" #port 17 + "0x00 0x1c 0x54 0x9 0x0" #port 18 + "0x00 0x1c 0x54 0x9 0x0" #port 19 + "0x00 0x1c 0x54 0x9 0x0" #port 20 + "0x00 0x1c 0x54 0x9 0x0" #port 21 + "0x00 0x1c 0x54 0x9 0x0" #port 22 + "0x00 0x1c 0x54 0x9 0x0" #port 23 + "0x00 0x1c 0x54 0x8 0x0" #port 24 + "0x00 0x1c 0x54 0x8 0x0" #port 25 + "0x00 0x18 0x58 0x8 0x0" #port 26 + "0x00 0x18 0x58 0x8 0x0" #port 27 + "0x00 0x14 0x5c 0x8 0x0" #port 28 + "0x00 0x19 0x57 0x8 0x0" #port 29 + "0x00 0x19 0x57 0x8 0x0" #port 30 + "0x00 0x19 0x57 0x8 0x0" #port 31 + "0x00 0x19 0x57 0xc 0x0" #port 32 + "0x00 0x20 0x50 0x9 0x0" #port 33 + "0x00 0x21 0x4f 0xc 0x0" #port 34 + "0x00 0x24 0x4c 0xc 0x0" #port 35 + "0x00 0x24 0x4c 0xc 0x0" #port 36 + "0x00 0x24 0x4c 0xc 0x0" #port 37 + "0x00 0x24 0x4c 0xc 0x0" #port 38 + "0x00 0x24 0x4c 0xc 0x0" #port 39 + "0x00 0x28 0x48 0xd 0x0" #port 40 + "0x00 0x28 0x48 0xc 0x0" #port 41 + "0x00 0x29 0x47 0xe 0x0" #port 42 + "0x00 0x29 0x47 0xe 0x0" #port 43 + "0x00 0x29 0x47 0xe 0x0" #port 44 + "0x00 0x28 0x48 0xf 0x0" #port 45 + "0x00 0x28 0x48 0xf 0x0" #port 46 + "0x00 0x30 0x40 0xf 0x0" #port 47 +) + +# TODO: need to change aoc si value when available +ce_aoc_si_value=( + "0x00 0x28 0x48 0xc 0x0" #port 0 lane 0 + "0x00 0x29 0x41 0xc 0x0" #port 0 lane 1 + "0x00 0x29 0x41 0xf 0x0" #port 0 lane 2 + "0x00 0x29 0x41 0xc 0x0" #port 0 lane 3 + "0x00 0x28 0x42 0xc 0x0" #port 1 lane 0 + "0x00 0x3a 0x36 0xf 0x0" #port 1 lane 1 + "0x00 0x2c 0x44 0xc 0x0" #port 1 lane 2 + "0x00 0x2c 0x44 0xc 0x0" #port 1 lane 3 + "0x00 0x2f 0x41 0xc 0x0" #port 2 lane 0 + "0x00 0x38 0x38 0xc 0x0" #port 2 lane 1 + "0x00 0x2f 0x41 0xc 0x0" #port 2 lane 2 + "0x00 0x30 0x40 0xc 0x0" #port 2 lane 3 + "0x00 0x30 0x40 0xc 0x0" #port 3 lane 0 + "0x00 0x3f 0x31 0xf 0x0" #port 3 lane 1 + "0x00 0x31 0x3f 0xc 0x0" #port 3 lane 2 + "0x00 0x30 0x40 0xa 0x0" #port 3 lane 3 + "0x00 0x30 0x40 0xc 0x0" #port 4 lane 0 + "0x00 0x31 0x3f 0xf 0x0" #port 4 lane 1 + "0x00 0x2f 0x41 0xc 0x0" #port 4 lane 2 + "0x00 0x2e 0x42 0xc 0x0" #port 4 lane 3 + "0x00 0x30 0x40 0xe 0x0" #port 5 lane 0 + "0x00 0x3f 0x31 0xf 0x0" #port 5 lane 1 + "0x00 0x38 0x38 0xf 0x0" #port 5 lane 2 + "0x00 0x3f 0x31 0xf 0x0" #port 5 lane 3 +) + +xe_dac_si_value=( + "0x00 0x3e 0x32 0xf 0x0" #port 0 + "0x00 0x3a 0x36 0xf 0x0" #port 1 + "0x00 0x3a 0x36 0xf 0x0" #port 2 + "0x00 0x38 0x38 0xf 0x0" #port 3 + "0x00 0x37 0x39 0xf 0x0" #port 4 + "0x00 0x2e 0x42 0xf 0x0" #port 5 + "0x00 0x33 0x3d 0xf 0x0" #port 6 + "0x00 0x30 0x40 0xc 0x0" #port 7 + "0x00 0x2f 0x43 0xe 0x0" #port 8 + "0x00 0x2d 0x43 0xc 0x0" #port 9 + "0x00 0x2c 0x44 0xc 0x0" #port 10 + "0x00 0x2d 0x43 0xc 0x0" #port 11 + "0x00 0x29 0x47 0xc 0x0" #port 12 + "0x00 0x28 0x48 0xc 0x0" #port 13 + "0x00 0x29 0x47 0xa 0x0" #port 14 + "0x00 0x29 0x47 0xf 0x0" #port 15 + "0x00 0x18 0x58 0x9 0x0" #port 16 + "0x00 0x1d 0x53 0x9 0x0" #port 17 + "0x00 0x1c 0x54 0x9 0x0" #port 18 + "0x00 0x1c 0x54 0x9 0x0" #port 19 + "0x00 0x1c 0x54 0x9 0x0" #port 20 + "0x00 0x1c 0x54 0x9 0x0" #port 21 + "0x00 0x1c 0x54 0x9 0x0" #port 22 + "0x00 0x1c 0x54 0x9 0x0" #port 23 + "0x00 0x1c 0x54 0x8 0x0" #port 24 + "0x00 0x1c 0x54 0x8 0x0" #port 25 + "0x00 0x18 0x58 0x8 0x0" #port 26 + "0x00 0x18 0x58 0x8 0x0" #port 27 + "0x00 0x14 0x5c 0x8 0x0" #port 28 + "0x00 0x19 0x57 0x8 0x0" #port 29 + "0x00 0x19 0x57 0x8 0x0" #port 30 + "0x00 0x19 0x57 0x8 0x0" #port 31 + "0x00 0x19 0x57 0xc 0x0" #port 32 + "0x00 0x20 0x50 0x9 0x0" #port 33 + "0x00 0x21 0x4f 0xc 0x0" #port 34 + "0x00 0x24 0x4c 0xc 0x0" #port 35 + "0x00 0x24 0x4c 0xc 0x0" #port 36 + "0x00 0x24 0x4c 0xc 0x0" #port 37 + "0x00 0x24 0x4c 0xc 0x0" #port 38 + "0x00 0x24 0x4c 0xc 0x0" #port 39 + "0x00 0x28 0x48 0xd 0x0" #port 40 + "0x00 0x28 0x48 0xc 0x0" #port 41 + "0x00 0x29 0x47 0xe 0x0" #port 42 + "0x00 0x29 0x47 0xe 0x0" #port 43 + "0x00 0x29 0x47 0xe 0x0" #port 44 + "0x00 0x28 0x48 0xf 0x0" #port 45 + "0x00 0x28 0x48 0xf 0x0" #port 46 + "0x00 0x30 0x40 0xf 0x0" #port 47 +) + +ce_dac_si_value=( + "0x00 0x28 0x48 0xc 0x0" #port 0 lane 0 + "0x00 0x29 0x41 0xc 0x0" #port 0 lane 1 + "0x00 0x29 0x41 0xf 0x0" #port 0 lane 2 + "0x00 0x29 0x41 0xc 0x0" #port 0 lane 3 + "0x00 0x28 0x42 0xc 0x0" #port 1 lane 0 + "0x00 0x3a 0x36 0xf 0x0" #port 1 lane 1 + "0x00 0x2c 0x44 0xc 0x0" #port 1 lane 2 + "0x00 0x2c 0x44 0xc 0x0" #port 1 lane 3 + "0x00 0x2f 0x41 0xc 0x0" #port 2 lane 0 + "0x00 0x38 0x38 0xc 0x0" #port 2 lane 1 + "0x00 0x2f 0x41 0xc 0x0" #port 2 lane 2 + "0x00 0x30 0x40 0xc 0x0" #port 2 lane 3 + "0x00 0x30 0x40 0xc 0x0" #port 3 lane 0 + "0x00 0x3f 0x31 0xf 0x0" #port 3 lane 1 + "0x00 0x31 0x3f 0xc 0x0" #port 3 lane 2 + "0x00 0x30 0x40 0xa 0x0" #port 3 lane 3 + "0x00 0x30 0x40 0xc 0x0" #port 4 lane 0 + "0x00 0x31 0x3f 0xf 0x0" #port 4 lane 1 + "0x00 0x2f 0x41 0xc 0x0" #port 4 lane 2 + "0x00 0x2e 0x42 0xc 0x0" #port 4 lane 3 + "0x00 0x30 0x40 0xe 0x0" #port 5 lane 0 + "0x00 0x3f 0x31 0xf 0x0" #port 5 lane 1 + "0x00 0x38 0x38 0xf 0x0" #port 5 lane 2 + "0x00 0x3f 0x31 0xf 0x0" #port 5 lane 3 +) + +#get field value in si value array for xe port +function get_xe_si { + local port=$1 + local field=$2 + local type=$3 + local index=$port + if [ "$type" == "${AOC_TYPE}" ]; then + SI_VAL=$(echo "${xe_aoc_si_value[$index]}" | awk '{print $'$field'}') + else + SI_VAL=$(echo "${xe_dac_si_value[$index]}" | awk '{print $'$field'}') + fi +} + +#get field value in si value array for ce port +function get_ce_si { + local port=$1 + local lane=$2 + local field=$3 + local type=$4 + index=$(( (${port}-1)*4+${lane} )) + if [ "$type" == "${AOC_TYPE}" ]; then + SI_VAL=$(echo "${ce_aoc_si_value[$index]}" | awk '{print $'$field'}') + else + SI_VAL=$(echo "${ce_dac_si_value[$index]}" | awk '{print $'$field'}') + fi +} + +# set si value for xe port +function _qsfp_xe_si_set { + # convert PORT to xe port index + local xe_port=$PORT + # generate command for SI PRE value + get_xe_si $xe_port $SI_PRE_IDX $TYPE + local pre_cmd="phy xe${xe_port} CL93N72_UT_CTL2r CL93N72_TXFIR_PRE=${SI_VAL}" + # generate command for SI POST value + get_xe_si $xe_port $SI_POST_IDX $TYPE + local post_cmd="phy xe${xe_port} CL93N72_UT_CTL2r CL93N72_TXFIR_POST=${SI_VAL}" + # generate command for SI MAIN value + get_xe_si $xe_port $SI_MAIN_IDX $TYPE + local main_cmd="phy xe${xe_port} CL93N72_UT_CTL3r CL93N72_TXFIR_MAIN=${SI_VAL}" + # generate command for SI AMP CONTROL value + get_xe_si $xe_port $SI_AMP_IDX $TYPE + local amp_val=$SI_VAL + get_xe_si $xe_port $SI_DRI_IDX $TYPE + local dri_val=$SI_VAL + local amp_cmd="phy xe${xe_port} AMS_TX_CTL2r AMS_TX_AMP_CTL=${amp_val} AMS_TX_DRIVERMODE=${dri_val}" + # apply bcmcmd + bcmcmd "${pre_cmd};${post_cmd};${main_cmd};${amp_cmd}" +} + +# set aoc si value for ce port +function _qsfp_ce_si_set { + # convert PORT to ce port index + local ce_port=$(( $PORT - 48 )) + for lane in {0..3}; + do + # generate command for SI PRE value + get_ce_si $ce_port $lane $SI_PRE_IDX $TYPE + local pre_cmd="phy ce${ce_port} CL93N72_UT_CTL2r.${lane} CL93N72_TXFIR_PRE=${SI_VAL}" + # generate command for SI POST value + get_ce_si $ce_port $lane $SI_POST_IDX $TYPE + local post_cmd="phy ce${ce_port} CL93N72_UT_CTL2r.${lane} CL93N72_TXFIR_POST=${SI_VAL}" + # generate command for SI MAIN value + get_ce_si $ce_port $lane $SI_MAIN_IDX $TYPE + local main_cmd="phy ce${ce_port} CL93N72_UT_CTL3r.${lane} CL93N72_TXFIR_MAIN=${SI_VAL}" + # generate command for SI AMP CONTROL value + get_ce_si $ce_port $lane $SI_AMP_IDX $TYPE + local amp_val=$SI_VAL + get_ce_si $ce_port $lane $SI_AMP_IDX $TYPE + local dri_val=$SI_VAL + local amp_cmd="phy ce${ce_port} AMS_TX_CTL2r.${lane} AMS_TX_AMP_CTL=${amp_val} AMS_TX_DRIVERMODE=${dri_val}" + # apply bcmcmd + bcmcmd "${pre_cmd};${post_cmd};${main_cmd};${amp_cmd}" + done +} + +#QSFP SI value set +function _qsfp_si_set { + if [[ $PORT -le 47 && $PORT -ge 0 ]]; then + # xe port + _qsfp_xe_si_set + else + # ce port + _qsfp_ce_si_set + fi +} + +function _util_input_check { + # input parameter validation + if [[ $1 -lt $2 || $1 -gt $3 ]]; then + echo "Please input number $2~$3" + exit + fi +} + +# Help usage function +function _help { + echo "=========================================================" + echo "# Description: Help Function" + echo "=========================================================" + echo "----------------------------------------------------" + echo "EX : ${0} help" + echo " : ${0} ${AOC_TYPE} [${MIN_PORT}-${MAX_PORT}]" + echo " : ${0} ${DAC_TYPE} [${MIN_PORT}-${MAX_PORT}]" + echo "----------------------------------------------------" +} + +#Main Function +function _main { + + # TODO: remove after SI value ready + #exit ${TRUE} + + if [ -z $PORT ]; then + _help + exit ${FALSE} + fi + + if [ "${TYPE}" == "help" ]; then + _help + elif [ "${TYPE}" == "${AOC_TYPE}" ] || [ "${TYPE}" == "${DAC_TYPE}" ]; then + _util_input_check "$PORT" "$MIN_PORT" "$MAX_PORT" + _qsfp_si_set + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi +} + +_main diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/s8900_54xc_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/s8900_54xc_monitor.sh new file mode 100755 index 000000000000..974da6d5001f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/s8900_54xc_monitor.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# Copyright (C) 2016 Ingrasys, 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 3 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, see . + +INTERVAL=5 +I2C_UTILS="/usr/sbin/i2c_utils.sh" + + +# LED status monitor +function _led_monitor { + ${I2C_UTILS} i2c_led_fan_status_set >/dev/null + ${I2C_UTILS} i2c_led_psu_status_set >/dev/null + ${I2C_UTILS} i2c_led_fan_tray_status_set >/dev/null +} + +# main function +function _main { + while true + do + _led_monitor + # Sleep while still handling signals + sleep $INTERVAL & + wait $! + done +} + +_main \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/README.md b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/README.md new file mode 100644 index 000000000000..28f395216e3c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/README.md @@ -0,0 +1,185 @@ +# Ingrasys S8900-64XC Platform Driver for SONiC + +Copyright (C) 2016 Ingrasys, 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 3 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, see . + + +## Licensing terms + +The Licensing terms of the files within this project is split 2 parts. +The Linux kernel is released under the GNU General Public License version 2. +All other code is released under the GNU General Public License version 3. +Please see the LICENSE file for copies of both licenses. + +## Contents of this package + + - service/ + > Service config files for platform initialization and monitoring + - utils/ + > Scripts useful during platform bringup and sysfs function + - conf/ + > Platform configure files. + +## Kernel modules and drivers + +The driver for interacting with Ingrasys S8900-64XC is contained in the I2C +kernel module and initialization script. The initialization script loads +the modules in the correct order. It has been built and tested against +the Linux 3.16 kernel. + +The initialization script will modprobe the needed modules, navigate to the +module's device directory in sysfs, and write configuration data to +the kernel module. + +### IGB + +This is OOB Ports on front panel for management plane. + +The IGB module must be loaded first on Ingrasys S8900-64XC platform. + +### I2C i801 + +The I2C i801 on Ingrasys S8900-64XC can be found in +`/sys/bus/i2c/devices/i2c-0/` + +This is I2C bus for Clock Gen, DIMM channel and digital potentiometers. + +The i801 module must be loaded second on Ingrasys S8900-64XC. + +### I2C iSMT + +The I2C iSMT module on S8900-64XC can be found in +`/sys/bus/i2c/devices/i2c-1/` + +This is I2C bus for CPLD, HWM, power controller and I2C Switches. + +The i801 module must be loaded third on Ingrasys S8900-64XC. + +### I2C PCA9548 +The PCA9548 module on S8900-64XC can be found in +`/sys/bus/i2c/devices/i2c-2/` , `/sys/bus/i2c/devices/i2c-3/`, +`/sys/bus/i2c/devices/i2c-4/`, `/sys/bus/i2c/devices/i2c-5/`, +`/sys/bus/i2c/devices/i2c-6/`, `/sys/bus/i2c/devices/i2c-7/`, +`/sys/bus/i2c/devices/i2c-8/`, `/sys/bus/i2c/devices/i2c-9/`. + +The pca9548 module for zQSFP module get/set functions, PSU information, +fan status and EEPROM. + +## Hardware components + +The hardware components are initialized in the init script on S8900-64XC. +The following describes manual initialization as well as interaction. +The examples below are just for Ingrasys S8900-64XC platform. + +### Hardware initialization + +When the sonic-platform-ingrasys-s8900-64xc package is installed on the S8900-64XC, +it is automatically initialized. If you want to manual initialization, the +utility command usage as follows: +``` + i2c_utils.sh i2c_init +``` + +### EEPROM + +The EEPROM is including the board SKU, model name, vendor name, serial number, +and other information can be accessed with the specific eeprom kernel module. +After using `modprobe eeprom_mb` to detect the eeprom, it will show up in sysfs. + +The hexdump utility can be used to decode the raw output of the EEPROM. +For example, +``` + bash# echo "mb_eeprom 0x54" > /sys/bus/i2c/devices/i2c-9/new_device + bash# cat /sys/bus/i2c/drivers/mb_eeprom/9-0054/eeprom | hexdump -C +``` + +### Front panel LEDs + +LEDs can be setup on/off by using i2c utility `/usr/sbin/i2c_utils.sh`. +Utility function command usage as follows: + +``` +Status LED: + i2c_utils.sh i2c_sys_led green|amber on|off + +Fan status LED: + i2c_utils.sh i2c_fan_led green|amber on|off + +PSU1 status LED: + i2c_utils.sh i2c_psu1_led green|amber on|off + +PSU2 status LED: + i2c_utils.sh i2c_psu2_led green|amber on|off + +``` +QSFP Module Port LEDs control by ASIC library. + + +### Fan speed + +Fan speed are controlled by the w83795 kernel module. +It can be found in `/sys/class/hwmon/hwmon1/device/`. +If they were compiled as modules, you will need to modprobe w83795 for +their sysfs entries to show up. Each fan has an `fan_input` file +for reading the fan speed. And `pwm1` setting fan1 to fan4, +`pwm2` setting fan5 to fan8. + +There is docker-platform-monitor container installed fancontrol package that can +automatic control platform fan speed. + + +### Temperature sensors + +Temperature sensors are controlled by the w83795 kernel +module. It can be found in `/sys/class/hwmon/hwmon1/device/`. +If they were compiled as modules, then you will need to modprobe w83795 for +their sysfs entries to show up. +`temp1_input` is front MAC temperature sensor. `temp2_input` is rear MAC +temperature sensor. + +There is docker-platform-monitor container installed lm-sensors package that can +monitor platform temperature. And `sensors` command can show each +temperature sensors status. + +### Power supplies + +Power supplies status and its EEPROM info can be used i2c utility +`/usr/sbin/i2c_utils.sh` to get. +The usage as follows: +``` +PSU EEPROM: + i2c_utils.sh i2c_psu_eeprom_get + hexdump -C psu0.rom + hexdump -C psu1.rom + +PSU Status: + i2c_utils.sh i2c_psu_status +``` + +### QSFPs +QSFP modules are managed by the pca9548 kernel driver. +The i2c utility `/usr/sbin/i2c_utils.sh` can be used to get status and +module EEPROM informations. +The usage as follows: +``` +QSFP EEPROM: + i2c_utils.sh i2c_qsfp_eeprom_get [1-32] + +QSFP Insert Event: + i2c_utils.sh i2c_qsfp_eeprom_get [1-32] + 0 => not insert + 1 => inserted +``` + diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/modules/Makefile b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/modules/Makefile new file mode 100644 index 000000000000..bf7d4baed71b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/modules/Makefile @@ -0,0 +1,4 @@ +#ccflags-y += -DDEBUG +obj-m := eeprom_mb.o +obj-m+= qsfp_cpld.o +obj-m+= i2c_cpld.o diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/modules/eeprom_mb.c b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/modules/eeprom_mb.c new file mode 100644 index 000000000000..0886cad58eb3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/modules/eeprom_mb.c @@ -0,0 +1,212 @@ +/* + * Copyright (C) 1998, 1999 Frodo Looijaard and + * Philip Edelbrock + * Copyright (C) 2003 Greg Kroah-Hartman + * Copyright (C) 2003 IBM Corp. + * Copyright (C) 2004 Jean Delvare + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Addresses to scan */ +static const unsigned short normal_i2c[] = { 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, I2C_CLIENT_END }; + + +/* Size of EEPROM in bytes */ +#define EEPROM_SIZE 256 + +#define SLICE_BITS (6) +#define SLICE_SIZE (1 << SLICE_BITS) +#define SLICE_NUM (EEPROM_SIZE/SLICE_SIZE) + +/* Each client has this additional data */ +struct eeprom_data { + struct mutex update_lock; + u8 valid; /* bitfield, bit!=0 if slice is valid */ + unsigned long last_updated[SLICE_NUM]; /* In jiffies, 8 slices */ + u8 data[EEPROM_SIZE]; /* Register values */ +}; + + +static void mb_eeprom_update_client(struct i2c_client *client, u8 slice) +{ + struct eeprom_data *data = i2c_get_clientdata(client); + int i, j; + int ret; + int addr; + + mutex_lock(&data->update_lock); + + if (!(data->valid & (1 << slice)) || + time_after(jiffies, data->last_updated[slice] + 300 * HZ)) { + dev_dbg(&client->dev, "Starting eeprom update, slice %u\n", slice); + + addr = slice << SLICE_BITS; + + ret = i2c_smbus_write_byte_data(client, ((u8)addr >> 8) & 0xFF, (u8)addr & 0xFF); + /* select the eeprom address */ + if (ret < 0) { + dev_err(&client->dev, "address set failed\n"); + goto exit; + } + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BYTE)) { + goto exit; + } + + for (i = slice << SLICE_BITS; i < (slice + 1) << SLICE_BITS; i+= SLICE_SIZE) { + for (j = i; j < (i+SLICE_SIZE); j++) { + int res; + + res = i2c_smbus_read_byte(client); + if (res < 0) { + goto exit; + } + + data->data[j] = res & 0xFF; + } + } + + data->last_updated[slice] = jiffies; + data->valid |= (1 << slice); + } +exit: + mutex_unlock(&data->update_lock); +} + +static ssize_t mb_eeprom_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj)); + struct eeprom_data *data = i2c_get_clientdata(client); + u8 slice; + + if (off > EEPROM_SIZE) { + return 0; + } + if (off + count > EEPROM_SIZE) { + count = EEPROM_SIZE - off; + } + if (count == 0) { + return 0; + } + + /* Only refresh slices which contain requested bytes */ + for (slice = off >> SLICE_BITS; slice <= (off + count - 1) >> SLICE_BITS; slice++) { + mb_eeprom_update_client(client, slice); + } + + memcpy(buf, &data->data[off], count); + + return count; +} + +static struct bin_attribute mb_eeprom_attr = { + .attr = { + .name = "eeprom", + .mode = S_IRUGO, + }, + .size = EEPROM_SIZE, + .read = mb_eeprom_read, +}; + +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int mb_eeprom_detect(struct i2c_client *client, struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = client->adapter; + + /* EDID EEPROMs are often 24C00 EEPROMs, which answer to all + addresses 0x50-0x57, but we only care about 0x50. So decline + attaching to addresses >= 0x51 on DDC buses */ + if (!(adapter->class & I2C_CLASS_SPD) && client->addr >= 0x51) { + return -ENODEV; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE) + && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { + return -ENODEV; + } + + strlcpy(info->type, "eeprom", I2C_NAME_SIZE); + + return 0; +} + +static int mb_eeprom_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct eeprom_data *data; + int err; + + if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) { + err = -ENOMEM; + goto exit; + } + + memset(data->data, 0xff, EEPROM_SIZE); + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + /* create the sysfs eeprom file */ + err = sysfs_create_bin_file(&client->dev.kobj, &mb_eeprom_attr); + if (err) { + goto exit_kfree; + } + + return 0; + +exit_kfree: + kfree(data); +exit: + return err; +} + +static int mb_eeprom_remove(struct i2c_client *client) +{ + sysfs_remove_bin_file(&client->dev.kobj, &mb_eeprom_attr); + kfree(i2c_get_clientdata(client)); + + return 0; +} + +static const struct i2c_device_id mb_eeprom_id[] = { + { "mb_eeprom", 0 }, + { } +}; + +static struct i2c_driver mb_eeprom_driver = { + .driver = { + .name = "mb_eeprom", + }, + .probe = mb_eeprom_probe, + .remove = mb_eeprom_remove, + .id_table = mb_eeprom_id, + + .class = I2C_CLASS_DDC | I2C_CLASS_SPD, + .detect = mb_eeprom_detect, + .address_list = normal_i2c, +}; + +module_i2c_driver(mb_eeprom_driver); + +MODULE_AUTHOR("Wade "); +MODULE_DESCRIPTION("Ingrasys S8900 Mother Borad EEPROM driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/modules/i2c_cpld.c b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/modules/i2c_cpld.c new file mode 100644 index 000000000000..626c63177b50 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/modules/i2c_cpld.c @@ -0,0 +1,448 @@ +/* + * S9100-32X I2C CPLD driver + * + * Copyright (C) 2017 Ingrasys, Inc. + * Wade He + * + * 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, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "i2c_cpld.h" + +#ifdef DEBUG + #define DEBUG_PRINT(fmt, args...) \ + printk(KERN_INFO "%s[%d]: " fmt "\r\n", \ + __FUNCTION__, __LINE__, ##args) +#else + #define DEBUG_PRINT(fmt, args...) +#endif + +#define I2C_READ_BYTE_DATA(ret, lock, i2c_client, reg) \ +{ \ + mutex_lock(lock); \ + ret = i2c_smbus_read_byte_data(i2c_client, reg); \ + mutex_unlock(lock); \ +} +#define I2C_WRITE_BYTE_DATA(ret, lock, i2c_client, reg, val) \ +{ \ + mutex_lock(lock); \ + ret = i2c_smbus_write_byte_data(i2c_client, reg, val); \ + mutex_unlock(lock); \ +} + +/* CPLD sysfs attributes index */ +enum i2c_cpld_sysfs_attributes { + CPLD_ACCESS_REG, + CPLD_REGISTER_VAL, + CPLD_PORT_START, + CPLD_PORTS, + CPLD_VERSION, + CPLD_ID, + CPLD_BOARD_TYPE, + CPLD_EXT_BOARD_TYPE, + CPLD_PW_GOOD, + CPLD_PW_ABS, +}; + +/* CPLD sysfs attributes hook functions */ +static ssize_t read_access_register(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t write_access_register(struct device *dev, + struct device_attribute *da, const char *buf, size_t count); +static ssize_t read_register_value(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t write_register_value(struct device *dev, + struct device_attribute *da, const char *buf, size_t count); +static ssize_t read_cpld_version(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_board_type(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_ext_board_type(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_pw_good(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_pw_abs(struct device *dev, + struct device_attribute *da, char *buf); + +static LIST_HEAD(cpld_client_list); /* client list for cpld */ +static struct mutex list_lock; /* mutex for client list */ + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; + +struct cpld_data { + int index; /* CPLD index */ + struct mutex access_lock; /* mutex for cpld access */ + u8 access_reg; /* register to access */ +}; + +/* CPLD device id and data */ +static const struct i2c_device_id i2c_cpld_id[] = { + { "i2c_cpld", i2c_cpld }, + {} +}; + +/* Addresses scanned for i2c_cpld */ +static const unsigned short cpld_i2c_addr[] = { 0x33, I2C_CLIENT_END }; +/* platform sysfs object */ +extern struct kobject *s9230_64x_kobj; + + +/* define all support register access of cpld in attribute */ +static SENSOR_DEVICE_ATTR(cpld_access_register, S_IWUSR | S_IRUGO, + read_access_register, write_access_register, CPLD_ACCESS_REG); +static SENSOR_DEVICE_ATTR(cpld_register_value, S_IWUSR | S_IRUGO, + read_register_value, write_register_value, CPLD_REGISTER_VAL); +static SENSOR_DEVICE_ATTR(cpld_version, S_IRUGO, + read_cpld_version, NULL, CPLD_VERSION); +static SENSOR_DEVICE_ATTR(cpld_board_type, S_IRUGO, + read_board_type, NULL, CPLD_BOARD_TYPE); +static SENSOR_DEVICE_ATTR(cpld_ext_board_type, S_IRUGO, + read_ext_board_type, NULL, CPLD_EXT_BOARD_TYPE); +static SENSOR_DEVICE_ATTR(cpld_pw_good, S_IRUGO, + read_pw_good, NULL, CPLD_PW_GOOD); +static SENSOR_DEVICE_ATTR(cpld_pw_abs, S_IRUGO, + read_pw_abs, NULL, CPLD_PW_ABS); + + +/* define support attributes of cpldx , total 5 */ +/* cpld 1 */ +static struct attribute *i2c_cpld_attributes[] = { + &sensor_dev_attr_cpld_access_register.dev_attr.attr, + &sensor_dev_attr_cpld_register_value.dev_attr.attr, + &sensor_dev_attr_cpld_version.dev_attr.attr, + &sensor_dev_attr_cpld_board_type.dev_attr.attr, + &sensor_dev_attr_cpld_ext_board_type.dev_attr.attr, + &sensor_dev_attr_cpld_pw_good.dev_attr.attr, + &sensor_dev_attr_cpld_pw_abs.dev_attr.attr, + NULL +}; + +/* cpld 1 attributes group */ +static const struct attribute_group i2c_cpld_group = { + .attrs = i2c_cpld_attributes, +}; + +/* read access register from cpld data */ +static ssize_t read_access_register(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg = data->access_reg; + + return sprintf(buf, "0x%x\n", reg); +} + +/* write access register to cpld data */ +static ssize_t write_access_register(struct device *dev, + struct device_attribute *da, + const char *buf, + size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + + if (kstrtou8(buf, 0, ®) < 0) + return -EINVAL; + + data->access_reg = reg; + return count; +} + +/* read the value of access register in cpld data */ +static ssize_t read_register_value(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg = data->access_reg; + int reg_val; + + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + + if (reg_val < 0) + return -1; + + return sprintf(buf, "0x%x\n", reg_val); +} + +/* wrtie the value to access register in cpld data */ +static ssize_t write_register_value(struct device *dev, + struct device_attribute *da, + const char *buf, + size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + int ret = -EIO; + u8 reg = data->access_reg; + u8 reg_val; + + if (kstrtou8(buf, 0, ®_val) < 0) + return -EINVAL; + + I2C_WRITE_BYTE_DATA(ret, &data->access_lock, client, reg, reg_val); + + return count; +} + +/* get cpdl version register value */ +static ssize_t read_cpld_version(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_VERSION) { + reg = CPLD_VERSION_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* get board type register value */ +static ssize_t read_board_type(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_BOARD_TYPE) { + reg = CPLD_BOARD_TYPE_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* get extend board type register value */ +static ssize_t read_ext_board_type(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_EXT_BOARD_TYPE) { + reg = CPLD_EXT_BOARD_TYPE_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* get extend board type register value */ +static ssize_t read_pw_good(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_PW_GOOD) { + reg = CPLD_PW_GOOD_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* get extend board type register value */ +static ssize_t read_pw_abs(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_PW_ABS) { + reg = CPLD_PW_ABS_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* add valid cpld client to list */ +static void i2c_cpld_add_client(struct i2c_client *client) +{ + struct cpld_client_node *node = NULL; + + node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); + if (!node) { + dev_info(&client->dev, + "Can't allocate cpld_client_node for index %d\n", + client->addr); + return; + } + + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &cpld_client_list); + mutex_unlock(&list_lock); +} + +/* remove exist cpld client in list */ +static void i2c_cpld_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + list_for_each(list_node, &cpld_client_list) { + cpld_node = list_entry(list_node, + struct cpld_client_node, list); + + if (cpld_node->client == client) { + found = 1; + break; + } + } + + if (found) { + list_del(list_node); + kfree(cpld_node); + } + mutex_unlock(&list_lock); +} + +/* cpld drvier probe */ +static int i2c_cpld_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int status; + struct cpld_data *data = NULL; + + data = kzalloc(sizeof(struct cpld_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + /* init cpld data for client */ + i2c_set_clientdata(client, data); + mutex_init(&data->access_lock); + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_info(&client->dev, + "i2c_check_functionality failed (0x%x)\n", + client->addr); + status = -EIO; + goto exit; + } + + + status = sysfs_create_group(&client->dev.kobj,&i2c_cpld_group); + + if (status) + goto exit; + + dev_info(&client->dev, "chip found\n"); + + /* add probe chip to client list */ + i2c_cpld_add_client(client); + + return 0; +exit: + sysfs_remove_group(&client->dev.kobj, &i2c_cpld_group); + return status; +} + +/* cpld drvier remove */ +static int i2c_cpld_remove(struct i2c_client *client) +{ + + sysfs_remove_group(&client->dev.kobj, &i2c_cpld_group); + + i2c_cpld_remove_client(client); + return 0; +} + +MODULE_DEVICE_TABLE(i2c, i2c_cpld_id); + +static struct i2c_driver i2c_cpld_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "i2c_cpld", + }, + .probe = i2c_cpld_probe, + .remove = i2c_cpld_remove, + .id_table = i2c_cpld_id, + .address_list = cpld_i2c_addr, +}; + +static int __init i2c_cpld_init(void) +{ + mutex_init(&list_lock); + return i2c_add_driver(&i2c_cpld_driver); +} + +static void __exit i2c_cpld_exit(void) +{ + i2c_del_driver(&i2c_cpld_driver); +} + +MODULE_AUTHOR("Wade He "); +MODULE_DESCRIPTION("Ingrasys S9100-32X Platform i2c cpld driver"); +MODULE_LICENSE("GPL"); + +module_init(i2c_cpld_init); +module_exit(i2c_cpld_exit); + + + diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/modules/i2c_cpld.h b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/modules/i2c_cpld.h new file mode 100644 index 000000000000..e103b05c717a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/modules/i2c_cpld.h @@ -0,0 +1,197 @@ +/* + * + * S9100-32X I2C CPLD driver header file + * + * Copyright (C) 2017 Ingrasys, Inc. + * Wade He + * + * 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, see . + */ + +#ifndef I2C_CPLD_H +#define I2C_CPLD_H + +// remove debug before release +#define DEBUG + +/* CPLD device index value */ +enum cpld_id { + i2c_cpld +}; + +/* port number on CPLD */ +#define CPLD_1_PORT_NUM 12 +#define CPLD_2_PORT_NUM 13 + +/* QSFP port number */ +#define QSFP_MAX_PORT_NUM 64 +#define QSFP_MIN_PORT_NUM 1 + +/* SFP+ port number */ +#define SFP_MAX_PORT_NUM 2 +#define SFP_MIN_PORT_NUM 1 + + +/* CPLD registers */ +#define CPLD_BOARD_TYPE_REG 0x0 +#define CPLD_EXT_BOARD_TYPE_REG 0x7 +#define CPLD_VERSION_REG 0x1 +#define CPLD_PW_GOOD_REG 0x2 +#define CPLD_PW_ABS_REG 0x3 + + +/* bit definition for register value */ + +enum CPLD_RESET_CONTROL_BITS { + CPLD_RESET_CONTROL_SWRST_BIT, + CPLD_RESET_CONTROL_CP2104RST_BIT, + CPLD_RESET_CONTROL_82P33814RST_BIT, + CPLD_RESET_CONTROL_BMCRST_BIT, +}; + +/* bit field structure for register value */ +struct cpld_reg_board_type_t { + u8 build_rev:2; + u8 hw_rev:2; + u8 board_id:4; +}; + +struct cpld_reg_version_t { + u8 revision:6; + u8 release:1; + u8 reserve:1; +}; + +struct cpld_reg_pw_good_t { + u8 reserve1:3; + u8 psu1:1; + u8 psu2:1; + u8 reserve2:3; +}; + +struct cpld_reg_pw_abs_t { + u8 psu1:1; + u8 psu2:1; + u8 reserve:6; +}; + +/* common manipulation */ +#define INVALID(i, min, max) ((i < min) || (i > max) ? 1u : 0u) +#define READ_BIT(val, bit) ((0u == (val & (1<bf_name) +#define READ_BF_1(bf_struct, val, bf_name, bf_value) \ + bf_struct bf; \ + bf.data = val; \ + bf_value = bf.bf_name +#define BOARD_TYPE_BUILD_REV_GET(val, res) \ + READ_BF(cpld_reg_board_type_t, val, build_rev, res) +#define BOARD_TYPE_HW_REV_GET(val, res) \ + READ_BF(cpld_reg_board_type_t, val, hw_rev, res) +#define BOARD_TYPE_BOARD_ID_GET(val, res) \ + READ_BF(cpld_reg_board_type_t, val, board_id, res) +#define CPLD_VERSION_REV_GET(val, res) \ + READ_BF(cpld_reg_version_t, val, revision, res) +#define CPLD_VERSION_REL_GET(val, res) \ + READ_BF(cpld_reg_version_t, val, release, res) +#define CPLD_PSU1_PW_GOOD_GET(val, res) \ + READ_BF(cpld_reg_pw_good_t, val, psu1, res) +#define CPLD_PSU2_PW_GOOD_GET(val, res) \ + READ_BF(cpld_reg_pw_good_t, val, psu2, res) +#define CPLD_PSU1_PW_ABS_GET(val, res) \ + READ_BF(cpld_reg_pw_abs_t, val, psu1, res) +#define CPLD_PSU2_PW_ABS_GET(val, res) \ + READ_BF(cpld_reg_pw_abs_t, val, psu2, res) +/* QSFP/SFP registers manipulation */ +#define QSFP_TO_CPLD_IDX(qsfp_port, cpld_index, cpld_port) \ +{ \ + if (QSFP_MIN_PORT_NUM <= qsfp_port && qsfp_port <= CPLD_1_PORT_NUM) { \ + cpld_index = cpld1; \ + cpld_port = qsfp_port - 1; \ + } else if (CPLD_1_PORT_NUM < qsfp_port \ + && qsfp_port <= QSFP_MAX_PORT_NUM) { \ + cpld_index = cpld2 + (qsfp_port - 1 - CPLD_1_PORT_NUM) \ + / CPLD_2_PORT_NUM; \ + cpld_port = (qsfp_port - 1 - CPLD_1_PORT_NUM) % \ + CPLD_2_PORT_NUM; \ + } else { \ + cpld_index = 0; \ + cpld_port = 0; \ + } \ +} +#define SFP_TO_CPLD_IDX(sfp_port, cpld_index) \ + (cpld_index = sfp_port - SFP_MIN_PORT_NUM) +#define QSFP_PORT_STATUS_REG(cpld_port) \ + (CPLD_QSFP_PORT_STATUS_BASE_REG + cpld_port) +#define QSFP_PORT_CONFIG_REG(cpld_port) \ + (CPLD_QSFP_PORT_CONFIG_BASE_REG + cpld_port) +#define QSFP_PORT_INT_BIT_GET(port_status_value) \ + READ_BIT(port_status_value, CPLD_QSFP_PORT_STATUS_INT_BIT) +#define QSFP_PORT_ABS_BIT_GET(port_status_value) \ + READ_BIT(port_status_value, CPLD_QSFP_PORT_STATUS_ABS_BIT) +#define QSFP_PORT_RESET_BIT_GET(port_config_value) \ + READ_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_RESET_BIT) +#define QSFP_PORT_LPMODE_BIT_GET(port_config_value) \ + READ_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_LPMODE_BIT) +#define QSFP_PORT_RESET_BIT_SET(port_config_value) \ + SET_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_RESET_BIT) +#define QSFP_PORT_RESET_BIT_CLEAR(port_config_value) \ + CLEAR_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_RESET_BIT) +#define QSFP_PORT_LPMODE_BIT_SET(port_config_value) \ + SET_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_LPMODE_BIT) +#define QSFP_PORT_LPMODE_BIT_CLEAR(port_config_value) \ + CLEAR_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_LPMODE_BIT) +#define SFP_PORT_PRESENT_BIT_GET(port_status_value) \ + READ_BIT(port_status_value, CPLD_SFP_PORT_STATUS_PRESENT_BIT) + + #define SFP_PORT_TXFAULT_BIT_GET(port_status_value) \ + READ_BIT(port_status_value, CPLD_SFP_PORT_STATUS_TXFAULT_BIT) + #define SFP_PORT_RXLOS_BIT_GET(port_status_value) \ + READ_BIT(port_status_value, CPLD_SFP_PORT_STATUS_RXLOS_BIT) + #define SFP_PORT_TXDIS_BIT_GET(port_status_value) \ + READ_BIT(port_status_value, CPLD_SFP_PORT_CONFIG_TXDIS_BIT) +#define SFP_PORT_RS_BIT_GET(port_config_value) \ + READ_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_RS_BIT) +#define SFP_PORT_TS_BIT_GET(port_config_value) \ + READ_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_TS_BIT) +#define SFP_PORT_TXDIS_BIT_SET(port_config_value) \ + SET_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_TXDIS_BIT) +#define SFP_PORT_TXDIS_BIT_CLEAR(port_config_value) \ + CLEAR_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_TXDIS_BIT) +#define SFP_PORT_RS_BIT_SET(port_config_value) \ + SET_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_RS_BIT) +#define SFP_PORT_RS_BIT_CLEAR(port_config_value) \ + CLEAR_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_RS_BIT) +#define SFP_PORT_TS_BIT_SET(port_config_value) \ + SET_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_TS_BIT) +#define SFP_PORT_TS_BIT_CLEAR(port_config_value) \ + CLEAR_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_TS_BIT) + +/* CPLD access functions */ +extern int i2c_cpld_get_qsfp_port_status_val(u8 port_num); +extern int i2c_cpld_get_qsfp_port_config_val(u8 port_num); +extern int i2c_cpld_set_qsfp_port_config_val(u8 port_num, u8 reg_val); +extern int i2c_cpld_get_sfp_port_status_val(u8 port_num); +extern int i2c_cpld_get_sfp_port_config_val(u8 port_num); +extern int i2c_cpld_set_sfp_port_config_val(u8 port_num, u8 reg_val); +extern u8 fp_port_to_phy_port(u8 fp_port); +#endif + diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/modules/qsfp_cpld.c b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/modules/qsfp_cpld.c new file mode 100644 index 000000000000..8ec03ecea340 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/modules/qsfp_cpld.c @@ -0,0 +1,1771 @@ +/* + * S8900-64XC QSFP CPLD driver + * + * Copyright (C) 2017 Ingrasys, 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, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#ifdef DEBUG + #define DEBUG_PRINT(fmt, args...) \ + printk (KERN_INFO "%s[%d]: " fmt "\r\n", \ + __FUNCTION__, __LINE__, ##args) +#else + #define DEBUG_PRINT(fmt, args...) +#endif + +#define ERROR_MSG(fmt, args...) \ + printk(KERN_ERR "%s[%d]: " fmt "\r\n", \ + __FUNCTION__, __LINE__, ##args) + + + + +#define SFF_8436_MMAP_SIZE (256) +#define EEPROM_SIZE (5 * 128) /* 640 byte eeprom */ +#define EEPROM_PAGE_SIZE (128) +#define EEPROM_DEFAULT_PAGE (0) +#define I2C_RW_RETRY_COUNT (3) +#define I2C_RW_RETRY_INTERVAL (100) /* ms */ +#define USE_I2C_BLOCK_READ (1) + +#define SFP_EEPROM_A0_I2C_ADDR (0xA0 >> 1) + +#define SFF_8436_PAGE_PROV_ADDR (0xC3) /* Memory Page 01/02 Provided */ +#define SFF_8436_PAGE_01_PRESENT (1 << 6) /* Memory Page 01 present */ +#define SFF_8436_PAGE_02_PRESENT (1 << 7) /* Memory Page 02 present */ +#define SFF_8436_PAGE_SELECT_ADDR (0x7F) +#define SFF_8436_STATUS_ADDR (0x02) +#define SFF_8436_STATUS_PAGE_03_PRESENT_L (1 << 2) /* Flat Memory:0-Paging, 1-Page 0 only */ + +#define S8900_64XC_MUX_BASE_NR 1 +#define S8900_64XC_SFP_EEPROM_BASE_NR 2 +#define CPLD_DEVICE_NUM 3 +#define SFP_CPLD_DEVICE_NUM 2 +#define QSFP_EEPROM_DEVICE_NUM 3 +#define TOTAL_PORT_NUM 64 +#define CPLD_MUX_OFFSET 24 +#define SFP_EEPROM_DEV_NUM 3 +#define SFP_EEPROM_NAME_LEN 16 +/* CPLD registers */ +#define CPLD_REG_REV 0x01 +#define CPLD_REG_ID 0x02 +#define CPLD_MUX_REG 0x4a + +/* QSFP signal bit in register */ +#define BIT_RST 0 +#define BIT_LPM 2 +#define BIT_INT 0 +#define BIT_ABS 1 +#define BIT_ABS_2 5 + +static ssize_t sfp_eeprom_read(struct i2c_client *, loff_t, u8 *,int); +static ssize_t sfp_eeprom_write(struct i2c_client *, loff_t, const char *,int); + + +enum port_numbers { + sfp1, sfp2, sfp3, sfp4, sfp5, sfp6, sfp7, sfp8, + sfp9, sfp10, sfp11, sfp12, sfp13, sfp14, sfp15, sfp16, + sfp17, sfp18, sfp19, sfp20, sfp21, sfp22, sfp23, sfp24, + sfp25, sfp26, sfp27, sfp28, sfp29, sfp30, sfp31, sfp32, + sfp33, sfp34, sfp35, sfp36, sfp37, sfp38, sfp39, sfp40, + sfp41, sfp42, sfp43, sfp44, sfp45, sfp46, sfp47, sfp48, + qsfp49, qsfp50, qsfp51, qsfp52, qsfp53, qsfp54, qsfp55, qsfp56, + qsfp57, qsfp58, qsfp59, qsfp60, qsfp61, qsfp62, qsfp63, qsfp64 +}; + +static const struct platform_device_id qsfp_device_id[] = { + {"sfp1", sfp1}, {"sfp2", sfp2}, {"sfp3", sfp3}, {"sfp4", sfp4}, + {"sfp5", sfp5}, {"sfp6", sfp6}, {"sfp7", sfp7}, {"sfp8", sfp8}, + {"sfp9", sfp9}, {"sfp10", sfp10}, {"sfp11", sfp11}, {"sfp12", sfp12}, + {"sfp13", sfp13}, {"sfp14", sfp14}, {"sfp15", sfp15}, {"sfp16", sfp16}, + {"sfp17", sfp17}, {"sfp18", sfp18}, {"sfp19", sfp19}, {"sfp20", sfp20}, + {"sfp21", sfp21}, {"sfp22", sfp22}, {"sfp23", sfp23}, {"sfp24", sfp24}, + {"sfp25", sfp25}, {"sfp26", sfp26}, {"sfp27", sfp27}, {"sfp28", sfp28}, + {"sfp29", sfp29}, {"sfp30", sfp30}, {"sfp31", sfp31}, {"sfp32", sfp32}, + {"sfp33", sfp33}, {"sfp34", sfp34}, {"sfp35", sfp35}, {"sfp36", sfp36}, + {"sfp37", sfp37}, {"sfp38", sfp38}, {"sfp39", sfp39}, {"sfp40", sfp40}, + {"sfp41", sfp41}, {"sfp42", sfp42}, {"sfp43", sfp43}, {"sfp44", sfp44}, + {"sfp45", sfp45}, {"sfp46", sfp46}, {"sfp47", sfp47}, {"sfp48", sfp48}, + {"qsfp49", qsfp49}, {"qsfp50", qsfp50}, {"qsfp51", qsfp51}, {"qsfp52", qsfp52}, + {"qsfp53", qsfp53}, {"qsfp54", qsfp54}, {"qsfp55", qsfp55}, {"qsfp56", qsfp56}, + {"qsfp57", qsfp57}, {"qsfp58", qsfp58}, {"qsfp59", qsfp59}, {"qsfp60", qsfp60}, + {"qsfp61", qsfp61}, {"qsfp62", qsfp62}, {"qsfp63", qsfp63}, {"qsfp64", qsfp64}, + {} +}; +MODULE_DEVICE_TABLE(platform, qsfp_device_id); + +/* + * list of valid port types + * note OOM_PORT_TYPE_NOT_PRESENT to indicate no + * module is present in this port + */ +typedef enum oom_driver_port_type_e { + OOM_DRIVER_PORT_TYPE_INVALID, + OOM_DRIVER_PORT_TYPE_NOT_PRESENT, + OOM_DRIVER_PORT_TYPE_SFP, + OOM_DRIVER_PORT_TYPE_SFP_PLUS, + OOM_DRIVER_PORT_TYPE_QSFP, + OOM_DRIVER_PORT_TYPE_QSFP_PLUS, + OOM_DRIVER_PORT_TYPE_QSFP28 +} oom_driver_port_type_t; + +enum driver_type_e { + DRIVER_TYPE_SFP_MSA, + DRIVER_TYPE_SFP_DDM, + DRIVER_TYPE_QSFP +}; + +typedef enum eeprom_operation_e { + EEPROM_READ, + EEPROM_WRITE +} eeprom_operation_t; + +/* + * Each client has this additional data + */ +struct eeprom_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + struct bin_attribute bin; /* eeprom data */ +}; + +struct qsfp_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 status[3]; /* bit0:port0, bit1:port1 and so on */ + /* index 0 => tx_fail + 1 => tx_disable + 2 => rx_loss + */ + u8 device_id; + struct eeprom_data eeprom; +}; + +struct sfp_port_data { + struct mutex update_lock; + enum driver_type_e driver_type; + int port; /* CPLD port index */ + oom_driver_port_type_t port_type; + u64 present; /* present status, bit0:port0, bit1:port1 and so on */ + + struct qsfp_data *qsfp; + + struct i2c_client *client; +}; + +enum sfp_sysfs_attributes { + PRESENT, + PRESENT_ALL, + PORT_NUMBER, + PORT_TYPE, + DDM_IMPLEMENTED, + TX_FAULT, + TX_FAULT1, + TX_FAULT2, + TX_FAULT3, + TX_FAULT4, + TX_DISABLE, + TX_DISABLE1, + TX_DISABLE2, + TX_DISABLE3, + TX_DISABLE4, + TX_DISABLE_ALL, + RX_LOS, + RX_LOS1, + RX_LOS2, + RX_LOS3, + RX_LOS4, + RX_LOS_ALL, +}; + +static void device_release(struct device *dev) +{ + return; +} + +/* + * S8900-64XC CPLD register addresses + */ +static const int int_abs_reg[CPLD_DEVICE_NUM][2]= { + {0x20, 0x31}, + {0x20, 0x31}, + {0x20, 0x2F}, +}; + +static const int rst_lp_reg[CPLD_DEVICE_NUM][2]= { + {0xFF, 0xFF}, /*dummy*/ + {0xFF, 0xFF}, /*dummy*/ + {0x30, 0x3F}, +}; + +/* + * S8900-64XC CPLD + */ + +enum cpld_type { + cpld_1, + cpld_2, + cpld_3, +}; + +enum qsfp_signal { + sig_int, + sig_abs, + sig_rst, + sig_lpm +}; + +struct cpld_platform_data { + int reg_addr; + struct i2c_client *client; +}; + +struct sfp_platform_data { + int reg_addr; + int parent; + int cpld_reg; + struct i2c_client *client; +}; + +static struct cpld_platform_data s8900_64xc_cpld_platform_data[] = { + [cpld_1] = { + .reg_addr = 0x33, + }, + + [cpld_2] = { + .reg_addr = 0x33, + }, + + [cpld_3] = { + .reg_addr = 0x33, + } +}; + +static struct sfp_platform_data s8900_64xc_sfp_platform_data[] = { + [sfp1] = { + .reg_addr = 0x50, + .parent = 2, + .cpld_reg = 0x01, + }, + + [sfp2] = { + .reg_addr = 0x50, + .parent = 2, + .cpld_reg = 0x02, + }, + + [sfp3] = { + .reg_addr = 0x50, + .parent = 2, + .cpld_reg = 0x03, + }, + [sfp4] = { + .reg_addr = 0x50, + .parent = 2, + .cpld_reg = 0x04, + }, + + [sfp5] = { + .reg_addr = 0x50, + .parent = 2, + .cpld_reg = 0x05, + }, + + [sfp6] = { + .reg_addr = 0x50, + .parent = 2, + .cpld_reg = 0x06, + }, + [sfp7] = { + .reg_addr = 0x50, + .parent = 2, + .cpld_reg = 0x07, + }, + + [sfp8] = { + .reg_addr = 0x50, + .parent = 2, + .cpld_reg = 0x08, + }, + + [sfp9] = { + .reg_addr = 0x50, + .parent = 2, + .cpld_reg = 0x09, + }, + [sfp10] = { + .reg_addr = 0x50, + .parent = 2, + .cpld_reg = 0x0A, + }, + + [sfp11] = { + .reg_addr = 0x50, + .parent = 2, + .cpld_reg = 0x0B, + }, + + [sfp12] = { + .reg_addr = 0x50, + .parent = 2, + .cpld_reg = 0x0C, + }, + [sfp13] = { + .reg_addr = 0x50, + .parent = 2, + .cpld_reg = 0x0D, + }, + + [sfp14] = { + .reg_addr = 0x50, + .parent = 2, + .cpld_reg = 0x0E, + }, + + [sfp15] = { + .reg_addr = 0x50, + .parent = 2, + .cpld_reg = 0x0F, + }, + [sfp16] = { + .reg_addr = 0x50, + .parent = 2, + .cpld_reg = 0x10, + }, + + [sfp17] = { + .reg_addr = 0x50, + .parent = 2, + .cpld_reg = 0x11, + }, + + [sfp18] = { + .reg_addr = 0x50, + .parent = 2, + .cpld_reg = 0x12, + }, + [sfp19] = { + .reg_addr = 0x50, + .parent = 2, + .cpld_reg = 0x13, + }, + + [sfp20] = { + .reg_addr = 0x50, + .parent = 2, + .cpld_reg = 0x14, + }, + + [sfp21] = { + .reg_addr = 0x50, + .parent = 2, + .cpld_reg = 0x15, + }, + [sfp22] = { + .reg_addr = 0x50, + .parent = 2, + .cpld_reg = 0x16, + }, + + [sfp23] = { + .reg_addr = 0x50, + .parent = 2, + .cpld_reg = 0x17, + }, + + [sfp24] = { + .reg_addr = 0x50, + .parent = 2, + .cpld_reg = 0x18, + }, + [sfp25] = { + .reg_addr = 0x50, + .parent = 3, + .cpld_reg = 0x01, + }, + + [sfp26] = { + .reg_addr = 0x50, + .parent = 3, + .cpld_reg = 0x02, + }, + [sfp27] = { + .reg_addr = 0x50, + .parent = 3, + .cpld_reg = 0x03, + }, + + [sfp28] = { + .reg_addr = 0x50, + .parent = 3, + .cpld_reg = 0x04, + }, + + [sfp29] = { + .reg_addr = 0x50, + + .parent = 3, + .cpld_reg = 0x05, + }, + [sfp30] = { + .reg_addr = 0x50, + .parent = 3, + .cpld_reg = 0x06, + }, + [sfp31] = { + .reg_addr = 0x50, + .parent = 3, + .cpld_reg = 0x07, + }, + [sfp32] = { + .reg_addr = 0x50, + .parent = 3, + .cpld_reg = 0x08, + }, + [sfp33] = { + .reg_addr = 0x50, + .parent = 3, + .cpld_reg = 0x09, + }, + [sfp34] = { + .reg_addr = 0x50, + .parent = 3, + .cpld_reg = 0x0A, + }, + [sfp35] = { + .reg_addr = 0x50, + .parent = 3, + .cpld_reg = 0x0B, + }, + [sfp36] = { + .reg_addr = 0x50, + .parent = 3, + .cpld_reg = 0x0C, + }, + [sfp37] = { + .reg_addr = 0x50, + .parent = 3, + .cpld_reg = 0x0D, + }, + [sfp38] = { + .reg_addr = 0x50, + .parent = 3, + .cpld_reg = 0x0E, + }, + [sfp39] = { + .reg_addr = 0x50, + .parent = 3, + .cpld_reg = 0x0F, + }, + [sfp40] = { + .reg_addr = 0x50, + .parent = 3, + .cpld_reg = 0x10, + }, + [sfp41] = { + .reg_addr = 0x50, + .parent = 3, + .cpld_reg = 0x11, + }, + [sfp42] = { + .reg_addr = 0x50, + .parent = 3, + .cpld_reg = 0x12, + }, + [sfp43] = { + .reg_addr = 0x50, + .parent = 3, + .cpld_reg = 0x13, + }, + [sfp44] = { + .reg_addr = 0x50, + .parent = 3, + .cpld_reg = 0x14, + }, + [sfp45] = { + .reg_addr = 0x50, + .parent = 3, + .cpld_reg = 0x15, + }, + [sfp46] = { + .reg_addr = 0x50, + .parent = 3, + .cpld_reg = 0x16, + }, + [sfp47] = { + .reg_addr = 0x50, + .parent = 3, + .cpld_reg = 0x17, + }, + [sfp48] = { + .reg_addr = 0x50, + .parent = 3, + .cpld_reg = 0x18, + }, + [qsfp49] = { + .reg_addr = 0x50, + .parent = 4, + .cpld_reg = 0x01, + }, + [qsfp50] = { + .reg_addr = 0x50, + .parent = 4, + .cpld_reg = 0x02, + }, + [qsfp51] = { + .reg_addr = 0x50, + .parent = 4, + .cpld_reg = 0x03, + }, + [qsfp52] = { + .reg_addr = 0x50, + .parent = 4, + .cpld_reg = 0x04, + }, + [qsfp53] = { + .reg_addr = 0x50, + .parent = 4, + .cpld_reg = 0x05, + }, + [qsfp54] = { + .reg_addr = 0x50, + .parent = 4, + .cpld_reg = 0x06, + }, + [qsfp55] = { + .reg_addr = 0x50, + .parent = 4, + .cpld_reg = 0x07, + }, + [qsfp56] = { + .reg_addr = 0x50, + .parent = 4, + .cpld_reg = 0x08, + }, + [qsfp57] = { + .reg_addr = 0x50, + .parent = 4, + .cpld_reg = 0x09, + }, + [qsfp58] = { + .reg_addr = 0x50, + .parent = 4, + .cpld_reg = 0x0A, + }, + [qsfp59] = { + .reg_addr = 0x50, + .parent = 4, + .cpld_reg = 0x0B, + }, + [qsfp60] = { + .reg_addr = 0x50, + .parent = 4, + .cpld_reg = 0x0C, + }, + [qsfp61] = { + .reg_addr = 0x50, + .parent = 4, + .cpld_reg = 0x0D, + }, + [qsfp62] = { + .reg_addr = 0x50, + .parent = 4, + .cpld_reg = 0x0E, + }, + [qsfp63] = { + .reg_addr = 0x50, + .parent = 4, + .cpld_reg = 0x0F, + }, + [qsfp64] = { + .reg_addr = 0x50, + .parent = 4, + .cpld_reg = 0x10, + } +}; + +static struct platform_device s8900_64xc_cpld = { + .name = "ingrasys-s8900-64xc-cpld", + .id = 0, + .dev = { + .platform_data = s8900_64xc_cpld_platform_data, + .release = device_release + }, +}; + +static struct platform_device s8900_64xc_sfp = { + .name = "ingrasys-s8900-64xc-sfp", + .id = 0, + .dev = { + .platform_data = s8900_64xc_sfp_platform_data, + .release = device_release + }, +}; + +/* + * S8900-64XC I2C DEVICES + */ + +struct i2c_device_platform_data { + int parent; + struct i2c_board_info info; + struct i2c_client *client; +}; + +/* module_platform_driver */ +static ssize_t +get_prs_cpld_reg(struct device *dev, + struct device_attribute *devattr, + char *buf, int signal) +{ + int ret; + u64 data = 0; + u64 shift = 0; + int i = 0; + int j = 0; + int port = 0; + int bit = 0; + int bit_mask = 0; + int bit_mask_2 = 0; + int (*reg)[CPLD_DEVICE_NUM][2]; + struct cpld_platform_data *pdata = NULL; + + pdata = dev->platform_data; + + switch(signal) { + case sig_int: + bit = BIT_INT; + reg = (typeof(reg)) &int_abs_reg; + break; + case sig_abs: + bit = BIT_ABS; + reg = (typeof(reg)) &int_abs_reg; + break; + default: + return sprintf(buf, "signal/na"); + } + bit_mask = 0x1 << bit; + bit_mask_2 = 0x1 << BIT_ABS_2; + + for (i=0; i= 0x2a && j <= 0x2f && i < SFP_CPLD_DEVICE_NUM) { + continue; + } + ret = i2c_smbus_read_byte_data(pdata[i].client, j); + if (ret < 0) { + return sprintf((char *)buf, "i2c_smbus_read_byte_data/na"); + } + shift = ((u64) ((ret & bit_mask) >> bit)) << port; + data |= shift; + DEBUG_PRINT("port=%d, shift=0x%016llx, ret=%x, bit_mask=%08x, bit=%08x, data=0x%016llx\n", port, shift, ret, bit_mask, bit, data); + /* CPLD2 and CPLD3 have BIT 1 and BIT 5 for present */ + if (i < SFP_CPLD_DEVICE_NUM) { + port++; + shift = ((u64) ((ret & bit_mask_2) >> BIT_ABS_2)) << port; + data |= shift; + DEBUG_PRINT("port=%d, shift=0x%016llx, ret=%x, bit_mask_2=0x%x, bit=%x, data=0x%016llx\n", port, shift, ret, bit_mask_2, bit, data); + } + + port++; + } + } + + return sprintf((char *)buf, "0x%016llx\n", data); +} + +/* module_platform_driver */ +static ssize_t +get_rst_lp_cpld_reg(struct device *dev, + struct device_attribute *devattr, + char *buf, int signal) +{ + int ret; + u64 data = 0; + u64 shift = 0; + int i = 0; + int j = 0; + int port = 0; + int bit = 0; + int bit_mask = 0; + int (*reg)[CPLD_DEVICE_NUM][2]; + struct cpld_platform_data *pdata = NULL; + + pdata = dev->platform_data; + + switch(signal) { + case sig_rst: + bit = BIT_RST; + reg = (typeof(reg)) &rst_lp_reg; + break; + case sig_lpm: + bit = BIT_LPM; + reg = (typeof(reg)) &rst_lp_reg; + break; + default: + return sprintf(buf, "na"); + } + bit_mask = 0x1 << bit; + + for (i=2; i> bit)) << port; + data |= shift; + port++; + } + } + + return sprintf(buf, "0x%04llx\n", data); +} + +static ssize_t +set_rst_lp_cpld_reg(struct device *dev, + struct device_attribute *devattr, + const char *buf, size_t count, int signal) +{ + unsigned long data; + int err; + struct cpld_platform_data *pdata = dev->platform_data; + u8 current_reg_val = 0; + u8 new_reg_val = 0; + int value; + int i = 0; + int j = 0; + int port = 0; + int ret = 0; + int bit = 0; + int (*reg)[CPLD_DEVICE_NUM][2]; + + err = kstrtoul(buf, 16, &data); + if (err) + return err; + + switch(signal) { + case sig_rst: + bit = BIT_RST; + reg = (typeof(reg)) &rst_lp_reg; + break; + case sig_lpm: + bit = BIT_LPM; + reg = (typeof(reg)) &rst_lp_reg; + break; + default: + return sprintf((char *)buf, "signal/na"); + } + + for (i=2; i> port) & 0x1; + + //set value on bit N of new_reg_val + if (value > 0) { + new_reg_val = current_reg_val | (u8) (0x1 << bit); + } else { + new_reg_val = current_reg_val & (u8) ~(0x1 << bit); + } + //write reg value if changed + if (current_reg_val != new_reg_val) { + ret = i2c_smbus_write_byte_data(pdata[i].client, j, + (u8)(new_reg_val)); + if (ret < 0){ + return ret; + } + } + port++; + } + } + + return count; +} + +static ssize_t +get_lpmode(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + return get_rst_lp_cpld_reg(dev, devattr, buf, sig_lpm); +} + +static ssize_t +set_lpmode(struct device *dev, + struct device_attribute *devattr, + const char *buf, size_t count) +{ + return set_rst_lp_cpld_reg(dev, devattr, buf, count, sig_lpm); +} + +static ssize_t +get_reset(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + return get_rst_lp_cpld_reg(dev, devattr, buf, sig_rst); +} + +static ssize_t +set_reset(struct device *dev, + struct device_attribute *devattr, + const char *buf, size_t count) +{ + return set_rst_lp_cpld_reg(dev, devattr, buf, count, sig_rst); +} + +static ssize_t +get_modprs(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + return get_prs_cpld_reg(dev, devattr, buf, sig_abs); +} + +static DEVICE_ATTR(qsfp_modprs, S_IRUGO, get_modprs, NULL); +static DEVICE_ATTR(qsfp_lpmode, S_IRUGO | S_IWUSR, get_lpmode, set_lpmode); +static DEVICE_ATTR(qsfp_reset, S_IRUGO | S_IWUSR, get_reset, set_reset); + +static struct attribute *s8900_64xc_cpld_attrs[] = { + &dev_attr_qsfp_lpmode.attr, + &dev_attr_qsfp_reset.attr, + &dev_attr_qsfp_modprs.attr, + NULL, +}; + +static struct attribute_group s8900_64xc_cpld_attr_grp = { + .attrs = s8900_64xc_cpld_attrs, +}; + +/* + * Assumes that sanity checks for offset happened at sysfs-layer. + * Offset within Lower Page 00h and Upper Page 00h are not recomputed + */ +static uint8_t +sff_8436_translate_offset(loff_t *offset) +{ + unsigned page = 0; + + if (*offset < SFF_8436_MMAP_SIZE) { + return 0; + } + + page = (*offset >> 7)-1; + + if (page > 0 ) { + *offset = 0x80 + (*offset & 0x7f); + } else { + *offset &= 0xff; + } + + return page; +} + +static ssize_t +eeprom_read(struct i2c_client *client, + u8 command, const char *data, + int data_len) +{ +#if USE_I2C_BLOCK_READ + int result, retry = I2C_RW_RETRY_COUNT; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + result = i2c_smbus_read_i2c_block_data(client, command, + data_len, (u8 *)data); + if (result < 0) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(result < 0)) { + goto abort; + } + + if (unlikely(result != data_len)) { + result = -EIO; + goto abort; + } + +abort: + return result; +#else + int result, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + result = i2c_smbus_read_byte_data(client, command); + if (result < 0) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(result < 0)) { + dev_dbg(&client->dev, "sfp read byte data failed, " \\ + "command(0x%2x), data(0x%2x)\r\n", + command, result); + goto abort; + } + + *data = (u8)result; + result = 1; + +abort: + return result; +#endif +} + +static ssize_t +eeprom_write(struct i2c_client *client, + u8 command, const char *data, + int data_len) +{ +#if USE_I2C_BLOCK_READ + int result, retry = I2C_RW_RETRY_COUNT; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + result = i2c_smbus_write_i2c_block_data(client, command, data_len, data); + if (result < 0) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(result < 0)) { + return result; + } + + return data_len; +#else + int result, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + result = i2c_smbus_write_byte_data(client, command, *data); + if (result < 0) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(result < 0)) { + return result; + } + + return 1; +#endif +} + +static ssize_t +sfp_eeprom_read_write(struct i2c_client *client, + eeprom_operation_t op, + loff_t off, + const char *data, + int data_len) +{ + u8 page, phy_page; + u8 val, refresh_page = 0; + int ret; + ssize_t retval = 0; + size_t pending_len = 0, page_len = 0; + loff_t page_offset = 0, page_start_offset = 0; + loff_t phy_offset; + + + if (off > EEPROM_SIZE) { + return 0; + } + + if (off + data_len > EEPROM_SIZE) { + data_len = EEPROM_SIZE - off; + } + + /* + * Refresh pages which covers the requested data + * from offset to off + len + * Only refresh pages which contain requested bytes + * + */ + + pending_len = data_len; + + for (page = off >> 7; page <= (off + data_len - 1) >> 7; page++) { + refresh_page = 0; + switch (page) { + case 0: + /* Lower page 00h */ + refresh_page = 1; + break; + case 1: + /* Upper page 00h */ + refresh_page = 1; + break; + case 2: + /* Upper page 01h */ + ret = eeprom_read(client, SFF_8436_PAGE_PROV_ADDR, &val, sizeof(val)); + if (ret < 0) { + DEBUG_PRINT("Can't read EEPROM offset %d.\n", + SFF_8436_PAGE_PROV_ADDR); + goto error; + } + if (val & SFF_8436_PAGE_01_PRESENT) { + DEBUG_PRINT("Offset:%d Value:(0x%02x & 0x%02x)", + SFF_8436_PAGE_PROV_ADDR, val, + SFF_8436_PAGE_01_PRESENT); + refresh_page = 1; + } + break; + case 3: + /* Upper page 02h */ + ret = eeprom_read(client, SFF_8436_PAGE_PROV_ADDR, &val, sizeof(val)); + if (ret < 0) { + ERROR_MSG("Can't read EEPROM offset %d.\n", + SFF_8436_PAGE_PROV_ADDR); + goto error; + } + if (val & SFF_8436_PAGE_02_PRESENT) { + DEBUG_PRINT("Offset:%d Value:(0x%02x & 0x%02x)", + SFF_8436_PAGE_PROV_ADDR, val, + SFF_8436_PAGE_02_PRESENT); + refresh_page = 1; + } + break; + case 4: + /* Upper page 03h */ + ret = eeprom_read(client, SFF_8436_STATUS_ADDR, &val, sizeof(val)); + if (ret < 0) { + ERROR_MSG("Can't read EEPROM offset %d.\n", + SFF_8436_STATUS_ADDR); + goto error; + } + if (!(val & SFF_8436_STATUS_PAGE_03_PRESENT_L)) { + DEBUG_PRINT("Offset:%d Value:(0x%02x & 0x%02x)", + SFF_8436_STATUS_ADDR, val, + SFF_8436_STATUS_PAGE_03_PRESENT_L); + refresh_page = 1; + } + break; + default: + DEBUG_PRINT("Invalid Page %d\n", page); + ret = retval; + goto error; + break; + } + + if (!refresh_page) { + /* if page is not valid or already refreshed */ + continue; + } + + /* + * Compute the offset and number of bytes to be read/write + * w.r.t requested page + * + * 1. start at offset 0 (within the page), and read/write the entire page + * 2. start at offset 0 (within the page) and read/write less than entire page + * 3. start at an offset not equal to 0 and read/write the rest of the page + * 4. start at an offset not equal to 0 and read/write less than (end of page - offset) + * + */ + page_start_offset = page * EEPROM_PAGE_SIZE; + + if (page_start_offset < off) { + page_offset = off; + if (off + pending_len < page_start_offset + EEPROM_PAGE_SIZE) { + page_len = pending_len; + } else { + page_len = EEPROM_PAGE_SIZE - off; + } + } else { + page_offset = page_start_offset; + if (pending_len > EEPROM_PAGE_SIZE) { + page_len = EEPROM_PAGE_SIZE; + } else { + page_len = pending_len; + } + } + + pending_len = pending_len - page_len; + + /* Change current EEPROM page */ + phy_offset = page_offset; + phy_page = sff_8436_translate_offset(&phy_offset); + if (phy_page > 0) { + ret = eeprom_write(client, SFF_8436_PAGE_SELECT_ADDR, + &phy_page, sizeof(phy_page)); + if (ret < 0) { + ERROR_MSG("Can't write EEPROM offset %d.\n", + SFF_8436_PAGE_SELECT_ADDR); + goto error; + } + } + + /* + * If page_len > 32, I2C client continue read or write EEPROM. + */ + while (page_len) { + if (op == EEPROM_READ) { + ret = eeprom_read(client, phy_offset, data, page_len); + } else if (op == EEPROM_WRITE) { + ret = eeprom_write(client, phy_offset, data, page_len); + } else { + ERROR_MSG("Bad EEPROM operation %d.\n", op); + break; + } + + if (ret <= 0) { + if (retval == 0) { + retval = ret; + } + break; + } + phy_offset += ret; + off += ret; + data += ret; + page_len -= ret; + retval += ret; + } + + /* Restore EEPROM page to default */ + if (phy_page > 0) { + phy_page = EEPROM_DEFAULT_PAGE; + ret = eeprom_write(client, SFF_8436_PAGE_SELECT_ADDR, + &phy_page, sizeof(phy_page)); + if (ret < 0) { + ERROR_MSG("Can't write EEPROM offset %d.\n", + SFF_8436_PAGE_SELECT_ADDR); + goto error; + } + } + } + + return retval; + +error: + return ret; +} + + +static inline ssize_t +sfp_eeprom_read(struct i2c_client *client, + loff_t off, u8 *data, + int data_len) +{ + return sfp_eeprom_read_write(client, EEPROM_READ, + off, data, data_len); +} + + +static inline ssize_t +sfp_eeprom_write(struct i2c_client *client, + loff_t off, const char *data, + int data_len) +{ + return sfp_eeprom_read_write(client, EEPROM_WRITE, + off, data, data_len); +} + +static struct i2c_client * +cpld_sfp_port_client(int port, + int *data_reg) +{ + *data_reg = s8900_64xc_sfp_platform_data[port].cpld_reg; + if (port >= sfp1 && port <= sfp24) { + return s8900_64xc_cpld_platform_data[cpld_1].client; + } else if (port >= sfp25 && port <= sfp48) { + return s8900_64xc_cpld_platform_data[cpld_2].client; + } else if (port >= qsfp49 && port <= qsfp64) { + return s8900_64xc_cpld_platform_data[cpld_3].client; + } else { + ERROR_MSG("Unknown port: %d", port); + return NULL; + } +} + +static ssize_t +sfp_port_read(struct sfp_port_data *data, + char *buf, loff_t off, + size_t count, int port) +{ + ssize_t retval = 0; + int data_reg = 0; + struct i2c_client *cpld_client = NULL; + + if (unlikely(!count)) { + DEBUG_PRINT("Count = 0, return"); + return count; + } + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&data->update_lock); + + //CPLD MUX select + cpld_client = cpld_sfp_port_client(port, &data_reg); + DEBUG_PRINT("data_reg=%d, port=%d", data_reg, port); + if (!cpld_client) { + ERROR_MSG("Error i2c client for port %d", port); + return 0; + } + i2c_smbus_write_byte_data(cpld_client, CPLD_MUX_REG ,data_reg); + + while (count) { + ssize_t status; + + status = sfp_eeprom_read(data->client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + + buf += status; + off += status; + count -= status; + retval += status; + } + + //CPLD MUX deselect + i2c_smbus_write_byte_data(cpld_client, CPLD_MUX_REG ,0x0); + + mutex_unlock(&data->update_lock); + return retval; +} + +static ssize_t +sfp_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + struct sfp_port_data *data; + struct platform_device_id *dev_id = NULL; + + dev_id = (struct platform_device_id *)attr->private; + + DEBUG_PRINT("offset = (%lld), count = (%ld) dev_port=%d", off, count, (int)dev_id->driver_data); + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + + return sfp_port_read(data, buf, off, count, (int)dev_id->driver_data); +} + +static ssize_t +sfp_port_write(struct sfp_port_data *data, + const char *buf, loff_t off, + size_t count, int port) +{ + ssize_t retval = 0; + int data_reg = 0; + struct i2c_client *cpld_client = NULL; + + if (unlikely(!count)) { + return count; + } + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&data->update_lock); + + //CPLD MUX select + cpld_client = cpld_sfp_port_client(port, &data_reg); + DEBUG_PRINT("data_reg=%d, port=%d", data_reg, port); + if (!cpld_client) { + ERROR_MSG("Error i2c client for port %d", port); + } + i2c_smbus_write_byte_data(cpld_client, CPLD_MUX_REG ,data_reg); + + while (count) { + ssize_t status; + + status = sfp_eeprom_write(data->client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + //CPLD MUX deselect + i2c_smbus_write_byte_data(cpld_client, CPLD_MUX_REG ,0x0); + + mutex_unlock(&data->update_lock); + return retval; +} + + +static ssize_t +sfp_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + struct sfp_port_data *data; + struct platform_device_id *dev_id = NULL; + + dev_id = (struct platform_device_id *)attr->private; + + DEBUG_PRINT("offset = (%lld), count = (%ld) dev_port=%d", + off, count, (int)dev_id->driver_data); + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + + return sfp_port_write(data, buf, off, count, (int)dev_id->driver_data); +} + +static int +sfp_sysfs_eeprom_init(struct kobject *kobj, + struct bin_attribute *eeprom, + const struct platform_device_id *dev_id) +{ + int err; + + sysfs_bin_attr_init(eeprom); + eeprom->attr.name = dev_id->name; + eeprom->attr.mode = S_IWUSR | S_IRUGO; + eeprom->read = sfp_bin_read; + eeprom->write = sfp_bin_write; + eeprom->private = (void *)dev_id; + eeprom->size = EEPROM_SIZE; + + /* Create eeprom file */ + err = sysfs_create_bin_file(kobj, eeprom); + if (err) { + DEBUG_PRINT("err=%d", err); + return err; + } + + return 0; +} + +static int +sfp_sysfs_eeprom_cleanup(struct kobject *kobj, + struct bin_attribute *eeprom) +{ + sysfs_remove_bin_file(kobj, eeprom); + + return 0; +} + +static int +sfp_i2c_check_functionality(struct i2c_client *client) +{ +#if USE_I2C_BLOCK_READ + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK); +#else + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA); +#endif +} + +static int +qsfp_probe(struct i2c_client *client, + const struct platform_device_id *dev_id, + struct qsfp_data **data) +{ + int status; + struct qsfp_data *qsfp; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + qsfp = kzalloc(sizeof(struct qsfp_data), GFP_KERNEL); + if (!qsfp) { + status = -ENOMEM; + DEBUG_PRINT("No memory."); + goto exit; + } + + /* Register sysfs hooks */ //TBD: must remove + /* status = sysfs_create_group(&client->dev.kobj, &qsfp_group); + if (status) { + goto exit_free; + } */ + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &qsfp->eeprom.bin, dev_id); + if (status) { + DEBUG_PRINT("sfp_sysfs_eeprom_init error"); + goto exit_free; + } + + //TBD: Must remove + /*if (s9130_32x_kobj) { + status = sysfs_create_link(s9130_32x_kobj, &client->dev.kobj, client->name); + if (status) { + goto exit_remove; + } + }*/ + + *data = qsfp; + dev_info(&client->dev, "qsfp '%s'\n", client->name); + + return 0; + +exit_free: + kfree(qsfp); +exit: + + return status; +} + +static int +qsfp_device_probe(struct platform_device *pdev) +{ + struct sfp_platform_data *pdata; + struct sfp_port_data *data[TOTAL_PORT_NUM]; + struct i2c_adapter *parent[SFP_EEPROM_DEV_NUM]; + struct i2c_client *sfp_client[SFP_EEPROM_DEV_NUM]; + int i; + int ret=0; + + DEBUG_PRINT("Start"); + + pdata = pdev->dev.platform_data; + if (!pdata) { + ERROR_MSG("Missing platform data\n"); + return -ENODEV; + } + + //New eeprom device + for (i=0; i < SFP_EEPROM_DEV_NUM; i++) { + parent[i] = i2c_get_adapter(i+S8900_64XC_SFP_EEPROM_BASE_NR); + if (!parent[i]) { + ERROR_MSG("Parent adapter (%d) not found\n", i+S8900_64XC_SFP_EEPROM_BASE_NR); + ret=-ENODEV; + goto error; + } + sfp_client[i] = i2c_new_dummy(parent[i], SFP_EEPROM_A0_I2C_ADDR); + if (!sfp_client[i]) { + ERROR_MSG("[%d]: Fail to create dummy i2c client for parent %d addr 0x%x\n", i, i+S8900_64XC_SFP_EEPROM_BASE_NR, SFP_EEPROM_A0_I2C_ADDR); + ret=-ENODEV; + goto error; + } + } + + //Assign client to dummy device + for (i = 0; i < TOTAL_PORT_NUM; i++) { + switch (pdata[i].parent) { + case 2: + pdata[i].client = sfp_client[0]; + break; + case 3: + pdata[i].client = sfp_client[1]; + break; + case 4: + pdata[i].client = sfp_client[2]; + break; + default: + ERROR_MSG("Error parent number: %d, ", i); + break; + } + + if (!pdata[i].client) { + ERROR_MSG("[%d]: Fail to create dummy i2c client for parent %d addr 0x%x\n", i, pdata[i].parent, pdata[i].reg_addr); + ret=-ENODEV; + goto error; + } + } + + + for (i = 0; i < TOTAL_PORT_NUM; i++) { + data[i] = kzalloc(sizeof(struct sfp_port_data), GFP_KERNEL); + if (!data[i]) { + ret=-ENOMEM; + ERROR_MSG("No memory"); + goto error; + } + + i2c_set_clientdata(pdata[i].client, data[i]); + mutex_init(&data[i]->update_lock); + data[i]->port = qsfp_device_id[i].driver_data; + data[i]->client = pdata[i].client; + + DEBUG_PRINT("data[%d]->port=%d", i, data[i]->port); + + if (pdata[i].client->addr != SFP_EEPROM_A0_I2C_ADDR) { + ret=-ENODEV; + ERROR_MSG("Not approve device address"); + goto error; + } + + data[i]->driver_type = DRIVER_TYPE_QSFP; + + ret |= qsfp_probe(pdata[i].client, &qsfp_device_id[i], &data[i]->qsfp); + } + + if (ret) { + ERROR_MSG("qsfp_probe failed someone."); + //goto error; + } + return 0; +error: + DEBUG_PRINT("error start"); + i2c_put_adapter(parent[i]); + i--; + for (; i >= 0; i--) { + if (pdata[i].client) { + i2c_unregister_device(pdata[i].client); + i2c_put_adapter(parent[i]); + } + } + + return ret; +} + +static int +qsfp_remove(struct i2c_client *client, + struct qsfp_data *data) +{ + //TBD: Must remove + /*if (s9130_32x_kobj) { + sysfs_remove_link(s9130_32x_kobj, client->name); + }*/ + + //TBD: Must remove all ports EEPROM BIN + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + //TBD: Must remove sysfs_remove_group(&client->dev.kobj, &qsfp_group); + kfree(data); + + return 0; +} + +static int __exit +qsfp_device_remove(struct platform_device *pdev) +{ + struct sfp_port_data *data = NULL; + struct sfp_platform_data *pdata = pdev->dev.platform_data; + struct i2c_adapter *parent = NULL; + int i; + + + + if (!pdata) { + ERROR_MSG("Missing platform data\n"); + return -ENOENT; + } + + for (i = 0; i < TOTAL_PORT_NUM; i+=CPLD_MUX_OFFSET) { + data = i2c_get_clientdata(pdata[i].client); + if (!data) { + ERROR_MSG("Empty data. skip. i=%d", i); + continue; + } + qsfp_remove(pdata[i].client, data->qsfp); + if (pdata[i].client) { + parent = (pdata[i].client)->adapter; + i2c_unregister_device(pdata[i].client); + i2c_put_adapter(parent); + } + kfree(data); + } + + + return 0; +} + +static int +cpld_probe(struct platform_device *pdev) +{ + struct cpld_platform_data *pdata; + struct i2c_adapter *parent[CPLD_DEVICE_NUM]; + int i; + int ret; + + pdata = pdev->dev.platform_data; + if (!pdata) { + ERROR_MSG("Missing platform data\n"); + return -ENODEV; + } + + for (i = 0; i < CPLD_DEVICE_NUM; i++) { + parent[i] = i2c_get_adapter(S8900_64XC_MUX_BASE_NR + i + 1); + if (!parent[i]) { + ERROR_MSG("Parent adapter (%d) not found\n", + S8900_64XC_MUX_BASE_NR + i + 1); + return -ENODEV; + } + pdata[i].client = i2c_new_dummy(parent[i], pdata[i].reg_addr); + if (!pdata[i].client) { + ERROR_MSG("Fail to create dummy i2c client for addr %d\n", pdata[i].reg_addr); + goto error; + } + } + + ret = sysfs_create_group(&pdev->dev.kobj, &s8900_64xc_cpld_attr_grp); + if (ret) + goto error; + + return 0; + +error: + if (i < CPLD_DEVICE_NUM) { + i2c_put_adapter(parent[i]); + } + i--; + for (; i >= 0; i--) { + if (pdata[i].client) { + i2c_unregister_device(pdata[i].client); + i2c_put_adapter(parent[i]); + } + } + + return -ENODEV; +} + +static int __exit cpld_remove(struct platform_device *pdev) +{ + int i; + struct i2c_adapter *parent = NULL; + struct cpld_platform_data *pdata = pdev->dev.platform_data; + + sysfs_remove_group(&pdev->dev.kobj, &s8900_64xc_cpld_attr_grp); + + if (!pdata) { + ERROR_MSG("Missing platform data\n"); + } else { + for (i = 0; i < CPLD_DEVICE_NUM; i++) { + if (pdata[i].client) { + parent = (pdata[i].client)->adapter; + i2c_unregister_device(pdata[i].client); + i2c_put_adapter(parent); + } + } + } + + return 0; +} + +static struct platform_driver cpld_driver = { + .probe = cpld_probe, + .remove = __exit_p(cpld_remove), + .driver = { + .owner = THIS_MODULE, + .name = "ingrasys-s8900-64xc-cpld", + }, +}; + +static struct platform_driver qsfp_driver = { + .probe = qsfp_device_probe, + .remove = __exit_p(qsfp_device_remove), + //.id_table = qsfp_device_id, + .driver = { + .owner = THIS_MODULE, + .name = "ingrasys-s8900-64xc-sfp", + }, +}; + + +static int __init ingrasys_s8900_64xc_platform_init(void) +{ + int ret = 0; + + DEBUG_PRINT("ingrasysl_s8900_64xc_platform module initialization\n"); + + //mdelay(10000); + + ret = platform_driver_register(&cpld_driver); + if (ret) { + ERROR_MSG("Fail to register cpld driver\n"); + goto error_cpld_driver; + } + ret = platform_device_register(&s8900_64xc_cpld); + if (ret) { + ERROR_MSG("Fail to create cpld device\n"); + goto error_cpld; + } + + ret = platform_driver_register(&qsfp_driver); + if (ret) { + ERROR_MSG("Fail to register sfp driver\n"); + goto error_cpld_driver; + } + + ret = platform_device_register(&s8900_64xc_sfp); + if (ret) { + ERROR_MSG("Fail to create sfp device\n"); + goto error_cpld; + } + + return 0; + +error_cpld: + platform_driver_unregister(&cpld_driver); + platform_driver_unregister(&qsfp_driver); +error_cpld_driver: + return ret; +} + +static void __exit ingrasys_s8900_64xc_platform_exit(void) +{ + platform_device_unregister(&s8900_64xc_sfp); + platform_device_unregister(&s8900_64xc_cpld); + platform_driver_unregister(&qsfp_driver); + platform_driver_unregister(&cpld_driver); +} + +module_init(ingrasys_s8900_64xc_platform_init); +module_exit(ingrasys_s8900_64xc_platform_exit); + +MODULE_DESCRIPTION("Ingrasys S8900-64XC Platform Support"); +MODULE_AUTHOR("Wade He "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/service/qsfp-monitor.service b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/service/qsfp-monitor.service new file mode 100644 index 000000000000..99c91b98ab52 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/service/qsfp-monitor.service @@ -0,0 +1,15 @@ +[Unit] +Description= This QSFP Monitor service is to setup QSFP SI. +Requires=s8900-64xc-monitor.service +After=s8900-64xc-monitor.service + +[Service] +ExecStart=/usr/sbin/qsfp_monitor.sh +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/service/s8900-64xc-monitor.service b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/service/s8900-64xc-monitor.service new file mode 100644 index 000000000000..decb0f943a9d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/service/s8900-64xc-monitor.service @@ -0,0 +1,18 @@ +[Unit] +Description= This Platform Monitor service is to initialize platform and monitor platform. +Before=platform-monitor.service +After=sysinit.target +Wants=fancontrol.service +DefaultDependencies=no + +[Service] +ExecStartPre=/usr/sbin/i2c_utils.sh i2c_init +ExecStart=/usr/sbin/s8900_64xc_monitor.sh +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/i2c_utils.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/i2c_utils.sh new file mode 100644 index 000000000000..cd33df48bd4f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/i2c_utils.sh @@ -0,0 +1,1157 @@ +#!/bin/bash + +# Copyright (C) 2016 Ingrasys, 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 3 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, see . + +VERSION="1.0.0" +TRUE=200 +FALSE=404 + +EXEC_FUNC=${1} +COLOR_LED=${2} +QSFP_PORT=${2} +ONOFF_LED=${3} +FAN_TRAY=${4} + +############################################################ +# Distributor ID: Debian +# Description: Debian GNU/Linux 8.6 (jessie) +# Release: 8.6 +# Codename: jessie +# Linux debian 3.16.0-4-amd64 #1 +# SMP Debian 3.16.36-1+deb8u1 (2016-09-03) x86_64 GNU/Linux +############################################################ + +# Color Definition +COLOR_TITLE="\e[1;32m" ### Green ### +COLOR_WARNING="\e[1;33m" ### Yellow ### +COLOR_ERROR="\e[1;31m" ### Red ### +COLOR_END="\e[0m" ### END ### + +NUM_IGB_DEVICE=0 +NUM_I801_DEVICE=0 +NUM_ISMT_DEVICE=$(( ${NUM_I801_DEVICE} + 1 )) +NUM_MUX1_CHAN0_DEVICE=$(( ${NUM_I801_DEVICE} + 2 )) +NUM_MUX1_CHAN1_DEVICE=$(( ${NUM_I801_DEVICE} + 3 )) +NUM_MUX1_CHAN2_DEVICE=$(( ${NUM_I801_DEVICE} + 4 )) +NUM_MUX1_CHAN3_DEVICE=$(( ${NUM_I801_DEVICE} + 5 )) +NUM_MUX1_CHAN4_DEVICE=$(( ${NUM_I801_DEVICE} + 6 )) +NUM_MUX1_CHAN5_DEVICE=$(( ${NUM_I801_DEVICE} + 7 )) +NUM_MUX1_CHAN6_DEVICE=$(( ${NUM_I801_DEVICE} + 8 )) +NUM_MUX1_CHAN7_DEVICE=$(( ${NUM_I801_DEVICE} + 9 )) + +PATH_SYS_I2C_DEVICES="/sys/bus/i2c/devices" +PATH_HWMON_ROOT_DEVICES="/sys/class/hwmon" +PATH_HWMON_W83795_DEVICE="${PATH_HWMON_ROOT_DEVICES}/hwmon1" +PATH_I801_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_I801_DEVICE}" +PATH_ISMT_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_ISMT_DEVICE}" +PATH_MUX_CHAN0_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN0_DEVICE}" +PATH_MUX_CHAN1_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN1_DEVICE}" +PATH_MUX_CHAN2_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN2_DEVICE}" +PATH_MUX_CHAN3_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN3_DEVICE}" +PATH_MUX_CHAN4_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN4_DEVICE}" +PATH_MUX_CHAN5_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN5_DEVICE}" +PATH_MUX_CHAN6_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN6_DEVICE}" +PATH_MUX_CHAN7_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN7_DEVICE}" + +#Power Supply Status +PSU_DC_ON=1 +PSU_DC_OFF=0 +PSU_EXIST=1 +PSU_NOT_EXIST=0 + +# Help usage function +function _help { + echo "=========================================================" + echo "# Description: Help Function" + echo "=========================================================" + echo "----------------------------------------------------" + echo "EX : ${0} help" + echo " : ${0} i2c_init" + echo " : ${0} i2c_temp_init" + echo " : ${0} i2c_fan_init" + echo " : ${0} i2c_volmon_init" + echo " : ${0} i2c_io_exp_init" + echo " : ${0} i2c_led_test" + echo " : ${0} i2c_psu_eeprom_get" + echo " : ${0} i2c_mb_eeprom_get" + echo " : ${0} i2c_qsfp_eeprom_get [1-64]" + echo " : ${0} i2c_qsfp_status_get [1-64]" + echo " : ${0} i2c_qsfp_type_get [1-64]" + echo " : ${0} i2c_qsfp_abs_get [1-64]" + echo " : ${0} i2c_qsfp_rst_get [49-64]" + echo " : ${0} i2c_qsfp_lpmode_get [49-64]" + echo " : ${0} i2c_board_type_get" + echo " : ${0} i2c_psu_status" + echo " : ${0} i2c_led_psu_status_set" + echo " : ${0} i2c_led_fan_status_set" + echo " : ${0} i2c_led_fan_tray_status_set" + echo " : ${0} i2c_cpld_version" + echo " : ${0} i2c_front_temp" + echo " : ${0} i2c_rear_temp" + echo " : ${0} i2c_test_all" + echo " : ${0} i2c_sys_led green|amber on|off" + echo " : ${0} i2c_fan_led green|amber on|off" + echo " : ${0} i2c_psu1_led green|amber on|off" + echo " : ${0} i2c_psu2_led green|amber on|off" + echo " : ${0} i2c_fan_tray_led green|amber on|off [1-5]" + echo "----------------------------------------------------" +} + +#Pause function +function _pause { + read -p "$*" +} + +#Retry command function +function _retry { + for i in {1..5}; + do + eval "${*}" && break || echo "retry"; sleep 1; + done +} + + +#I2C Init +function _i2c_init { + echo "=========================================================" + echo "# Description: I2C Init" + echo "=========================================================" + + rmmod i2c_ismt + rmmod i2c_i801 + modprobe i2c_i801 + modprobe i2c_ismt + modprobe i2c_dev + modprobe i2c_mux_pca954x force_deselect_on_exit=1 + + if [ ! -e "${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN0_DEVICE}" ]; then + _retry "echo 'pca9548 0x72' > ${PATH_ISMT_DEVICE}/new_device" + else + echo "pca9548 0x72 already init." + fi + #Init CPLD LED_CLR Register (Front Port LED) + i2cset -y ${NUM_I801_DEVICE} 0x33 0x34 0x10 + + rmmod coretemp + rmmod jc42 + rmmod w83795 + rmmod lm75 + _i2c_temp_init + _i2c_volmon_init + _i2c_hwmon_init + modprobe coretemp + modprobe w83795 + modprobe lm75 + modprobe jc42 + modprobe sff_8436_eeprom + modprobe eeprom + modprobe eeprom_mb + modprobe qsfp_cpld + _i2c_fan_init + _i2c_io_exp_init + _i2c_cpld_init + _i2c_psu_eeprom_init + _i2c_led_psu_status_set + _i2c_led_fan_status_set + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_sys_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_sys_led + + echo "tmp75 0x48" > ${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN3_DEVICE}/new_device + echo "tmp75 0x49" > ${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN3_DEVICE}/new_device + echo "Mount Main Board EEPROM" + echo "mb_eeprom 0x54" > /sys/bus/i2c/devices/i2c-7/new_device + + _config_rmem +} + +#I2C Deinit +function _i2c_deinit { + for mod in coretemp jc42 w83795 lm75 eeprom_mb i2c_mux_pca954x i2c_ismt i2c_i801; + do + [ "$(lsmod | grep "^$mod ")" != "" ] && rmmod $mod + done +} + +#Temperature sensor Init +function _i2c_temp_init { + i2cset -y -r ${NUM_I801_DEVICE} 0x2F 0x00 0x80 + i2cset -y -r ${NUM_I801_DEVICE} 0x2F 0x05 0xFF + echo "TEMP INIT Done" +} + +#FAN Init +function _i2c_fan_init { + echo -n "FAN INIT..." + if [ -e "${PATH_HWMON_W83795_DEVICE}" ]; then + echo 120 > ${PATH_HWMON_W83795_DEVICE}/device/pwm1 + echo 120 > ${PATH_HWMON_W83795_DEVICE}/device/pwm2 + echo "SUCCESS" + else + echo "FAIL" + fi + +} + +#VOLMON Init +function _i2c_volmon_init { + echo -n "VOLMON INIT..." + i2cset -y -r ${NUM_I801_DEVICE} 0x2F 0x00 0x80 + i2cset -y -r ${NUM_I801_DEVICE} 0x2F 0x02 0xFF + i2cset -y -r ${NUM_I801_DEVICE} 0x2F 0x03 0x50 + i2cset -y -r ${NUM_I801_DEVICE} 0x2F 0x04 0x0A + echo "Done" +} + +#HWMON Init +function _i2c_hwmon_init { + echo -n "HWMON INIT..." + i2cset -y ${NUM_I801_DEVICE} 0x2f 0x00 0x80 + i2cset -y ${NUM_I801_DEVICE} 0x2f 0x06 0xFF + i2cset -y ${NUM_I801_DEVICE} 0x2f 0x07 0x03 + echo "Done" +} + +#IO Expander Init +function _i2c_io_exp_init { + echo "=========================================================" + echo "# Description: I2C IO Expender Init" + echo "=========================================================" + #SMBUS0 IO_EXPENDER + i2cset -y -r ${NUM_I801_DEVICE} 0x27 4 0x00 + i2cset -y -r ${NUM_I801_DEVICE} 0x27 5 0x00 + i2cset -y -r ${NUM_I801_DEVICE} 0x27 2 0x00 + i2cset -y -r ${NUM_I801_DEVICE} 0x27 3 0x00 + i2cset -y -r ${NUM_I801_DEVICE} 0x27 6 0xFF + i2cset -y -r ${NUM_I801_DEVICE} 0x27 7 0xFF + + #LED board after PVT (S8900_IO_EXP_LED_ID) + echo "Init LED IO Expender" + i2cset -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x22 4 0x00 + i2cset -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x22 5 0x00 + i2cset -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0xFF + i2cset -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x22 3 0x00 + i2cset -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x22 6 0x00 + i2cset -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x22 7 0xFF + + #PSU I/O (S8900_IO_EXP_PSU_ID) + echo "Init PSU IO Expender" + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x20 4 0x00 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x20 5 0x00 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x20 2 0x44 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x20 3 0x00 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x20 6 0xBB + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x20 7 0xFF + + #FAN I/O (S8900_IO_EXP_FAN_ID) + echo "Init FAN1 IO Expender" + i2cset -y -r ${NUM_MUX1_CHAN3_DEVICE} 0x20 4 0x00 + i2cset -y -r ${NUM_MUX1_CHAN3_DEVICE} 0x20 5 0x00 + i2cset -y -r ${NUM_MUX1_CHAN3_DEVICE} 0x20 2 0x11 + i2cset -y -r ${NUM_MUX1_CHAN3_DEVICE} 0x20 3 0x11 + i2cset -y -r ${NUM_MUX1_CHAN3_DEVICE} 0x20 6 0xCC + i2cset -y -r ${NUM_MUX1_CHAN3_DEVICE} 0x20 7 0xCC + + #FAN I/O (S8900_IO_EXP_FAN_ID) + echo "Init FAN2 IO Expender" + i2cset -y -r ${NUM_MUX1_CHAN3_DEVICE} 0x21 4 0x00 + i2cset -y -r ${NUM_MUX1_CHAN3_DEVICE} 0x21 5 0x00 + i2cset -y -r ${NUM_MUX1_CHAN3_DEVICE} 0x21 2 0x10 + i2cset -y -r ${NUM_MUX1_CHAN3_DEVICE} 0x21 3 0x00 + i2cset -y -r ${NUM_MUX1_CHAN3_DEVICE} 0x21 6 0xCC + i2cset -y -r ${NUM_MUX1_CHAN3_DEVICE} 0x21 7 0xFF +} + +#I2C CPLD init +function _i2c_cpld_init { + echo "=========================================================" + echo "# Description: I2C CPLD Init..." + echo "=========================================================" + + ## modprobe i2c_cpld + modprobe i2c_cpld + ## Add CPLD device + echo "i2c_cpld 0x33" > ${PATH_SYS_I2C_DEVICES}/i2c-${NUM_I801_DEVICE}/new_device + + echo "done..." +} +#Set FAN Tray LED +function _i2c_led_fan_tray_status_set { + echo "FAN Tray Status Setup" + #FAN Status set + FAN1_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan1_alarm` + FAN2_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan2_alarm` + FAN3_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan3_alarm` + FAN4_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan4_alarm` + FAN5_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan5_alarm` + FAN6_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan6_alarm` + FAN7_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan7_alarm` + FAN8_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan8_alarm` + FAN9_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan9_alarm` + FAN10_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan10_alarm` + + if [ "${FAN1_ALARM}" == "0" ] && [ "${FAN2_ALARM}" == "0" ]; then + FAN_TRAY=1 + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + else + FAN_TRAY=1 + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + fi + if [ "${FAN3_ALARM}" == "0" ] && [ "${FAN4_ALARM}" == "0" ]; then + FAN_TRAY=2 + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + else + FAN_TRAY=2 + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + fi + if [ "${FAN5_ALARM}" == "0" ] && [ "${FAN6_ALARM}" == "0" ]; then + FAN_TRAY=3 + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + else + FAN_TRAY=3 + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + fi + if [ "${FAN7_ALARM}" == "0" ] && [ "${FAN8_ALARM}" == "0" ]; then + FAN_TRAY=4 + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + else + FAN_TRAY=4 + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + fi + if [ "${FAN9_ALARM}" == "0" ] && [ "${FAN10_ALARM}" == "0" ]; then + FAN_TRAY=5 + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + else + FAN_TRAY=5 + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + fi +} + +#Set FAN LED +function _i2c_led_fan_status_set { + echo "FAN Status Setup" + #PSU Status set + FAN1_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan1_alarm` + FAN2_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan2_alarm` + FAN3_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan3_alarm` + FAN4_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan4_alarm` + FAN5_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan5_alarm` + FAN6_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan6_alarm` + FAN7_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan7_alarm` + FAN8_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan8_alarm` + FAN9_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan9_alarm` + FAN10_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan10_alarm` + + if [ "${FAN1_ALARM}" == "0" ] && [ "${FAN2_ALARM}" == "0" ] \ + && [ "${FAN3_ALARM}" == "0" ] && [ "${FAN4_ALARM}" == "0" ] \ + && [ "${FAN5_ALARM}" == "0" ] && [ "${FAN6_ALARM}" == "0" ] \ + && [ "${FAN7_ALARM}" == "0" ] && [ "${FAN8_ALARM}" == "0" ] \ + && [ "${FAN9_ALARM}" == "0" ] && [ "${FAN10_ALARM}" == "0" ]; then + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_led + else + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_led + fi +} + +#Set Power Supply LED +function _i2c_led_psu_status_set { + echo "PSU LED Status Setup" + + #PSU Status set + _i2c_psu_status + + #PSU1 Status + if [ "${psu1Exist}" == ${PSU_EXIST} ]; then + if [ "${psu1PwGood}" == ${PSU_DC_ON} ]; then + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu1_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu1_led + else + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu1_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu1_led + fi + else + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu1_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu1_led + fi + + #PSU2 Status + if [ "${psu2Exist}" == ${PSU_EXIST} ]; then + if [ "${psu2PwGood}" == ${PSU_DC_ON} ]; then + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu2_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu2_led + else + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu2_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu2_led + fi + else + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu2_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu2_led + fi +} + +#LED Test +function _i2c_led_test { + echo "=========================================================" + echo "# Description: I2C LED TEST..." + echo "=========================================================" + #sys led (green) + i2cset -y ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0xFF + i2cset -y ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0xBF + _pause 'Check SYS LED green light and Press [Enter] key to continue...' + #sys led (amber) + i2cset -y ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0xFF + i2cset -y ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0x7F + _pause 'Check SYS LED amber light and Press [Enter] key to continue...' + + #FAN led (green) + i2cset -y ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0xFF + i2cset -y ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0xEF + _pause 'Check FAN LED green light and Press [Enter] key to continue...' + #FAN led (amber) + i2cset -y ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0xFF + i2cset -y ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0xDF + _pause 'Check FAN LED amber light and Press [Enter] key to continue...' + + #PSU2 led (green) + i2cset -y ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0xFF + i2cset -y ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0xFB + _pause 'Check PSU2 LED green light and Press [Enter] key to continue...' + #PSU2 led (amber) + i2cset -y ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0xFF + i2cset -y ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0xF7 + _pause 'Check PSU2 LED amber light and Press [Enter] key to continue...' + + #PSU1 led (green) + i2cset -y ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0xFF + i2cset -y ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0xFE + _pause 'Check PSU1 LED green light and Press [Enter] key to continue...' + #PSU1 led (amber) + i2cset -y ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0xFF + i2cset -y ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0xFD + _pause 'Check PSU1 LED amber light and Press [Enter] key to continue...' + + #Turn OFF All LED + i2cset -y ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0xFF + _pause 'Check turn off all LEDs and Press [Enter] key to continue...' + echo "done..." +} + +#Set QSFP Port variable +function _qsfp_port_i2c_var_set { + local port=$1 + case ${port} in + 1|2|3|4|5|6|7|8) + i2cbus=${NUM_MUX1_CHAN0_DEVICE} + regAddr=0x33 + idx=$(( ((${port} - 1) / 2) )) + dataAddr=$(( (32 + $idx) )) + presentChan=$(( $((${port} % 2)) == 1 ? 0x1 : 0x5 )) + eeprombus=${NUM_MUX1_CHAN0_DEVICE} + eepromidx=${port} + eepromAddr=0x50 + ;; + 9|10|11|12|13|14|15|16) + i2cbus=${NUM_MUX1_CHAN0_DEVICE} + regAddr=0x33 + idx=$(( ((${port} - 1) / 2) )) + dataAddr=$(( (32 + $idx) )) + presentChan=$(( $((${port} % 2)) == 1 ? 0x1 : 0x5 )) + eeprombus=${NUM_MUX1_CHAN0_DEVICE} + eepromidx=${port} + eepromAddr=0x50 + ;; + 17|18|19|20) + i2cbus=${NUM_MUX1_CHAN0_DEVICE} + regAddr=0x33 + idx=$(( ((${port} - 1) / 2) )) + dataAddr=$(( (32 + $idx) )) + presentChan=$(( $((${port} % 2)) == 1 ? 0x1 : 0x5 )) + eeprombus=${NUM_MUX1_CHAN0_DEVICE} + eepromidx=${port} + eepromAddr=0x50 + ;; + 21|22|23|24) + i2cbus=${NUM_MUX1_CHAN0_DEVICE} + regAddr=0x33 + idx=$(( ((${port} - 1) / 2) )) + dataAddr=$(( (38 + $idx) )) + presentChan=$(( $((${port} % 2)) == 1 ? 0x1 : 0x5 )) + eeprombus=${NUM_MUX1_CHAN0_DEVICE} + eepromidx=${port} + eepromAddr=0x50 + ;; + 25|26|27|28|29|30|31|32) + i2cbus=${NUM_MUX1_CHAN1_DEVICE} + regAddr=0x33 + idx=$(( ((${port} - 25) / 2) )) + dataAddr=$(( (32 + $idx) )) + presentChan=$(( $((${port} % 2)) == 1 ? 0x1 : 0x5 )) + eeprombus=${NUM_MUX1_CHAN1_DEVICE} + eepromidx=$(( (${port} - 24) )) + eepromAddr=0x50 + ;; + 33|34|35|36|37|38|39|40) + i2cbus=${NUM_MUX1_CHAN1_DEVICE} + regAddr=0x33 + idx=$(( ((${port} - 25) / 2) )) + dataAddr=$(( (32 + $idx) )) + presentChan=$(( $((${port} % 2)) == 1 ? 0x1 : 0x5 )) + eeprombus=${NUM_MUX1_CHAN1_DEVICE} + eepromidx=$(( (${port} - 24) )) + eepromAddr=0x50 + ;; + 41|42|43|44) + i2cbus=${NUM_MUX1_CHAN1_DEVICE} + regAddr=0x33 + idx=$(( ((${port} - 25) / 2) )) + dataAddr=$(( (32 + $idx) )) + presentChan=$(( $((${port} % 2)) == 1 ? 0x1 : 0x5 )) + eeprombus=${NUM_MUX1_CHAN1_DEVICE} + eepromidx=$(( (${port} - 24) )) + eepromAddr=0x50 + ;; + 45|46|47|48) + i2cbus=${NUM_MUX1_CHAN1_DEVICE} + regAddr=0x33 + idx=$(( ((${port} - 25) / 2) )) + dataAddr=$(( (38 + $idx) )) + presentChan=$(( $((${port} % 2)) == 1 ? 0x1 : 0x5 )) + eeprombus=${NUM_MUX1_CHAN1_DEVICE} + eepromidx=$(( (${port} - 24) )) + eepromAddr=0x50 + ;; + 49|50|51|52|53|54|55|56) + i2cbus=${NUM_MUX1_CHAN2_DEVICE} + regAddr=0x33 + idx=$(( (${port} - 49) )) + dataAddr=$(( (32 + $idx) )) + rstsellpdataAddr=$(( (48 + $idx) )) + intChan=0x0 + rstChan=0x0 + presentChan=0x1 + modselChan=0x1 + lpmodeChan=0x2 + eeprombus=${NUM_MUX1_CHAN2_DEVICE} + eepromidx=$(( (${port} - 48) )) + intabsidx=$(( (${port} - 28) )) + rstsellpidx=$(( (${port} - 18) )) + eepromAddr=0x50 + ;; + 57|58|59|60|61|62|63|64) + i2cbus=${NUM_MUX1_CHAN2_DEVICE} + regAddr=0x33 + idx=$(( (${port} - 49) )) + dataAddr=$(( (32 + $idx) )) + rstsellpdataAddr=$(( (48 + $idx) )) + intChan=0x0 + rstChan=0x0 + presentChan=0x1 + modselChan=0x1 + lpmodeChan=0x2 + eeprombus=${NUM_MUX1_CHAN2_DEVICE} + eepromidx=$(( (${port} - 48) )) + intabsidx=$(( (${port} - 28) )) + rstsellpidx=$(( (${port} - 18) )) + eepromAddr=0x50 + ;; + *) + echo "Please input 1~64" + exit + ;; + esac +} + +#Get SFP/QSFP EEPROM Information +function _i2c_qsfp_eeprom_get { + _qsfp_port_i2c_var_set ${QSFP_PORT} + + regData=`cat /sys/devices/platform/ingrasys-s8900-64xc-cpld.0/qsfp_modprs` + port_num=$(( ${QSFP_PORT} - 1 )) + + #status: 0 -> Down, 1 -> Up + status=$(( $(($regData & ( 1 << $port_num))) != 0 ? 0 : 1 )) + + + if [ $status = 0 ]; then + echo "Module not present." + exit + fi + + #Read SFP/QSFP EEPROM + if [ ${QSFP_PORT} -lt 49 ]; then + cat ${PATH_SYS_I2C_DEVICES}/$eeprombus-$(printf "%04x" $eepromAddr)/sfp${QSFP_PORT} | hexdump -C + elif [ ${QSFP_PORT} -ge 49 ]; then + cat ${PATH_SYS_I2C_DEVICES}/$eeprombus-$(printf "%04x" $eepromAddr)/qsfp${QSFP_PORT} | hexdump -C + fi +} + +#Get QSFP Status for QSFP monitor service +function _i2c_qsfp_status_get { + _i2c_qsfp_abs_get + echo "status=$status" +} + +#Get QSFP type for QSFP monitor server +function _i2c_qsfp_type_get { + _qsfp_port_i2c_var_set ${QSFP_PORT} + + regData=`cat /sys/devices/platform/ingrasys-s8900-64xc-cpld.0/qsfp_modprs` + port_num=$(( ${QSFP_PORT} - 1 )) + + #status: 0 -> Down, 1 -> Up + status=$(( $(($regData & ( 1 << $port_num))) != 0 ? 0 : 1 )) + + if [ $status = 0 ]; then + echo "Module not present." + exit + fi + + #Read SFP/QSFP EEPROM + if [ ${QSFP_PORT} -lt 49 ]; then + qsfp_info=$(base64 ${PATH_SYS_I2C_DEVICES}/$eeprombus-$(printf "%04x" $eepromAddr)/sfp${QSFP_PORT}) + elif [ ${QSFP_PORT} -ge 49 ]; then + qsfp_info=$(base64 ${PATH_SYS_I2C_DEVICES}/$eeprombus-$(printf "%04x" $eepromAddr)/qsfp${QSFP_PORT}) + fi + + if [ ${QSFP_PORT} -ge 1 ] && [ ${QSFP_PORT} -le 48 ]; then + echo "sfp" + # 1~48 port is sfp port + identifier=$(echo $qsfp_info | base64 -d -i | hexdump -s 0 -n 1 -e '"%x"') + connector=$(echo $qsfp_info | base64 -d -i | hexdump -s 2 -n 1 -e '"%x"') + transceiver=$(echo $qsfp_info | base64 -d -i | hexdump -s 3 -n 1 -e '"%x"') + else + echo "qsfp" + # 49~64 port is qsfp port + identifier=$(echo $qsfp_info | base64 -d -i | hexdump -s 128 -n 1 -e '"%x"') + connector=$(echo $qsfp_info | base64 -d -i | hexdump -s 130 -n 1 -e '"%x"') + transceiver=$(echo $qsfp_info | base64 -d -i | hexdump -s 131 -n 1 -e '"%x"') + fi + + echo "identifier=$identifier" + echo "connector=$connector" + echo "transceiver=$transceiver" +} + +#Get QSFP ABS +function _i2c_qsfp_abs_get { + _qsfp_port_i2c_var_set ${QSFP_PORT} + + regData=`cat /sys/devices/platform/ingrasys-s8900-64xc-cpld.0/qsfp_modprs` + port_num=$(( ${QSFP_PORT} - 1 )) + + #status: 0 -> Down, 1 -> Up + status=$(( $(($regData & ( 1 << $port_num))) != 0 ? 0 : 1 )) + echo "ABS=$status regData=$regData" + + +} + +#Get QSFP RST +function _i2c_qsfp_rst_get { + + if [ ${QSFP_PORT} -lt 49 ] || [ ${QSFP_PORT} -gt 64 ]; then + echo "Please input 49~64" + exit + fi + _qsfp_port_i2c_var_set ${QSFP_PORT} + + + regData=`cat /sys/devices/platform/ingrasys-s8900-64xc-cpld.0/qsfp_reset` + port_num=$(( ${QSFP_PORT} - 49 )) + + #status: 0 -> Down, 1 -> Up + status=$(( $(($regData & ( 1 << $port_num))) != 0 ? 0 : 1 )) + echo "RST=$status regData=$regData" + +} + +#Get QSFP LPMODE +function _i2c_qsfp_lpmode_get { + + if [ ${QSFP_PORT} -lt 49 ] || [ ${QSFP_PORT} -gt 64 ]; then + echo "Please input 49~64" + exit + fi + _qsfp_port_i2c_var_set ${QSFP_PORT} + + + regData=`cat /sys/devices/platform/ingrasys-s8900-64xc-cpld.0/qsfp_lpmode` + port_num=$(( ${QSFP_PORT} - 49 )) + + #status: 0 -> Down, 1 -> Up + status=$(( $(($regData & ( 1 << $port_num))) != 0 ? 1 : 0 )) + echo "LPMODE=$status regData=$regData" + +} +#PSU EEPROM init +function _i2c_psu_eeprom_init { + echo "=========================================================" + echo "# Description: I2C PSU EEPROM Init..." + echo "=========================================================" + + ## modprobe eeprom + modprobe eeprom + ## PUS(0) EEPROM + echo "eeprom 0x50" > ${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN6_DEVICE}/new_device + + ## PUS(1) EEPROM + echo "eeprom 0x50" > ${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN7_DEVICE}/new_device + + echo "done..." +} + +#Get PSU EEPROM Information +function _i2c_psu_eeprom_get { + echo "=========================================================" + echo "# Description: I2C PSU EEPROM Get..." + echo "=========================================================" + + ## modprobe eeprom + modprobe eeprom + ## PUS(0) EEPROM + cat ${PATH_SYS_I2C_DEVICES}/${NUM_MUX1_CHAN6_DEVICE}-0050/eeprom | hexdump -C + + ## PUS(1) EEPROM + cat ${PATH_SYS_I2C_DEVICES}/${NUM_MUX1_CHAN7_DEVICE}-0050/eeprom | hexdump -C + echo "done..." +} + +#Get MotherBoard EEPROM Information +function _i2c_mb_eeprom_get { + echo "=========================================================" + echo "# Description: I2C MB EEPROM Get..." + echo "=========================================================" + + ## modprobe eeprom + modprobe eeprom_mb + + ## MB EEPROM + cat ${PATH_SYS_I2C_DEVICES}/${NUM_MUX1_CHAN5_DEVICE}-0054/eeprom | hexdump -C + echo "done..." +} + +#Set System Status LED +function _i2c_sys_led { + if [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "on" ]; then + i2cset -m 0x40 -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0x00 + elif [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "off" ]; then + i2cset -m 0x40 -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0xFF + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "on" ]; then + i2cset -m 0x80 -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0x00 + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "off" ]; then + i2cset -m 0x80 -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0xFF + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + echo "done..." +} + +#Set PSU2 LED +function _i2c_psu2_led { + if [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "on" ]; then + i2cset -m 0x04 -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0x00 + elif [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "off" ]; then + i2cset -m 0x04 -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0xFF + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "on" ]; then + i2cset -m 0x08 -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0x00 + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "off" ]; then + i2cset -m 0x08 -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0xFF + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + echo "done..." +} + +#Set FAN Tray LED +function _i2c_fan_tray_led { + + case ${FAN_TRAY} in + 1) + i2cAddr=0x20 + ioPort=2 + if [ "${COLOR_LED}" == "green" ]; then + mask=0x01 + elif [ "${COLOR_LED}" == "amber" ]; then + mask=0x02 + fi + ;; + 2) + i2cAddr=0x20 + ioPort=2 + if [ "${COLOR_LED}" == "green" ]; then + mask=0x10 + elif [ "${COLOR_LED}" == "amber" ]; then + mask=0x20 + fi + ;; + 3) + i2cAddr=0x20 + ioPort=3 + if [ "${COLOR_LED}" == "green" ]; then + mask=0x01 + elif [ "${COLOR_LED}" == "amber" ]; then + mask=0x02 + fi + ;; + 4) + i2cAddr=0x20 + ioPort=3 + if [ "${COLOR_LED}" == "green" ]; then + mask=0x10 + elif [ "${COLOR_LED}" == "amber" ]; then + mask=0x20 + fi + ;; + 5) + i2cAddr=0x21 + ioPort=2 + if [ "${COLOR_LED}" == "green" ]; then + mask=0x10 + elif [ "${COLOR_LED}" == "amber" ]; then + mask=0x20 + fi + ;; + *) + echo "Please input 1~5" + exit + ;; + esac + + if [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "on" ]; then + i2cset -m $mask -y -r ${NUM_MUX1_CHAN3_DEVICE} $i2cAddr $ioPort 0x00 + elif [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "off" ]; then + i2cset -m $mask -y -r ${NUM_MUX1_CHAN3_DEVICE} $i2cAddr $ioPort 0x33 + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "on" ]; then + i2cset -m $mask -y -r ${NUM_MUX1_CHAN3_DEVICE} $i2cAddr $ioPort 0x00 + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "off" ]; then + i2cset -m $mask -y -r ${NUM_MUX1_CHAN3_DEVICE} $i2cAddr $ioPort 0x33 + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + echo "done..." +} + +#Set FAN LED +function _i2c_fan_led { + if [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "on" ]; then + i2cset -m 0x10 -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0x00 + elif [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "off" ]; then + i2cset -m 0x10 -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0xFF + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "on" ]; then + i2cset -m 0x20 -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0x00 + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "off" ]; then + i2cset -m 0x20 -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0xFF + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + echo "done..." +} + +#Set PSU1 LED +function _i2c_psu1_led { + if [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "on" ]; then + i2cset -m 0x01 -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0x00 + elif [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "off" ]; then + i2cset -m 0x01 -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0xFF + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "on" ]; then + i2cset -m 0x02 -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0x00 + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "off" ]; then + i2cset -m 0x02 -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x22 2 0xFF + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + echo "done..." +} + +#Get Board Version and Type +function _i2c_board_type_get { + boardType=`cat ${PATH_SYS_I2C_DEVICES}/0-0033/cpld_board_type` + boardBuildRev=$((($boardType) & 0x03)) + boardHwRev=$((($boardType) >> 2 & 0x03)) + boardId=$((($boardType) >> 4)) + printf "BOARD_ID is 0x%02x, HW Rev %d, Build Rev %d\n" $boardId $boardHwRev $boardBuildRev + +} + +#Get CPLD Version +function _i2c_cpld_version { + cpldRev=`cat ${PATH_SYS_I2C_DEVICES}/0-0033/cpld_version` + cpldRelease=$((($cpldRev) >> 6 & 0x01)) + cpldVersion=$((($cpldRev) & 0x3F)) + printf "CPLD is %s version(0:RD 1:Release), Revision is 0x%02x\n" $cpldRelease $cpldVersion + +} + +#Get PSU Status +function _i2c_psu_status { + psuPresent=`cat ${PATH_SYS_I2C_DEVICES}/0-0033/cpld_pw_abs` + psu1Exist=$(($((($psuPresent) & 0x01))?0:1)) + psu2Exist=$(($((($psuPresent) & 0x02))?0:1)) + psuPwGood=`cat ${PATH_SYS_I2C_DEVICES}/0-0033/cpld_pw_good` + psu1PwGood=$(($((($psuPwGood) >> 2 & 0x01))?1:0)) + psu2PwGood=$(($((($psuPwGood) >> 2 & 0x02))?1:0)) + printf "PSU1 Exist:%d PSU1 PW Good:%d\n" $psu1Exist $psu1PwGood + printf "PSU2 Exist:%d PSU2 PW Good:%d\n" $psu2Exist $psu2PwGood +} + +#Get Front Sensor Temperature +function _i2c_front_temp { + #Front MAC + sensors | grep 'Front MAC Temp' -A 1 +} + +#Get Rear Sensor Temperature +function _i2c_rear_temp { + #Rear MAC + sensors | grep 'Rear MAC Temp' -A 1 +} + +#Increase read socket buffer for CoPP Test +function _config_rmem { + echo "109430400" > /proc/sys/net/core/rmem_max +} + +#Main Function +function _main { + tart_time_str=`date` + start_time_sec=$(date +%s) + + if [ "${EXEC_FUNC}" == "help" ]; then + _help + elif [ "${EXEC_FUNC}" == "i2c_init" ]; then + _i2c_init + elif [ "${EXEC_FUNC}" == "i2c_deinit" ]; then + _i2c_deinit + elif [ "${EXEC_FUNC}" == "i2c_temp_init" ]; then + _i2c_temp_init + elif [ "${EXEC_FUNC}" == "i2c_fan_init" ]; then + _i2c_fan_init + elif [ "${EXEC_FUNC}" == "i2c_volmon_init" ]; then + _i2c_volmon_init + elif [ "${EXEC_FUNC}" == "i2c_io_exp_init" ]; then + _i2c_io_exp_init + elif [ "${EXEC_FUNC}" == "i2c_led_test" ]; then + _i2c_led_test + elif [ "${EXEC_FUNC}" == "i2c_mb_eeprom_get" ]; then + _i2c_mb_eeprom_get + elif [ "${EXEC_FUNC}" == "i2c_psu_eeprom_get" ]; then + _i2c_psu_eeprom_get + elif [ "${EXEC_FUNC}" == "i2c_qsfp_eeprom_get" ]; then + _i2c_qsfp_eeprom_get + elif [ "${EXEC_FUNC}" == "i2c_qsfp_status_get" ]; then + _i2c_qsfp_status_get + elif [ "${EXEC_FUNC}" == "i2c_qsfp_type_get" ]; then + _i2c_qsfp_type_get + elif [ "${EXEC_FUNC}" == "i2c_qsfp_abs_get" ]; then + _i2c_qsfp_abs_get + elif [ "${EXEC_FUNC}" == "i2c_qsfp_rst_get" ]; then + _i2c_qsfp_rst_get + elif [ "${EXEC_FUNC}" == "i2c_qsfp_lpmode_get" ]; then + _i2c_qsfp_lpmode_get + elif [ "${EXEC_FUNC}" == "i2c_led_psu_status_set" ]; then + _i2c_led_psu_status_set + elif [ "${EXEC_FUNC}" == "i2c_led_fan_status_set" ]; then + _i2c_led_fan_status_set + elif [ "${EXEC_FUNC}" == "i2c_led_fan_tray_status_set" ]; then + _i2c_led_fan_tray_status_set + elif [ "${EXEC_FUNC}" == "i2c_sys_led" ]; then + _i2c_sys_led + elif [ "${EXEC_FUNC}" == "i2c_fan_led" ]; then + _i2c_fan_led + elif [ "${EXEC_FUNC}" == "i2c_fan_tray_led" ]; then + _i2c_fan_tray_led + elif [ "${EXEC_FUNC}" == "i2c_psu1_led" ]; then + _i2c_psu1_led + elif [ "${EXEC_FUNC}" == "i2c_psu2_led" ]; then + _i2c_psu2_led + elif [ "${EXEC_FUNC}" == "i2c_board_type_get" ]; then + _i2c_board_type_get + elif [ "${EXEC_FUNC}" == "i2c_cpld_version" ]; then + _i2c_cpld_version + elif [ "${EXEC_FUNC}" == "i2c_psu_status" ]; then + _i2c_psu_status + elif [ "${EXEC_FUNC}" == "i2c_front_temp" ]; then + _i2c_front_temp + elif [ "${EXEC_FUNC}" == "i2c_rear_temp" ]; then + _i2c_rear_temp + elif [ "${EXEC_FUNC}" == "i2c_test_all" ]; then + _i2c_init + _i2c_temp_init + _i2c_fan_init + _i2c_io_exp_init + _i2c_led_test + _i2c_psu_eeprom_get + _i2c_mb_eeprom_get + _i2c_board_type_get + _i2c_cpld_version + _i2c_psu_status + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + end_time_str=`date` + end_time_sec=$(date +%s) + diff_time=$[ ${end_time_sec} - ${start_time_sec} ] + echo "Start Time: ${start_time_str} (${start_time_sec})" + echo "End Time : ${end_time_str} (${end_time_sec})" + echo "Total Execution Time: ${diff_time} sec" + + echo "done!!!" +} + +_main diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_monitor.sh new file mode 100644 index 000000000000..36f9e53ef108 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_monitor.sh @@ -0,0 +1,106 @@ +#!/bin/bash +# Copyright (C) 2017 Ingrasys, 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 3 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, see . + +INTERVAL=3 +I2C_UTILS="/usr/sbin/i2c_utils.sh" +QSFP_SI_SCRIPT="/usr/sbin/qsfp_si_cfg.sh" +QSFP_ARRAY=(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \ + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) + +#QSFP SI monitor +function _qsfp_si_monitor { + local i + local status + for i in {0..63}; + do + status=`${I2C_UTILS} i2c_qsfp_status_get $(expr $i + 1) | egrep '^status=.*$' | sed -e 's/status=//g'` + if [ "${status}" == "1" ]; then + _qsfp_type_check $i + fi + done +} + +#QSFP type +function _qsfp_type_check { + local port=$1 + local qsfp_type=`${I2C_UTILS} i2c_qsfp_type_get $(expr $port + 1)` + local identifier=`echo "$qsfp_type" | grep '^identifier=.*$' | sed -e 's/identifier=//g'` + # identifier 11 for qsfp, 3 for sfp + if [ "${identifier}" == "11" ] || [ "${identifier}" == "3" ]; then + connector=`echo "$qsfp_type" | grep '^connector=.*$' | sed -e 's/connector=//g'` + case ${connector} in + 21|23) + #DAC + if [ "${QSFP_ARRAY[$port]}" != "${connector}" ]; then + echo "Change Port $(expr $port + 1) to DAC" + QSFP_ARRAY[$port]=${connector} + ${QSFP_SI_SCRIPT} dac $port >/dev/null + fi + ;; + *) + #AOC + if [ "${QSFP_ARRAY[$port]}" != "${connector}" ]; then + echo "Change Port $(expr $port + 1) to AOC" + QSFP_ARRAY[$port]=${connector} + ${QSFP_SI_SCRIPT} aoc $port >/dev/null + fi + ;; + esac + fi +} + +#Docker exist check +function _docker_swss_check { + while true + do + # Check if syncd starts + result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + if [ "$result" == "3" ]; then + return + fi + sleep $INTERVAL + done +} + +#Docker exist check +function _qsfp_si_cfg_script_check { + + if [ -f ${QSFP_SI_SCRIPT} ] && [ -x ${QSFP_SI_SCRIPT} ]; then + echo "SI Script exists. Start monitor." + return + else + echo "SI Script not exist. Exit monitor." + exit + fi +} + +# main function +function _main { + #Check SI Script + _qsfp_si_cfg_script_check + #Check docker swss is running + _docker_swss_check + while true + do + _qsfp_si_monitor + # Sleep while still handling signals + sleep $INTERVAL & + wait $! + done +} + +_main + diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_si_cfg.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_si_cfg.sh new file mode 100644 index 000000000000..3d132641f516 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_si_cfg.sh @@ -0,0 +1,409 @@ +#!/bin/bash +# Copyright (C) 2017 Ingrasys, 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 3 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, see . + +VERSION="1.0.0" +TRUE=200 +FALSE=404 + +TYPE=${1} +PORT=${2} + +# port number +MIN_PORT=0 +MAX_PORT=63 + +# INDEX of value field in array +SI_PRE_IDX=1 +SI_POST_IDX=2 +SI_MAIN_IDX=3 +SI_AMP_IDX=4 +SI_DRI_IDX=5 + +# type string +AOC_TYPE="aoc" +DAC_TYPE="dac" + +# si value for bcm command +SI_VAL="" + +# "PRE POST MAIN AMP DRIVERMODE" for each port in array +xe_aoc_si_value=( + "0x00 0x30 0x40 0x9 0x0" #port 0 + "0x00 0x30 0x40 0x9 0x0" #port 1 + "0x00 0x30 0x40 0x9 0x0" #port 2 + "0x00 0x2c 0x44 0x9 0x0" #port 3 + "0x00 0x30 0x40 0x9 0x0" #port 4 + "0x00 0x30 0x40 0x9 0x0" #port 5 + "0x00 0x2c 0x44 0x9 0x0" #port 6 + "0x00 0x2c 0x44 0x9 0x0" #port 7 + "0x00 0x2c 0x44 0x9 0x0" #port 8 + "0x00 0x28 0x48 0x9 0x0" #port 9 + "0x00 0x2c 0x44 0x9 0x0" #port 10 + "0x00 0x2c 0x44 0x9 0x0" #port 11 + "0x00 0x2c 0x44 0x9 0x0" #port 12 + "0x00 0x2c 0x44 0x9 0x0" #port 13 + "0x00 0x2c 0x44 0x9 0x0" #port 14 + "0x00 0x2c 0x44 0x9 0x0" #port 15 + "0x00 0x2c 0x44 0xb 0x0" #port 16 + "0x00 0x30 0x40 0xb 0x0" #port 17 + "0x00 0x2c 0x44 0xa 0x0" #port 18 + "0x00 0x2c 0x44 0x9 0x0" #port 19 + "0x00 0x30 0x40 0xa 0x0" #port 20 + "0x00 0x2c 0x44 0x9 0x0" #port 21 + "0x00 0x2c 0x44 0x9 0x0" #port 22 + "0x00 0x30 0x40 0xc 0x0" #port 23 + "0x00 0x30 0x40 0xc 0x0" #port 24 + "0x00 0x2c 0x44 0x9 0x0" #port 25 + "0x00 0x30 0x40 0x9 0x0" #port 26 + "0x00 0x30 0x40 0x9 0x0" #port 27 + "0x00 0x30 0x40 0xa 0x0" #port 28 + "0x00 0x28 0x48 0x9 0x0" #port 29 + "0x00 0x2c 0x44 0x9 0x0" #port 30 + "0x00 0x2c 0x44 0xa 0x0" #port 31 + "0x00 0x28 0x48 0x9 0x0" #port 32 + "0x00 0x28 0x48 0x7 0x0" #port 33 + "0x00 0x28 0x48 0x9 0x0" #port 34 + "0x00 0x28 0x48 0x9 0x0" #port 35 + "0x00 0x28 0x48 0x9 0x0" #port 36 + "0x00 0x2c 0x44 0x9 0x0" #port 37 + "0x00 0x28 0x48 0x9 0x0" #port 38 + "0x00 0x28 0x48 0x9 0x0" #port 39 + "0x00 0x28 0x48 0xa 0x0" #port 40 + "0x00 0x2c 0x44 0x9 0x0" #port 41 + "0x00 0x2c 0x44 0x9 0x0" #port 42 + "0x00 0x2e 0x42 0xa 0x0" #port 43 + "0x00 0x2e 0x42 0xa 0x0" #port 44 + "0x00 0x2c 0x44 0xa 0x0" #port 45 + "0x00 0x2c 0x44 0x9 0x0" #port 46 + "0x00 0x2c 0x44 0x9 0x0" #port 47 +) + +ce_aoc_si_value=( + "0x00 0x2c 0x44 0x9 0x0" #port 0 lane 0 + "0x00 0x34 0x3c 0xf 0x0" #port 0 lane 1 + "0x00 0x2c 0x44 0x9 0x0" #port 0 lane 2 + "0x00 0x2c 0x44 0x9 0x0" #port 0 lane 3 + "0x00 0x28 0x48 0x9 0x0" #port 1 lane 0 + "0x00 0x28 0x48 0x9 0x0" #port 1 lane 1 + "0x00 0x2c 0x44 0x9 0x0" #port 1 lane 2 + "0x00 0x2c 0x44 0xe 0x0" #port 1 lane 3 + "0x00 0x28 0x48 0x9 0x0" #port 2 lane 0 + "0x00 0x34 0x3c 0xf 0x0" #port 2 lane 1 + "0x00 0x28 0x48 0x9 0x0" #port 2 lane 2 + "0x00 0x30 0x40 0xd 0x0" #port 2 lane 3 + "0x00 0x2c 0x44 0x9 0x0" #port 3 lane 0 + "0x00 0x30 0x40 0xd 0x0" #port 3 lane 1 + "0x00 0x2c 0x44 0x9 0x0" #port 3 lane 2 + "0x00 0x30 0x40 0xd 0x0" #port 3 lane 3 + "0x00 0x2c 0x44 0x9 0x0" #port 4 lane 0 + "0x00 0x2c 0x44 0x9 0x0" #port 4 lane 1 + "0x00 0x2c 0x44 0x9 0x0" #port 4 lane 2 + "0x00 0x30 0x40 0xd 0x0" #port 4 lane 3 + "0x00 0x2c 0x44 0x9 0x0" #port 5 lane 0 + "0x00 0x38 0x38 0xf 0x0" #port 5 lane 1 + "0x00 0x2c 0x44 0x9 0x0" #port 5 lane 2 + "0x00 0x2c 0x44 0x9 0x0" #port 5 lane 3 + "0x00 0x2c 0x44 0x9 0x0" #port 6 lane 0 + "0x00 0x2c 0x44 0x9 0x0" #port 6 lane 1 + "0x00 0x2c 0x44 0x9 0x0" #port 6 lane 2 + "0x00 0x30 0x40 0xe 0x0" #port 6 lane 3 + "0x00 0x28 0x48 0x9 0x0" #port 7 lane 0 + "0x00 0x30 0x40 0xa 0x0" #port 7 lane 1 + "0x00 0x2c 0x44 0x9 0x0" #port 7 lane 2 + "0x00 0x34 0x3c 0xe 0x0" #port 7 lane 3 + "0x00 0x2c 0x44 0x9 0x0" #port 8 lane 0 + "0x00 0x30 0x40 0xe 0x0" #port 8 lane 1 + "0x00 0x34 0x3c 0xf 0x0" #port 8 lane 2 + "0x00 0x30 0x40 0xe 0x0" #port 8 lane 3 + "0x00 0x2c 0x44 0x9 0x0" #port 9 lane 0 + "0x00 0x34 0x3c 0xd 0x0" #port 9 lane 1 + "0x00 0x34 0x3c 0xd 0x0" #port 9 lane 2 + "0x00 0x34 0x3c 0xf 0x0" #port 9 lane 3 + "0x00 0x34 0x3c 0xd 0x0" #port 10 lane 0 + "0x00 0x34 0x3c 0xe 0x0" #port 10 lane 1 + "0x00 0x34 0x3c 0xd 0x0" #port 10 lane 2 + "0x00 0x34 0x3c 0xd 0x0" #port 10 lane 3 + "0x00 0x34 0x3c 0xd 0x0" #port 11 lane 0 + "0x00 0x34 0x3c 0xd 0x0" #port 11 lane 1 + "0x00 0x30 0x40 0xd 0x0" #port 11 lane 2 + "0x00 0x30 0x40 0xd 0x0" #port 11 lane 3 + "0x00 0x34 0x3c 0xd 0x0" #port 12 lane 0 + "0x00 0x34 0x3c 0xd 0x0" #port 12 lane 1 + "0x00 0x34 0x3c 0xd 0x0" #port 12 lane 2 + "0x00 0x34 0x3c 0xd 0x0" #port 12 lane 3 + "0x00 0x34 0x3c 0xd 0x0" #port 13 lane 0 + "0x00 0x34 0x3c 0xd 0x0" #port 13 lane 1 + "0x00 0x34 0x3c 0xd 0x0" #port 13 lane 2 + "0x00 0x34 0x3c 0xf 0x0" #port 13 lane 3 + "0x00 0x38 0x38 0xe 0x0" #port 14 lane 0 + "0x00 0x34 0x3c 0xd 0x0" #port 14 lane 1 + "0x00 0x34 0x3c 0xd 0x0" #port 14 lane 2 + "0x00 0x38 0x38 0xe 0x0" #port 14 lane 3 + "0x00 0x34 0x3c 0xd 0x0" #port 15 lane 0 + "0x00 0x30 0x40 0xc 0x0" #port 15 lane 1 + "0x00 0x30 0x40 0xc 0x0" #port 15 lane 2 + "0x00 0x34 0x3c 0xd 0x0" #port 15 lane 3 +) + +xe_dac_si_value=( + "0x14 0x00 0x3c 0xf 0x0" #port 0 + "0x1c 0x00 0x3c 0xf 0x0" #port 1 + "0x08 0x00 0x3c 0xf 0x0" #port 2 + "0x08 0x00 0x3c 0xf 0x0" #port 3 + "0x08 0x00 0x3c 0xf 0x0" #port 4 + "0x10 0x00 0x3c 0xf 0x0" #port 5 + "0x08 0x08 0x3c 0xf 0x0" #port 6 + "0x10 0x04 0x3c 0xf 0x0" #port 7 + "0x08 0x00 0x3c 0x9 0x0" #port 8 + "0x08 0x00 0x3c 0x9 0x0" #port 9 + "0x08 0x00 0x3c 0x9 0x0" #port 10 + "0x08 0x00 0x3c 0x9 0x0" #port 11 + "0x08 0x00 0x3c 0x9 0x0" #port 12 + "0x08 0x00 0x3c 0x9 0x0" #port 13 + "0x08 0x00 0x3c 0x9 0x0" #port 14 + "0x08 0x00 0x3c 0x9 0x0" #port 15 + "0x08 0x0c 0x3c 0xb 0x0" #port 16 + "0x10 0x0c 0x3c 0xb 0x0" #port 17 + "0x08 0x08 0x3c 0xa 0x0" #port 18 + "0x10 0x0c 0x3c 0x9 0x0" #port 19 + "0x08 0x04 0x3c 0xc 0x0" #port 20 + "0x08 0x08 0x3c 0x9 0x0" #port 21 + "0x08 0x08 0x3c 0xc 0x0" #port 22 + "0x10 0x08 0x3c 0xa 0x0" #port 23 + "0x08 0x08 0x3c 0x9 0x0" #port 24 + "0x08 0x04 0x3c 0x9 0x0" #port 25 + "0x08 0x00 0x3c 0x9 0x0" #port 26 + "0x08 0x08 0x3c 0xc 0x0" #port 27 + "0x10 0x00 0x3c 0xa 0x0" #port 28 + "0x10 0x04 0x3c 0x9 0x0" #port 29 + "0x14 0x00 0x3c 0x9 0x0" #port 30 + "0x14 0x00 0x3c 0xa 0x0" #port 31 + "0x08 0x00 0x3c 0x9 0x0" #port 32 + "0x08 0x00 0x3c 0x7 0x0" #port 33 + "0x08 0x00 0x3c 0x9 0x0" #port 34 + "0x08 0x00 0x3c 0x9 0x0" #port 35 + "0x08 0x00 0x3c 0x9 0x0" #port 36 + "0x0c 0x00 0x3c 0x9 0x0" #port 37 + "0x08 0x00 0x3c 0x9 0x0" #port 38 + "0x08 0x00 0x3c 0x9 0x0" #port 39 + "0x10 0x00 0x3c 0xa 0x0" #port 40 + "0x10 0x00 0x3c 0x9 0x0" #port 41 + "0x08 0x08 0x3c 0xc 0x0" #port 42 + "0x10 0x00 0x3c 0xa 0x0" #port 43 + "0x08 0x00 0x3c 0xa 0x0" #port 44 + "0x10 0x00 0x3c 0x9 0x0" #port 45 + "0x08 0x04 0x3c 0x9 0x0" #port 46 + "0x08 0x00 0x3c 0xa 0x0" #port 47 +) + +ce_dac_si_value=( + "0x08 0x00 0x3c 0x9 0x0" #port 0 lane 0 + "0x08 0x00 0x3c 0xf 0x0" #port 0 lane 1 + "0x08 0x00 0x3c 0x9 0x0" #port 0 lane 2 + "0x08 0x00 0x3c 0x9 0x0" #port 0 lane 3 + "0x08 0x00 0x3c 0x9 0x0" #port 1 lane 0 + "0x08 0x00 0x3c 0x9 0x0" #port 1 lane 1 + "0x08 0x00 0x3c 0x9 0x0" #port 1 lane 2 + "0x08 0x00 0x3c 0xe 0x0" #port 1 lane 3 + "0x08 0x00 0x3c 0x9 0x0" #port 2 lane 0 + "0x08 0x00 0x3c 0xf 0x0" #port 2 lane 1 + "0x08 0x00 0x3c 0x9 0x0" #port 2 lane 2 + "0x08 0x00 0x3c 0xd 0x0" #port 2 lane 3 + "0x08 0x00 0x3c 0x9 0x0" #port 3 lane 0 + "0x08 0x00 0x3c 0xd 0x0" #port 3 lane 1 + "0x08 0x00 0x3c 0x9 0x0" #port 3 lane 2 + "0x08 0x00 0x3c 0xd 0x0" #port 3 lane 3 + "0x08 0x00 0x3c 0x9 0x0" #port 4 lane 0 + "0x08 0x00 0x3c 0x9 0x0" #port 4 lane 1 + "0x08 0x00 0x3c 0x9 0x0" #port 4 lane 2 + "0x08 0x00 0x3c 0xd 0x0" #port 4 lane 3 + "0x08 0x00 0x3c 0x9 0x0" #port 5 lane 0 + "0x08 0x00 0x3c 0xf 0x0" #port 5 lane 1 + "0x08 0x00 0x3c 0x9 0x0" #port 5 lane 2 + "0x08 0x00 0x3c 0x9 0x0" #port 5 lane 3 + "0x08 0x00 0x3c 0x9 0x0" #port 6 lane 0 + "0x08 0x00 0x3c 0x9 0x0" #port 6 lane 1 + "0x08 0x00 0x3c 0x9 0x0" #port 6 lane 2 + "0x08 0x00 0x3c 0xe 0x0" #port 6 lane 3 + "0x08 0x00 0x3c 0x9 0x0" #port 7 lane 0 + "0x08 0x00 0x3c 0xa 0x0" #port 7 lane 1 + "0x08 0x00 0x3c 0x9 0x0" #port 7 lane 2 + "0x08 0x00 0x3c 0xe 0x0" #port 7 lane 3 + "0x08 0x04 0x3c 0xf 0x0" #port 8 lane 0 + "0x08 0x00 0x3c 0xf 0x0" #port 8 lane 1 + "0x08 0x04 0x3c 0xf 0x0" #port 8 lane 2 + "0x08 0x00 0x3c 0xf 0x0" #port 8 lane 3 + "0x08 0x04 0x3c 0xf 0x0" #port 9 lane 0 + "0x08 0x04 0x3c 0xf 0x0" #port 9 lane 1 + "0x08 0x04 0x3c 0xf 0x0" #port 9 lane 2 + "0x08 0x04 0x3c 0xf 0x0" #port 9 lane 3 + "0x08 0x04 0x3c 0xf 0x0" #port 10 lane 0 + "0x10 0x08 0x3c 0xf 0x0" #port 10 lane 1 + "0x08 0x04 0x3c 0xf 0x0" #port 10 lane 2 + "0x08 0x04 0x3c 0xf 0x0" #port 10 lane 3 + "0x08 0x08 0x3c 0xf 0x0" #port 11 lane 0 + "0x08 0x04 0x3c 0xf 0x0" #port 11 lane 1 + "0x08 0x04 0x3c 0xf 0x0" #port 11 lane 2 + "0x08 0x04 0x3c 0xf 0x0" #port 11 lane 3 + "0x08 0x0c 0x3c 0xf 0x0" #port 12 lane 0 + "0x08 0x08 0x3c 0xf 0x0" #port 12 lane 1 + "0x08 0x0c 0x3c 0xf 0x0" #port 12 lane 2 + "0x08 0x08 0x3c 0xf 0x0" #port 12 lane 3 + "0x08 0x08 0x3c 0xf 0x0" #port 13 lane 0 + "0x08 0x0c 0x3c 0xf 0x0" #port 13 lane 1 + "0x08 0x08 0x3c 0xf 0x0" #port 13 lane 2 + "0x08 0x0c 0x3c 0xf 0x0" #port 13 lane 3 + "0x10 0x10 0x3c 0xf 0x0" #port 14 lane 0 + "0x08 0x0c 0x3c 0xf 0x0" #port 14 lane 1 + "0x08 0x0c 0x3c 0xf 0x0" #port 14 lane 2 + "0x08 0x0c 0x3c 0xf 0x0" #port 14 lane 3 + "0x08 0x14 0x3c 0xf 0x0" #port 15 lane 0 + "0x08 0x10 0x3c 0xf 0x0" #port 15 lane 1 + "0x08 0x10 0x3c 0xf 0x0" #port 15 lane 2 + "0x08 0x10 0x3c 0xf 0x0" #port 15 lane 3 +) + +#get field value in si value array for xe port +function get_xe_si { + local port=$1 + local field=$2 + local type=$3 + local index=$port + if [ "$type" == "${AOC_TYPE}" ]; then + SI_VAL=$(echo "${xe_aoc_si_value[$index]}" | awk '{print $'$field'}') + else + SI_VAL=$(echo "${xe_dac_si_value[$index]}" | awk '{print $'$field'}') + fi +} + +#get field value in si value array for ce port +function get_ce_si { + local port=$1 + local lane=$2 + local field=$3 + local type=$4 + index=$(( (${port}-1)*4+${lane} )) + if [ "$type" == "${AOC_TYPE}" ]; then + SI_VAL=$(echo "${ce_aoc_si_value[$index]}" | awk '{print $'$field'}') + else + SI_VAL=$(echo "${ce_dac_si_value[$index]}" | awk '{print $'$field'}') + fi +} + +# set si value for xe port +function _qsfp_xe_si_set { + # convert PORT to xe port index + local xe_port=$PORT + # generate command for SI PRE value + get_xe_si $xe_port $SI_PRE_IDX $TYPE + local pre_cmd="phy xe${xe_port} CL93N72_UT_CTL2r CL93N72_TXFIR_PRE=${SI_VAL}" + # generate command for SI POST value + get_xe_si $xe_port $SI_POST_IDX $TYPE + local post_cmd="phy xe${xe_port} CL93N72_UT_CTL2r CL93N72_TXFIR_POST=${SI_VAL}" + # generate command for SI MAIN value + get_xe_si $xe_port $SI_MAIN_IDX $TYPE + local main_cmd="phy xe${xe_port} CL93N72_UT_CTL3r CL93N72_TXFIR_MAIN=${SI_VAL}" + # generate command for SI AMP CONTROL value + get_xe_si $xe_port $SI_AMP_IDX $TYPE + local amp_val=$SI_VAL + get_xe_si $xe_port $SI_DRI_IDX $TYPE + local dri_val=$SI_VAL + local amp_cmd="phy xe${xe_port} AMS_TX_CTL2r AMS_TX_AMP_CTL=${amp_val} AMS_TX_DRIVERMODE=${dri_val}" + # apply bcmcmd + bcmcmd "${pre_cmd};${post_cmd};${main_cmd};${amp_cmd}" +} + +# set aoc si value for ce port +function _qsfp_ce_si_set { + # convert PORT to ce port index + local ce_port=$(( $PORT - 48 )) + for lane in {0..3}; + do + # generate command for SI PRE value + get_ce_si $ce_port $lane $SI_PRE_IDX $TYPE + local pre_cmd="phy ce${ce_port} CL93N72_UT_CTL2r.${lane} CL93N72_TXFIR_PRE=${SI_VAL}" + # generate command for SI POST value + get_ce_si $ce_port $lane $SI_POST_IDX $TYPE + local post_cmd="phy ce${ce_port} CL93N72_UT_CTL2r.${lane} CL93N72_TXFIR_POST=${SI_VAL}" + # generate command for SI MAIN value + get_ce_si $ce_port $lane $SI_MAIN_IDX $TYPE + local main_cmd="phy ce${ce_port} CL93N72_UT_CTL3r.${lane} CL93N72_TXFIR_MAIN=${SI_VAL}" + # generate command for SI AMP CONTROL value + get_ce_si $ce_port $lane $SI_AMP_IDX $TYPE + local amp_val=$SI_VAL + get_ce_si $ce_port $lane $SI_AMP_IDX $TYPE + local dri_val=$SI_VAL + local amp_cmd="phy ce${ce_port} AMS_TX_CTL2r.${lane} AMS_TX_AMP_CTL=${amp_val} AMS_TX_DRIVERMODE=${dri_val}" + # apply bcmcmd + bcmcmd "${pre_cmd};${post_cmd};${main_cmd};${amp_cmd}" + done +} + +#QSFP SI value set +function _qsfp_si_set { + if [[ $PORT -le 47 && $PORT -ge 0 ]]; then + # xe port + _qsfp_xe_si_set + else + # ce port + _qsfp_ce_si_set + fi +} + +function _util_input_check { + # input parameter validation + if [[ $1 -lt $2 || $1 -gt $3 ]]; then + echo "Please input number $2~$3" + exit + fi +} + +# Help usage function +function _help { + echo "=========================================================" + echo "# Description: Help Function" + echo "=========================================================" + echo "----------------------------------------------------" + echo "EX : ${0} help" + echo " : ${0} ${AOC_TYPE} [${MIN_PORT}-${MAX_PORT}]" + echo " : ${0} ${DAC_TYPE} [${MIN_PORT}-${MAX_PORT}]" + echo "----------------------------------------------------" +} + +#Main Function +function _main { + + # TODO: remove after SI value ready + #exit ${TRUE} + + if [ -z $PORT ]; then + _help + exit ${FALSE} + fi + + if [ "${TYPE}" == "help" ]; then + _help + elif [ "${TYPE}" == "${AOC_TYPE}" ] || [ "${TYPE}" == "${DAC_TYPE}" ]; then + _util_input_check "$PORT" "$MIN_PORT" "$MAX_PORT" + _qsfp_si_set + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi +} + +_main diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/s8900_64xc_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/s8900_64xc_monitor.sh new file mode 100755 index 000000000000..8bfb22328003 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/s8900_64xc_monitor.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# Copyright (C) 2016 Ingrasys, 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 3 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, see . + +INTERVAL=5 +I2C_UTILS="/usr/sbin/i2c_utils.sh" + + +# LED status monitor +function _led_monitor { + ${I2C_UTILS} i2c_led_fan_status_set >/dev/null + ${I2C_UTILS} i2c_led_psu_status_set >/dev/null + ${I2C_UTILS} i2c_led_fan_tray_status_set >/dev/null +} + +# main function +function _main { + while true + do + _led_monitor + # Sleep while still handling signals + sleep $INTERVAL & + wait $! + done +} + +_main diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9100/README.md b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/README.md new file mode 100644 index 000000000000..78f828e25310 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/README.md @@ -0,0 +1,185 @@ +# Ingrasys S9100-32X Platform Driver for SONiC + +Copyright (C) 2016 Ingrasys, 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 3 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, see . + + +## Licensing terms + +The Licensing terms of the files within this project is split 2 parts. +The Linux kernel is released under the GNU General Public License version 2. +All other code is released under the GNU General Public License version 3. +Please see the LICENSE file for copies of both licenses. + +## Contents of this package + + - service/ + > Service config files for platform initialization and monitoring + - utils/ + > Scripts useful during platform bringup and sysfs function + - conf/ + > Platform configure files. + +## Kernel modules and drivers + +The driver for interacting with Ingrasys S9100-32X is contained in the I2C +kernel module and initialization script. The initialization script loads +the modules in the correct order. It has been built and tested against +the Linux 3.16 kernel. + +The initialization script will modprobe the needed modules, navigate to the +module's device directory in sysfs, and write configuration data to +the kernel module. + +### IGB + +This is OOB Ports on front panel for management plane. + +The IGB module must be loaded first on Ingrasys S9100-32X platform. + +### I2C i801 + +The I2C i801 on Ingrasys S9100-32X can be found in +`/sys/bus/i2c/devices/i2c-0/` + +This is I2C bus for Clock Gen, DIMM channel and digital potentiometers. + +The i801 module must be loaded second on Ingrasys S9100-32X. + +### I2C iSMT + +The I2C iSMT module on S9100-32X can be found in +`/sys/bus/i2c/devices/i2c-1/` + +This is I2C bus for CPLD, HWM, power controller and I2C Switches. + +The i801 module must be loaded third on Ingrasys S9100-32X. + +### I2C PCA9548 +The PCA9548 module on S9100-32X can be found in +`/sys/bus/i2c/devices/i2c-2/` , `/sys/bus/i2c/devices/i2c-3/`, +`/sys/bus/i2c/devices/i2c-4/`, `/sys/bus/i2c/devices/i2c-5/`, +`/sys/bus/i2c/devices/i2c-6/`, `/sys/bus/i2c/devices/i2c-7/`, +`/sys/bus/i2c/devices/i2c-8/`, `/sys/bus/i2c/devices/i2c-9/`. + +The pca9548 module for zQSFP module get/set functions, PSU information, +fan status and EEPROM. + +## Hardware components + +The hardware components are initialized in the init script on S9100-32X. +The following describes manual initialization as well as interaction. +The examples below are just for Ingrasys S9100-32X platform. + +### Hardware initialization + +When the sonic-platform-ingrasys-s9100 package is installed on the S9100-32X, +it is automatically initialized. If you want to manual initialization, the +utility command usage as follows: +``` + i2c_utils.sh i2c_init +``` + +### EEPROM + +The EEPROM is including the board SKU, model name, vendor name, serial number, +and other information can be accessed with the specific eeprom kernel module. +After using `modprobe eeprom_mb` to detect the eeprom, it will show up in sysfs. + +The hexdump utility can be used to decode the raw output of the EEPROM. +For example, +``` + bash# echo "mb_eeprom 0x54" > /sys/bus/i2c/devices/i2c-9/new_device + bash# cat /sys/bus/i2c/drivers/mb_eeprom/9-0054/eeprom | hexdump -C +``` + +### Front panel LEDs + +LEDs can be setup on/off by using i2c utility `/usr/sbin/i2c_utils.sh`. +Utility function command usage as follows: + +``` +Status LED: + i2c_utils.sh i2c_sys_led green|amber on|off + +Fan status LED: + i2c_utils.sh i2c_fan_led green|amber on|off + +PSU1 status LED: + i2c_utils.sh i2c_psu1_led green|amber on|off + +PSU2 status LED: + i2c_utils.sh i2c_psu2_led green|amber on|off + +``` +QSFP Module Port LEDs control by ASIC library. + + +### Fan speed + +Fan speed are controlled by the w83795 kernel module. +It can be found in `/sys/class/hwmon/hwmon1/device/`. +If they were compiled as modules, you will need to modprobe w83795 for +their sysfs entries to show up. Each fan has an `fan_input` file +for reading the fan speed. And `pwm1` setting fan1 to fan4, +`pwm2` setting fan5 to fan8. + +There is docker-platform-monitor container installed fancontrol package that can +automatic control platform fan speed. + + +### Temperature sensors + +Temperature sensors are controlled by the w83795 kernel +module. It can be found in `/sys/class/hwmon/hwmon1/device/`. +If they were compiled as modules, then you will need to modprobe w83795 for +their sysfs entries to show up. +`temp1_input` is front MAC temperature sensor. `temp2_input` is rear MAC +temperature sensor. + +There is docker-platform-monitor container installed lm-sensors package that can +monitor platform temperature. And `sensors` command can show each +temperature sensors status. + +### Power supplies + +Power supplies status and its EEPROM info can be used i2c utility +`/usr/sbin/i2c_utils.sh` to get. +The usage as follows: +``` +PSU EEPROM: + i2c_utils.sh i2c_psu_eeprom_get + hexdump -C psu0.rom + hexdump -C psu1.rom + +PSU Status: + i2c_utils.sh i2c_psu_status +``` + +### QSFPs +QSFP modules are managed by the pca9548 kernel driver. +The i2c utility `/usr/sbin/i2c_utils.sh` can be used to get status and +module EEPROM informations. +The usage as follows: +``` +QSFP EEPROM: + i2c_utils.sh i2c_qsfp_eeprom_get [1-32] + +QSFP Insert Event: + i2c_utils.sh i2c_qsfp_eeprom_get [1-32] + 0 => not insert + 1 => inserted +``` + diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9100/modules/Makefile b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/modules/Makefile new file mode 100755 index 000000000000..0247bd586f63 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/modules/Makefile @@ -0,0 +1,2 @@ +obj-m := eeprom_mb.o +obj-m+= i2c_cpld.o \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9100/modules/eeprom_mb.c b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/modules/eeprom_mb.c new file mode 100755 index 000000000000..01ce44ad3fee --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/modules/eeprom_mb.c @@ -0,0 +1,212 @@ +/* + * Copyright (C) 1998, 1999 Frodo Looijaard and + * Philip Edelbrock + * Copyright (C) 2003 Greg Kroah-Hartman + * Copyright (C) 2003 IBM Corp. + * Copyright (C) 2004 Jean Delvare + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Addresses to scan */ +static const unsigned short normal_i2c[] = { 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, I2C_CLIENT_END }; + + +/* Size of EEPROM in bytes */ +#define EEPROM_SIZE 256 + +#define SLICE_BITS (6) +#define SLICE_SIZE (1 << SLICE_BITS) +#define SLICE_NUM (EEPROM_SIZE/SLICE_SIZE) + +/* Each client has this additional data */ +struct eeprom_data { + struct mutex update_lock; + u8 valid; /* bitfield, bit!=0 if slice is valid */ + unsigned long last_updated[SLICE_NUM]; /* In jiffies, 8 slices */ + u8 data[EEPROM_SIZE]; /* Register values */ +}; + + +static void mb_eeprom_update_client(struct i2c_client *client, u8 slice) +{ + struct eeprom_data *data = i2c_get_clientdata(client); + int i, j; + int ret; + int addr; + + mutex_lock(&data->update_lock); + + if (!(data->valid & (1 << slice)) || + time_after(jiffies, data->last_updated[slice] + 300 * HZ)) { + dev_dbg(&client->dev, "Starting eeprom update, slice %u\n", slice); + + addr = slice << SLICE_BITS; + + ret = i2c_smbus_write_byte_data(client, ((u8)addr >> 8) & 0xFF, (u8)addr & 0xFF); + /* select the eeprom address */ + if (ret < 0) { + dev_err(&client->dev, "address set failed\n"); + goto exit; + } + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BYTE)) { + goto exit; + } + + for (i = slice << SLICE_BITS; i < (slice + 1) << SLICE_BITS; i+= SLICE_SIZE) { + for (j = i; j < (i+SLICE_SIZE); j++) { + int res; + + res = i2c_smbus_read_byte(client); + if (res < 0) { + goto exit; + } + + data->data[j] = res & 0xFF; + } + } + + data->last_updated[slice] = jiffies; + data->valid |= (1 << slice); + } +exit: + mutex_unlock(&data->update_lock); +} + +static ssize_t mb_eeprom_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj)); + struct eeprom_data *data = i2c_get_clientdata(client); + u8 slice; + + if (off > EEPROM_SIZE) { + return 0; + } + if (off + count > EEPROM_SIZE) { + count = EEPROM_SIZE - off; + } + if (count == 0) { + return 0; + } + + /* Only refresh slices which contain requested bytes */ + for (slice = off >> SLICE_BITS; slice <= (off + count - 1) >> SLICE_BITS; slice++) { + mb_eeprom_update_client(client, slice); + } + + memcpy(buf, &data->data[off], count); + + return count; +} + +static struct bin_attribute mb_eeprom_attr = { + .attr = { + .name = "eeprom", + .mode = S_IRUGO, + }, + .size = EEPROM_SIZE, + .read = mb_eeprom_read, +}; + +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int mb_eeprom_detect(struct i2c_client *client, struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = client->adapter; + + /* EDID EEPROMs are often 24C00 EEPROMs, which answer to all + addresses 0x50-0x57, but we only care about 0x50. So decline + attaching to addresses >= 0x51 on DDC buses */ + if (!(adapter->class & I2C_CLASS_SPD) && client->addr >= 0x51) { + return -ENODEV; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE) + && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { + return -ENODEV; + } + + strlcpy(info->type, "eeprom", I2C_NAME_SIZE); + + return 0; +} + +static int mb_eeprom_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct eeprom_data *data; + int err; + + if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) { + err = -ENOMEM; + goto exit; + } + + memset(data->data, 0xff, EEPROM_SIZE); + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + /* create the sysfs eeprom file */ + err = sysfs_create_bin_file(&client->dev.kobj, &mb_eeprom_attr); + if (err) { + goto exit_kfree; + } + + return 0; + +exit_kfree: + kfree(data); +exit: + return err; +} + +static int mb_eeprom_remove(struct i2c_client *client) +{ + sysfs_remove_bin_file(&client->dev.kobj, &mb_eeprom_attr); + kfree(i2c_get_clientdata(client)); + + return 0; +} + +static const struct i2c_device_id mb_eeprom_id[] = { + { "mb_eeprom", 0 }, + { } +}; + +static struct i2c_driver mb_eeprom_driver = { + .driver = { + .name = "mb_eeprom", + }, + .probe = mb_eeprom_probe, + .remove = mb_eeprom_remove, + .id_table = mb_eeprom_id, + + .class = I2C_CLASS_DDC | I2C_CLASS_SPD, + .detect = mb_eeprom_detect, + .address_list = normal_i2c, +}; + +module_i2c_driver(mb_eeprom_driver); + +MODULE_AUTHOR("Wade "); +MODULE_DESCRIPTION("Ingrasys S9100 Mother Borad EEPROM driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9100/modules/i2c_cpld.c b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/modules/i2c_cpld.c new file mode 100755 index 000000000000..626c63177b50 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/modules/i2c_cpld.c @@ -0,0 +1,448 @@ +/* + * S9100-32X I2C CPLD driver + * + * Copyright (C) 2017 Ingrasys, Inc. + * Wade He + * + * 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, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "i2c_cpld.h" + +#ifdef DEBUG + #define DEBUG_PRINT(fmt, args...) \ + printk(KERN_INFO "%s[%d]: " fmt "\r\n", \ + __FUNCTION__, __LINE__, ##args) +#else + #define DEBUG_PRINT(fmt, args...) +#endif + +#define I2C_READ_BYTE_DATA(ret, lock, i2c_client, reg) \ +{ \ + mutex_lock(lock); \ + ret = i2c_smbus_read_byte_data(i2c_client, reg); \ + mutex_unlock(lock); \ +} +#define I2C_WRITE_BYTE_DATA(ret, lock, i2c_client, reg, val) \ +{ \ + mutex_lock(lock); \ + ret = i2c_smbus_write_byte_data(i2c_client, reg, val); \ + mutex_unlock(lock); \ +} + +/* CPLD sysfs attributes index */ +enum i2c_cpld_sysfs_attributes { + CPLD_ACCESS_REG, + CPLD_REGISTER_VAL, + CPLD_PORT_START, + CPLD_PORTS, + CPLD_VERSION, + CPLD_ID, + CPLD_BOARD_TYPE, + CPLD_EXT_BOARD_TYPE, + CPLD_PW_GOOD, + CPLD_PW_ABS, +}; + +/* CPLD sysfs attributes hook functions */ +static ssize_t read_access_register(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t write_access_register(struct device *dev, + struct device_attribute *da, const char *buf, size_t count); +static ssize_t read_register_value(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t write_register_value(struct device *dev, + struct device_attribute *da, const char *buf, size_t count); +static ssize_t read_cpld_version(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_board_type(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_ext_board_type(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_pw_good(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_pw_abs(struct device *dev, + struct device_attribute *da, char *buf); + +static LIST_HEAD(cpld_client_list); /* client list for cpld */ +static struct mutex list_lock; /* mutex for client list */ + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; + +struct cpld_data { + int index; /* CPLD index */ + struct mutex access_lock; /* mutex for cpld access */ + u8 access_reg; /* register to access */ +}; + +/* CPLD device id and data */ +static const struct i2c_device_id i2c_cpld_id[] = { + { "i2c_cpld", i2c_cpld }, + {} +}; + +/* Addresses scanned for i2c_cpld */ +static const unsigned short cpld_i2c_addr[] = { 0x33, I2C_CLIENT_END }; +/* platform sysfs object */ +extern struct kobject *s9230_64x_kobj; + + +/* define all support register access of cpld in attribute */ +static SENSOR_DEVICE_ATTR(cpld_access_register, S_IWUSR | S_IRUGO, + read_access_register, write_access_register, CPLD_ACCESS_REG); +static SENSOR_DEVICE_ATTR(cpld_register_value, S_IWUSR | S_IRUGO, + read_register_value, write_register_value, CPLD_REGISTER_VAL); +static SENSOR_DEVICE_ATTR(cpld_version, S_IRUGO, + read_cpld_version, NULL, CPLD_VERSION); +static SENSOR_DEVICE_ATTR(cpld_board_type, S_IRUGO, + read_board_type, NULL, CPLD_BOARD_TYPE); +static SENSOR_DEVICE_ATTR(cpld_ext_board_type, S_IRUGO, + read_ext_board_type, NULL, CPLD_EXT_BOARD_TYPE); +static SENSOR_DEVICE_ATTR(cpld_pw_good, S_IRUGO, + read_pw_good, NULL, CPLD_PW_GOOD); +static SENSOR_DEVICE_ATTR(cpld_pw_abs, S_IRUGO, + read_pw_abs, NULL, CPLD_PW_ABS); + + +/* define support attributes of cpldx , total 5 */ +/* cpld 1 */ +static struct attribute *i2c_cpld_attributes[] = { + &sensor_dev_attr_cpld_access_register.dev_attr.attr, + &sensor_dev_attr_cpld_register_value.dev_attr.attr, + &sensor_dev_attr_cpld_version.dev_attr.attr, + &sensor_dev_attr_cpld_board_type.dev_attr.attr, + &sensor_dev_attr_cpld_ext_board_type.dev_attr.attr, + &sensor_dev_attr_cpld_pw_good.dev_attr.attr, + &sensor_dev_attr_cpld_pw_abs.dev_attr.attr, + NULL +}; + +/* cpld 1 attributes group */ +static const struct attribute_group i2c_cpld_group = { + .attrs = i2c_cpld_attributes, +}; + +/* read access register from cpld data */ +static ssize_t read_access_register(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg = data->access_reg; + + return sprintf(buf, "0x%x\n", reg); +} + +/* write access register to cpld data */ +static ssize_t write_access_register(struct device *dev, + struct device_attribute *da, + const char *buf, + size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + + if (kstrtou8(buf, 0, ®) < 0) + return -EINVAL; + + data->access_reg = reg; + return count; +} + +/* read the value of access register in cpld data */ +static ssize_t read_register_value(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg = data->access_reg; + int reg_val; + + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + + if (reg_val < 0) + return -1; + + return sprintf(buf, "0x%x\n", reg_val); +} + +/* wrtie the value to access register in cpld data */ +static ssize_t write_register_value(struct device *dev, + struct device_attribute *da, + const char *buf, + size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + int ret = -EIO; + u8 reg = data->access_reg; + u8 reg_val; + + if (kstrtou8(buf, 0, ®_val) < 0) + return -EINVAL; + + I2C_WRITE_BYTE_DATA(ret, &data->access_lock, client, reg, reg_val); + + return count; +} + +/* get cpdl version register value */ +static ssize_t read_cpld_version(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_VERSION) { + reg = CPLD_VERSION_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* get board type register value */ +static ssize_t read_board_type(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_BOARD_TYPE) { + reg = CPLD_BOARD_TYPE_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* get extend board type register value */ +static ssize_t read_ext_board_type(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_EXT_BOARD_TYPE) { + reg = CPLD_EXT_BOARD_TYPE_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* get extend board type register value */ +static ssize_t read_pw_good(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_PW_GOOD) { + reg = CPLD_PW_GOOD_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* get extend board type register value */ +static ssize_t read_pw_abs(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_PW_ABS) { + reg = CPLD_PW_ABS_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* add valid cpld client to list */ +static void i2c_cpld_add_client(struct i2c_client *client) +{ + struct cpld_client_node *node = NULL; + + node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); + if (!node) { + dev_info(&client->dev, + "Can't allocate cpld_client_node for index %d\n", + client->addr); + return; + } + + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &cpld_client_list); + mutex_unlock(&list_lock); +} + +/* remove exist cpld client in list */ +static void i2c_cpld_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + list_for_each(list_node, &cpld_client_list) { + cpld_node = list_entry(list_node, + struct cpld_client_node, list); + + if (cpld_node->client == client) { + found = 1; + break; + } + } + + if (found) { + list_del(list_node); + kfree(cpld_node); + } + mutex_unlock(&list_lock); +} + +/* cpld drvier probe */ +static int i2c_cpld_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int status; + struct cpld_data *data = NULL; + + data = kzalloc(sizeof(struct cpld_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + /* init cpld data for client */ + i2c_set_clientdata(client, data); + mutex_init(&data->access_lock); + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_info(&client->dev, + "i2c_check_functionality failed (0x%x)\n", + client->addr); + status = -EIO; + goto exit; + } + + + status = sysfs_create_group(&client->dev.kobj,&i2c_cpld_group); + + if (status) + goto exit; + + dev_info(&client->dev, "chip found\n"); + + /* add probe chip to client list */ + i2c_cpld_add_client(client); + + return 0; +exit: + sysfs_remove_group(&client->dev.kobj, &i2c_cpld_group); + return status; +} + +/* cpld drvier remove */ +static int i2c_cpld_remove(struct i2c_client *client) +{ + + sysfs_remove_group(&client->dev.kobj, &i2c_cpld_group); + + i2c_cpld_remove_client(client); + return 0; +} + +MODULE_DEVICE_TABLE(i2c, i2c_cpld_id); + +static struct i2c_driver i2c_cpld_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "i2c_cpld", + }, + .probe = i2c_cpld_probe, + .remove = i2c_cpld_remove, + .id_table = i2c_cpld_id, + .address_list = cpld_i2c_addr, +}; + +static int __init i2c_cpld_init(void) +{ + mutex_init(&list_lock); + return i2c_add_driver(&i2c_cpld_driver); +} + +static void __exit i2c_cpld_exit(void) +{ + i2c_del_driver(&i2c_cpld_driver); +} + +MODULE_AUTHOR("Wade He "); +MODULE_DESCRIPTION("Ingrasys S9100-32X Platform i2c cpld driver"); +MODULE_LICENSE("GPL"); + +module_init(i2c_cpld_init); +module_exit(i2c_cpld_exit); + + + diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9100/modules/i2c_cpld.h b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/modules/i2c_cpld.h new file mode 100755 index 000000000000..e103b05c717a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/modules/i2c_cpld.h @@ -0,0 +1,197 @@ +/* + * + * S9100-32X I2C CPLD driver header file + * + * Copyright (C) 2017 Ingrasys, Inc. + * Wade He + * + * 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, see . + */ + +#ifndef I2C_CPLD_H +#define I2C_CPLD_H + +// remove debug before release +#define DEBUG + +/* CPLD device index value */ +enum cpld_id { + i2c_cpld +}; + +/* port number on CPLD */ +#define CPLD_1_PORT_NUM 12 +#define CPLD_2_PORT_NUM 13 + +/* QSFP port number */ +#define QSFP_MAX_PORT_NUM 64 +#define QSFP_MIN_PORT_NUM 1 + +/* SFP+ port number */ +#define SFP_MAX_PORT_NUM 2 +#define SFP_MIN_PORT_NUM 1 + + +/* CPLD registers */ +#define CPLD_BOARD_TYPE_REG 0x0 +#define CPLD_EXT_BOARD_TYPE_REG 0x7 +#define CPLD_VERSION_REG 0x1 +#define CPLD_PW_GOOD_REG 0x2 +#define CPLD_PW_ABS_REG 0x3 + + +/* bit definition for register value */ + +enum CPLD_RESET_CONTROL_BITS { + CPLD_RESET_CONTROL_SWRST_BIT, + CPLD_RESET_CONTROL_CP2104RST_BIT, + CPLD_RESET_CONTROL_82P33814RST_BIT, + CPLD_RESET_CONTROL_BMCRST_BIT, +}; + +/* bit field structure for register value */ +struct cpld_reg_board_type_t { + u8 build_rev:2; + u8 hw_rev:2; + u8 board_id:4; +}; + +struct cpld_reg_version_t { + u8 revision:6; + u8 release:1; + u8 reserve:1; +}; + +struct cpld_reg_pw_good_t { + u8 reserve1:3; + u8 psu1:1; + u8 psu2:1; + u8 reserve2:3; +}; + +struct cpld_reg_pw_abs_t { + u8 psu1:1; + u8 psu2:1; + u8 reserve:6; +}; + +/* common manipulation */ +#define INVALID(i, min, max) ((i < min) || (i > max) ? 1u : 0u) +#define READ_BIT(val, bit) ((0u == (val & (1<bf_name) +#define READ_BF_1(bf_struct, val, bf_name, bf_value) \ + bf_struct bf; \ + bf.data = val; \ + bf_value = bf.bf_name +#define BOARD_TYPE_BUILD_REV_GET(val, res) \ + READ_BF(cpld_reg_board_type_t, val, build_rev, res) +#define BOARD_TYPE_HW_REV_GET(val, res) \ + READ_BF(cpld_reg_board_type_t, val, hw_rev, res) +#define BOARD_TYPE_BOARD_ID_GET(val, res) \ + READ_BF(cpld_reg_board_type_t, val, board_id, res) +#define CPLD_VERSION_REV_GET(val, res) \ + READ_BF(cpld_reg_version_t, val, revision, res) +#define CPLD_VERSION_REL_GET(val, res) \ + READ_BF(cpld_reg_version_t, val, release, res) +#define CPLD_PSU1_PW_GOOD_GET(val, res) \ + READ_BF(cpld_reg_pw_good_t, val, psu1, res) +#define CPLD_PSU2_PW_GOOD_GET(val, res) \ + READ_BF(cpld_reg_pw_good_t, val, psu2, res) +#define CPLD_PSU1_PW_ABS_GET(val, res) \ + READ_BF(cpld_reg_pw_abs_t, val, psu1, res) +#define CPLD_PSU2_PW_ABS_GET(val, res) \ + READ_BF(cpld_reg_pw_abs_t, val, psu2, res) +/* QSFP/SFP registers manipulation */ +#define QSFP_TO_CPLD_IDX(qsfp_port, cpld_index, cpld_port) \ +{ \ + if (QSFP_MIN_PORT_NUM <= qsfp_port && qsfp_port <= CPLD_1_PORT_NUM) { \ + cpld_index = cpld1; \ + cpld_port = qsfp_port - 1; \ + } else if (CPLD_1_PORT_NUM < qsfp_port \ + && qsfp_port <= QSFP_MAX_PORT_NUM) { \ + cpld_index = cpld2 + (qsfp_port - 1 - CPLD_1_PORT_NUM) \ + / CPLD_2_PORT_NUM; \ + cpld_port = (qsfp_port - 1 - CPLD_1_PORT_NUM) % \ + CPLD_2_PORT_NUM; \ + } else { \ + cpld_index = 0; \ + cpld_port = 0; \ + } \ +} +#define SFP_TO_CPLD_IDX(sfp_port, cpld_index) \ + (cpld_index = sfp_port - SFP_MIN_PORT_NUM) +#define QSFP_PORT_STATUS_REG(cpld_port) \ + (CPLD_QSFP_PORT_STATUS_BASE_REG + cpld_port) +#define QSFP_PORT_CONFIG_REG(cpld_port) \ + (CPLD_QSFP_PORT_CONFIG_BASE_REG + cpld_port) +#define QSFP_PORT_INT_BIT_GET(port_status_value) \ + READ_BIT(port_status_value, CPLD_QSFP_PORT_STATUS_INT_BIT) +#define QSFP_PORT_ABS_BIT_GET(port_status_value) \ + READ_BIT(port_status_value, CPLD_QSFP_PORT_STATUS_ABS_BIT) +#define QSFP_PORT_RESET_BIT_GET(port_config_value) \ + READ_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_RESET_BIT) +#define QSFP_PORT_LPMODE_BIT_GET(port_config_value) \ + READ_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_LPMODE_BIT) +#define QSFP_PORT_RESET_BIT_SET(port_config_value) \ + SET_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_RESET_BIT) +#define QSFP_PORT_RESET_BIT_CLEAR(port_config_value) \ + CLEAR_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_RESET_BIT) +#define QSFP_PORT_LPMODE_BIT_SET(port_config_value) \ + SET_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_LPMODE_BIT) +#define QSFP_PORT_LPMODE_BIT_CLEAR(port_config_value) \ + CLEAR_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_LPMODE_BIT) +#define SFP_PORT_PRESENT_BIT_GET(port_status_value) \ + READ_BIT(port_status_value, CPLD_SFP_PORT_STATUS_PRESENT_BIT) + + #define SFP_PORT_TXFAULT_BIT_GET(port_status_value) \ + READ_BIT(port_status_value, CPLD_SFP_PORT_STATUS_TXFAULT_BIT) + #define SFP_PORT_RXLOS_BIT_GET(port_status_value) \ + READ_BIT(port_status_value, CPLD_SFP_PORT_STATUS_RXLOS_BIT) + #define SFP_PORT_TXDIS_BIT_GET(port_status_value) \ + READ_BIT(port_status_value, CPLD_SFP_PORT_CONFIG_TXDIS_BIT) +#define SFP_PORT_RS_BIT_GET(port_config_value) \ + READ_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_RS_BIT) +#define SFP_PORT_TS_BIT_GET(port_config_value) \ + READ_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_TS_BIT) +#define SFP_PORT_TXDIS_BIT_SET(port_config_value) \ + SET_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_TXDIS_BIT) +#define SFP_PORT_TXDIS_BIT_CLEAR(port_config_value) \ + CLEAR_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_TXDIS_BIT) +#define SFP_PORT_RS_BIT_SET(port_config_value) \ + SET_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_RS_BIT) +#define SFP_PORT_RS_BIT_CLEAR(port_config_value) \ + CLEAR_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_RS_BIT) +#define SFP_PORT_TS_BIT_SET(port_config_value) \ + SET_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_TS_BIT) +#define SFP_PORT_TS_BIT_CLEAR(port_config_value) \ + CLEAR_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_TS_BIT) + +/* CPLD access functions */ +extern int i2c_cpld_get_qsfp_port_status_val(u8 port_num); +extern int i2c_cpld_get_qsfp_port_config_val(u8 port_num); +extern int i2c_cpld_set_qsfp_port_config_val(u8 port_num, u8 reg_val); +extern int i2c_cpld_get_sfp_port_status_val(u8 port_num); +extern int i2c_cpld_get_sfp_port_config_val(u8 port_num); +extern int i2c_cpld_set_sfp_port_config_val(u8 port_num, u8 reg_val); +extern u8 fp_port_to_phy_port(u8 fp_port); +#endif + diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9100/service/qsfp-monitor.service b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/service/qsfp-monitor.service new file mode 100644 index 000000000000..584d6fcae895 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/service/qsfp-monitor.service @@ -0,0 +1,15 @@ +[Unit] +Description= This QSFP Monitor service is to setup QSFP SI. +Requires=s9100-monitor.service +After=s9100-monitor.service + +[Service] +ExecStart=/usr/sbin/qsfp_monitor.sh +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9100/service/s9100-monitor.service b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/service/s9100-monitor.service new file mode 100644 index 000000000000..5e074782a852 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/service/s9100-monitor.service @@ -0,0 +1,19 @@ +[Unit] +Description= This Platform Monitor service is to initialize platform and monitor platform. +Before=platform-monitor.service +After=sysinit.target +Wants=fancontrol.service +Wants=qsfp-monitor.service +DefaultDependencies=no + +[Service] +ExecStartPre=/usr/sbin/i2c_utils.sh i2c_init +ExecStart=/usr/sbin/s9100_monitor.sh +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/i2c_utils.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/i2c_utils.sh new file mode 100755 index 000000000000..bdcd4f1d7f9e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/i2c_utils.sh @@ -0,0 +1,1518 @@ +#!/bin/bash + +# Copyright (C) 2016 Ingrasys, 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 3 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, see . + +VERSION="1.0.0" +TRUE=200 +FALSE=404 + +EXEC_FUNC=${1} +COLOR_LED=${2} +QSFP_PORT=${2} +QSFP_ACTION=${2} +MB_EEPROM_ACTION=${2} +ONOFF_LED=${3} +FAN_TRAY=${4} + +############################################################ +# Distributor ID: Debian +# Description: Debian GNU/Linux 8.6 (jessie) +# Release: 8.6 +# Codename: jessie +# Linux debian 3.16.0-4-amd64 #1 +# SMP Debian 3.16.36-1+deb8u1 (2016-09-03) x86_64 GNU/Linux +############################################################ + +# Color Definition +COLOR_TITLE="\e[1;32m" ### Green ### +COLOR_WARNING="\e[1;33m" ### Yellow ### +COLOR_ERROR="\e[1;31m" ### Red ### +COLOR_END="\e[0m" ### END ### + +NUM_IGB_DEVICE=0 +NUM_I801_DEVICE=0 +NUM_ISMT_DEVICE=$(( ${NUM_I801_DEVICE} + 1 )) +NUM_MUX1_CHAN0_DEVICE=$(( ${NUM_I801_DEVICE} + 2 )) +NUM_MUX1_CHAN1_DEVICE=$(( ${NUM_I801_DEVICE} + 3 )) +NUM_MUX1_CHAN2_DEVICE=$(( ${NUM_I801_DEVICE} + 4 )) +NUM_MUX1_CHAN3_DEVICE=$(( ${NUM_I801_DEVICE} + 5 )) +NUM_MUX1_CHAN4_DEVICE=$(( ${NUM_I801_DEVICE} + 6 )) +NUM_MUX1_CHAN5_DEVICE=$(( ${NUM_I801_DEVICE} + 7 )) +NUM_MUX1_CHAN6_DEVICE=$(( ${NUM_I801_DEVICE} + 8 )) +NUM_MUX1_CHAN7_DEVICE=$(( ${NUM_I801_DEVICE} + 9 )) +NUM_MUX3_CHAN0_DEVICE=$(( ${NUM_I801_DEVICE} + 10 )) +NUM_MUX4_CHAN0_DEVICE=$(( ${NUM_I801_DEVICE} + 18 )) +NUM_MUX5_CHAN0_DEVICE=$(( ${NUM_I801_DEVICE} + 26 )) +NUM_MUX6_CHAN0_DEVICE=$(( ${NUM_I801_DEVICE} + 34 )) + +PATH_SYS_I2C_DEVICES="/sys/bus/i2c/devices" +PATH_HWMON_ROOT_DEVICES="/sys/class/hwmon" +PATH_HWMON_W83795_DEVICE="${PATH_HWMON_ROOT_DEVICES}/hwmon1" +PATH_I801_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_I801_DEVICE}" +PATH_ISMT_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_ISMT_DEVICE}" +PATH_MUX_CHAN0_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN0_DEVICE}" +PATH_MUX_CHAN1_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN1_DEVICE}" +PATH_MUX_CHAN2_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN2_DEVICE}" +PATH_MUX_CHAN3_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN3_DEVICE}" +PATH_MUX_CHAN4_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN4_DEVICE}" +PATH_MUX_CHAN5_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN5_DEVICE}" +PATH_MUX_CHAN6_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN6_DEVICE}" +PATH_MUX_CHAN7_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN7_DEVICE}" + +#Power Supply Status +PSU_DC_ON=1 +PSU_DC_OFF=0 +PSU_EXIST=1 +PSU_NOT_EXIST=0 + +# Help usage function +function _help { + echo "=========================================================" + echo "# Description: Help Function" + echo "=========================================================" + echo "----------------------------------------------------" + echo "EX : ${0} help" + echo " : ${0} i2c_init" + echo " : ${0} i2c_deinit" + echo " : ${0} i2c_temp_init" + echo " : ${0} i2c_fan_init" + echo " : ${0} i2c_volmon_init" + echo " : ${0} i2c_io_exp_init" + echo " : ${0} i2c_gpio_init" + echo " : ${0} i2c_gpio_deinit" + echo " : ${0} i2c_led_test" + echo " : ${0} i2c_psu_eeprom_get" + echo " : ${0} i2c_mb_eeprom_get" + echo " : ${0} i2c_qsfp_eeprom_get [1-32]" + echo " : ${0} i2c_qsfp_eeprom_init new|delete" + echo " : ${0} i2c_mb_eeprom_init new|delete" + echo " : ${0} i2c_qsfp_status_get [1-32]" + echo " : ${0} i2c_qsfp_type_get [1-32]" + echo " : ${0} i2c_board_type_get" + echo " : ${0} i2c_psu_status" + echo " : ${0} i2c_led_psu_status_set" + echo " : ${0} i2c_led_fan_status_set" + echo " : ${0} i2c_led_fan_tray_status_set" + echo " : ${0} i2c_cpld_version" + echo " : ${0} i2c_front_temp" + echo " : ${0} i2c_rear_temp" + echo " : ${0} i2c_test_all" + echo " : ${0} i2c_sys_led green|amber on|off" + echo " : ${0} i2c_fan_led green|amber on|off" + echo " : ${0} i2c_psu1_led green|amber on|off" + echo " : ${0} i2c_psu2_led green|amber on|off" + echo " : ${0} i2c_fan_tray_led green|amber on|off [1-4]" + echo "----------------------------------------------------" +} + +#Pause function +function _pause { + read -p "$*" +} + +#Retry command function +function _retry { + local i + for i in {1..5}; + do + eval "${*}" && break || echo "retry"; sleep 1; + done +} + +#I2C Init +function _i2c_init { + echo "=========================================================" + echo "# Description: I2C Init" + echo "=========================================================" + + rmmod i2c_ismt + rmmod i2c_i801 + modprobe i2c_i801 + modprobe i2c_ismt + modprobe i2c_dev + modprobe i2c_mux_pca954x force_deselect_on_exit=1 + + if [ ! -e "${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN0_DEVICE}" ]; then + _retry "echo 'pca9548 0x70' > ${PATH_ISMT_DEVICE}/new_device" + else + echo "pca9548 0x70 already init." + fi + if [ ! -e "${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX3_CHAN0_DEVICE}" ]; then + _retry "echo 'pca9548 0x71' > ${PATH_MUX_CHAN0_DEVICE}/new_device" + else + echo "pca9548 0x71 already init." + fi + if [ ! -e "${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX4_CHAN0_DEVICE}" ]; then + _retry "echo 'pca9548 0x72' > ${PATH_MUX_CHAN1_DEVICE}/new_device" + else + echo "pca9548 0x72 already init." + fi + if [ ! -e "${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX5_CHAN0_DEVICE}" ]; then + _retry "echo 'pca9548 0x73' > ${PATH_MUX_CHAN2_DEVICE}/new_device" + else + echo "pca9548 0x73 already init." + fi + if [ ! -e "${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX6_CHAN0_DEVICE}" ]; then + _retry "echo 'pca9548 0x74' > ${PATH_MUX_CHAN3_DEVICE}/new_device" + else + echo "pca9548 0x74 already init." + fi + if [ ! -e "${PATH_SYS_I2C_DEVICES}/${NUM_MUX1_CHAN6_DEVICE}-0075" ]; then + _retry "echo 'pca9546 0x75' > ${PATH_MUX_CHAN6_DEVICE}/new_device" + else + echo "pca9548 0x75 already init." + fi + #Init CPLD LED_CLR Register (Front Port LED) + i2cset -y ${NUM_I801_DEVICE} 0x33 0x34 0x10 + + rmmod coretemp + rmmod jc42 + rmmod w83795 + _i2c_temp_init + _i2c_volmon_init + modprobe coretemp + modprobe w83795 + modprobe jc42 + modprobe eeprom + modprobe eeprom_mb + modprobe gpio-pca953x + _i2c_fan_init + _i2c_io_exp_init + _i2c_gpio_init + _i2c_cpld_init + _i2c_qsfp_eeprom_init "new" + _i2c_mb_eeprom_init "new" + _i2c_psu_eeprom_init + _i2c_led_psu_status_set + _i2c_led_fan_status_set + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_sys_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_sys_led + _config_rmem +} + +#I2C Deinit +function _i2c_deinit { + _i2c_gpio_deinit + for mod in i2c_cpld coretemp jc42 w83795 eeprom_mb gpio-pca953x i2c_mux_pca954x i2c_ismt i2c_i801; + do + [ "$(lsmod | grep "^$mod ")" != "" ] && rmmod $mod + done +} + +#Temperature sensor Init +function _i2c_temp_init { + echo -n "TEMP INIT..." + i2cset -y -r ${NUM_I801_DEVICE} 0x2F 0x00 0x80 + i2cset -y -r ${NUM_I801_DEVICE} 0x2F 0x05 0x7F + i2cset -y -r ${NUM_I801_DEVICE} 0x2F 0x04 0x0A + echo "Done" +} + +#FAN Init +function _i2c_fan_init { + echo -n "FAN INIT..." + if [ -e "${PATH_HWMON_W83795_DEVICE}" ]; then + echo 120 > ${PATH_HWMON_W83795_DEVICE}/device/pwm1 + echo 120 > ${PATH_HWMON_W83795_DEVICE}/device/pwm2 + echo "SUCCESS" + else + echo "FAIL" + fi + +} + +#VOLMON Init +function _i2c_volmon_init { + echo -n "VOLMON INIT..." + i2cset -y -r ${NUM_I801_DEVICE} 0x2F 0x00 0x80 + i2cset -y -r ${NUM_I801_DEVICE} 0x2F 0x02 0xFF + i2cset -y -r ${NUM_I801_DEVICE} 0x2F 0x03 0x50 + i2cset -y -r ${NUM_I801_DEVICE} 0x2F 0x04 0x0A + echo "Done" +} + +#IO Expander Init +function _i2c_io_exp_init { + echo "=========================================================" + echo "# Description: I2C IO Expender Init" + echo "=========================================================" + #SMBUS0 IO_EXPENDER + i2cset -y -r ${NUM_I801_DEVICE} 0x27 4 0x00 + i2cset -y -r ${NUM_I801_DEVICE} 0x27 5 0x00 + i2cset -y -r ${NUM_I801_DEVICE} 0x27 2 0x00 + i2cset -y -r ${NUM_I801_DEVICE} 0x27 3 0x00 + i2cset -y -r ${NUM_I801_DEVICE} 0x27 6 0xFF + i2cset -y -r ${NUM_I801_DEVICE} 0x27 7 0xFF + + #SMBUS1 + #ABS + i2cset -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x20 4 0x00 + i2cset -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x20 5 0x00 + i2cset -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x20 6 0xFF + i2cset -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x20 7 0xFF + + i2cset -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x21 4 0x00 + i2cset -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x21 5 0x00 + i2cset -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x21 6 0xFF + i2cset -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x21 7 0xFF + + #Transcevior INT + i2cset -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x22 4 0x00 + i2cset -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x22 5 0x00 + i2cset -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x22 6 0xFF + i2cset -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x22 7 0xFF + + i2cset -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x23 4 0x00 + i2cset -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x23 5 0x00 + i2cset -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x23 6 0xFF + i2cset -y -r ${NUM_MUX1_CHAN4_DEVICE} 0x23 7 0xFF + + echo "Init ZQSFP IO Expender" + echo "set ZQSFP LP_MODE = 0" + #set ZQSFP LP_MODE = 0 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x20 4 0x00 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x20 5 0x00 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x20 2 0x00 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x20 3 0x00 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x20 6 0x00 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x20 7 0x00 + + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x21 4 0x00 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x21 5 0x00 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x21 2 0x00 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x21 3 0x00 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x21 6 0x00 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x21 7 0x00 + + echo "set ZQSFP RST = 1" + #set ZQSFP RST = 1 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x22 4 0x00 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x22 5 0x00 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x22 2 0xFF + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x22 3 0xFF + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x22 6 0x00 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x22 7 0x00 + + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x23 4 0x00 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x23 5 0x00 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x23 2 0xFF + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x23 3 0xFF + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x23 6 0x00 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x23 7 0x00 + + echo "set ZQSFP mode" + #ZQSFP mode + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x24 4 0x00 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x24 5 0x00 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x24 2 0x00 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x24 3 0x00 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x24 6 0x00 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x24 7 0x00 + + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x25 4 0x00 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x25 5 0x00 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x25 2 0x00 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x25 3 0x00 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x25 6 0x00 + i2cset -y -r ${NUM_MUX1_CHAN5_DEVICE} 0x25 7 0x00 + + #ZQSFP/SFP+/E-Card General + i2cset -y -r ${NUM_MUX1_CHAN6_DEVICE} 0x20 4 0x00 + i2cset -y -r ${NUM_MUX1_CHAN6_DEVICE} 0x20 5 0x00 + i2cset -y -r ${NUM_MUX1_CHAN6_DEVICE} 0x20 6 0xFF + i2cset -y -r ${NUM_MUX1_CHAN6_DEVICE} 0x20 7 0xFF + + #LED board after PVT (S9100_IO_EXP_LED_ID) + echo "Init LED IO Expender" + i2cset -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 4 0x00 + i2cset -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 5 0x00 + i2cset -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 6 0x00 + i2cset -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 7 0x00 + + #PSU I/O (S9100_IO_EXP_PSU_ID) + echo "Init PSU IO Expender" + i2cset -y -r ${NUM_MUX1_CHAN6_DEVICE} 0x23 4 0x00 + i2cset -y -r ${NUM_MUX1_CHAN6_DEVICE} 0x23 5 0x00 + i2cset -y -r ${NUM_MUX1_CHAN6_DEVICE} 0x23 2 0x00 + i2cset -y -r ${NUM_MUX1_CHAN6_DEVICE} 0x23 3 0x00 + i2cset -y -r ${NUM_MUX1_CHAN6_DEVICE} 0x23 6 0xBB + i2cset -y -r ${NUM_MUX1_CHAN6_DEVICE} 0x23 7 0xFF + + #FAN I/O (S9100_IO_EXP_FAN_ID) + echo "Init FAN IO Expender" + i2cset -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x20 4 0x00 + i2cset -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x20 5 0x00 + i2cset -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x20 2 0x00 + i2cset -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x20 3 0x00 + i2cset -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x20 6 0xCC + i2cset -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x20 7 0xCC +} + +#GPIO Init +function _i2c_gpio_init { + #ABS Port 0-15 + echo "pca9535 0x20" > /sys/bus/i2c/devices/i2c-${NUM_MUX1_CHAN4_DEVICE}/new_device + echo 240 > /sys/class/gpio/export + echo 241 > /sys/class/gpio/export + echo 242 > /sys/class/gpio/export + echo 243 > /sys/class/gpio/export + echo 244 > /sys/class/gpio/export + echo 245 > /sys/class/gpio/export + echo 246 > /sys/class/gpio/export + echo 247 > /sys/class/gpio/export + echo 248 > /sys/class/gpio/export + echo 249 > /sys/class/gpio/export + echo 250 > /sys/class/gpio/export + echo 251 > /sys/class/gpio/export + echo 252 > /sys/class/gpio/export + echo 253 > /sys/class/gpio/export + echo 254 > /sys/class/gpio/export + echo 255 > /sys/class/gpio/export + echo 1 > /sys/class/gpio/gpio241/active_low #zQSFP00 + echo 1 > /sys/class/gpio/gpio240/active_low #zQSFP01 + echo 1 > /sys/class/gpio/gpio243/active_low #zQSFP02 + echo 1 > /sys/class/gpio/gpio242/active_low #zQSFP03 + echo 1 > /sys/class/gpio/gpio245/active_low #zQSFP04 + echo 1 > /sys/class/gpio/gpio244/active_low #zQSFP05 + echo 1 > /sys/class/gpio/gpio247/active_low #zQSFP06 + echo 1 > /sys/class/gpio/gpio246/active_low #zQSFP07 + echo 1 > /sys/class/gpio/gpio249/active_low #zQSFP08 + echo 1 > /sys/class/gpio/gpio248/active_low #zQSFP09 + echo 1 > /sys/class/gpio/gpio251/active_low #zQSFP10 + echo 1 > /sys/class/gpio/gpio250/active_low #zQSFP11 + echo 1 > /sys/class/gpio/gpio253/active_low #zQSFP12 + echo 1 > /sys/class/gpio/gpio252/active_low #zQSFP13 + echo 1 > /sys/class/gpio/gpio255/active_low #zQSFP14 + echo 1 > /sys/class/gpio/gpio254/active_low #zQSFP15 + + #ABS Port 16-31 + echo "pca9535 0x21" > /sys/bus/i2c/devices/i2c-${NUM_MUX1_CHAN4_DEVICE}/new_device + echo 224 > /sys/class/gpio/export + echo 225 > /sys/class/gpio/export + echo 226 > /sys/class/gpio/export + echo 227 > /sys/class/gpio/export + echo 228 > /sys/class/gpio/export + echo 229 > /sys/class/gpio/export + echo 230 > /sys/class/gpio/export + echo 231 > /sys/class/gpio/export + echo 232 > /sys/class/gpio/export + echo 233 > /sys/class/gpio/export + echo 234 > /sys/class/gpio/export + echo 235 > /sys/class/gpio/export + echo 236 > /sys/class/gpio/export + echo 237 > /sys/class/gpio/export + echo 238 > /sys/class/gpio/export + echo 239 > /sys/class/gpio/export + echo 1 > /sys/class/gpio/gpio225/active_low #zQSFP16 + echo 1 > /sys/class/gpio/gpio224/active_low #zQSFP17 + echo 1 > /sys/class/gpio/gpio227/active_low #zQSFP18 + echo 1 > /sys/class/gpio/gpio226/active_low #zQSFP19 + echo 1 > /sys/class/gpio/gpio229/active_low #zQSFP20 + echo 1 > /sys/class/gpio/gpio228/active_low #zQSFP21 + echo 1 > /sys/class/gpio/gpio231/active_low #zQSFP22 + echo 1 > /sys/class/gpio/gpio230/active_low #zQSFP23 + echo 1 > /sys/class/gpio/gpio233/active_low #zQSFP24 + echo 1 > /sys/class/gpio/gpio232/active_low #zQSFP25 + echo 1 > /sys/class/gpio/gpio235/active_low #zQSFP26 + echo 1 > /sys/class/gpio/gpio234/active_low #zQSFP27 + echo 1 > /sys/class/gpio/gpio237/active_low #zQSFP28 + echo 1 > /sys/class/gpio/gpio236/active_low #zQSFP29 + echo 1 > /sys/class/gpio/gpio239/active_low #zQSFP30 + echo 1 > /sys/class/gpio/gpio238/active_low #zQSFP31 + + #INT Port 0-15 + echo "pca9535 0x22" > /sys/bus/i2c/devices/i2c-${NUM_MUX1_CHAN4_DEVICE}/new_device + echo 208 > /sys/class/gpio/export + echo 209 > /sys/class/gpio/export + echo 210 > /sys/class/gpio/export + echo 211 > /sys/class/gpio/export + echo 212 > /sys/class/gpio/export + echo 213 > /sys/class/gpio/export + echo 214 > /sys/class/gpio/export + echo 215 > /sys/class/gpio/export + echo 216 > /sys/class/gpio/export + echo 217 > /sys/class/gpio/export + echo 218 > /sys/class/gpio/export + echo 219 > /sys/class/gpio/export + echo 220 > /sys/class/gpio/export + echo 221 > /sys/class/gpio/export + echo 222 > /sys/class/gpio/export + echo 223 > /sys/class/gpio/export + echo 1 > /sys/class/gpio/gpio208/active_low + echo 1 > /sys/class/gpio/gpio209/active_low + echo 1 > /sys/class/gpio/gpio210/active_low + echo 1 > /sys/class/gpio/gpio211/active_low + echo 1 > /sys/class/gpio/gpio212/active_low + echo 1 > /sys/class/gpio/gpio213/active_low + echo 1 > /sys/class/gpio/gpio214/active_low + echo 1 > /sys/class/gpio/gpio215/active_low + echo 1 > /sys/class/gpio/gpio216/active_low + echo 1 > /sys/class/gpio/gpio217/active_low + echo 1 > /sys/class/gpio/gpio218/active_low + echo 1 > /sys/class/gpio/gpio219/active_low + echo 1 > /sys/class/gpio/gpio220/active_low + echo 1 > /sys/class/gpio/gpio221/active_low + echo 1 > /sys/class/gpio/gpio222/active_low + echo 1 > /sys/class/gpio/gpio223/active_low + + #INT Port 16-31 + echo "pca9535 0x23" > /sys/bus/i2c/devices/i2c-${NUM_MUX1_CHAN4_DEVICE}/new_device + echo 192 > /sys/class/gpio/export + echo 193 > /sys/class/gpio/export + echo 194 > /sys/class/gpio/export + echo 195 > /sys/class/gpio/export + echo 196 > /sys/class/gpio/export + echo 197 > /sys/class/gpio/export + echo 198 > /sys/class/gpio/export + echo 199 > /sys/class/gpio/export + echo 200 > /sys/class/gpio/export + echo 201 > /sys/class/gpio/export + echo 202 > /sys/class/gpio/export + echo 203 > /sys/class/gpio/export + echo 204 > /sys/class/gpio/export + echo 205 > /sys/class/gpio/export + echo 206 > /sys/class/gpio/export + echo 207 > /sys/class/gpio/export + echo 1 > /sys/class/gpio/gpio192/active_low + echo 1 > /sys/class/gpio/gpio193/active_low + echo 1 > /sys/class/gpio/gpio194/active_low + echo 1 > /sys/class/gpio/gpio195/active_low + echo 1 > /sys/class/gpio/gpio196/active_low + echo 1 > /sys/class/gpio/gpio197/active_low + echo 1 > /sys/class/gpio/gpio198/active_low + echo 1 > /sys/class/gpio/gpio199/active_low + echo 1 > /sys/class/gpio/gpio200/active_low + echo 1 > /sys/class/gpio/gpio201/active_low + echo 1 > /sys/class/gpio/gpio202/active_low + echo 1 > /sys/class/gpio/gpio203/active_low + echo 1 > /sys/class/gpio/gpio204/active_low + echo 1 > /sys/class/gpio/gpio205/active_low + echo 1 > /sys/class/gpio/gpio206/active_low + echo 1 > /sys/class/gpio/gpio207/active_low + + #LP Mode Port 0-15 + echo "pca9535 0x20" > /sys/bus/i2c/devices/i2c-${NUM_MUX1_CHAN5_DEVICE}/new_device + echo 176 > /sys/class/gpio/export + echo 177 > /sys/class/gpio/export + echo 178 > /sys/class/gpio/export + echo 179 > /sys/class/gpio/export + echo 180 > /sys/class/gpio/export + echo 181 > /sys/class/gpio/export + echo 182 > /sys/class/gpio/export + echo 183 > /sys/class/gpio/export + echo 184 > /sys/class/gpio/export + echo 185 > /sys/class/gpio/export + echo 186 > /sys/class/gpio/export + echo 187 > /sys/class/gpio/export + echo 188 > /sys/class/gpio/export + echo 189 > /sys/class/gpio/export + echo 190 > /sys/class/gpio/export + echo 191 > /sys/class/gpio/export + echo out > /sys/class/gpio/gpio176/direction + echo out > /sys/class/gpio/gpio177/direction + echo out > /sys/class/gpio/gpio178/direction + echo out > /sys/class/gpio/gpio179/direction + echo out > /sys/class/gpio/gpio180/direction + echo out > /sys/class/gpio/gpio181/direction + echo out > /sys/class/gpio/gpio182/direction + echo out > /sys/class/gpio/gpio183/direction + echo out > /sys/class/gpio/gpio184/direction + echo out > /sys/class/gpio/gpio185/direction + echo out > /sys/class/gpio/gpio186/direction + echo out > /sys/class/gpio/gpio187/direction + echo out > /sys/class/gpio/gpio188/direction + echo out > /sys/class/gpio/gpio189/direction + echo out > /sys/class/gpio/gpio190/direction + echo out > /sys/class/gpio/gpio191/direction + + #LP Mode Port 16-31 + echo "pca9535 0x21" > /sys/bus/i2c/devices/i2c-${NUM_MUX1_CHAN5_DEVICE}/new_device + echo 160 > /sys/class/gpio/export + echo 161 > /sys/class/gpio/export + echo 162 > /sys/class/gpio/export + echo 163 > /sys/class/gpio/export + echo 164 > /sys/class/gpio/export + echo 165 > /sys/class/gpio/export + echo 166 > /sys/class/gpio/export + echo 167 > /sys/class/gpio/export + echo 168 > /sys/class/gpio/export + echo 169 > /sys/class/gpio/export + echo 170 > /sys/class/gpio/export + echo 171 > /sys/class/gpio/export + echo 172 > /sys/class/gpio/export + echo 173 > /sys/class/gpio/export + echo 174 > /sys/class/gpio/export + echo 175 > /sys/class/gpio/export + echo out > /sys/class/gpio/gpio160/direction + echo out > /sys/class/gpio/gpio161/direction + echo out > /sys/class/gpio/gpio162/direction + echo out > /sys/class/gpio/gpio163/direction + echo out > /sys/class/gpio/gpio164/direction + echo out > /sys/class/gpio/gpio165/direction + echo out > /sys/class/gpio/gpio166/direction + echo out > /sys/class/gpio/gpio167/direction + echo out > /sys/class/gpio/gpio168/direction + echo out > /sys/class/gpio/gpio169/direction + echo out > /sys/class/gpio/gpio170/direction + echo out > /sys/class/gpio/gpio171/direction + echo out > /sys/class/gpio/gpio172/direction + echo out > /sys/class/gpio/gpio173/direction + echo out > /sys/class/gpio/gpio174/direction + echo out > /sys/class/gpio/gpio175/direction + + #RST Port 0-15 + echo "pca9535 0x22" > /sys/bus/i2c/devices/i2c-${NUM_MUX1_CHAN5_DEVICE}/new_device + echo 144 > /sys/class/gpio/export + echo 145 > /sys/class/gpio/export + echo 146 > /sys/class/gpio/export + echo 147 > /sys/class/gpio/export + echo 148 > /sys/class/gpio/export + echo 149 > /sys/class/gpio/export + echo 150 > /sys/class/gpio/export + echo 151 > /sys/class/gpio/export + echo 152 > /sys/class/gpio/export + echo 153 > /sys/class/gpio/export + echo 154 > /sys/class/gpio/export + echo 155 > /sys/class/gpio/export + echo 156 > /sys/class/gpio/export + echo 157 > /sys/class/gpio/export + echo 158 > /sys/class/gpio/export + echo 159 > /sys/class/gpio/export + echo out > /sys/class/gpio/gpio144/direction + echo out > /sys/class/gpio/gpio145/direction + echo out > /sys/class/gpio/gpio146/direction + echo out > /sys/class/gpio/gpio147/direction + echo out > /sys/class/gpio/gpio148/direction + echo out > /sys/class/gpio/gpio149/direction + echo out > /sys/class/gpio/gpio150/direction + echo out > /sys/class/gpio/gpio151/direction + echo out > /sys/class/gpio/gpio152/direction + echo out > /sys/class/gpio/gpio153/direction + echo out > /sys/class/gpio/gpio154/direction + echo out > /sys/class/gpio/gpio155/direction + echo out > /sys/class/gpio/gpio156/direction + echo out > /sys/class/gpio/gpio157/direction + echo out > /sys/class/gpio/gpio158/direction + echo out > /sys/class/gpio/gpio159/direction + echo 1 > /sys/class/gpio/gpio144/active_low + echo 1 > /sys/class/gpio/gpio145/active_low + echo 1 > /sys/class/gpio/gpio146/active_low + echo 1 > /sys/class/gpio/gpio147/active_low + echo 1 > /sys/class/gpio/gpio148/active_low + echo 1 > /sys/class/gpio/gpio149/active_low + echo 1 > /sys/class/gpio/gpio150/active_low + echo 1 > /sys/class/gpio/gpio151/active_low + echo 1 > /sys/class/gpio/gpio152/active_low + echo 1 > /sys/class/gpio/gpio153/active_low + echo 1 > /sys/class/gpio/gpio154/active_low + echo 1 > /sys/class/gpio/gpio155/active_low + echo 1 > /sys/class/gpio/gpio156/active_low + echo 1 > /sys/class/gpio/gpio157/active_low + echo 1 > /sys/class/gpio/gpio158/active_low + echo 1 > /sys/class/gpio/gpio159/active_low + echo 0 > /sys/class/gpio/gpio144/value + echo 0 > /sys/class/gpio/gpio145/value + echo 0 > /sys/class/gpio/gpio146/value + echo 0 > /sys/class/gpio/gpio147/value + echo 0 > /sys/class/gpio/gpio148/value + echo 0 > /sys/class/gpio/gpio149/value + echo 0 > /sys/class/gpio/gpio150/value + echo 0 > /sys/class/gpio/gpio151/value + echo 0 > /sys/class/gpio/gpio152/value + echo 0 > /sys/class/gpio/gpio153/value + echo 0 > /sys/class/gpio/gpio154/value + echo 0 > /sys/class/gpio/gpio155/value + echo 0 > /sys/class/gpio/gpio156/value + echo 0 > /sys/class/gpio/gpio157/value + echo 0 > /sys/class/gpio/gpio158/value + echo 0 > /sys/class/gpio/gpio159/value + + #RST Port 16-31 + echo "pca9535 0x23" > /sys/bus/i2c/devices/i2c-${NUM_MUX1_CHAN5_DEVICE}/new_device + echo 128 > /sys/class/gpio/export + echo 129 > /sys/class/gpio/export + echo 130 > /sys/class/gpio/export + echo 131 > /sys/class/gpio/export + echo 132 > /sys/class/gpio/export + echo 133 > /sys/class/gpio/export + echo 134 > /sys/class/gpio/export + echo 135 > /sys/class/gpio/export + echo 136 > /sys/class/gpio/export + echo 137 > /sys/class/gpio/export + echo 138 > /sys/class/gpio/export + echo 139 > /sys/class/gpio/export + echo 140 > /sys/class/gpio/export + echo 141 > /sys/class/gpio/export + echo 142 > /sys/class/gpio/export + echo 143 > /sys/class/gpio/export + echo out > /sys/class/gpio/gpio128/direction + echo out > /sys/class/gpio/gpio129/direction + echo out > /sys/class/gpio/gpio130/direction + echo out > /sys/class/gpio/gpio131/direction + echo out > /sys/class/gpio/gpio132/direction + echo out > /sys/class/gpio/gpio133/direction + echo out > /sys/class/gpio/gpio134/direction + echo out > /sys/class/gpio/gpio135/direction + echo out > /sys/class/gpio/gpio136/direction + echo out > /sys/class/gpio/gpio137/direction + echo out > /sys/class/gpio/gpio138/direction + echo out > /sys/class/gpio/gpio139/direction + echo out > /sys/class/gpio/gpio140/direction + echo out > /sys/class/gpio/gpio141/direction + echo out > /sys/class/gpio/gpio142/direction + echo out > /sys/class/gpio/gpio143/direction + echo 1 > /sys/class/gpio/gpio128/active_low + echo 1 > /sys/class/gpio/gpio129/active_low + echo 1 > /sys/class/gpio/gpio130/active_low + echo 1 > /sys/class/gpio/gpio131/active_low + echo 1 > /sys/class/gpio/gpio132/active_low + echo 1 > /sys/class/gpio/gpio133/active_low + echo 1 > /sys/class/gpio/gpio134/active_low + echo 1 > /sys/class/gpio/gpio135/active_low + echo 1 > /sys/class/gpio/gpio136/active_low + echo 1 > /sys/class/gpio/gpio137/active_low + echo 1 > /sys/class/gpio/gpio138/active_low + echo 1 > /sys/class/gpio/gpio139/active_low + echo 1 > /sys/class/gpio/gpio140/active_low + echo 1 > /sys/class/gpio/gpio141/active_low + echo 1 > /sys/class/gpio/gpio142/active_low + echo 1 > /sys/class/gpio/gpio143/active_low + echo 0 > /sys/class/gpio/gpio128/value + echo 0 > /sys/class/gpio/gpio129/value + echo 0 > /sys/class/gpio/gpio130/value + echo 0 > /sys/class/gpio/gpio131/value + echo 0 > /sys/class/gpio/gpio132/value + echo 0 > /sys/class/gpio/gpio133/value + echo 0 > /sys/class/gpio/gpio134/value + echo 0 > /sys/class/gpio/gpio135/value + echo 0 > /sys/class/gpio/gpio136/value + echo 0 > /sys/class/gpio/gpio137/value + echo 0 > /sys/class/gpio/gpio138/value + echo 0 > /sys/class/gpio/gpio139/value + echo 0 > /sys/class/gpio/gpio140/value + echo 0 > /sys/class/gpio/gpio141/value + echo 0 > /sys/class/gpio/gpio142/value + echo 0 > /sys/class/gpio/gpio143/value + +} + +#GPIO DeInit +function _i2c_gpio_deinit { + echo "0x20" > /sys/bus/i2c/devices/i2c-${NUM_MUX1_CHAN4_DEVICE}/delete_device + echo "0x21" > /sys/bus/i2c/devices/i2c-${NUM_MUX1_CHAN4_DEVICE}/delete_device + echo "0x22" > /sys/bus/i2c/devices/i2c-${NUM_MUX1_CHAN4_DEVICE}/delete_device + echo "0x23" > /sys/bus/i2c/devices/i2c-${NUM_MUX1_CHAN4_DEVICE}/delete_device + echo "0x20" > /sys/bus/i2c/devices/i2c-${NUM_MUX1_CHAN5_DEVICE}/delete_device + echo "0x21" > /sys/bus/i2c/devices/i2c-${NUM_MUX1_CHAN5_DEVICE}/delete_device + echo "0x22" > /sys/bus/i2c/devices/i2c-${NUM_MUX1_CHAN5_DEVICE}/delete_device + echo "0x23" > /sys/bus/i2c/devices/i2c-${NUM_MUX1_CHAN5_DEVICE}/delete_device +} + +#I2C CPLD init +function _i2c_cpld_init { + echo "=========================================================" + echo "# Description: I2C CPLD Init..." + echo "=========================================================" + + ## modprobe i2c_cpld + modprobe i2c_cpld + ## Add CPLD device + echo "i2c_cpld 0x33" > ${PATH_SYS_I2C_DEVICES}/i2c-${NUM_I801_DEVICE}/new_device + + echo "done..." +} + +#Set FAN Tray LED +function _i2c_led_fan_tray_status_set { + echo "FAN Tray Status Setup" + #FAN Status get + FAN1_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan1_alarm` + FAN2_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan2_alarm` + FAN3_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan3_alarm` + FAN4_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan4_alarm` + FAN5_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan5_alarm` + FAN6_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan6_alarm` + FAN7_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan7_alarm` + FAN8_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan8_alarm` + + if [ "${FAN1_ALARM}" == "0" ] && [ "${FAN2_ALARM}" == "0" ]; then + FAN_TRAY=1 + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + else + FAN_TRAY=1 + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + fi + + if [ "${FAN3_ALARM}" == "0" ] && [ "${FAN4_ALARM}" == "0" ]; then + FAN_TRAY=2 + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + else + FAN_TRAY=2 + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + fi + + if [ "${FAN5_ALARM}" == "0" ] && [ "${FAN6_ALARM}" == "0" ]; then + FAN_TRAY=3 + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + else + FAN_TRAY=3 + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + fi + + if [ "${FAN7_ALARM}" == "0" ] && [ "${FAN8_ALARM}" == "0" ]; then + FAN_TRAY=4 + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + else + FAN_TRAY=4 + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + fi +} + +#Set FAN LED +function _i2c_led_fan_status_set { + echo "FAN Status Setup" + #PSU Status set + FAN1_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan1_alarm` + FAN2_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan2_alarm` + FAN3_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan3_alarm` + FAN4_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan4_alarm` + FAN5_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan5_alarm` + FAN6_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan6_alarm` + FAN7_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan7_alarm` + FAN8_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan8_alarm` + + if [ "${FAN1_ALARM}" == "0" ] && [ "${FAN2_ALARM}" == "0" ] \ + && [ "${FAN3_ALARM}" == "0" ] && [ "${FAN4_ALARM}" == "0" ] \ + && [ "${FAN5_ALARM}" == "0" ] && [ "${FAN6_ALARM}" == "0" ] \ + && [ "${FAN7_ALARM}" == "0" ] && [ "${FAN8_ALARM}" == "0" ]; then + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_led + else + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_led + fi +} + +#Set Power Supply LED +function _i2c_led_psu_status_set { + echo "PSU LED Status Setup" + + #PSU Status set + _i2c_psu_status + + #PSU1 Status + if [ "${psu1Exist}" == ${PSU_EXIST} ]; then + if [ "${psu1PwGood}" == ${PSU_DC_ON} ]; then + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu1_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu1_led + else + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu1_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu1_led + fi + else + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu1_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu1_led + fi + + #PSU2 Status + if [ "${psu2Exist}" == ${PSU_EXIST} ]; then + if [ "${psu2PwGood}" == ${PSU_DC_ON} ]; then + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu2_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu2_led + else + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu2_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu2_led + fi + else + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu2_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu2_led + fi +} + +#LED Test +function _i2c_led_test { + echo "=========================================================" + echo "# Description: I2C LED TEST..." + echo "=========================================================" + #sys led (green) + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0x7F + _pause 'Check SYS LED green light and Press [Enter] key to continue...' + #sys led (amber) + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xBF + _pause 'Check SYS LED amber light and Press [Enter] key to continue...' + + #FAN led (green) + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xF7 + _pause 'Check FAN LED green light and Press [Enter] key to continue...' + #FAN led (amber) + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFB + _pause 'Check FAN LED amber light and Press [Enter] key to continue...' + + #PSU2 led (green) + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xDF + _pause 'Check PSU2 LED green light and Press [Enter] key to continue...' + #PSU2 led (amber) + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xEF + _pause 'Check PSU2 LED amber light and Press [Enter] key to continue...' + + #PSU1 led (green) + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFD + _pause 'Check PSU1 LED green light and Press [Enter] key to continue...' + #PSU1 led (amber) + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFE + _pause 'Check PSU1 LED amber light and Press [Enter] key to continue...' + + #Turn OFF All LED + i2cset -y ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + _pause 'Check turn off all LEDs and Press [Enter] key to continue...' + echo "done..." +} + +#Set QSFP Port variable +function _qsfp_port_i2c_var_set { + local port=$1 + case ${port} in + 1|2|3|4|5|6|7|8) + i2cbus=${NUM_MUX1_CHAN4_DEVICE} + regAddr=0x20 + dataAddr=0 + eeprombusbase=${NUM_MUX3_CHAN0_DEVICE} + gpioBase=240 + ;; + 9|10|11|12|13|14|15|16) + i2cbus=${NUM_MUX1_CHAN4_DEVICE} + regAddr=0x20 + dataAddr=1 + eeprombusbase=${NUM_MUX4_CHAN0_DEVICE} + gpioBase=240 + ;; + 17|18|19|20|21|22|23|24) + i2cbus=${NUM_MUX1_CHAN4_DEVICE} + regAddr=0x21 + dataAddr=0 + eeprombusbase=${NUM_MUX5_CHAN0_DEVICE} + gpioBase=$((224 - 16)) + ;; + 25|26|27|28|29|30|31|32) + i2cbus=${NUM_MUX1_CHAN4_DEVICE} + regAddr=0x21 + dataAddr=1 + eeprombusbase=${NUM_MUX6_CHAN0_DEVICE} + gpioBase=$((224 - 16)) + ;; + 33) + i2cbus=${NUM_MUX1_CHAN7_DEVICE} + regAddr=0x22 + dataAddr=0 + ;; + 34) + i2cbus=${NUM_MUX1_CHAN7_DEVICE} + regAddr=0x22 + dataAddr=1 + ;; + *) + echo "Please input 1~32" + ;; + esac +} + +#Set QSFP Port variable +function _qsfp_eeprom_var_set { + local port=$1 + eeprombusidx=$(( ${port} % 8)) + case $eeprombusidx in + 1) + eeprombus=$(( $eeprombusbase + 1 )) + eepromAddr=0x50 + ;; + 2) + eeprombus=$(( $eeprombusbase + 0 )) + eepromAddr=0x50 + ;; + 3) + eeprombus=$(( $eeprombusbase + 3 )) + eepromAddr=0x50 + ;; + 4) + eeprombus=$(( $eeprombusbase + 2 )) + eepromAddr=0x50 + ;; + 5) + eeprombus=$(( $eeprombusbase + 5 )) + eepromAddr=0x50 + ;; + 6) + eeprombus=$(( $eeprombusbase + 4 )) + eepromAddr=0x50 + ;; + 7) + eeprombus=$(( $eeprombusbase + 7 )) + eepromAddr=0x50 + ;; + 0) + eeprombus=$(( $eeprombusbase + 6 )) + eepromAddr=0x50 + ;; + esac +} + +#Get QSFP EEPROM Information +function _i2c_qsfp_eeprom_get { + + _qsfp_port_i2c_var_set ${QSFP_PORT} + + #status: 0 -> Down, 1 -> Up + status=`cat /sys/class/gpio/gpio$(( $(($gpioBase + (${QSFP_PORT} - 1) ^ 1)) ))/value` + echo $status + + if [ $status = 0 ]; then + exit + fi + + _qsfp_eeprom_var_set ${QSFP_PORT} + + cat ${PATH_SYS_I2C_DEVICES}/$eeprombus-$(printf "%04x" $eepromAddr)/eeprom | hexdump -C +} + +#Init QSFP EEPROM +function _i2c_qsfp_eeprom_init { + echo -n "QSFP EEPROM INIT..." + + #Action check + action=$1 + if [ -z "${action}" ]; then + echo "No action, skip" + return + elif [ "${action}" != "new" ] && [ "${action}" != "delete" ]; then + echo "Error action, skip" + return + fi + + #Init 1-32 ports EEPROM + local i + for i in {1..32}; + do + _qsfp_port_i2c_var_set ${i} + + _qsfp_eeprom_var_set ${i} + + if [ "${action}" == "new" ] && \ + ! [ -L ${PATH_SYS_I2C_DEVICES}/$eeprombus-$(printf "%04x" $eepromAddr) ]; then + echo "sff8436 $eepromAddr" > ${PATH_SYS_I2C_DEVICES}/i2c-$eeprombus/new_device + elif [ "${action}" == "delete" ] && \ + [ -L ${PATH_SYS_I2C_DEVICES}/$eeprombus-$(printf "%04x" $eepromAddr) ]; then + echo "$eepromAddr" > ${PATH_SYS_I2C_DEVICES}/i2c-$eeprombus/delete_device + fi + done + echo "DONE" +} + +#Init Main Board EEPROM +function _i2c_mb_eeprom_init { + echo -n "Main Board EEPROM INIT..." + + #Action check + action=$1 + if [ -z "${action}" ]; then + echo "No action, skip" + return + elif [ "${action}" != "new" ] && [ "${action}" != "delete" ]; then + echo "Error action, skip" + return + fi + + #Init 1-32 ports EEPROM + if [ "${action}" == "new" ] && \ + ! [ -L ${PATH_SYS_I2C_DEVICES}/${NUM_MUX1_CHAN7_DEVICE}-0054 ]; then + echo "mb_eeprom 0x54" > ${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN7_DEVICE}/new_device + elif [ "${action}" == "delete" ] && \ + [ -L ${PATH_SYS_I2C_DEVICES}/${NUM_MUX1_CHAN7_DEVICE}-0054 ]; then + echo "0x54" > ${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN7_DEVICE}/delete_device + fi + echo "DONE" +} + +#PSU EEPROM init +function _i2c_psu_eeprom_init { + echo "=========================================================" + echo "# Description: I2C PSU EEPROM Init..." + echo "=========================================================" + + ## modprobe eeprom + modprobe eeprom + ## PUS(0) EEPROM + echo "eeprom 0x50" > ${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN6_DEVICE}/new_device + + ## PUS(1) EEPROM + echo "eeprom 0x50" > ${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX1_CHAN7_DEVICE}/new_device + + echo "done..." +} + +#get QSFP Status +function _i2c_qsfp_status_get { + + _qsfp_port_i2c_var_set ${QSFP_PORT} + + #status: 0 -> Down, 1 -> Up + status=`cat /sys/class/gpio/gpio$(( $(($gpioBase + (${QSFP_PORT} - 1) ^ 1)) ))/value` + echo "status=$status" +} + +#get QSFP Type +function _i2c_qsfp_type_get { + + _qsfp_port_i2c_var_set ${QSFP_PORT} + + _qsfp_eeprom_var_set ${QSFP_PORT} + + #Get QSFP EEPROM info + qsfp_info=$(base64 ${PATH_SYS_I2C_DEVICES}/$eeprombus-$(printf "%04x" $eepromAddr)/eeprom) + + identifier=$(echo $qsfp_info | base64 -d -i | hexdump -s 128 -n 1 -e '"%x"') + connector=$(echo $qsfp_info | base64 -d -i | hexdump -s 130 -n 1 -e '"%x"') + transceiver=$(echo $qsfp_info | base64 -d -i | hexdump -s 131 -n 1 -e '"%x"') + + echo "identifier=$identifier" + echo "connector=$connector" + echo "transceiver=$transceiver" +} + +#Get PSU EEPROM Information +function _i2c_psu_eeprom_get { + echo "=========================================================" + echo "# Description: I2C PSU EEPROM Get..." + echo "=========================================================" + + ## modprobe eeprom + modprobe eeprom + ## PUS(0) EEPROM + cat ${PATH_SYS_I2C_DEVICES}/${NUM_MUX1_CHAN6_DEVICE}-0050/eeprom | hexdump -C + + ## PUS(1) EEPROM + cat ${PATH_SYS_I2C_DEVICES}/${NUM_MUX1_CHAN7_DEVICE}-0050/eeprom | hexdump -C + + echo "done..." +} + +#Get MotherBoard EEPROM Information +function _i2c_mb_eeprom_get { + echo "=========================================================" + echo "# Description: I2C MB EEPROM Get..." + echo "=========================================================" + + ## MB EEPROM + cat ${PATH_SYS_I2C_DEVICES}/${NUM_MUX1_CHAN7_DEVICE}-0054/eeprom | hexdump -C + echo "done..." +} + +#Set System Status LED +function _i2c_sys_led { + if [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "on" ]; then + i2cset -m 0x80 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0x00 + elif [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "off" ]; then + i2cset -m 0x80 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "on" ]; then + i2cset -m 0x40 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0x00 + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "off" ]; then + i2cset -m 0x40 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + echo "done..." +} + +#Set PSU2 LED +function _i2c_psu2_led { + if [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "on" ]; then + i2cset -m 0x20 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0x00 + elif [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "off" ]; then + i2cset -m 0x20 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "on" ]; then + i2cset -m 0x10 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0x00 + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "off" ]; then + i2cset -m 0x10 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + echo "done..." +} + +#Set FAN Tray LED +function _i2c_fan_tray_led { + case ${FAN_TRAY} in + 1) + i2cAddr=0x20 + ioPort=2 + if [ "${COLOR_LED}" == "green" ]; then + mask=0x01 + elif [ "${COLOR_LED}" == "amber" ]; then + mask=0x02 + fi + ;; + 2) + i2cAddr=0x20 + ioPort=2 + if [ "${COLOR_LED}" == "green" ]; then + mask=0x10 + elif [ "${COLOR_LED}" == "amber" ]; then + mask=0x20 + fi + ;; + 3) + i2cAddr=0x20 + ioPort=3 + if [ "${COLOR_LED}" == "green" ]; then + mask=0x01 + elif [ "${COLOR_LED}" == "amber" ]; then + mask=0x02 + fi + ;; + 4) + i2cAddr=0x20 + ioPort=3 + if [ "${COLOR_LED}" == "green" ]; then + mask=0x10 + elif [ "${COLOR_LED}" == "amber" ]; then + mask=0x20 + fi + ;; + *) + echo "Please input 1~4" + exit + ;; + esac + + if [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "on" ]; then + i2cset -m $mask -y -r ${NUM_MUX1_CHAN7_DEVICE} $i2cAddr $ioPort 0x33 + elif [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "off" ]; then + i2cset -m $mask -y -r ${NUM_MUX1_CHAN7_DEVICE} $i2cAddr $ioPort 0x00 + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "on" ]; then + i2cset -m $mask -y -r ${NUM_MUX1_CHAN7_DEVICE} $i2cAddr $ioPort 0x33 + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "off" ]; then + i2cset -m $mask -y -r ${NUM_MUX1_CHAN7_DEVICE} $i2cAddr $ioPort 0x00 + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + echo "done..." +} + +#Set FAN LED +function _i2c_fan_led { + if [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "on" ]; then + i2cset -m 0x08 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0x00 + elif [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "off" ]; then + i2cset -m 0x08 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "on" ]; then + i2cset -m 0x04 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0x00 + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "off" ]; then + i2cset -m 0x04 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + echo "done..." +} + +#Set PSU1 LED +function _i2c_psu1_led { + if [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "on" ]; then + i2cset -m 0x02 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0x00 + elif [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "off" ]; then + i2cset -m 0x02 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "on" ]; then + i2cset -m 0x01 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0x00 + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "off" ]; then + i2cset -m 0x01 -y -r ${NUM_MUX1_CHAN7_DEVICE} 0x22 2 0xFF + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + echo "done..." +} + +#Get Board Version and Type +function _i2c_board_type_get { + boardType=`cat ${PATH_SYS_I2C_DEVICES}/0-0033/cpld_board_type` + boardBuildRev=$((($boardType) & 0x03)) + boardHwRev=$((($boardType) >> 2 & 0x03)) + boardId=$((($boardType) >> 4)) + printf "BOARD_ID is 0x%02x, HW Rev %d, Build Rev %d\n" $boardId $boardHwRev $boardBuildRev + +} + +#Get CPLD Version +function _i2c_cpld_version { + cpldRev=`cat ${PATH_SYS_I2C_DEVICES}/0-0033/cpld_version` + cpldRelease=$((($cpldRev) >> 6 & 0x01)) + cpldVersion=$((($cpldRev) & 0x3F)) + printf "CPLD is %s version(0:RD 1:Release), Revision is 0x%02x\n" $cpldRelease $cpldVersion + +} + +#Get PSU Status +function _i2c_psu_status { + psuPresent=`cat ${PATH_SYS_I2C_DEVICES}/0-0033/cpld_pw_abs` + psu1Exist=$(($((($psuPresent) & 0x01))?0:1)) + psu2Exist=$(($((($psuPresent) & 0x02))?0:1)) + psuPwGood=`cat ${PATH_SYS_I2C_DEVICES}/0-0033/cpld_pw_good` + psu1PwGood=$(($((($psuPwGood) >> 3 & 0x01))?1:0)) + psu2PwGood=$(($((($psuPwGood) >> 3 & 0x02))?1:0)) + printf "PSU1 Exist:%d PSU1 PW Good:%d\n" $psu1Exist $psu1PwGood + printf "PSU2 Exist:%d PSU2 PW Good:%d\n" $psu2Exist $psu2PwGood +} + +#Get Front Sensor Temperature +function _i2c_front_temp { + #Front MAC + sensors | grep 'Front MAC Temp' -A 1 +} + +#Get Rear Sensor Temperature +function _i2c_rear_temp { + #Rear MAC + sensors | grep 'Rear MAC Temp' -A 1 +} + +#Increase read socket buffer for CoPP Test +function _config_rmem { + echo "109430400" > /proc/sys/net/core/rmem_max +} + +#Main Function +function _main { + tart_time_str=`date` + start_time_sec=$(date +%s) + + if [ "${EXEC_FUNC}" == "help" ]; then + _help + elif [ "${EXEC_FUNC}" == "i2c_init" ]; then + _i2c_init + elif [ "${EXEC_FUNC}" == "i2c_deinit" ]; then + _i2c_deinit + elif [ "${EXEC_FUNC}" == "i2c_temp_init" ]; then + _i2c_temp_init + elif [ "${EXEC_FUNC}" == "i2c_fan_init" ]; then + _i2c_fan_init + elif [ "${EXEC_FUNC}" == "i2c_volmon_init" ]; then + _i2c_volmon_init + elif [ "${EXEC_FUNC}" == "i2c_io_exp_init" ]; then + _i2c_io_exp_init + elif [ "${EXEC_FUNC}" == "i2c_gpio_init" ]; then + _i2c_gpio_init + elif [ "${EXEC_FUNC}" == "i2c_gpio_deinit" ]; then + _i2c_gpio_deinit + elif [ "${EXEC_FUNC}" == "i2c_led_test" ]; then + _i2c_led_test + elif [ "${EXEC_FUNC}" == "i2c_mb_eeprom_get" ]; then + _i2c_mb_eeprom_get + elif [ "${EXEC_FUNC}" == "i2c_psu_eeprom_get" ]; then + _i2c_psu_eeprom_get + elif [ "${EXEC_FUNC}" == "i2c_qsfp_eeprom_get" ]; then + _i2c_qsfp_eeprom_get + elif [ "${EXEC_FUNC}" == "i2c_qsfp_eeprom_init" ]; then + _i2c_qsfp_eeprom_init ${QSFP_ACTION} + elif [ "${EXEC_FUNC}" == "i2c_mb_eeprom_init" ]; then + _i2c_mb_eeprom_init ${MB_EEPROM_ACTION} + elif [ "${EXEC_FUNC}" == "i2c_qsfp_status_get" ]; then + _i2c_qsfp_status_get + elif [ "${EXEC_FUNC}" == "i2c_qsfp_type_get" ]; then + _i2c_qsfp_type_get + elif [ "${EXEC_FUNC}" == "i2c_led_psu_status_set" ]; then + _i2c_led_psu_status_set + elif [ "${EXEC_FUNC}" == "i2c_led_fan_status_set" ]; then + _i2c_led_fan_status_set + elif [ "${EXEC_FUNC}" == "i2c_led_fan_tray_status_set" ]; then + _i2c_led_fan_tray_status_set + elif [ "${EXEC_FUNC}" == "i2c_sys_led" ]; then + _i2c_sys_led + elif [ "${EXEC_FUNC}" == "i2c_fan_led" ]; then + _i2c_fan_led + elif [ "${EXEC_FUNC}" == "i2c_fan_tray_led" ]; then + _i2c_fan_tray_led + elif [ "${EXEC_FUNC}" == "i2c_psu1_led" ]; then + _i2c_psu1_led + elif [ "${EXEC_FUNC}" == "i2c_psu2_led" ]; then + _i2c_psu2_led + elif [ "${EXEC_FUNC}" == "i2c_board_type_get" ]; then + _i2c_board_type_get + elif [ "${EXEC_FUNC}" == "i2c_cpld_version" ]; then + _i2c_cpld_version + elif [ "${EXEC_FUNC}" == "i2c_psu_status" ]; then + _i2c_psu_status + elif [ "${EXEC_FUNC}" == "i2c_front_temp" ]; then + _i2c_front_temp + elif [ "${EXEC_FUNC}" == "i2c_rear_temp" ]; then + _i2c_rear_temp + elif [ "${EXEC_FUNC}" == "i2c_test_all" ]; then + _i2c_init + _i2c_temp_init + _i2c_fan_init + _i2c_io_exp_init + _i2c_led_test + _i2c_psu_eeprom_get + _i2c_mb_eeprom_get + _i2c_board_type_get + _i2c_cpld_version + _i2c_psu_status + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + end_time_str=`date` + end_time_sec=$(date +%s) + diff_time=$[ ${end_time_sec} - ${start_time_sec} ] + echo "Start Time: ${start_time_str} (${start_time_sec})" + echo "End Time : ${end_time_str} (${end_time_sec})" + echo "Total Execution Time: ${diff_time} sec" + + echo "done!!!" +} + +_main diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_monitor.sh new file mode 100755 index 000000000000..249f179216a6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_monitor.sh @@ -0,0 +1,104 @@ +#!/bin/bash +# Copyright (C) 2017 Ingrasys, 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 3 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, see . + +INTERVAL=3 +I2C_UTILS="/usr/sbin/i2c_utils.sh" +QSFP_SI_SCRIPT="/usr/sbin/qsfp_si_cfg.sh" +QSFP_ARRAY=(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) + +#QSFP SI monitor +function _qsfp_si_monitor { + local i + local status + for i in {0..31}; + do + status=`${I2C_UTILS} i2c_qsfp_status_get $(expr $i + 1) | egrep '^status=.*$' | sed -e 's/status=//g'` + if [ "${status}" == "1" ]; then + _qsfp_type_check $i + fi + done +} + +#QSFP type +function _qsfp_type_check { + local port=$1 + local qsfp_type=`${I2C_UTILS} i2c_qsfp_type_get $(expr $port + 1)` + local identifier=`echo "$qsfp_type" | grep '^identifier=.*$' | sed -e 's/identifier=//g'` + if [ "${identifier}" == "11" ]; then + connector=`echo "$qsfp_type" | grep '^connector=.*$' | sed -e 's/connector=//g'` + case ${connector} in + 21|23) + #DAC + if [ "${QSFP_ARRAY[$port]}" != "${connector}" ]; then + echo "Change Port $(expr $port + 1) to DAC" + QSFP_ARRAY[$port]=${connector} + ${QSFP_SI_SCRIPT} dac $port >/dev/null + fi + ;; + *) + #Optical + if [ "${QSFP_ARRAY[$port]}" != "${connector}" ]; then + echo "Change Port $(expr $port + 1) to Optical" + QSFP_ARRAY[$port]=${connector} + ${QSFP_SI_SCRIPT} optical $port >/dev/null + fi + ;; + esac + fi +} + +#Docker exist check +function _docker_swss_check { + while true + do + # Check if syncd starts + result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + if [ "$result" == "3" ]; then + return + fi + sleep $INTERVAL + done +} + +#Docker exist check +function _qsfp_si_cfg_script_check { + + if [ -f ${QSFP_SI_SCRIPT} ] && [ -x ${QSFP_SI_SCRIPT} ]; then + echo "SI Script exists. Start monitor." + return + else + echo "SI Script not exist. Exit monitor." + exit + fi +} + +# main function +function _main { + #Check SI Script + _qsfp_si_cfg_script_check + #Check docker swss is running + _docker_swss_check + while true + do + _qsfp_si_monitor + # Sleep while still handling signals + sleep $INTERVAL & + wait $! + done +} + +_main + diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_si_cfg.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_si_cfg.sh new file mode 100755 index 000000000000..f2bf35bc7715 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_si_cfg.sh @@ -0,0 +1,339 @@ +#!/bin/bash +# Copyright (C) 2017 Ingrasys, 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 3 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, see . + +VERSION="1.0.0" +TRUE=200 +FALSE=404 + +TYPE=${1} +PORT=${2} + +#QSFP Optical +function _qsfp_optical_si_set { + case ${PORT} in + 0) + bcmcmd "phy ce0 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x39;phy ce0 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x37;phy ce0 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0;phy ce0 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x39" + bcmcmd "phy ce0 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x37;phy ce0 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0xA AMS_TX_DRIVERMODE=0x0;phy ce0 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x35;phy ce0 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x37" + bcmcmd "phy ce0 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0x9 AMS_TX_DRIVERMODE=0x0;phy ce0 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x30;phy ce0 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x40;phy ce0 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + ;; + 1) + bcmcmd "phy ce1 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x3E;phy ce1 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x32;phy ce1 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0;phy ce1 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x38" + bcmcmd "phy ce1 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x38;phy ce1 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0xE AMS_TX_DRIVERMODE=0x0;phy ce1 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x33;phy ce1 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x3D" + bcmcmd "phy ce1 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0x9 AMS_TX_DRIVERMODE=0x0;phy ce1 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x35;phy ce1 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x3B;phy ce1 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0xE AMS_TX_DRIVERMODE=0x0" + ;; + 2) + bcmcmd "phy ce2 CL93N72_UT_CTL2r CL93N72_TXFIR_POST=0x35;phy ce2 CL93N72_UT_CTL3r CL93N72_TXFIR_MAIN=0x3B;phy ce2 AMS_TX_CTL2r AMS_TX_AMP_CTL=0xB AMS_TX_DRIVERMODE=0x0" + ;; + 3) + bcmcmd "phy ce3 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x3B;phy ce3 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x35;phy ce3 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0;phy ce3 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x35" + bcmcmd "phy ce3 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x37;phy ce3 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0xC AMS_TX_DRIVERMODE=0x0;phy ce3 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x35;phy ce3 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x37" + bcmcmd "phy ce3 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0xB AMS_TX_DRIVERMODE=0x0;phy ce3 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x35;phy ce3 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x37;phy ce3 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0xB AMS_TX_DRIVERMODE=0x0" + ;; + 4) + bcmcmd "phy ce4 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x30;phy ce4 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x40;phy ce4 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0xA AMS_TX_DRIVERMODE=0x0;phy ce4 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x33" + bcmcmd "phy ce4 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x3D;phy ce4 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0xA AMS_TX_DRIVERMODE=0x0;phy ce4 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x30;phy ce4 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x40" + bcmcmd "phy ce4 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0xA AMS_TX_DRIVERMODE=0x0;phy ce4 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x30;phy ce4 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x40;phy ce4 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0xA AMS_TX_DRIVERMODE=0x0" + ;; + 5) + bcmcmd "phy ce5 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x30;phy ce5 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x40;phy ce5 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0xA AMS_TX_DRIVERMODE=0x0;phy ce5 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x35" + bcmcmd "phy ce5 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x3B;phy ce5 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0;phy ce5 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x30;phy ce5 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x40" + bcmcmd "phy ce5 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0xA AMS_TX_DRIVERMODE=0x0;phy ce5 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x30;phy ce5 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x40;phy ce5 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0xA AMS_TX_DRIVERMODE=0x0" + ;; + 6) + bcmcmd "phy ce6 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x30;phy ce6 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x40;phy ce6 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0xA AMS_TX_DRIVERMODE=0x0;phy ce6 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x36" + bcmcmd "phy ce6 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x3A;phy ce6 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0xC AMS_TX_DRIVERMODE=0x0;phy ce6 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x30;phy ce6 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x40" + bcmcmd "phy ce6 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0xA AMS_TX_DRIVERMODE=0x0;phy ce6 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x30;phy ce6 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x40;phy ce6 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0xA AMS_TX_DRIVERMODE=0x0" + ;; + 7) + bcmcmd "phy ce7 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x30;phy ce7 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x40;phy ce7 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0;phy ce7 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x30" + bcmcmd "phy ce7 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x40;phy ce7 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0;phy ce7 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x30;phy ce7 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x40" + bcmcmd "phy ce7 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0;phy ce7 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x30;phy ce7 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x40;phy ce7 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0" + ;; + 8) + bcmcmd "phy ce8 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x25;phy ce8 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x4B;phy ce8 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0;phy ce8 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x2C" + bcmcmd "phy ce8 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x44;phy ce8 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0x9 AMS_TX_DRIVERMODE=0x0;phy ce8 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x25;phy ce8 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x4B" + bcmcmd "phy ce8 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0;phy ce8 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x25;phy ce8 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x4B;phy ce8 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0" + ;; + 9) + bcmcmd "phy ce9 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x25;phy ce9 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x4B;phy ce9 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0;phy ce9 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x2B" + bcmcmd "phy ce9 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x45;phy ce9 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0x9 AMS_TX_DRIVERMODE=0x0;phy ce9 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x25;phy ce9 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x4B" + bcmcmd "phy ce9 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0;phy ce9 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x25;phy ce9 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x4B;phy ce9 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0" + ;; + 10) + bcmcmd "phy ce10 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x25;phy ce10 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x4B;phy ce10 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0;phy ce10 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x2B" + bcmcmd "phy ce10 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x45;phy ce10 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0x7 AMS_TX_DRIVERMODE=0x0;phy ce10 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x25;phy ce10 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x4B" + bcmcmd "phy ce10 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0;phy ce10 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x25;phy ce10 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x4B;phy ce10 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0" + ;; + 11) + bcmcmd "phy ce11 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x25;phy ce11 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x4B;phy ce11 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0;phy ce11 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x2C" + bcmcmd "phy ce11 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x44;phy ce11 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0;phy ce11 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x25;phy ce11 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x4B" + bcmcmd "phy ce11 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0;phy ce11 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x25;phy ce11 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x4B;phy ce11 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0" + ;; + 12) + bcmcmd "phy ce12 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x25;phy ce12 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x4B;phy ce12 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0;phy ce12 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x25" + bcmcmd "phy ce12 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x4B;phy ce12 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0x5 AMS_TX_DRIVERMODE=0x0;phy ce12 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x25;phy ce12 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x4B" + bcmcmd "phy ce12 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0;phy ce12 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x25;phy ce12 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x4B;phy ce12 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0" + ;; + 13) + bcmcmd "phy ce13 CL93N72_UT_CTL2r CL93N72_TXFIR_POST=0x25;phy ce13 CL93N72_UT_CTL3r CL93N72_TXFIR_MAIN=0x4B;phy ce13 AMS_TX_CTL2r AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0" + ;; + 14) + bcmcmd "phy ce14 CL93N72_UT_CTL2r CL93N72_TXFIR_POST=0x25;phy ce14 CL93N72_UT_CTL3r CL93N72_TXFIR_MAIN=0x4B;phy ce14 AMS_TX_CTL2r AMS_TX_AMP_CTL=0x7 AMS_TX_DRIVERMODE=0x0" + ;; + 15) + bcmcmd "phy ce15 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x25;phy ce15 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x4B;phy ce15 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0x7 AMS_TX_DRIVERMODE=0x0;phy ce15 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x25" + bcmcmd "phy ce15 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x4B;phy ce15 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0x5 AMS_TX_DRIVERMODE=0x0;phy ce15 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x25;phy ce15 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x4B" + bcmcmd "phy ce15 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0x7 AMS_TX_DRIVERMODE=0x0;phy ce15 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x25;phy ce15 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x4B;phy ce15 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0x7 AMS_TX_DRIVERMODE=0x0" + ;; + 16) + bcmcmd "phy ce16 CL93N72_UT_CTL2r CL93N72_TXFIR_POST=0x27;phy ce16 CL93N72_UT_CTL3r CL93N72_TXFIR_MAIN=0x49;phy ce16 AMS_TX_CTL2r AMS_TX_AMP_CTL=0x4 AMS_TX_DRIVERMODE=0x0" + ;; + 17) + bcmcmd "phy ce17 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x25;phy ce17 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x4B;phy ce17 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0;phy ce17 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x30" + bcmcmd "phy ce17 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x40;phy ce17 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0;phy ce17 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x30;phy ce17 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x40" + bcmcmd "phy ce17 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0;phy ce17 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x30;phy ce17 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x40;phy ce17 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + ;; + 18) + bcmcmd "phy ce18 CL93N72_UT_CTL2r CL93N72_TXFIR_POST=0x20;phy ce18 CL93N72_UT_CTL3r CL93N72_TXFIR_MAIN=0x50;phy ce18 AMS_TX_CTL2r AMS_TX_AMP_CTL=0x2 AMS_TX_DRIVERMODE=0x0" + ;; + 19) + bcmcmd "phy ce19 CL93N72_UT_CTL2r CL93N72_TXFIR_POST=0x20;phy ce19 CL93N72_UT_CTL3r CL93N72_TXFIR_MAIN=0x50;phy ce19 AMS_TX_CTL2r AMS_TX_AMP_CTL=0x2 AMS_TX_DRIVERMODE=0x0" + ;; + 20) + bcmcmd "phy ce20 CL93N72_UT_CTL2r CL93N72_TXFIR_POST=0x20;phy ce20 CL93N72_UT_CTL3r CL93N72_TXFIR_MAIN=0x50;phy ce20 AMS_TX_CTL2r AMS_TX_AMP_CTL=0x2 AMS_TX_DRIVERMODE=0x0" + ;; + 21) + bcmcmd "phy ce21 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x17;phy ce21 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x59;phy ce21 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0x4 AMS_TX_DRIVERMODE=0x0;phy ce21 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x17" + bcmcmd "phy ce21 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x59;phy ce21 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0x2 AMS_TX_DRIVERMODE=0x0;phy ce21 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x20;phy ce21 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x50" + bcmcmd "phy ce21 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0x2 AMS_TX_DRIVERMODE=0x0;phy ce21 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x20;phy ce21 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x50;phy ce21 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0x2 AMS_TX_DRIVERMODE=0x0" + ;; + 22) + bcmcmd "phy ce22 CL93N72_UT_CTL2r CL93N72_TXFIR_POST=0x25;phy ce22 CL93N72_UT_CTL3r CL93N72_TXFIR_MAIN=0x4B;phy ce22 AMS_TX_CTL2r AMS_TX_AMP_CTL=0x7 AMS_TX_DRIVERMODE=0x0" + ;; + 23) + bcmcmd "phy ce23 CL93N72_UT_CTL2r CL93N72_TXFIR_POST=0x25;phy ce23 CL93N72_UT_CTL3r CL93N72_TXFIR_MAIN=0x4B;phy ce23 AMS_TX_CTL2r AMS_TX_AMP_CTL=0x7 AMS_TX_DRIVERMODE=0x0" + ;; + 24) + bcmcmd "phy ce24 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x23;phy ce24 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x4D;phy ce24 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0;phy ce24 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x29" + bcmcmd "phy ce24 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x47;phy ce24 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0;phy ce24 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x29;phy ce24 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x47" + bcmcmd "phy ce24 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0x4 AMS_TX_DRIVERMODE=0x0;phy ce24 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x29;phy ce24 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x47;phy ce24 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0x4 AMS_TX_DRIVERMODE=0x0" + ;; + 25) + bcmcmd "phy ce25 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x29;phy ce25 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x47;phy ce25 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0;phy ce25 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x29" + bcmcmd "phy ce25 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x47;phy ce25 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0;phy ce25 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x29;phy ce25 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x47" + bcmcmd "phy ce25 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0x4 AMS_TX_DRIVERMODE=0x0;phy ce25 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x29;phy ce25 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x47;phy ce25 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0x4 AMS_TX_DRIVERMODE=0x0" + ;; + 26) + bcmcmd "phy ce26 CL93N72_UT_CTL2r CL93N72_TXFIR_POST=0x30;phy ce26 CL93N72_UT_CTL3r CL93N72_TXFIR_MAIN=0x40;phy ce26 AMS_TX_CTL2r AMS_TX_AMP_CTL=0x9 AMS_TX_DRIVERMODE=0x0" + ;; + 27) + bcmcmd "phy ce27 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x30;phy ce27 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x40;phy ce27 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0x9 AMS_TX_DRIVERMODE=0x0;phy ce27 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x30" + bcmcmd "phy ce27 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x40;phy ce27 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0x9 AMS_TX_DRIVERMODE=0x0;phy ce27 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x30;phy ce27 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x40" + bcmcmd "phy ce27 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0xB AMS_TX_DRIVERMODE=0x0;phy ce27 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x30;phy ce27 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x40;phy ce27 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0x9 AMS_TX_DRIVERMODE=0x0" + ;; + 28) + bcmcmd "phy ce28 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x30;phy ce28 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x40;phy ce28 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0xA AMS_TX_DRIVERMODE=0x0;phy ce28 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x30" + bcmcmd "phy ce28 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x40;phy ce28 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0xA AMS_TX_DRIVERMODE=0x0;phy ce28 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x30;phy ce28 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x40" + bcmcmd "phy ce28 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0x9 AMS_TX_DRIVERMODE=0x0;phy ce28 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x30;phy ce28 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x40;phy ce28 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0x9 AMS_TX_DRIVERMODE=0x0" + ;; + 29) + bcmcmd "phy ce29 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x30;phy ce29 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x40;phy ce29 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0xA AMS_TX_DRIVERMODE=0x0;phy ce29 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x30" + bcmcmd "phy ce29 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x40;phy ce29 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0x9 AMS_TX_DRIVERMODE=0x0;phy ce29 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x30;phy ce29 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x40" + bcmcmd "phy ce29 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0x9 AMS_TX_DRIVERMODE=0x0;phy ce29 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x30;phy ce29 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x40;phy ce29 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0x9 AMS_TX_DRIVERMODE=0x0" + ;; + 30) + bcmcmd "phy ce30 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x30;phy ce30 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x40;phy ce30 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0xA AMS_TX_DRIVERMODE=0x0;phy ce30 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x30" + bcmcmd "phy ce30 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x40;phy ce30 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0;phy ce30 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x30;phy ce30 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x40" + bcmcmd "phy ce30 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0xA AMS_TX_DRIVERMODE=0x0;phy ce30 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x30;phy ce30 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x40;phy ce30 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0xA AMS_TX_DRIVERMODE=0x0" + ;; + 31) + bcmcmd "phy ce31 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x39;phy ce31 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x37;phy ce31 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0xC AMS_TX_DRIVERMODE=0x0;phy ce31 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x39" + bcmcmd "phy ce31 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x37;phy ce31 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0xC AMS_TX_DRIVERMODE=0x0;phy ce31 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x30;phy ce31 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x40" + bcmcmd "phy ce31 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0;phy ce31 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x30;phy ce31 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x40;phy ce31 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0" + ;; + *) + echo "Unknown Port" + return + ;; + esac +} + +function _qsfp_dac_si_set { + case ${PORT} in + 0) + bcmcmd "phy ce0 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_PRE=0x1F;phy ce0 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x15;phy ce0 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x3C;phy ce0 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce0 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_PRE=0x1C;phy ce0 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x20;phy ce0 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x34;phy ce0 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce0 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_PRE=0x1F;phy ce0 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x15;phy ce0 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x3C;phy ce0 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce0 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_PRE=0x18;phy ce0 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x24;phy ce0 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x34;phy ce0 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + ;; + 1) + bcmcmd "phy ce1 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_PRE=0x1F;phy ce1 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x15;phy ce1 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x3C;phy ce1 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce1 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_PRE=0x1C;phy ce1 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x20;phy ce1 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x34;phy ce1 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce1 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_PRE=0x1F;phy ce1 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x15;phy ce1 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x3C;phy ce1 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce1 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_PRE=0x1C;phy ce1 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x20;phy ce1 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x34;phy ce1 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + ;; + 2) + bcmcmd "phy ce2 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_PRE=0x1F;phy ce2 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x15;phy ce2 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x3C;phy ce2 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce2 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_PRE=0x18;phy ce2 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x24;phy ce2 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x34;phy ce2 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0xD AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce2 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_PRE=0x1F;phy ce2 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x15;phy ce2 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x3C;phy ce2 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce2 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_PRE=0x14;phy ce2 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x20;phy ce2 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x3C;phy ce2 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0xD AMS_TX_DRIVERMODE=0x0" + ;; + 3) + bcmcmd "phy ce3 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_PRE=0x1F;phy ce3 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x15;phy ce3 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x3C;phy ce3 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce3 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_PRE=0x14;phy ce3 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x20;phy ce3 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x3C;phy ce3 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0xD AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce3 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_PRE=0x1F;phy ce3 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x15;phy ce3 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x3C;phy ce3 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce3 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_PRE=0x18;phy ce3 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x24;phy ce3 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x34;phy ce3 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0xD AMS_TX_DRIVERMODE=0x0" + ;; + 4) + bcmcmd "phy ce4 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_PRE=0x1F;phy ce4 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x15;phy ce4 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x3C;phy ce4 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce4 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_PRE=0x0;phy ce4 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x33;phy ce4 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x3D;phy ce4 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0xB AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce4 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_PRE=0x1F;phy ce4 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x15;phy ce4 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x3C;phy ce4 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce4 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_PRE=0x0;phy ce4 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x30;phy ce4 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x40;phy ce4 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0xA AMS_TX_DRIVERMODE=0x0" + ;; + 5) + bcmcmd "phy ce5 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_PRE=0x1F;phy ce5 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x15;phy ce5 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x3C;phy ce5 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce5 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_PRE=0x0;phy ce5 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x30;phy ce5 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x40;phy ce5 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0xB AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce5 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_PRE=0x1F;phy ce5 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x15;phy ce5 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x3C;phy ce5 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce5 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_PRE=0x0;phy ce5 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x30;phy ce5 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x40;phy ce5 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0xA AMS_TX_DRIVERMODE=0x0" + ;; + 6) + bcmcmd "phy ce6 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_PRE=0x1F;phy ce6 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x15;phy ce6 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x3C;phy ce6 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce6 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_PRE=0x0;phy ce6 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x36;phy ce6 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x3A;phy ce6 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0xC AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce6 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_PRE=0x1F;phy ce6 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x15;phy ce6 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x3C;phy ce6 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce6 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_PRE=0x0;phy ce6 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x30;phy ce6 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x40;phy ce6 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0xA AMS_TX_DRIVERMODE=0x0" + ;; + 7) + bcmcmd "phy ce7 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_PRE=0x1F;phy ce7 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x15;phy ce7 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x3C;phy ce7 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce7 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_PRE=0x0;phy ce7 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x30;phy ce7 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x40;phy ce7 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce7 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_PRE=0x1F;phy ce7 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x15;phy ce7 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x3C;phy ce7 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce7 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_PRE=0x0;phy ce7 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x30;phy ce7 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x40;phy ce7 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0" + ;; + 8) + ;; + 9) + ;; + 10) + ;; + 11) + ;; + 12) + ;; + 13) + ;; + 14) + ;; + 15) + ;; + 16) + ;; + 17) + ;; + 18) + ;; + 19) + ;; + 20) + ;; + 21) + ;; + 22) + ;; + 23) + ;; + 24) + bcmcmd "phy ce24 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_PRE=0x1F;phy ce24 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x15;phy ce24 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x3C;phy ce24 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce24 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_PRE=0x0;phy ce24 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x29;phy ce24 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x47;phy ce24 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce24 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_PRE=0X1F;phy ce24 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x15;phy ce24 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x3C;phy ce24 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce24 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_PRE=0x0;phy ce24 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x29;phy ce24 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x47;phy ce24 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0x4 AMS_TX_DRIVERMODE=0x0" + ;; + 25) + bcmcmd "phy ce25 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_PRE=0x1F;phy ce25 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x15;phy ce25 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x3C;phy ce25 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce25 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_PRE=0x0;phy ce25 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x29;phy ce25 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x47;phy ce25 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0x8 AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce25 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_PRE=0x1F;phy ce25 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x15;phy ce25 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x3C;phy ce25 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce25 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_PRE=0x0;phy ce25 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x29;phy ce25 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x47;phy ce25 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0x4 AMS_TX_DRIVERMODE=0x0" + ;; + 26) + bcmcmd "phy ce26 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_PRE=0x1F;phy ce26 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x15;phy ce26 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x3C;phy ce26 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce26 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_PRE=0x0;phy ce26 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x30;phy ce26 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x40;phy ce26 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0xA AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce26 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_PRE=0x1F;phy ce26 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x15;phy ce26 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x3C;phy ce26 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce26 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_PRE=0x0;phy ce26 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x30;phy ce26 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x40;phy ce26 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0x9 AMS_TX_DRIVERMODE=0x0" + ;; + 27) + bcmcmd "phy ce27 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_PRE=0x1F;phy ce27 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x15;phy ce27 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x3C;phy ce27 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce27 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_PRE=0x0;phy ce27 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x30;phy ce27 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x40;phy ce27 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0x9 AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce27 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_PRE=0x1F;phy ce27 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x15;phy ce27 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x3C;phy ce27 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce27 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_PRE=0x0;phy ce27 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x30;phy ce27 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x40;phy ce27 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0x9 AMS_TX_DRIVERMODE=0x0" + ;; + 28) + bcmcmd "phy ce28 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_PRE=0x1F;phy ce28 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x15;phy ce28 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x3C;phy ce28 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce28 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_PRE=0x10;phy ce28 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x18;phy ce28 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x3C;phy ce28 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0xC AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce28 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_PRE=0x1F;phy ce28 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x15;phy ce28 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x3C;phy ce28 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce28 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_PRE=0x10;phy ce28 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x1C;phy ce28 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x3C;phy ce28 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0xC AMS_TX_DRIVERMODE=0x0" + ;; + 29) + bcmcmd "phy ce29 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_PRE=0x1F;phy ce29 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x15;phy ce29 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x3C;phy ce29 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce29 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_PRE=0x10;phy ce29 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x20;phy ce29 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x3C;phy ce29 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0xC AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce29 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_PRE=0x1F;phy ce29 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x15;phy ce29 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x3C;phy ce29 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce29 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_PRE=0x10;phy ce29 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x20;phy ce29 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x3C;phy ce29 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0xC AMS_TX_DRIVERMODE=0x0" + ;; + 30) + bcmcmd "phy ce30 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_PRE=0x1F;phy ce30 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x15;phy ce30 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x3C;phy ce30 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce30 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_PRE=0x10;phy ce30 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x24;phy ce30 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x3C;phy ce30 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0xC AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce30 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_PRE=0x1F;phy ce30 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x15;phy ce30 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x3C;phy ce30 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce30 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_PRE=0x8;phy ce30 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x24;phy ce30 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x3C;phy ce30 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0xC AMS_TX_DRIVERMODE=0x0" + ;; + 31) + bcmcmd "phy ce31 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_PRE=0x1F;phy ce31 CL93N72_UT_CTL2r.0 CL93N72_TXFIR_POST=0x15;phy ce31 CL93N72_UT_CTL3r.0 CL93N72_TXFIR_MAIN=0x3C;phy ce31 AMS_TX_CTL2r.0 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce31 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_PRE=0x10;phy ce31 CL93N72_UT_CTL2r.1 CL93N72_TXFIR_POST=0x24;phy ce31 CL93N72_UT_CTL3r.1 CL93N72_TXFIR_MAIN=0x3C;phy ce31 AMS_TX_CTL2r.1 AMS_TX_AMP_CTL=0xC AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce31 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_PRE=0x1F;phy ce31 CL93N72_UT_CTL2r.2 CL93N72_TXFIR_POST=0x15;phy ce31 CL93N72_UT_CTL3r.2 CL93N72_TXFIR_MAIN=0x3C;phy ce31 AMS_TX_CTL2r.2 AMS_TX_AMP_CTL=0xF AMS_TX_DRIVERMODE=0x0" + bcmcmd "phy ce31 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_PRE=0x14;phy ce31 CL93N72_UT_CTL2r.3 CL93N72_TXFIR_POST=0x20;phy ce31 CL93N72_UT_CTL3r.3 CL93N72_TXFIR_MAIN=0x3C;phy ce31 AMS_TX_CTL2r.3 AMS_TX_AMP_CTL=0xE AMS_TX_DRIVERMODE=0x0" + ;; + *) + echo "Unknown Port" + return + ;; + esac +} + +# Help usage function +function _help { + echo "=========================================================" + echo "# Description: Help Function" + echo "=========================================================" + echo "----------------------------------------------------" + echo "EX : ${0} help" + echo " : ${0} optical [0-31]" + echo " : ${0} dac [0-31]" + echo "----------------------------------------------------" +} + +#Main Function +function _main { + + if [ "${TYPE}" == "help" ]; then + _help + elif [ "${TYPE}" == "optical" ]; then + _qsfp_optical_si_set + elif [ "${TYPE}" == "dac" ]; then + _qsfp_dac_si_set + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi +} + +_main diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/s9100_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/s9100_monitor.sh new file mode 100755 index 000000000000..974da6d5001f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/s9100_monitor.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# Copyright (C) 2016 Ingrasys, 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 3 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, see . + +INTERVAL=5 +I2C_UTILS="/usr/sbin/i2c_utils.sh" + + +# LED status monitor +function _led_monitor { + ${I2C_UTILS} i2c_led_fan_status_set >/dev/null + ${I2C_UTILS} i2c_led_psu_status_set >/dev/null + ${I2C_UTILS} i2c_led_fan_tray_status_set >/dev/null +} + +# main function +function _main { + while true + do + _led_monitor + # Sleep while still handling signals + sleep $INTERVAL & + wait $! + done +} + +_main \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/README.md b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/README.md new file mode 100644 index 000000000000..940d15f497c9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/README.md @@ -0,0 +1,184 @@ +# Ingrasys S9200-64X Platform Driver for SONiC + +Copyright (C) 2016 Ingrasys, 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 3 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, see . + + +## Licensing terms + +The Licensing terms of the files within this project is split 2 parts. +The Linux kernel is released under the GNU General Public License version 2. +All other code is released under the GNU General Public License version 3. +Please see the LICENSE file for copies of both licenses. + +## Contents of this package + + - service/ + > Service config files for platform initialization and monitoring + - utils/ + > Scripts useful during platform bringup and sysfs function + - conf/ + > Platform configure files. + +## Kernel modules and drivers + +The driver for interacting with Ingrasys S9200-64X is contained in the I2C +kernel module and initialization script. The initialization script loads +the modules in the correct order. It has been built and tested against +the Linux 3.16 kernel. + +The initialization script will modprobe the needed modules, navigate to the +module's device directory in sysfs, and write configuration data to +the kernel module. + +### IGB + +This is OOB Ports on front panel for management plane. + +The IGB module must be loaded first on Ingrasys S9200-64X platform. + +### I2C i801 + +The I2C i801 on Ingrasys S9200-64X can be found in +`/sys/bus/i2c/devices/i2c-0/` + +This is I2C bus for Clock Gen, DIMM channel and digital potentiometers. + +The i801 module must be loaded second on Ingrasys S9200-64X. + +### I2C iSMT + +The I2C iSMT module on S9200-64X can be found in +`/sys/bus/i2c/devices/i2c-1/` + +This is I2C bus for CPLD, HWM, power controller and I2C Switches. + +The i801 module must be loaded third on Ingrasys S9200-64X. + +### I2C PCA9548 +The PCA9548 module on S9200-64X can be found in +`/sys/bus/i2c/devices/i2c-2/` , `/sys/bus/i2c/devices/i2c-3/`, +`/sys/bus/i2c/devices/i2c-4/`, `/sys/bus/i2c/devices/i2c-5/`, +`/sys/bus/i2c/devices/i2c-6/`, `/sys/bus/i2c/devices/i2c-7/`, +`/sys/bus/i2c/devices/i2c-8/`, `/sys/bus/i2c/devices/i2c-9/`. + +The pca9548 module for zQSFP module get/set functions, PSU information, +fan status and EEPROM. + +## Hardware components + +The hardware components are initialized in the init script on S9200-64X. +The following describes manual initialization as well as interaction. +The examples below are just for Ingrasys S9200-64X platform. + +### Hardware initialization + +When the sonic-platform-ingrasys-s9200-64x package is installed on the S9200-64X, +it is automatically initialized. If you want to manual initialization, the +utility command usage as follows: +``` + i2c_utils.sh i2c_init +``` + +### EEPROM + +The EEPROM is including the board SKU, model name, vendor name, serial number, +and other information can be accessed with the specific eeprom kernel module. +After using `modprobe eeprom_mb` to detect the eeprom, it will show up in sysfs. + +The hexdump utility can be used to decode the raw output of the EEPROM. +For example, +``` + bash# echo "mb_eeprom 0x54" > /sys/bus/i2c/devices/i2c-9/new_device + bash# cat /sys/bus/i2c/drivers/mb_eeprom/9-0054/eeprom | hexdump -C +``` + +### Front panel LEDs + +LEDs can be setup on/off by using i2c utility `/usr/sbin/i2c_utils.sh`. +Utility function command usage as follows: + +``` +Status LED: + i2c_utils.sh i2c_sys_led green|amber + +Fan status LED: + i2c_utils.sh i2c_fan_led green|amber + +PSU1 status LED: + i2c_utils.sh i2c_psu1_led green|amber + +PSU2 status LED: + i2c_utils.sh i2c_psu2_led green|amber + +``` +QSFP Module Port LEDs control by ASIC library. + + +### Fan speed + +Fan speed are controlled by the w83795 kernel module. +It can be found in `/sys/class/hwmon/hwmon5/device/`. +If they were compiled as modules, you will need to modprobe w83795 for +their sysfs entries to show up. Each fan has an `fan_input` file +for reading the fan speed. And `pwm2` setting fan1/fan3/fan5/fan7. + +There is docker-platform-monitor container installed fancontrol package that can +automatic control platform fan speed. + + +### Temperature sensors + +Temperature sensors are controlled by the w83795 kernel +module. It can be found in `/sys/class/hwmon/hwmon5/device/`. +If they were compiled as modules, then you will need to modprobe w83795 for +their sysfs entries to show up. +`temp1_input` is front MAC temperature sensor. `temp2_input` is rear MAC +temperature sensor. + +There is docker-platform-monitor container installed lm-sensors package that can +monitor platform temperature. And `sensors` command can show each +temperature sensors status. + +### Power supplies + +Power supplies status and its EEPROM info can be used i2c utility +`/usr/sbin/i2c_utils.sh` to get. +The usage as follows: +``` +PSU EEPROM: + i2c_utils.sh i2c_psu_eeprom_get + hexdump -C psu0.rom + hexdump -C psu1.rom + +PSU Status: + i2c_utils.sh i2c_psu_status +``` + +### QSFPs +QSFP modules are managed by the pca9548 kernel driver. +The i2c utility `/usr/sbin/i2c_utils.sh` can be used to get status and +module EEPROM informations. +The usage as follows: +``` +QSFP EEPROM: + i2c_utils.sh i2c_qsfp_eeprom_get [1-64] + +QSFP Insert Event: + i2c_utils.sh i2c_qsfp_eeprom_get [1-64] + 0 => not insert + 1 => inserted +``` + diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/modules/Makefile b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/modules/Makefile new file mode 100755 index 000000000000..1a9e4e314e8e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/modules/Makefile @@ -0,0 +1,3 @@ +obj-m := eeprom_mb.o +obj-m += cpld.o +obj-m += ingrasys_s9200_64x_psu.o diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/modules/cpld.c b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/modules/cpld.c new file mode 100755 index 000000000000..7b16f5d3e321 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/modules/cpld.c @@ -0,0 +1,498 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define S9200_MUX_BASE_NR 0 +#define CPLD_DEVICE_NUM 5 + +/* CPLD registers */ +#define CPLD_REG_REV 0x01 +#define CPLD_REG_ID 0x02 +#define CPLD_REG_10G_MUX 0x41 + +/* QSFP signal bit in register */ +#define BIT_RST 0 +#define BIT_LPM 2 +#define BIT_INT 0 +#define BIT_ABS 1 + +static void device_release(struct device *dev) +{ + return; +} + +/* + * S9200 CPLD register addresses + */ +static const int int_abs_reg[CPLD_DEVICE_NUM][2]= { + {0x20, 0x2B}, + {0x20, 0x2C}, + {0x20, 0x2C}, + {0x20, 0x2C}, + {0x20, 0x2C} +}; + +static const int rst_lp_reg[CPLD_DEVICE_NUM][2]= { + {0x30, 0x3B}, + {0x30, 0x3C}, + {0x30, 0x3C}, + {0x30, 0x3C}, + {0x30, 0x3C} +}; + +/* + * S9200 CPLD + */ + +enum cpld_type { + cpld_1, + cpld_2, + cpld_3, + cpld_4, + cpld_5, +}; + +enum qsfp_signal { + sig_int, + sig_abs, + sig_rst, + sig_lpm +}; + +struct cpld_platform_data { + int reg_addr; + struct i2c_client *client; +}; + +static struct cpld_platform_data s9200_cpld_platform_data[] = { + [cpld_1] = { + .reg_addr = 0x33, + }, + + [cpld_2] = { + .reg_addr = 0x33, + }, + + [cpld_3] = { + .reg_addr = 0x33, + }, + + [cpld_4] = { + .reg_addr = 0x33, + }, + + [cpld_5] = { + .reg_addr = 0x33, + }, +}; + +static struct platform_device s9200_cpld = { + .name = "ingrasys-s9200-cpld", + .id = 0, + .dev = { + .platform_data = s9200_cpld_platform_data, + .release = device_release + }, +}; + +/* + * S9200 I2C DEVICES + */ + +struct i2c_device_platform_data { + int parent; + struct i2c_board_info info; + struct i2c_client *client; +}; + +/* module_platform_driver */ +static ssize_t get_cpld_reg(struct device *dev, struct device_attribute *devattr, char *buf, int signal) +{ + int ret; + u64 data = 0; + u64 shift = 0; + int i = 0; + int j = 0; + int port = 0; + int bit = 0; + int bit_mask = 0; + int (*reg)[CPLD_DEVICE_NUM][2]; + struct cpld_platform_data *pdata = NULL; + + pdata = dev->platform_data; + + switch(signal) { + case sig_int: + bit = BIT_INT; + reg = (typeof(reg)) &int_abs_reg; + break; + case sig_abs: + bit = BIT_ABS; + reg = (typeof(reg)) &int_abs_reg; + break; + case sig_rst: + bit = BIT_RST; + reg = (typeof(reg)) &rst_lp_reg; + break; + case sig_lpm: + bit = BIT_LPM; + reg = (typeof(reg)) &rst_lp_reg; + break; + default: + return sprintf(buf, "na"); + } + bit_mask = 0x1 << bit; + + for (i=0; i> bit)) << port; + data |= shift; + port++; + } + } + + return sprintf(buf, "0x%016llx\n", data); +} + +static ssize_t set_cpld_reg(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count, int signal) +{ + unsigned long data; + int err; + struct cpld_platform_data *pdata = dev->platform_data; + u8 current_reg_val = 0; + u8 new_reg_val = 0; + int value; + int i = 0; + int j = 0; + int port = 0; + int ret = 0; + int bit = 0; + int (*reg)[CPLD_DEVICE_NUM][2]; + + err = kstrtoul(buf, 16, &data); + if (err) + return err; + + switch(signal) { + case sig_int: + bit = BIT_INT; + reg = (typeof(reg)) &int_abs_reg; + break; + case sig_abs: + bit = BIT_ABS; + reg = (typeof(reg)) &int_abs_reg; + break; + case sig_rst: + bit = BIT_RST; + reg = (typeof(reg)) &rst_lp_reg; + break; + case sig_lpm: + bit = BIT_LPM; + reg = (typeof(reg)) &rst_lp_reg; + break; + default: + return sprintf(buf, "na"); + } + + for (i=0; i> port) & 0x1; + + //set value on bit N of new_reg_val + if (value > 0) { + new_reg_val = current_reg_val | (u8) (0x1 << bit); + } else { + new_reg_val = current_reg_val & (u8) ~(0x1 << bit); + } + //write reg value if changed + if (current_reg_val != new_reg_val) { + ret = i2c_smbus_write_byte_data(pdata[i].client, j, + (u8)(new_reg_val)); + if (ret < 0){ + return ret; + } + } + port++; + } + } + + return count; +} + +static ssize_t get_lpmode(struct device *dev, struct device_attribute *devattr, char *buf) +{ + return get_cpld_reg(dev, devattr, buf, sig_lpm); +} + +static ssize_t set_lpmode(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + return set_cpld_reg(dev, devattr, buf, count, sig_lpm); +} + +static ssize_t get_reset(struct device *dev, struct device_attribute *devattr, char *buf) +{ + return get_cpld_reg(dev, devattr, buf, sig_rst); +} + +static ssize_t set_reset(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + return set_cpld_reg(dev, devattr, buf, count, sig_rst); +} + +static ssize_t get_modprs(struct device *dev, struct device_attribute *devattr, char *buf) +{ + return get_cpld_reg(dev, devattr, buf, sig_abs); +} + +static ssize_t get_int(struct device *dev, struct device_attribute *devattr, char *buf) +{ + return get_cpld_reg(dev, devattr, buf, sig_int); +} + +static ssize_t get_cpld_version(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int i = 0; + int cnt = 0; + u8 reg_val_rev[CPLD_DEVICE_NUM]; + u8 reg_val_id[CPLD_DEVICE_NUM]; + + struct cpld_platform_data *pdata = dev->platform_data; + + //get reg value + for (i=0; i> 6 & 0x1, + reg_val_id[i] & 0x7); + } + + return cnt; +} + +static ssize_t set_10g_mux(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + u8 data; + u8 current_reg_val = 0; + u8 new_reg_val = 0; + int cpld_dev_num=cpld_1; + int reg_offset=CPLD_REG_10G_MUX; + int err; + struct cpld_platform_data *pdata = dev->platform_data; + int value; + int i = 0; + int port = 0; + int ret = 0; + int bit = 0; + + err = kstrtou8(buf, 16, &new_reg_val); + if (err) + return err; + + //read reg value + current_reg_val = i2c_smbus_read_byte_data(pdata[cpld_dev_num].client, reg_offset); + if (current_reg_val < 0) { + return current_reg_val; + } + + //write reg value if changed + if (current_reg_val != new_reg_val) { + ret = i2c_smbus_write_byte_data(pdata[cpld_dev_num].client, reg_offset, + (u8)(new_reg_val)); + if (ret < 0){ + return ret; + } + } + + return count; +} + +static ssize_t get_10g_mux(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int cpld_dev_num=cpld_1; + int reg_offset=CPLD_REG_10G_MUX; + u8 reg_val=0; + struct cpld_platform_data *pdata = dev->platform_data; + + //read 10G mux register + reg_val = i2c_smbus_read_byte_data(pdata[cpld_dev_num].client, reg_offset); + if (reg_val < 0) { + return sprintf(buf, "na"); + } + + return sprintf(buf, "0x%x\n", reg_val); +} + +static DEVICE_ATTR(qsfp_int, S_IRUGO, get_int, NULL); +static DEVICE_ATTR(qsfp_modprs, S_IRUGO, get_modprs, NULL); +static DEVICE_ATTR(qsfp_lpmode, S_IRUGO | S_IWUSR, get_lpmode, set_lpmode); +static DEVICE_ATTR(qsfp_reset, S_IRUGO | S_IWUSR, get_reset, set_reset); +static DEVICE_ATTR(cpld_version, S_IRUGO, get_cpld_version, NULL); +static DEVICE_ATTR(cpld_10g_mux, S_IRUGO | S_IWUSR, get_10g_mux, set_10g_mux); + +static struct attribute *s9200_cpld_attrs[] = { + &dev_attr_qsfp_int.attr, + &dev_attr_qsfp_lpmode.attr, + &dev_attr_qsfp_reset.attr, + &dev_attr_qsfp_modprs.attr, + &dev_attr_cpld_version.attr, + &dev_attr_cpld_10g_mux.attr, + NULL, +}; + +static struct attribute_group s9200_cpld_attr_grp = { + .attrs = s9200_cpld_attrs, +}; + +static int __init cpld_probe(struct platform_device *pdev) +{ + struct cpld_platform_data *pdata; + struct i2c_adapter *parent[CPLD_DEVICE_NUM]; + int i; + int ret; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + return -ENODEV; + } + + for (i = 0; i < CPLD_DEVICE_NUM; i++) { + parent[i] = i2c_get_adapter(S9200_MUX_BASE_NR + i + 1); + if (!parent[i]) { + printk(KERN_WARNING "Parent adapter (%d) not found\n", + S9200_MUX_BASE_NR + i + 1); + return -ENODEV; + } + pdata[i].client = i2c_new_dummy(parent[i], pdata[i].reg_addr); + if (!pdata[i].client) { + printk(KERN_WARNING "Fail to create dummy i2c client for addr %d\n", pdata[i].reg_addr); + goto error; + } + } + + ret = sysfs_create_group(&pdev->dev.kobj, &s9200_cpld_attr_grp); + if (ret) + goto error; + + return 0; + +error: + i2c_put_adapter(parent[i]); + i--; + for (; i >= 0; i--) { + if (pdata[i].client) { + i2c_unregister_device(pdata[i].client); + i2c_put_adapter(parent[i]); + } + } + + return -ENODEV; +} + +static int __exit cpld_remove(struct platform_device *pdev) +{ + int i; + struct i2c_adapter *parent = NULL; + struct cpld_platform_data *pdata = pdev->dev.platform_data; + + sysfs_remove_group(&pdev->dev.kobj, &s9200_cpld_attr_grp); + + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + } else { + for (i = 0; i < CPLD_DEVICE_NUM; i++) { + if (pdata[i].client) { + parent = (pdata[i].client)->adapter; + i2c_unregister_device(pdata[i].client); + i2c_put_adapter(parent); + } + } + } + + return 0; +} + +static struct platform_driver cpld_driver = { + .probe = cpld_probe, + .remove = __exit_p(cpld_remove), + .driver = { + .owner = THIS_MODULE, + .name = "ingrasys-s9200-cpld", + }, +}; + +static int __init ingrasys_s9200_platform_init(void) +{ + int ret = 0; + + printk("ingrasysl_s9200_platform module initialization\n"); + + mdelay(10000); + + ret = platform_driver_register(&cpld_driver); + if (ret) { + printk(KERN_WARNING "Fail to register cpld driver\n"); + goto error_cpld_driver; + } + ret = platform_device_register(&s9200_cpld); + if (ret) { + printk(KERN_WARNING "Fail to create cpld device\n"); + goto error_cpld; + } + + return 0; + +error_cpld: + platform_driver_unregister(&cpld_driver); +error_cpld_driver: + return ret; +} + +static void __exit ingrasys_s9200_platform_exit(void) +{ + platform_device_unregister(&s9200_cpld); + platform_driver_unregister(&cpld_driver); +} + +module_init(ingrasys_s9200_platform_init); +module_exit(ingrasys_s9200_platform_exit); + +MODULE_DESCRIPTION("Ingrasys S9200 Platform Support"); +MODULE_AUTHOR("Jason Tsai "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/modules/eeprom_mb.c b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/modules/eeprom_mb.c new file mode 100755 index 000000000000..1cdb26658f5a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/modules/eeprom_mb.c @@ -0,0 +1,267 @@ +/* + * Copyright (C) 1998, 1999 Frodo Looijaard and + * Philip Edelbrock + * Copyright (C) 2003 Greg Kroah-Hartman + * Copyright (C) 2003 IBM Corp. + * Copyright (C) 2004 Jean Delvare + * + * 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. + */ + +/* enable dev_dbg print out */ +//#define DEBUG + +#include +#include +#include +#include +#include +#include +#include + +/* Addresses to scan */ +static const unsigned short normal_i2c[] = { /*0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57,*/ I2C_CLIENT_END }; + +/* Size of EEPROM in bytes */ +#define EEPROM_SIZE 512 + +#define SLICE_BITS (6) +#define SLICE_SIZE (1 << SLICE_BITS) +#define SLICE_NUM (EEPROM_SIZE/SLICE_SIZE) + +/* Each client has this additional data */ +struct eeprom_data { + struct mutex update_lock; + u8 valid; /* bitfield, bit!=0 if slice is valid */ + unsigned long last_updated[SLICE_NUM]; /* In jiffies, 8 slices */ + u8 data[EEPROM_SIZE]; /* Register values */ +}; + + +static void mb_eeprom_update_client(struct i2c_client *client, u8 slice) +{ + struct eeprom_data *data = i2c_get_clientdata(client); + int i, j; + int ret; + int addr; + + mutex_lock(&data->update_lock); + + if (!(data->valid & (1 << slice)) || + time_after(jiffies, data->last_updated[slice] + 300 * HZ)) { + dev_dbg(&client->dev, "Starting eeprom update, slice %u\n", slice); + + addr = slice << SLICE_BITS; + + ret = i2c_smbus_write_byte_data(client, (u8)((addr >> 8) & 0xFF), (u8)(addr & 0xFF)); + /* select the eeprom address */ + if (ret < 0) { + dev_err(&client->dev, "address set failed\n"); + goto exit; + } + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BYTE)) { + goto exit; + } + + for (i = slice << SLICE_BITS; i < (slice + 1) << SLICE_BITS; i+= SLICE_SIZE) { + for (j = i; j < (i+SLICE_SIZE); j++) { + int res; + + res = i2c_smbus_read_byte(client); + if (res < 0) { + goto exit; + } + + data->data[j] = res & 0xFF; + } + } + + data->last_updated[slice] = jiffies; + data->valid |= (1 << slice); + } +exit: + mutex_unlock(&data->update_lock); +} + +static ssize_t mb_eeprom_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj)); + struct eeprom_data *data = i2c_get_clientdata(client); + u8 slice; + + if (off > EEPROM_SIZE) { + return 0; + } + if (off + count > EEPROM_SIZE) { + count = EEPROM_SIZE - off; + } + if (count == 0) { + return 0; + } + + /* Only refresh slices which contain requested bytes */ + for (slice = off >> SLICE_BITS; slice <= (off + count - 1) >> SLICE_BITS; slice++) { + mb_eeprom_update_client(client, slice); + } + + memcpy(buf, &data->data[off], count); + + return count; +} + +static ssize_t mb_eeprom_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj)); + struct eeprom_data *data = i2c_get_clientdata(client); + int ret; + int i; + u8 cmd; + u16 value16; + + dev_dbg(&client->dev, "mb_eeprom_write off=%d, count=%d\n", (int)off, (int)count); + + if (off > EEPROM_SIZE) { + return 0; + } + if (off + count > EEPROM_SIZE) { + count = EEPROM_SIZE - off; + } + if (count == 0) { + return 0; + } + + mutex_lock(&data->update_lock); + + for(i=0; i < count; i++) { + /* write command */ + cmd = (off >> 8) & 0xff; + value16 = off & 0xff; + value16 |= buf[i] << 8; + ret = i2c_smbus_write_word_data(client, cmd, value16); + + if (ret < 0) { + dev_err(&client->dev, "write address failed at %d \n", (int)off); + goto exit; + } + + off++; + + /* need to wait for write complete */ + udelay(10000); + } +exit: + mutex_unlock(&data->update_lock); + /* force to update client when reading */ + for(i=0; i < SLICE_NUM; i++) { + data->last_updated[i] = 0; + } + + return count; +} + +static struct bin_attribute mb_eeprom_attr = { + .attr = { + .name = "eeprom", + .mode = S_IRUGO | S_IWUSR, + }, + .size = EEPROM_SIZE, + .read = mb_eeprom_read, + .write = mb_eeprom_write, +}; + +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int mb_eeprom_detect(struct i2c_client *client, struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = client->adapter; + + /* EDID EEPROMs are often 24C00 EEPROMs, which answer to all + addresses 0x50-0x57, but we only care about 0x51 and 0x55. So decline + attaching to addresses >= 0x56 on DDC buses */ + if (!(adapter->class & I2C_CLASS_SPD) && client->addr >= 0x56) { + return -ENODEV; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE) + && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { + return -ENODEV; + } + + strlcpy(info->type, "eeprom", I2C_NAME_SIZE); + + return 0; +} + +static int mb_eeprom_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct eeprom_data *data; + int err; + + if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) { + err = -ENOMEM; + goto exit; + } + + memset(data->data, 0xff, EEPROM_SIZE); + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + /* create the sysfs eeprom file */ + err = sysfs_create_bin_file(&client->dev.kobj, &mb_eeprom_attr); + if (err) { + goto exit_kfree; + } + + return 0; + +exit_kfree: + kfree(data); +exit: + return err; +} + +static int mb_eeprom_remove(struct i2c_client *client) +{ + sysfs_remove_bin_file(&client->dev.kobj, &mb_eeprom_attr); + kfree(i2c_get_clientdata(client)); + + return 0; +} + +static const struct i2c_device_id mb_eeprom_id[] = { + { "mb_eeprom", 0 }, + { } +}; + +static struct i2c_driver mb_eeprom_driver = { + .driver = { + .name = "mb_eeprom", + }, + .probe = mb_eeprom_probe, + .remove = mb_eeprom_remove, + .id_table = mb_eeprom_id, + + .class = I2C_CLASS_DDC | I2C_CLASS_SPD, + .detect = mb_eeprom_detect, + .address_list = normal_i2c, +}; + +module_i2c_driver(mb_eeprom_driver); + +MODULE_AUTHOR("Wade "); +MODULE_DESCRIPTION("Ingrasys Mother Board EEPROM driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/modules/ingrasys_s9200_64x_platform.h b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/modules/ingrasys_s9200_64x_platform.h new file mode 100644 index 000000000000..8a38965e7932 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/modules/ingrasys_s9200_64x_platform.h @@ -0,0 +1,148 @@ +#ifndef _S9200_64X_PLATFORM_H +#define _S9200_64X_PLATFORM_H + +#include + +// remove debug before release +#define DEBUG + +enum bus_order { + I2C_BUS_MAIN, + MUX_9548_0_CH0, + MUX_9548_0_CH1, + MUX_9548_0_CH2, + MUX_9548_0_CH3, + MUX_9548_0_CH4, + MUX_9548_0_CH5, + MUX_9548_0_CH6, + MUX_9548_0_CH7, + MUX_9548_1_CH0, + MUX_9548_1_CH1, + MUX_9548_1_CH2, + MUX_9548_1_CH3, + MUX_9548_1_CH4, + MUX_9548_1_CH5, + MUX_9548_1_CH6, + MUX_9548_1_CH7, + MUX_9546_0_CH0, + MUX_9546_0_CH1, + MUX_9546_0_CH2, + MUX_9546_0_CH3, + MUX_9546_1_CH0, + MUX_9546_1_CH1, + MUX_9546_1_CH2, + MUX_9546_1_CH3, + MUX_9548_2_CH0, + MUX_9548_2_CH1, + MUX_9548_2_CH2, + MUX_9548_2_CH3, + MUX_9548_2_CH4, + MUX_9548_2_CH5, + MUX_9548_2_CH6, + MUX_9548_2_CH7, + MUX_9548_3_CH0, + MUX_9548_3_CH1, + MUX_9548_3_CH2, + MUX_9548_3_CH3, + MUX_9548_3_CH4, + MUX_9548_3_CH5, + MUX_9548_3_CH6, + MUX_9548_3_CH7, + MUX_9548_4_CH0, + MUX_9548_4_CH1, + MUX_9548_4_CH2, + MUX_9548_4_CH3, + MUX_9548_4_CH4, + MUX_9548_4_CH5, + MUX_9548_4_CH6, + MUX_9548_4_CH7, + MUX_9548_5_CH0, + MUX_9548_5_CH1, + MUX_9548_5_CH2, + MUX_9548_5_CH3, + MUX_9548_5_CH4, + MUX_9548_5_CH5, + MUX_9548_5_CH6, + MUX_9548_5_CH7, + MUX_9548_6_CH0, + MUX_9548_6_CH1, + MUX_9548_6_CH2, + MUX_9548_6_CH3, + MUX_9548_6_CH4, + MUX_9548_6_CH5, + MUX_9548_6_CH6, + MUX_9548_6_CH7, + MUX_9548_7_CH0, + MUX_9548_7_CH1, + MUX_9548_7_CH2, + MUX_9548_7_CH3, + MUX_9548_7_CH4, + MUX_9548_7_CH5, + MUX_9548_7_CH6, + MUX_9548_7_CH7, + MUX_9548_8_CH0, + MUX_9548_8_CH1, + MUX_9548_8_CH2, + MUX_9548_8_CH3, + MUX_9548_8_CH4, + MUX_9548_8_CH5, + MUX_9548_8_CH6, + MUX_9548_8_CH7, + MUX_9548_9_CH0, + MUX_9548_9_CH1, + MUX_9548_9_CH2, + MUX_9548_9_CH3, + MUX_9548_9_CH4, + MUX_9548_9_CH5, + MUX_9548_9_CH6, + MUX_9548_9_CH7, + MUX_9548_10_CH0, + MUX_9548_10_CH1, + MUX_9548_10_CH2, + MUX_9548_10_CH3, + MUX_9548_10_CH4, + MUX_9548_10_CH5, + MUX_9548_10_CH6, + MUX_9548_10_CH7, +}; + +#define I2C_ADDR_MUX_9555_0 (0x20) +#define I2C_ADDR_MUX_9555_1 (0x24) +#define I2C_ADDR_MUX_9555_2 (0x25) +#define I2C_ADDR_MUX_9555_3 (0x26) +#define I2C_ADDR_MUX_9539_0 (0x76) +#define I2C_ADDR_MUX_9539_1 (0x76) +#define I2C_BUS_FAN_STATUS (I2C_BUS_MAIN) +#define I2C_BUS_SYS_LED (MUX_9548_1_CH1) + +#define NUM_OF_I2C_MUX (11) +#define NUM_OF_CPLD (5) +#define NUM_OF_QSFP_PORT (64) +#define NUM_OF_SFP_PORT (2) +#define QSFP_EEPROM_I2C_ADDR (0x50) + +enum gpio_reg { + REG_PORT0_IN, + REG_PORT1_IN, + REG_PORT0_OUT, + REG_PORT1_OUT, + REG_PORT0_POL, + REG_PORT1_POL, + REG_PORT0_DIR, + REG_PORT1_DIR, +}; + +struct ing_i2c_board_info { + int ch; + int size; + struct i2c_board_info *board_info; +}; + +struct i2c_init_data { + __u16 ch; + __u16 addr; + __u8 reg; + __u8 value; +}; + +#endif diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/modules/ingrasys_s9200_64x_psu.c b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/modules/ingrasys_s9200_64x_psu.c new file mode 100644 index 000000000000..46642f1271ca --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/modules/ingrasys_s9200_64x_psu.c @@ -0,0 +1,389 @@ +/* + * S9200-64X PSU driver + * + * Copyright (C) 2017 Ingrasys, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ingrasys_s9200_64x_platform.h" + +static ssize_t show_psu_eeprom(struct device *dev, + struct device_attribute *da, + char *buf); +static struct s9200_psu_data *s9200_psu_update_status(struct device *dev); +static struct s9200_psu_data *s9200_psu_update_eeprom(struct device *dev); +static int s9200_psu_read_block(struct i2c_client *client, + u8 command, + u8 *data, + int data_len); + + +#define DRIVER_NAME "psu" + +// Addresses scanned +static const unsigned short normal_i2c[] = { 0x50, I2C_CLIENT_END }; + +/* PSU EEPROM SIZE */ +#define EEPROM_SZ 256 +#define READ_EEPROM 1 +#define NREAD_EEPROM 0 + +static struct i2c_client pca9555_client; + +/* pca9555 gpio pin mapping */ +#define PSU2_PWROK 0 +#define PSU2_PRSNT_L 1 +#define PSU2_PWRON_L 2 +#define PSU1_PWROK 3 +#define PSU1_PRSNT_L 4 +#define PSU1_PWRON_L 5 +#define TMP_75_INT_L 6 + +/* Driver Private Data */ +struct s9200_psu_data { + struct mutex lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 index; /* PSU index */ + s32 status; /* IO expander value */ + char eeprom[EEPROM_SZ]; /* psu eeprom data */ + char psuABS; /* PSU absent */ + char psuPG; /* PSU power good */ +}; + +enum psu_index +{ + s9200_psu1, + s9200_psu2 +}; + +/* + * display power good attribute + */ +static ssize_t +show_psu_pg(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct s9200_psu_data *data = s9200_psu_update_status(dev); + unsigned int value; + + mutex_lock(&data->lock); + value = data->psuPG; + mutex_unlock(&data->lock); + + return sprintf(buf, "%d\n", value); +} + +/* + * display power absent attribute + */ +static ssize_t +show_psu_abs(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct s9200_psu_data *data = s9200_psu_update_status(dev); + unsigned int value; + + mutex_lock(&data->lock); + value = data->psuABS; + mutex_unlock(&data->lock); + + return sprintf(buf, "%d\n", value); +} + + +/* + * sysfs attributes for psu + */ +static DEVICE_ATTR(psu_pg, S_IRUGO, show_psu_pg, NULL); +static DEVICE_ATTR(psu_abs, S_IRUGO, show_psu_abs, NULL); +static DEVICE_ATTR(psu_eeprom, S_IRUGO, show_psu_eeprom, NULL); + +static struct attribute *s9200_psu_attributes[] = { + &dev_attr_psu_pg.attr, + &dev_attr_psu_abs.attr, + &dev_attr_psu_eeprom.attr, + NULL +}; + +/* + * display psu eeprom content + */ +static ssize_t +show_psu_eeprom(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct s9200_psu_data *data = s9200_psu_update_eeprom(dev); + + memcpy(buf, (char *)data->eeprom, EEPROM_SZ); + return EEPROM_SZ; +} + +static const struct attribute_group s9200_psu_group = { + .attrs = s9200_psu_attributes, +}; + +/* + * check gpio expander is accessible + */ +static int +pca9555_detect(struct i2c_client *client) +{ + if (i2c_smbus_read_byte_data(client, REG_PORT0_DIR) < 0) { + return -ENODEV; + } + + return 0; +} + +/* + * client address init + */ +static void +i2c_devices_client_address_init(struct i2c_client *client) +{ + pca9555_client = *client; + pca9555_client.addr = 0x25; +} + +static int +s9200_psu_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct s9200_psu_data *data; + int status, err; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct s9200_psu_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + memset(data, 0, sizeof(struct s9200_psu_data)); + i2c_set_clientdata(client, data); + data->valid = 0; + data->index = dev_id->driver_data; + mutex_init(&data->lock); + + i2c_devices_client_address_init(client); + + err = pca9555_detect(&pca9555_client); + if (err) { + dev_info(&client->dev, "pca9555_detect failed\n"); + return err; + } + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &s9200_psu_group); + if (status) { + goto exit_free; + } + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &s9200_psu_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int +s9200_psu_remove(struct i2c_client *client) +{ + struct s9200_psu_data *data = i2c_get_clientdata(client); + + sysfs_remove_group(&client->dev.kobj, &s9200_psu_group); + kfree(data); + + return 0; +} + + +/* + * psu eeprom read utility + */ +static int +s9200_psu_read_block(struct i2c_client *client, + u8 command, + u8 *data, + int data_len) +{ + int i=0, ret=0; + int blk_max = 32; //max block read size + + /* read eeprom, 32 * 8 = 256 bytes */ + for (i=0; i < EEPROM_SZ/blk_max; i++) { + ret = i2c_smbus_read_i2c_block_data(client, (i*blk_max), blk_max, + data + (i*blk_max)); + if (ret < 0) { + return ret; + } + } + return ret; +} + +/* + * update eeprom content + */ +static struct s9200_psu_data +*s9200_psu_update_eeprom(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct s9200_psu_data *data = i2c_get_clientdata(client); + s32 status = 0; + int psu_pwrok = 0; + int psu_prsnt_l = 0; + + mutex_lock(&data->lock); + + if (time_after(jiffies, data->last_updated + 300 * HZ) + || !data->valid) { + + /* Read psu status */ + + status = i2c_smbus_read_word_data(&(pca9555_client), REG_PORT0_IN); + data->status = status; + + /*read psu status from io expander*/ + + if (data->index == s9200_psu1) { + psu_pwrok = PSU1_PWROK; + psu_prsnt_l = PSU1_PRSNT_L; + } else { + psu_pwrok = PSU2_PWROK; + psu_prsnt_l = PSU2_PRSNT_L; + } + data->psuPG = (status >> psu_pwrok) & 0x1; + data->psuABS = (status >> psu_prsnt_l) & 0x1; + + /* Read eeprom */ + if (!data->psuABS) { + //clear local eeprom data + memset(data->eeprom, 0, EEPROM_SZ); + + //read eeprom + status = s9200_psu_read_block(client, 0, data->eeprom, + ARRAY_SIZE(data->eeprom)); + + if (status < 0) { + memset(data->eeprom, 0, EEPROM_SZ); + dev_err(&client->dev, "Read eeprom failed, status=(%d)\n", status); + } else { + data->valid = 1; + } + } else { + memset(data->eeprom, 0, EEPROM_SZ); + } + data->last_updated = jiffies; + } + + mutex_unlock(&data->lock); + + return data; +} + +/* + * update psu status + */ +static struct s9200_psu_data +*s9200_psu_update_status(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct s9200_psu_data *data = i2c_get_clientdata(client); + s32 status = 0; + int psu_pwrok = 0; + int psu_prsnt_l = 0; + + mutex_lock(&data->lock); + + /* Read psu status */ + + status = i2c_smbus_read_word_data(&(pca9555_client), REG_PORT0_IN); + data->status = status; + + /*read psu status from io expander*/ + + if (data->index == s9200_psu1) { + psu_pwrok = PSU1_PWROK; + psu_prsnt_l = PSU1_PRSNT_L; + } else { + psu_pwrok = PSU2_PWROK; + psu_prsnt_l = PSU2_PRSNT_L; + } + data->psuPG = (status >> psu_pwrok) & 0x1; + data->psuABS = (status >> psu_prsnt_l) & 0x1; + + mutex_unlock(&data->lock); + + return data; +} + +static const struct i2c_device_id s9200_psu_id[] = { + { "psu1", s9200_psu1 }, + { "psu2", s9200_psu2 }, + {} +}; + +MODULE_DEVICE_TABLE(i2c, s9200_psu_id); + +static struct i2c_driver s9200_psu_driver = { + .driver = { + .name = DRIVER_NAME, + }, + .probe = s9200_psu_probe, + .remove = s9200_psu_remove, + .id_table = s9200_psu_id, + .address_list = normal_i2c, +}; + +static int __init s9200_psu_init(void) +{ + return i2c_add_driver(&s9200_psu_driver); +} + +static void __exit s9200_psu_exit(void) +{ + i2c_del_driver(&s9200_psu_driver); +} + +module_init(s9200_psu_init); +module_exit(s9200_psu_exit); + +MODULE_AUTHOR("Jason Tsai "); +MODULE_DESCRIPTION("S9200-64X psu driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/service/qsfp-monitor.service b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/service/qsfp-monitor.service new file mode 100644 index 000000000000..bcb9beb6a999 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/service/qsfp-monitor.service @@ -0,0 +1,15 @@ +[Unit] +Description= This QSFP Monitor service is to setup QSFP SI. +Requires=s9200-64x-monitor.service +After=s9200-64x-monitor.service + +[Service] +ExecStart=/usr/sbin/qsfp_monitor.sh +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/service/s9200-64x-monitor.service b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/service/s9200-64x-monitor.service new file mode 100644 index 000000000000..bd92628a6c3f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/service/s9200-64x-monitor.service @@ -0,0 +1,19 @@ +[Unit] +Description= This Platform Monitor service is to initialize platform and monitor platform. +Before=platform-monitor.service +After=sysinit.target +Wants=fancontrol.service +Wants=qsfp-monitor.service +DefaultDependencies=no + +[Service] +ExecStartPre=/usr/sbin/i2c_utils.sh i2c_init +ExecStart=/usr/sbin/s9200_64x_monitor.sh +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/i2c_utils.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/i2c_utils.sh new file mode 100644 index 000000000000..d0ca56f4d1b0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/i2c_utils.sh @@ -0,0 +1,1942 @@ +#!/bin/bash + +# Copyright (C) 2016 Ingrasys, 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 3 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, see . + +VERSION="1.0.0" +TRUE=200 +FALSE=404 + +EXEC_FUNC=${1} +COLOR_LED=${2} +QSFP_PORT=${2} +QSFP_INIT_ACTION=${2} +MB_EEPROM_ACTION=${2} +TARGET_10G_MUX=${2} +QSFP_ACTION=${3} +QSFP_VALUE=${4} +ONOFF_LED=${3} +FAN_TRAY=${4} + +############################################################ +# Distributor ID: Debian +# Description: Debian GNU/Linux 8.6 (jessie) +# Release: 8.6 +# Codename: jessie +# Linux debian 3.16.0-4-amd64 #1 +# SMP Debian 3.16.36-1+deb8u1 (2016-09-03) x86_64 GNU/Linux +############################################################ + +# Color Definition +COLOR_TITLE="\e[1;32m" ### Green ### +COLOR_WARNING="\e[1;33m" ### Yellow ### +COLOR_ERROR="\e[1;31m" ### Red ### +COLOR_END="\e[0m" ### END ### + +I2C_NUM=0 +NUM_I801_DEVICE=$((I2C_NUM++)) #0 + +#MUX PCA9548#0 CPLD (I2C_NUM 1~8) +NUM_MUX_9548_CPLD_CHAN=() +for (( i=0; i<8; ++i )) +do + NUM_MUX_9548_CPLD_CHAN[i]=$((I2C_NUM++)) +done + +#MUX PCA9548#1 UCD (I2C_NUM 9~16) +NUM_MUX_9548_UCD_CHAN=() +for (( i=0; i<8; ++i )) +do + NUM_MUX_9548_UCD_CHAN[i]=$((I2C_NUM++)) +done + +#MUX PCA9545 PSU (I2C_NUM 17~20) +NUM_MUX_9545_PSU_CHAN=() +for (( i=0; i<4; ++i )) +do + NUM_MUX_9545_PSU_CHAN[i]=$((I2C_NUM++)) +done + +#MUX PCA9548 QSFP ROOT (I2C_NUM 21~28) +NUM_MUX_9548_QSFP_ROOT_CHAN=() +for (( i=0; i<8; ++i )) +do + NUM_MUX_9548_QSFP_ROOT_CHAN[i]=$((I2C_NUM++)) +done + +#MUX PCA9548 QSFP Port 0~7 (I2C_NUM 29~36) +NUM_MUX_9548_QSFP_0_CHAN=() +for (( i=0; i<8; ++i )) +do + NUM_MUX_9548_QSFP_0_CHAN[i]=$((I2C_NUM++)) +done + +#MUX PCA9548 QSFP Port 8~15 (I2C_NUM 37~44) +NUM_MUX_9548_QSFP_1_CHAN=() +for (( i=0; i<8; ++i )) +do + NUM_MUX_9548_QSFP_1_CHAN[i]=$((I2C_NUM++)) +done + +#MUX PCA9548 QSFP Port 16~23 (I2C_NUM 45~52) +NUM_MUX_9548_QSFP_2_CHAN=() +for (( i=0; i<8; ++i )) +do + NUM_MUX_9548_QSFP_2_CHAN[i]=$((I2C_NUM++)) +done + +#MUX PCA9548 QSFP Port 24~31 (I2C_NUM 53~60) +NUM_MUX_9548_QSFP_3_CHAN=() +for (( i=0; i<8; ++i )) +do + NUM_MUX_9548_QSFP_3_CHAN[i]=$((I2C_NUM++)) +done + +#MUX PCA9548 QSFP Port 32~39 (I2C_NUM 61~68) +NUM_MUX_9548_QSFP_4_CHAN=() +for (( i=0; i<8; ++i )) +do + NUM_MUX_9548_QSFP_4_CHAN[i]=$((I2C_NUM++)) +done + +#MUX PCA9548 QSFP Port 40~47 (I2C_NUM 69~76) +NUM_MUX_9548_QSFP_5_CHAN=() +for (( i=0; i<8; ++i )) +do + NUM_MUX_9548_QSFP_5_CHAN[i]=$((I2C_NUM++)) +done + +#MUX PCA9548 QSFP Port 48~55 (I2C_NUM 77~84) +NUM_MUX_9548_QSFP_6_CHAN=() +for (( i=0; i<8; ++i )) +do + NUM_MUX_9548_QSFP_6_CHAN[i]=$((I2C_NUM++)) +done + +#MUX PCA9548 QSFP Port 56~63 (I2C_NUM 85~92) +NUM_MUX_9548_QSFP_7_CHAN=() +for (( i=0; i<8; ++i )) +do + NUM_MUX_9548_QSFP_7_CHAN[i]=$((I2C_NUM++)) +done + +#MUX PCA9545 SFP (I2C_NUM 93~96) +NUM_MUX_9545_SFP_CHAN=() +for (( i=0; i<4; ++i )) +do + NUM_MUX_9545_SFP_CHAN[i]=$((I2C_NUM++)) +done + +#MUX PCA9548 CPLD SW Upgrade (I2C_NUM 97~104) +NUM_MUX_9548_CPLD_SW_CHAN=() +for (( i=0; i<8; ++i )) +do + NUM_MUX_9548_CPLD_SW_CHAN[i]=$((I2C_NUM++)) +done + +#MUX Alias +I2C_BUS_PSU1_EEPROM=${NUM_MUX_9545_PSU_CHAN[1]} +I2C_BUS_PSU2_EEPROM=${NUM_MUX_9545_PSU_CHAN[0]} +I2C_BUS_LED_BOARD=${NUM_MUX_9548_UCD_CHAN[1]} +I2C_BUS_ID_GPIO=${NUM_MUX_9548_UCD_CHAN[2]} +I2C_BUS_10GMUX=${NUM_MUX_9548_UCD_CHAN[4]} +I2C_BUS_HWM=${NUM_MUX_9548_UCD_CHAN[7]} +I2C_BUS_FAN_BOARD=${NUM_I801_DEVICE} +I2C_BUS_MB_EEPROM=${NUM_I801_DEVICE} +I2C_BUS_TH_RESET=${NUM_I801_DEVICE} +I2C_BUS_BOARD_TYPE=${NUM_I801_DEVICE} +I2C_BUS_BMC_BOARD_TYPE=${NUM_I801_DEVICE} +I2C_BUS_LM75_MAC=${NUM_MUX_9548_CPLD_CHAN[5]} +I2C_BUS_LM75_FRONT=${NUM_MUX_9548_CPLD_CHAN[6]} +I2C_BUS_LM75_REAR=${NUM_MUX_9548_CPLD_CHAN[5]} +I2C_BUS_PSU_INT=${NUM_I801_DEVICE} +I2C_BUS_PSU_STATUS=${NUM_I801_DEVICE} +I2C_BUS_MUX_RST=${NUM_I801_DEVICE} +#CPU Board +I2C_BUS_CPU_EEPROM=${NUM_I801_DEVICE} +I2C_BUS_CPU_TMP75=${NUM_I801_DEVICE} +I2C_BUS_MUX_CPU_CPLD=${NUM_I801_DEVICE} + +PATH_SYS_I2C_DEVICES="/sys/bus/i2c/devices" +PATH_SYS_CPLD="/sys/devices/platform/ingrasys-s9200-cpld.0" +PATH_HWMON_ROOT_DEVICES="/sys/class/hwmon" +PATH_HWMON_W83795_DEVICE="${PATH_HWMON_ROOT_DEVICES}/hwmon5" +PATH_I801_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_I801_DEVICE}" +PATH_LM75_MAC="${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_LM75_MAC}" +PATH_LM75_FRONT="${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_LM75_FRONT}" +PATH_LM75_REAR="${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_LM75_REAR}" +PATH_CPU_TMP75="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_I801_DEVICE}" +PATH_BMC_TMP75="${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_HWM}" +PATH_PSU1_EERPOM=${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_PSU1_EEPROM} +PATH_PSU2_EEPROM=${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_PSU2_EEPROM} +PATH_10GMUX=${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_10GMUX} +#PATH for MUX PCA9548_QSFP_ROOT +PATH_MUX_9548_QSFP_ROOT="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9545_PSU_CHAN[2]}" +PATH_MUX_9548_QSFP_ROOT_CHAN=() +for (( i=0; i<8; ++i )) +do + PATH_MUX_9548_QSFP_ROOT_CHAN[i]="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_QSFP_ROOT_CHAN[i]}" +done +PATH_MUX_9545_SFP="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9545_PSU_CHAN[3]}" +PATH_MUX_9545_SFP_CHAN=() +for (( i=0; i<4; ++i )) +do + PATH_MUX_9545_SFP_CHAN[i]="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9545_SFP_CHAN[i]}" +done + +#i2cmap and gpiomap path +PATH_I2CMAP=/tmp/i2cmap + +#Mother Board +I2C_ADDR_MUX_9539_TH_RST=0x74 +I2C_ADDR_LED_BOARD=0x75 +I2C_ADDR_FAN_BOARD=0x20 +I2C_ADDR_ID_GPIO=0x27 +I2C_ADDR_MUX_9548_CPLD=0x70 +I2C_ADDR_MUX_9548_UCD=0x76 +I2C_ADDR_MUX_9545_PSU=0x72 +I2C_ADDR_MUX_9548_QSFP_ROOT=0x71 +I2C_ADDR_MUX_9548_QSFP=0x73 +I2C_ADDR_MUX_9545_SFP=0x73 +I2C_ADDR_CPLD=0x33 +I2C_ADDR_MB_EEPROM=0x55 +I2C_ADDR_QSFP_EEPROM=0x50 +I2C_ADDR_PSU_EEPROM=0x50 +I2C_ADDR_LM75_MAC=0x4E +I2C_ADDR_LM75_FRONT=0x4D +I2C_ADDR_LM75_REAR=0x4D +I2C_ADDR_10GMUX=0x67 +#Dummy BMC Board +I2C_ADDR_HWM=0x2F +I2C_ADDR_PSU_INT=0x24 #PSU Interrup on Dummy BMC Board +I2C_ADDR_BMC_BOARD_TYPE=0x24 #PSU Status on Dummy BMC Board +I2C_ADDR_PSU_STATUS=0x25 #PSU Status on Dummy BMC Board +I2C_ADDR_MUX_RST=0x26 #MUX RST on Dummy BMC Board +I2C_ADDR_TMP75_BB=0x4A +#CPU Board +I2C_ADDR_CPU_EEPROM=0x51 +I2C_ADDR_CPU_TMP75=0x4F +I2C_ADDR_MUX_CPU_CPLD=0x77 + +#sysfs +PATH_SYSFS_PSU1="${PATH_SYS_I2C_DEVICES}/${I2C_BUS_PSU1_EEPROM}-$(printf "%04x" $I2C_ADDR_PSU_EEPROM)" +PATH_SYSFS_PSU2="${PATH_SYS_I2C_DEVICES}/${I2C_BUS_PSU2_EEPROM}-$(printf "%04x" $I2C_ADDR_PSU_EEPROM)" + +#Active High/Low +ACTIVE_LOW=1 +ACTIVE_HIGH=0 +#GPIO Direction In/Out +DIR_IN=in +DIR_OUT=out + +#Power Supply Status +PSU_DC_ON=1 +PSU_DC_OFF=0 +PSU_EXIST=1 +PSU_NOT_EXIST=0 + +#W83795 Registers +REG_BANK_SEL=0x00 +REG_VOLT_CTRL1=0x02 +REG_VOLT_CTRL2=0x03 +REG_TEMP_CTRL1=0x04 +REG_TEMP_CTRL2=0x05 + +#PCA9535 Registers +REG_IN_0=0 +REG_IN_1=1 +REG_OUT_0=2 +REG_OUT_1=3 +REG_POLARITY_0=4 +REG_POLARITY_1=5 +REG_CFG_0=6 +REG_CFG_1=7 + +#LM75 Registers +LM75_REG_TEMP=0x00 +LM75_REG_CONF=0x01 +LM75_REG_HYST=0x02 +LM75_REG_TOS=0x03 + +#Bit Mask +BIT_MASK=(1 2 4 8 16 32 64 128) + +#MUX Type +PCA9545="pca9545" +PCA9548="pca9548" + +#PLATFORM Variables +PORT_NUM=64 + +#CPLD Variables +CPLD_QSFP_GROUP=(12 25 38 51 64) +CPLD_QSFP_STATUS_REG_BASE=0x20 +CPLD_QSFP_MODE_SELECT_REG_BASE=0x30 +CPLD_QSFP_ABS="abs" +CPLD_QSFP_INT="int" +CPLD_QSFP_RST="rst" +CPLD_QSFP_LP="lp" + + +# Help usage function +function _help { + echo "=========================================================" + echo "# Description: Help Function" + echo "=========================================================" + echo "----------------------------------------------------" + echo "EX : ${0} help" + echo " : ${0} i2c_init" + echo " : ${0} i2c_deinit" + echo " : ${0} i2c_temp_init" + echo " : ${0} i2c_fan_init" + echo " : ${0} i2c_volmon_init" + echo " : ${0} i2c_io_exp_init" + echo " : ${0} i2c_psu_eeprom_get" + echo " : ${0} i2c_mb_eeprom_get" + echo " : ${0} i2c_cpu_eeprom_get" + echo " : ${0} i2c_qsfp_eeprom_get [1-${PORT_NUM}]" + echo " : ${0} i2c_qsfp_eeprom_init new|delete" + echo " : ${0} i2c_mb_eeprom_init new|delete" + echo " : ${0} i2c_cpu_eeprom_init new|delete" + echo " : ${0} i2c_qsfp_status_get [1-${PORT_NUM}]" + echo " : ${0} i2c_qsfp_type_get [1-${PORT_NUM}]" + echo " : ${0} i2c_qsfp_signal_get [1-${PORT_NUM}] [abs|int|rst|lp]" + echo " : ${0} i2c_qsfp_signal_set [1-${PORT_NUM}] [rst|lp] [0|1] (low_active)" + echo " : ${0} i2c_board_type_get" + echo " : ${0} i2c_bmc_board_type_get" + echo " : ${0} i2c_psu_status" + echo " : ${0} i2c_led_psu_status_set" + echo " : ${0} i2c_led_fan_status_set" + echo " : ${0} i2c_led_fan_tray_status_set" + echo " : ${0} i2c_led_fan_tray_test" + echo " : ${0} i2c_cpld_version" + echo " : ${0} i2c_test_all" + echo " : ${0} i2c_led_test" + echo " : ${0} i2c_sys_led green|amber" + echo " : ${0} i2c_fan_led green|amber" + echo " : ${0} i2c_psu1_led green|amber" + echo " : ${0} i2c_psu2_led green|amber" + echo " : ${0} i2c_fan_tray_led green|amber on|off [1-4]" + echo " : ${0} i2c_10g_mux cpu|fp" + echo "----------------------------------------------------" +} + +#Pause function +function _pause { + read -p "$*" +} + +#Retry command function +function _retry { + local i + for i in {1..5}; + do + eval "${*}" && break || echo "retry"; sleep 1; + done +} + +#logical(front panel) to physical (falcon core) port mapping +function _port_logic2phy { + + local logic_port=$1 + local phy_port=0 + + if (( $logic_port >=1 && $logic_port <= 32 )) ; then + phy_port=$(( (logic_port-1)/2*4 + (logic_port-1)%2 + 1)) + elif (( $logic_port >=33 && $logic_port <= 64 )) ; then + phy_port=$(( (((logic_port-1)%32))/2*4 + (logic_port-1)%2 + 3)) + fi + + echo $phy_port +} + +#set i2cmap +function _set_i2cmap { + local i2c_n=$1 + local alias=$2 + + #create i2cmap dir if not exist + mkdir -p $PATH_I2CMAP + + #check i2c_n exists in sysfs + if [ ! -L ${PATH_SYS_I2C_DEVICES}/i2c-${i2c_n} ]; then + echo "${PATH_SYS_I2C_DEVICES}/i2c-${i2c_n} does not exist." + return + fi + + #create or update link + ln -sf ${PATH_SYS_I2C_DEVICES}/i2c-${i2c_n} ${PATH_I2CMAP}/${alias} +} + +#clear i2cmap +function _clear_i2cmap { + #delete i2cmap dir + rm -rf ${PATH_I2CMAP}/ +} + +#remove kernel module if exists +function _util_rmmod { + local mod=$1 + [ "$(lsmod | grep "^$mod ")" != "" ] && rmmod $mod +} + +function _create_i2c_mux_device { + local mux_type=$1 + local mux_addr=$2 + local mux_parent_chan=$3 + local mux_chan0=$4 + local mux_desc=$5 + + if [ ! -e "${PATH_SYS_I2C_DEVICES}/i2c-${mux_chan0}" ]; then + _retry "echo '$mux_type ${mux_addr}' > ${mux_parent_chan}/new_device" + _set_i2cmap ${mux_chan0} "${mux_desc}" + else + echo "${mux_desc} ${mux_addr} already init." + fi +} + +#I2C Init +function _i2c_init { + echo "=========================================================" + echo "# Description: I2C Init" + echo "=========================================================" + + _util_rmmod i2c_i801 + modprobe i2c_i801 #disable_features=0x10 + modprobe i2c_dev + modprobe i2c_mux_pca954x force_deselect_on_exit=1 + + #add MUX_9548_CPLD on I801 + _create_i2c_mux_device $PCA9548 $I2C_ADDR_MUX_9548_CPLD ${PATH_I801_DEVICE} ${NUM_MUX_9548_CPLD_CHAN[0]} "PCA9548_CPLD" + + #add MUX_9548_UCD on I801 + _create_i2c_mux_device $PCA9548 $I2C_ADDR_MUX_9548_UCD ${PATH_I801_DEVICE} ${NUM_MUX_9548_UCD_CHAN[0]} "PCA9548_UCD" + + #add MUX_9545_PSU on I801 + _create_i2c_mux_device $PCA9545 $I2C_ADDR_MUX_9545_PSU ${PATH_I801_DEVICE} ${NUM_MUX_9545_PSU_CHAN[0]} "PCA9545_PSU" + + #add MUX_9548_QSFP_ROOT on MUX_9545_PSU_CHAN[2] + _create_i2c_mux_device $PCA9548 $I2C_ADDR_MUX_9548_QSFP_ROOT ${PATH_MUX_9548_QSFP_ROOT} ${NUM_MUX_9548_QSFP_ROOT_CHAN[0]} "PCA9548_QSPF_ROOT" + + #add MUX_9548_QSFP_0 on MUX_9548_QSFP_ROOT_CHAN[0] + _create_i2c_mux_device $PCA9548 $I2C_ADDR_MUX_9548_QSFP ${PATH_MUX_9548_QSFP_ROOT_CHAN[0]} ${NUM_MUX_9548_QSFP_0_CHAN[0]} "PCA9548_QSPF_0" + + #add MUX_9548_QSFP_1 on MUX_9548_QSFP_ROOT_CHAN[1] + _create_i2c_mux_device $PCA9548 $I2C_ADDR_MUX_9548_QSFP ${PATH_MUX_9548_QSFP_ROOT_CHAN[1]} ${NUM_MUX_9548_QSFP_1_CHAN[0]} "PCA9548_QSPF_1" + + #add MUX_9548_QSFP_2 on MUX_9548_QSFP_ROOT_CHAN[2] + _create_i2c_mux_device $PCA9548 $I2C_ADDR_MUX_9548_QSFP ${PATH_MUX_9548_QSFP_ROOT_CHAN[2]} ${NUM_MUX_9548_QSFP_2_CHAN[0]} "PCA9548_QSPF_2" + + #add MUX_9548_QSFP_3 on MUX_9548_QSFP_ROOT_CHAN[3] + _create_i2c_mux_device $PCA9548 $I2C_ADDR_MUX_9548_QSFP ${PATH_MUX_9548_QSFP_ROOT_CHAN[3]} ${NUM_MUX_9548_QSFP_3_CHAN[0]} "PCA9548_QSPF_3" + + #add MUX_9548_QSFP_4 on MUX_9548_QSFP_ROOT_CHAN[4] + _create_i2c_mux_device $PCA9548 $I2C_ADDR_MUX_9548_QSFP ${PATH_MUX_9548_QSFP_ROOT_CHAN[4]} ${NUM_MUX_9548_QSFP_4_CHAN[0]} "PCA9548_QSPF_4" + + #add MUX_9548_QSFP_5 on MUX_9548_QSFP_ROOT_CHAN[5] + _create_i2c_mux_device $PCA9548 $I2C_ADDR_MUX_9548_QSFP ${PATH_MUX_9548_QSFP_ROOT_CHAN[5]} ${NUM_MUX_9548_QSFP_5_CHAN[0]} "PCA9548_QSPF_5" + + #add MUX_9548_QSFP_6 on MUX_9548_QSFP_ROOT_CHAN[6] + _create_i2c_mux_device $PCA9548 $I2C_ADDR_MUX_9548_QSFP ${PATH_MUX_9548_QSFP_ROOT_CHAN[6]} ${NUM_MUX_9548_QSFP_6_CHAN[0]} "PCA9548_QSPF_6" + + #add MUX_9548_QSFP_7 on MUX_9548_QSFP_ROOT_CHAN[7] + _create_i2c_mux_device $PCA9548 $I2C_ADDR_MUX_9548_QSFP ${PATH_MUX_9548_QSFP_ROOT_CHAN[7]} ${NUM_MUX_9548_QSFP_7_CHAN[0]} "PCA9548_QSPF_7" + + #add MUX_9545_SFP on QSFP_ROOT + _create_i2c_mux_device $PCA9545 $I2C_ADDR_MUX_9545_SFP ${PATH_MUX_9545_SFP} ${NUM_MUX_9545_SFP_CHAN[0]} "PCA9545_SPF" + + #Init CPLD LED_CLR Register (QSFP LED) + i2cset -y -m ${BIT_MASK[2]} ${NUM_I801_DEVICE} ${I2C_ADDR_MUX_9539_TH_RST} ${REG_OUT_0} 0xFF + + _util_rmmod coretemp + _util_rmmod jc42 + _util_rmmod w83795 + _util_rmmod lm75 + + _i2c_temp_init + _i2c_volmon_init + modprobe coretemp + modprobe lm75 + modprobe jc42 + modprobe eeprom_mb + _i2c_mb_eeprom_init "new" + _i2c_cpu_eeprom_init "new" + modprobe eeprom + modprobe gpio-pca953x + _i2c_sensors_init + _i2c_fan_init + _i2c_io_exp_init + _i2c_psu_init + _i2c_qsfp_eeprom_init "new" + _i2c_led_psu_status_set + _i2c_led_fan_status_set + COLOR_LED="green" + echo "${COLOR_LED}" + _i2c_sys_led + modprobe cpld + _config_rmem +} + +#I2C Deinit +function _i2c_deinit { + for mod in cpld coretemp jc42 w83795 lm75 eeprom eeprom_mb gpio-pca953x i2c_mux_pca954x i2c_i801 ingrasys_s9200_64x_psu; + do + _util_rmmod $mod + done + _clear_i2cmap +} + +#Temperature sensor Init +function _i2c_temp_init { + local lm="lm75" + local tmp="tmp75" + local i2c_bus=${I2C_BUS_HWM} + local i2c_addr=${I2C_ADDR_HWM} + + echo "=========================================================" + echo "# Description: TEMP INIT" + echo "=========================================================" + + # select bank0 + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_BANK_SEL} 0x80 + echo "enable VDSEN14, VDSEN15, VDSEN16, and TR4 temperature monitoring" + i2cset -y -r ${i2c_bus=} ${i2c_addr} ${REG_TEMP_CTRL2} 0x6A + + echo "export CPU sensor TMP75 to sysfs" + echo "${tmp} ${I2C_ADDR_CPU_TMP75}" > ${PATH_CPU_TMP75}/new_device + + echo "Add Dummy Board LM75 to sysfs" + echo "${lm} ${I2C_ADDR_LM75_MAC}" > ${PATH_LM75_MAC}/new_device + echo "${lm} ${I2C_ADDR_LM75_FRONT}" > ${PATH_LM75_FRONT}/new_device + echo "${lm} ${I2C_ADDR_LM75_REAR}" > ${PATH_LM75_REAR}/new_device + + echo "CLKIN clock frequency set as 48Mhz" + i2cset -y -r ${i2c_bus} ${i2c_addr} 0x01 0x1C + + # select bank 2 + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_BANK_SEL} 0x82 + echo "set PWM mode in FOMC" + i2cset -y -r ${i2c_bus} ${i2c_addr} 0x0F 0x00 +} + +#FAN Init +function _i2c_fan_init { + local init_fan_speed=120 + + echo "=========================================================" + echo "# Description: FAN INIT" + echo "=========================================================" + + if [ -e "${PATH_HWMON_W83795_DEVICE}" ]; then + echo "Init Fan Speed to ${init_fan_speed} (MAX is 255)" + echo $init_fan_speed > ${PATH_HWMON_W83795_DEVICE}/device/pwm1 + echo $init_fan_speed > ${PATH_HWMON_W83795_DEVICE}/device/pwm2 + else + echo "FAIL, W83795 not found in path ${PATH_HWMON_W83795_DEVICE}" + fi +} + +#VOLMON Init +function _i2c_volmon_init { + echo -n "VOLMON INIT" + local i2c_bus=${I2C_BUS_HWM} + local i2c_addr=${I2C_ADDR_HWM} + + #select bank0 + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_BANK_SEL} 0x80 + #enable voltage monitoring VSEN 1~8 + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_VOLT_CTRL1} 0xFF + #enable voltage monitoring 3VDD and 3VBAT + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_VOLT_CTRL2} 0x50 + #eable voltage monitoring VSEN12 and VSEN13 + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_TEMP_CTRL1} 0x0A + + echo "Done" +} + +#IO Expander Init +function _i2c_io_exp_init { + local i2c_bus=0 + local i2c_addr=0 + + echo "=========================================================" + echo "# Description: I2C IO Expander Init" + echo "=========================================================" + + echo "Init PCA9539 TH RESET IO Expander" + #PCA9539 TH RESET + #0.0 TH_RST_L OUT 1 + #0.1 TH_PCIE_RST_L OUT 1 + #0.2 LED_CLR OUT 1 + #0.3 HOST_TO_BMC_I2C_GPIO OUT 0 + #0.4 USB_MUX_SEL OUT 0 + #0.5 UART_MUX_SEL OUT 0 + #0.6 FIN0 OUT 0 + #0.7 FIN7 OUT 0 + #1.0 TH_INT_L IN + #1.1 CPLD4_TO_CPU_INT_L IN + #1.2 CPLD3_TO_CPU_INT_L IN + #1.3 CPLD2_TO_CPU_INT_L IN + #1.4 CPLD1_TO_CPU_INT_L IN + #1.5 REF_SEL OUT 0 + #1.6 I210_PE_RST_L OUT 1 + #1.7 I210_RST_L OUT 1 + i2c_bus=${I2C_BUS_TH_RESET} + i2c_addr=${I2C_ADDR_MUX_9539_TH_RST} + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_OUT_0} $((2#00000111)) + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_OUT_1} $((2#11000000)) + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_POLARITY_0} 0x00 + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_POLARITY_1} 0x00 + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_CFG_0} 0x00 + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_CFG_1} $((2#00011111)) + + echo "Init PCA9539 LED BOARD IO Expander" + #PCA9539 LED BOARD + #0.0 SYS_LED_G OUT 1 + #0.1 FAN_LED_EN OUT 1 + #0.2 FAN_LED_Y OUT 0 + #0.3 PSU1_LED_Y OUT 0 + #0.4 PSU0_LED_Y OUT 0 + #0.5~0.7 X + #1.0 PSU1_PWROK OUT 1 + #1.1 PSU0_PWROK OUT 1 + i2c_bus=${I2C_BUS_LED_BOARD} + i2c_addr=${I2C_ADDR_LED_BOARD} + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_OUT_0} $((2#00000011)) + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_OUT_1} $((2#00000011)) + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_POLARITY_0} 0x00 + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_POLARITY_1} 0x00 + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_CFG_0} 0x00 + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_CFG_1} 0x00 + + echo "Init PCA9535 ID_GPIO IO Expander" + #PCA9535 ID_GPIO + #0.0 ~ 0.7 X + #1.0 Build_REV_0 IN + #1.1 Build_REV_1 IN + #1.2 HW_REV_0 IN + #1.3 HW_REV_1 IN + #1.4 Board_ID_0 IN + #1.5 Board_ID_1 IN + #1.6 Board_ID_2 IN + #1.7 Board_ID_3 IN + i2c_bus=${I2C_BUS_ID_GPIO} + i2c_addr=${I2C_ADDR_ID_GPIO} + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_POLARITY_0} 0x00 + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_POLARITY_1} 0x00 + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_CFG_0} 0xFF + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_CFG_1} 0xFF + + #I2C_ADDR_FAN_BOARD + echo "Init PCA9535 FAN_BOARD IO Expander" + #PCA9535 FAN_BOARD + #0.0 EN_FAN1_LED_G_H OUT 1 + #0.1 EN_FAN1_LED_Y_H OUT 0 + #0.2 FAN1_ABS# IN 0 + #0.3 FAN1_DIR# IN 0 + #0.4 EN_FAN2_LED_G_H OUT 1 + #0.5 EN_FAN2_LED_Y_H OUT 0 + #0.6 FAN2_ABS# IN 0 + #0.7 FAN2_DIR# IN 0 + #1.0 EN_FAN3_LED_G_H OUT 1 + #1.1 EN_FAN3_LED_Y_H OUT 0 + #1.2 FAN3_ABS# IN 0 + #1.3 FAN3_DIR# IN 0 + #1.4 EN_FAN4_LED_G_H OUT 1 + #1.5 EN_FAN4_LED_Y_H OUT 0 + #1.6 FAN4_ABS# IN 0 + #1.7 FAN4_DIR# IN 0 + i2c_bus=${I2C_BUS_FAN_BOARD} + i2c_addr=${I2C_ADDR_FAN_BOARD} + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_OUT_0} $((2#00010001)) + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_OUT_1} $((2#00010001)) + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_POLARITY_0} 0x00 + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_POLARITY_1} 0x00 + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_CFG_0} $((2#11001100)) + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_CFG_1} $((2#11001100)) + + #PCA9555 on BMC Dummy Board + echo "Init PCA9555 Interrupt IO Expander" + #PCA9555 Interrupt Expander + #0.0 HWM_INT_L IN + #0.1 UCD9090_INT_L IN + #0.2 ETHX_INT_L IN + #0.3 HOST_TO_BMC_INT_L IN + #0.4 THERMAL_ALT1# IN + #0.5 FAN_STATUS_INT_L IN + #0.6 PSU0_INT_L IN + #0.7 PSU1_INT_L IN + #1.0 Build_REV_0 IN + #1.1 Build_REV_1 IN + #1.2 HW_REV_0 IN + #1.3 HW_REV_1 IN + #1.4 Board_ID_0 IN + #1.5 Board_ID_1 IN + #1.6 Board_ID_2 IN + #1.7 Board_ID_3 IN + i2c_bus=${I2C_BUS_PSU_INT} + i2c_addr=${I2C_ADDR_PSU_INT} + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_POLARITY_0} 0x00 + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_POLARITY_1} 0x00 + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_CFG_0} 0xFF + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_CFG_1} 0xFF + + #PCA9555 on BMC Dummy Board + echo "Init PCA9555 PSU0_PWROK IO Expander" + #PCA9555 PSU0_PWROK Expander + #0.0 PSU0_PWROK IN + #0.1 PSU0_PRSNT_L IN + #0.2 PSU0_PWRON_L OUT 0 + #0.3 PSU1_PWROK IN + #0.4 PSU1_PRSNT_L IN + #0.5 PSU1_PWRON_L OUT 0 + #0.6 TMP75_INT_L IN + #0.7 GPIOF7 IN + #1.0 ALL_PWR_GOOD IN + #1.1 CPU_PRSNT_L IN + #1.2 FP_BTN_UARTSEL_EN_L OUT 0 + #1.3 HOST_TO_BMC_I2C_GPIO OUT 0 + #1.4 HOST_CPU_PWRBTN_L OUT 1 + #1.5 N/A + #1.6 N/A + #1.7 N/A + i2c_bus=${I2C_BUS_PSU_STATUS} + i2c_addr=${I2C_ADDR_PSU_STATUS} + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_OUT_0} 0x00 + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_OUT_1} $((2#00010000)) + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_POLARITY_0} 0x00 + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_POLARITY_1} 0x00 + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_CFG_0} $((2#11011011)) + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_CFG_1} $((2#11100011)) + + #PCA9555 on BMC Dummy Board + echo "Init PCA9555 MUX RST IO Expander" + #PCA9555 MUX RST Expander + #0.0 FRU_I2C_MUX_RST_L OUT 1 + #0.1 MAIN_I2C_MUX_RST_L OUT 1 + #0.2 SYSTEM_LED_RST_L OUT 1 + #0.3 BMC_TO_UCD_RST_L OUT 1 + #0.4 BMC_TO_HOST_RST_L OUT 1 + #0.5 ETHX_RST_L OUT 1 + #0.6 GPIOF4 IN + #0.7 N/A + #1.0 CPU_to_FRU_I2C_EN OUT 1 + #1.1 CPU_to_MAIN_I2C_EN OUT 1 + #1.2 P3V3_FAN_EN OUT 1 + #1.3 P3V3_I2C_EN OUT 1 + #1.4 UCD9090_CNTRL OUT 1 + #1.5 UART_MUX_SEL OUT 0 + #1.6 USB_MUX_SEL OUT 0 + #1.7 ETHX_CPU_EEPROM_SEL OUT 0 + i2c_bus=${I2C_BUS_MUX_RST} + i2c_addr=${I2C_ADDR_MUX_RST} + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_OUT_0} $((2#00111111)) + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_OUT_1} $((2#00011111)) + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_POLARITY_0} 0x00 + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_POLARITY_1} 0x00 + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_CFG_0} $((2#01000000)) + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_CFG_1} 0x00 + + #PCA9539 on CPU Board + echo "Init PCA9539 CPLD IO Expander on CPU" + i2c_bus=${I2C_BUS_MUX_CPU_CPLD} + i2c_addr=${I2C_ADDR_MUX_CPU_CPLD} + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_CFG_0} 0xFF + i2cset -y -r ${i2c_bus} ${i2c_addr} ${REG_CFG_1} 0xFF +} + +function _i2c_sensors_init { + echo "SENSORS init" + local dev_path + + # add w83795 to sysfs + dev_path="${PATH_SYS_I2C_DEVICES}/${I2C_BUS_HWM}-$(printf "%04x" ${I2C_ADDR_HWM})" + if ! [ -L ${dev_path} ]; then + echo "w83795adg ${I2C_ADDR_HWM}" > ${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_HWM}/new_device + while [ ! -e "${PATH_HWMON_W83795_DEVICE}" ]; do + sleep 1 + done + else + echo "${dev_path} already exist (w83795)" + fi + + # BMC board thermal + dev_path="${PATH_SYS_I2C_DEVICES}/${NUM_I801_DEVICE}-$(printf "%04x" ${I2C_ADDR_TMP75_BB})" + if ! [ -L ${dev_path} ]; then + echo "tmp75 ${I2C_ADDR_TMP75_BB}" > ${PATH_BMC_TMP75}/new_device + else + echo "${dev_path} already exist" + fi + + echo "Done" +} + +#Set FAN Tray LED +function _i2c_led_fan_tray_status_set { + echo "=========================================================" + echo "# Description: FAN Tray Status Setup" + echo "=========================================================" + + #check W83795 exists + if [ ! -e "${PATH_HWMON_W83795_DEVICE}" ]; then + echo "FAIL, W83795 not found in path ${PATH_HWMON_W83795_DEVICE}" + return + fi + #FAN Status get + FAN1_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan1_alarm` + FAN3_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan3_alarm` + FAN5_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan5_alarm` + FAN7_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan7_alarm` + + FAN_TRAY=1 + if [ "${FAN1_ALARM}" == "0" ]; then + COLOR_LED="green" + ONOFF_LED="on" + _i2c_fan_tray_led + + COLOR_LED="amber" + ONOFF_LED="off" + _i2c_fan_tray_led + + echo "set [FAN TRAY 1] [Green]=on [Amber]=off" + else + COLOR_LED="green" + ONOFF_LED="off" + _i2c_fan_tray_led + + COLOR_LED="amber" + ONOFF_LED="on" + _i2c_fan_tray_led + + echo "set [FAN TRAY 1] [Green]=off [Amber]=on" + fi + + FAN_TRAY=2 + if [ "${FAN3_ALARM}" == "0" ]; then + COLOR_LED="green" + ONOFF_LED="on" + _i2c_fan_tray_led + + COLOR_LED="amber" + ONOFF_LED="off" + _i2c_fan_tray_led + + echo "set [FAN TRAY 2] [Green]=on [Amber]=off" + else + COLOR_LED="green" + ONOFF_LED="off" + _i2c_fan_tray_led + + COLOR_LED="amber" + ONOFF_LED="on" + _i2c_fan_tray_led + + echo "set [FAN TRAY 2] [Green]=off [Amber]=on" + fi + + FAN_TRAY=3 + if [ "${FAN5_ALARM}" == "0" ]; then + COLOR_LED="green" + ONOFF_LED="on" + _i2c_fan_tray_led + + COLOR_LED="amber" + ONOFF_LED="off" + _i2c_fan_tray_led + + echo "set [FAN TRAY 3] [Green]=on [Amber]=off" + else + COLOR_LED="green" + ONOFF_LED="off" + _i2c_fan_tray_led + + COLOR_LED="amber" + ONOFF_LED="on" + _i2c_fan_tray_led + + echo "set [FAN TRAY 3] [Green]=off [Amber]=on" + fi + + FAN_TRAY=4 + if [ "${FAN7_ALARM}" == "0" ]; then + COLOR_LED="green" + ONOFF_LED="on" + _i2c_fan_tray_led + + COLOR_LED="amber" + ONOFF_LED="off" + _i2c_fan_tray_led + + echo "set [FAN TRAY 4] [Green]=on [Amber]=off" + else + COLOR_LED="green" + ONOFF_LED="off" + _i2c_fan_tray_led + + COLOR_LED="amber" + ONOFF_LED="on" + _i2c_fan_tray_led + + echo "set [FAN TRAY 4] [Green]=off [Amber]=on" + fi +} + +#Test FAN Tray LED +function _i2c_led_fan_tray_test { + echo "=========================================================" + echo "# Description: FAN Tray LED Test" + echo "=========================================================" + + for i in {1..4} + do + FAN_TRAY=$i + COLOR_LED="green" + ONOFF_LED="on" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="off" + _i2c_fan_tray_led + _pause "Check [Fan Tray ${i} LED] = Green and Press [Enter] key to continue..." + + COLOR_LED="green" + ONOFF_LED="off" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="on" + _i2c_fan_tray_led + _pause "Check [Fan Tray ${i} LED] = Amber and Press [Enter] key to continue..." + done +} +#Set FAN LED +function _i2c_led_fan_status_set { + echo "=========================================================" + echo "# Description: FAN Status Setup" + echo "=========================================================" + + #check W83795 exists in hwmon2 + if [ ! -e "${PATH_HWMON_W83795_DEVICE}" ]; then + echo "FAIL, W83795 not found in path ${PATH_HWMON_W83795_DEVICE}" + return + fi + + #PSU Status set + FAN1_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan1_alarm` + FAN3_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan3_alarm` + FAN5_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan5_alarm` + FAN7_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan7_alarm` + + if [ "${FAN1_ALARM}" == "0" ] \ + && [ "${FAN3_ALARM}" == "0" ] \ + && [ "${FAN5_ALARM}" == "0" ] \ + && [ "${FAN7_ALARM}" == "0" ] ; then + COLOR_LED="green" + _i2c_fan_led + else + COLOR_LED="amber" + _i2c_fan_led + fi + echo "set [FAN LED] = ${COLOR_LED}" +} + +#Set PSU LED on LED Board +function _i2c_led_psu_status_set { + + echo "=========================================================" + echo "# Description: PSU LED Status Setup" + echo "=========================================================" + + #Get PSU Status + _i2c_psu_status + + #PSU1 Status + echo "------------------------------" + if [ "${psu1Exist}" == ${PSU_EXIST} ]; then + if [ "${psu1PwGood}" == ${PSU_DC_ON} ]; then + COLOR_LED="green" + _i2c_psu1_led + else + COLOR_LED="amber" + _i2c_psu1_led + fi + else + COLOR_LED="amber" + _i2c_psu1_led + fi + echo "set [PSU1 LED] = ${COLOR_LED}" + + #PSU2 Status + echo "------------------------------" + if [ "${psu2Exist}" == ${PSU_EXIST} ]; then + if [ "${psu2PwGood}" == ${PSU_DC_ON} ]; then + COLOR_LED="green" + _i2c_psu2_led + else + COLOR_LED="amber" + #ONOFF_LED="on" + _i2c_psu2_led + fi + else + COLOR_LED="amber" + _i2c_psu2_led + fi + echo "set [PSU2 LED] = ${COLOR_LED}" +} + +#LED Test +function _i2c_led_test { + echo "=========================================================" + echo "# Description: I2C LED TEST" + echo "=========================================================" + #sys led (green) + _i2c_reset_led + COLOR_LED="green" + _i2c_sys_led + _pause 'Check [SYS LED] = Green and Press [Enter] key to continue...' + #sys led (amber) + _i2c_reset_led + COLOR_LED="amber" + _i2c_sys_led + _pause 'Check [SYS LED] = Amber and Press [Enter] key to continue...' + + #FAN led (green) + _i2c_reset_led + COLOR_LED="green" + _i2c_fan_led + _pause 'Check [FAN LED] Green and Press [Enter] key to continue...' + #FAN led (amber) + _i2c_reset_led + COLOR_LED="amber" + _i2c_fan_led + _pause 'Check [FAN LED] = Amber and Press [Enter] key to continue...' + + #PSU2 led (green) + _i2c_reset_led + COLOR_LED="green" + _i2c_psu2_led + _pause 'Check [PSU2 LED] = Green and Press [Enter] key to continue...' + #PSU2 led (amber) + _i2c_reset_led + COLOR_LED="amber" + _i2c_psu2_led + _pause 'Check [PSU2 LED] = Amber and Press [Enter] key to continue...' + + #PSU1 led (green) + _i2c_reset_led + COLOR_LED="green" + _i2c_psu1_led + _pause 'Check [PSU1 LED] = Green and Press [Enter] key to continue...' + #PSU2 led (amber) + _i2c_reset_led + COLOR_LED="amber" + _i2c_psu1_led + _pause 'Check [PSU1 LED] = Amber and Press [Enter] key to continue...' + + #Turn OFF All LED + _i2c_reset_led + _pause 'Check turn off all LEDs and Press [Enter] key to continue...' +} + +#Set QSFP Port variable +function _qsfp_port_i2c_var_set { + #global variables + cpld_group=0 + cpld_i2c_bus=0 + cpld_i2c_addr=$I2C_ADDR_CPLD + cpld_qsfp_status_reg_offset=0 + cpld_qsfp_mode_reg_offset=0 + + #local variables + local i=0 + local port=$1 + local port_group=$(( (port - 1)/8 )) + + case ${port_group} in + 0) + #the i2c expander base bus num to read qsfp eeprom + eeprombusbase=${NUM_MUX_9548_QSFP_0_CHAN[0]} + ;; + 1) + eeprombusbase=${NUM_MUX_9548_QSFP_1_CHAN[0]} + ;; + 2) + eeprombusbase=${NUM_MUX_9548_QSFP_2_CHAN[0]} + ;; + 3) + eeprombusbase=${NUM_MUX_9548_QSFP_3_CHAN[0]} + ;; + 4) + eeprombusbase=${NUM_MUX_9548_QSFP_4_CHAN[0]} + ;; + 5) + eeprombusbase=${NUM_MUX_9548_QSFP_5_CHAN[0]} + ;; + 6) + eeprombusbase=${NUM_MUX_9548_QSFP_6_CHAN[0]} + ;; + 7) + eeprombusbase=${NUM_MUX_9548_QSFP_7_CHAN[0]} + ;; + *) + echo "Please input 1~${PORT_NUM}" + ;; + esac + + #set cpld_group and cpld_i2c_bus according to port + for ((i=0; i<5; ++i)) + do + if (("${port}" <= "${CPLD_QSFP_GROUP[i]}")); + then + local port_offset=0 + cpld_group=$i + cpld_i2c_bus=${NUM_MUX_9548_CPLD_CHAN[i]} + + if ((i>0)) + then + port_offset=$(( port - CPLD_QSFP_GROUP[i-1] )) + else + port_offset=$port + fi + cpld_qsfp_status_reg_offset=$((CPLD_QSFP_STATUS_REG_BASE + port_offset)) + cpld_qsfp_mode_reg_offset=$((CPLD_QSFP_MODE_SELECT_REG_BASE + port_offset)) + + break + fi + done +} + +function _i2c_get { + local i2c_bus=$1 + local i2c_addr=$2 + local reg=$3 + echo `i2cget -y ${i2c_bus} ${i2c_addr} ${reg}` +} + +function _i2c_set { + local i2c_bus=$1 + local i2c_addr=$2 + local reg=$3 + local mask=$4 + local value=$5 + + echo `i2cset -m $mask -y -r ${i2c_bus} ${i2c_addr} ${reg} ${value}` +} + +#Set QSFP Port variable +function _qsfp_eeprom_var_set { + #local variables + local port=$1 + + #global variables + eeprombusidx=$(( (port - 1)%8 )) + + case $eeprombusidx in + 0) + eeprombus=$(( $eeprombusbase + 0 )) + ;; + 1) + eeprombus=$(( $eeprombusbase + 1 )) + ;; + 2) + eeprombus=$(( $eeprombusbase + 2 )) + ;; + 3) + eeprombus=$(( $eeprombusbase + 3 )) + ;; + 4) + eeprombus=$(( $eeprombusbase + 4 )) + ;; + 5) + eeprombus=$(( $eeprombusbase + 5 )) + ;; + 6) + eeprombus=$(( $eeprombusbase + 6 )) + ;; + 7) + eeprombus=$(( $eeprombusbase + 7 )) + ;; + esac + eepromAddr=${I2C_ADDR_QSFP_EEPROM} +} + +#Get QSFP EEPROM Information +function _i2c_qsfp_eeprom_get { + local value=0 + local status=0 + + echo "=========================================================" + echo "# Description: QSFP EEPROM GET" + echo "=========================================================" + + #status: 0 -> Down, 1 -> Up + _i2c_qsfp_signal_get ${QSFP_PORT} ${CPLD_QSFP_ABS} + + value=$qsfp_signal + status=$(( value?0:1 )) + + if [ $status = 0 ]; then + echo "[Fail] QSFP ${QSFP_PORT} is not present" + exit + fi + + echo "------------------------------" + cat ${PATH_SYS_I2C_DEVICES}/$eeprombus-$(printf "%04x" $eepromAddr)/eeprom | hexdump -C +} + +#Init QSFP EEPROM +function _i2c_qsfp_eeprom_init { + echo "=========================================================" + echo "# Description: QSFP EEPROM INIT" + echo "=========================================================" + + #Action check + action=$1 + if [ -z "${action}" ]; then + echo "No action, skip" + return + elif [ "${action}" != "new" ] && [ "${action}" != "delete" ]; then + echo "Error action, skip" + return + fi + + #Init EEPROM + local i + for (( i=1; i<=${PORT_NUM}; i++ )) + do + _qsfp_port_i2c_var_set ${i} + + _qsfp_eeprom_var_set ${i} + + if [ "${action}" == "new" ] && \ + ! [ -L ${PATH_SYS_I2C_DEVICES}/$eeprombus-$(printf "%04x" $eepromAddr) ]; then + echo "sff8436 $eepromAddr" > ${PATH_SYS_I2C_DEVICES}/i2c-$eeprombus/new_device + elif [ "${action}" == "delete" ] && \ + [ -L ${PATH_SYS_I2C_DEVICES}/$eeprombus-$(printf "%04x" $eepromAddr) ]; then + echo "$eepromAddr" > ${PATH_SYS_I2C_DEVICES}/i2c-$eeprombus/delete_device + fi + done +} + +#get qsfp singals (ABS, INT, RST, LP) from CPLD +function _i2c_qsfp_signal_get { + local port=$1 #port start from 1 + local signal=$2 + local attr_file="" + local phy_port=0 + local active="low_active" + + #global + qsfp_signal=0 + qsfp_signals=0 + + #verify port + if [ -z "${port}" ]; then + echo "No port, skip" + return + fi + + #verify port + if (( $port < 1 || $port > $PORT_NUM )) ; then + echo "invalid port, skip" + fi + + #get physical port + phy_port=$(_port_logic2phy $port) + + _qsfp_port_i2c_var_set ${phy_port} + _qsfp_eeprom_var_set ${phy_port} + + #verify signal + if [ -z "${signal}" ]; then + echo "No signal, skip" + return + elif [ "${signal}" == "${CPLD_QSFP_ABS}" ]; then + attr_file="qsfp_modprs" + elif [ "${signal}" == "${CPLD_QSFP_INT}" ]; then + attr_file="qsfp_int" + elif [ "${signal}" == "${CPLD_QSFP_RST}" ]; then + attr_file="qsfp_reset" + elif [ "${signal}" == "${CPLD_QSFP_LP}" ]; then + attr_file="qsfp_lpmode" + active="high_active" + else + echo "invalid signal ${signal}, skip" + return + fi + + mask=${BIT_MASK[bit_shift]} + + #signals of all ports + qsfp_signals=`cat ${PATH_SYS_CPLD}/${attr_file}` + #signal of single port + qsfp_signal=$(( (qsfp_signals >> (phy_port-1)) & 0x1)) + #print signals + printf "[port]=%d, [signal]=%s, [value]=%d (${active}), [qsfp_signals]=%016x\n" $port $signal $qsfp_signal $qsfp_signals +} + +#set qsfp singals (RST, LP) via CPLD +function _i2c_qsfp_signal_set { + local port=$1 #port start from 1 + local signal=$2 + local value=$3 + local values_ori=0 + local value_ori=0 + local values=0 + local attr_file="" + + #verify port + if [ -z "${port}" ]; then + echo "No port, skip" + return + fi + + #verify port + if (( $port < 1 || $port > $PORT_NUM )) ; then + echo "invalid port, skip" + fi + + #verify signal + if [ -z "${signal}" ]; then + echo "No signal, skip" + return + elif [ "${signal}" == "${CPLD_QSFP_RST}" ]; then + attr_file="qsfp_reset" + elif [ "${signal}" == "${CPLD_QSFP_LP}" ]; then + attr_file="qsfp_lpmode" + else + echo "invalid signal ${signal}, skip" + return + fi + + #get current signal values + _i2c_qsfp_signal_get $port $signal + value_ori=$qsfp_signal + values_ori=$qsfp_signals + + #if signal value is not changed, return + if [ "${value}" == "${value_ori}" ]; then + echo "value not changed, skip set operation" + return + fi + + #toggle the bit for update + values=$(( values_ori ^ (1 << (port-1)))) + + #set value to register + echo "$(printf "%016x" $values)" > ${PATH_SYS_CPLD}/${attr_file} + + #get updated signal values + _i2c_qsfp_signal_get $port $signal + values=$qsfp_signals + + #result + printf "Before: %016x\n" $values_ori + printf "After: %016x\n" $values +} + +#Init EEPROM +function _i2c_eeprom_init { + local i2c_bus=$1 + local i2c_addr=$2 + local action=$3 + local desc=$4 + local sys_i2c_dev=$PATH_SYS_I2C_DEVICES + + echo -n "${desc} EEPROM INIT" + + #Action check + if [ -z "${action}" ]; then + echo "No action, skip" + return + elif [ "${action}" != "new" ] && [ "${action}" != "delete" ]; then + echo "Error action, skip" + return + fi + + #Init EEPROM + if [ "${action}" == "new" ] && \ + ! [ -L ${sys_i2c_dev}/${i2c_bus}-$(printf "%04x" $i2c_addr) ]; then + echo "mb_eeprom ${i2c_addr}" > ${sys_i2c_dev}/i2c-${i2c_bus}/new_device + elif [ "${action}" == "delete" ] && \ + [ -L ${sys_i2c_dev}/${i2c_bus}-$(printf "%04x" $i2c_addr) ]; then + echo "${i2c_addr}" > ${sys_i2c_dev}/i2c-${i2c_bus}/delete_device + fi + echo "DONE" +} + +#Init Main Board EEPROM +function _i2c_mb_eeprom_init { + local action=$1 + local i2c_bus=$I2C_BUS_MB_EEPROM + local i2c_addr=$I2C_ADDR_MB_EEPROM + local desc="Main Board" + + _i2c_eeprom_init $i2c_bus $i2c_addr $action $desc +} + +#Init CPU EEPROM +function _i2c_cpu_eeprom_init { + local action=$1 + local i2c_bus=$I2C_BUS_CPU_EEPROM + local i2c_addr=$I2C_ADDR_CPU_EEPROM + local desc="CPU Board" + + _i2c_eeprom_init $i2c_bus $i2c_addr $action $desc +} + +#get QSFP Status +function _i2c_qsfp_status_get { + local value=0 + local status=0 + + #status: 0 -> Down, 1 -> Up + _i2c_qsfp_signal_get ${QSFP_PORT} ${CPLD_QSFP_ABS} + value=$qsfp_signal + status=$(( value?0:1 )) + echo "status=$status" +} + +#get QSFP Type +function _i2c_qsfp_type_get { + local phy_port=0 + local value=0 + local status=0 + + echo "=========================================================" + echo "# Description: QSFP TYPE Get" + echo "=========================================================" + + phy_port=$(_port_logic2phy ${QSFP_PORT}) + _qsfp_port_i2c_var_set ${phy_port} + _qsfp_eeprom_var_set ${phy_port} + + #get abs signal + _i2c_qsfp_signal_get ${QSFP_PORT} ${CPLD_QSFP_ABS} + value=$qsfp_signal + status=$(( value?0:1 )) + + #check qsfp is present + if [ $status = 0 ]; then + echo "[Fail] QSFP ${QSFP_PORT} is not present" + exit + fi + + #Get QSFP EEPROM info + if [ ! -e "${PATH_SYS_I2C_DEVICES}/$eeprombus-$(printf '%04x' $eepromAddr)/eeprom" ]; then + echo "FAIL, qsfp eeprom file does not exist. " + echo "qsfp eeprom file path: ${PATH_SYS_I2C_DEVICES}/$eeprombus-$(printf '%04x' $eepromAddr)/eeprom" + return + fi + + qsfp_info=$(base64 ${PATH_SYS_I2C_DEVICES}/$eeprombus-$(printf "%04x" $eepromAddr)/eeprom) + + identifier=$(echo $qsfp_info | base64 -d -i | hexdump -s 128 -n 1 -e '"%x"') + connector=$(echo $qsfp_info | base64 -d -i | hexdump -s 130 -n 1 -e '"%x"') + transceiver=$(echo $qsfp_info | base64 -d -i | hexdump -s 131 -n 1 -e '"%x"') + + echo "------------------------------" + echo "identifier = $identifier" + echo "connector = $connector" + echo "transceiver = $transceiver" +} + +#Init PSU Kernel Module +function _i2c_psu_init { + echo "=========================================================" + echo "# Description: I2C PSU Init" + echo "=========================================================" + modprobe ingrasys_s9200_64x_psu + + echo "psu1 ${I2C_ADDR_PSU_EEPROM}" > ${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_PSU1_EEPROM}/new_device + echo "psu2 ${I2C_ADDR_PSU_EEPROM}" > ${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_PSU2_EEPROM}/new_device +} + +#Get PSU EEPROM Information +function _i2c_psu_eeprom_get { + local eeprom_psu1="" + local eeprom_psu2="" + + echo "=========================================================" + echo "# Description: I2C PSU EEPROM Get..." + echo "=========================================================" + + echo "PUS1 EEPROM" + eeprom_psu1="${PATH_SYSFS_PSU1}/psu_eeprom" + cat ${eeprom_psu1} | hexdump -C + + echo "------------------------------" + echo "PUS2 EEPROM" + eeprom_psu2="${PATH_SYSFS_PSU2}/psu_eeprom" + cat ${eeprom_psu2} | hexdump -C +} + +#Get MotherBoard EEPROM Information +function _i2c_mb_eeprom_get { + local path_i2c_dev=${PATH_SYS_I2C_DEVICES} + local i2c_bus=${I2C_BUS_MB_EEPROM} + local i2c_addr=${I2C_ADDR_MB_EEPROM} + echo "=========================================================" + echo "# Description: I2C MB EEPROM Get" + echo "=========================================================" + + ## MB EEPROM + cat ${path_i2c_dev}/${i2c_bus}-$(printf "%04x" ${i2c_addr})/eeprom | hexdump -v -C +} + +#Get CPU EEPROM Information +function _i2c_cpu_eeprom_get { + local path_i2c_dev=${PATH_SYS_I2C_DEVICES} + local i2c_bus=${I2C_BUS_CPU_EEPROM} + local i2c_addr=${I2C_ADDR_CPU_EEPROM} + echo "=========================================================" + echo "# Description: I2C CPU EEPROM Get" + echo "=========================================================" + + ## CPU EEPROM + cat ${path_i2c_dev}/${i2c_bus}-$(printf "%04x" ${i2c_addr})/eeprom | hexdump -v -C +} + +#Set FAN Tray LED +function _i2c_fan_tray_led { + local value=0 + + echo "=========================================================" + echo "# Description: Set Fan Tray LED" + echo "=========================================================" + + case ${FAN_TRAY} in + 1) + ioPort=$REG_OUT_0 + if [ "${COLOR_LED}" == "green" ]; then + mask=${BIT_MASK[0]} + elif [ "${COLOR_LED}" == "amber" ]; then + mask=${BIT_MASK[1]} + fi + ;; + 2) + ioPort=$REG_OUT_0 + if [ "${COLOR_LED}" == "green" ]; then + mask=${BIT_MASK[4]} + elif [ "${COLOR_LED}" == "amber" ]; then + mask=${BIT_MASK[5]} + fi + ;; + 3) + ioPort=$REG_OUT_1 + if [ "${COLOR_LED}" == "green" ]; then + mask=${BIT_MASK[0]} + elif [ "${COLOR_LED}" == "amber" ]; then + mask=${BIT_MASK[1]} + fi + ;; + 4) + ioPort=$REG_OUT_1 + if [ "${COLOR_LED}" == "green" ]; then + mask=${BIT_MASK[4]} + elif [ "${COLOR_LED}" == "amber" ]; then + mask=${BIT_MASK[5]} + fi + ;; + *) + echo "Please input 1~4" + exit + ;; + esac + + if [ "${ONOFF_LED}" == "on" ]; then + value=0xFF + elif [ "${ONOFF_LED}" == "off" ]; then + value=0x00 + else + echo "Invalid Parameters ${ONOFF_LED}, Exit!!!" + _help + exit ${FALSE} + fi + i2cset -m $mask -y -r ${I2C_BUS_FAN_BOARD} ${I2C_ADDR_FAN_BOARD} $ioPort $value + +} + +#Set System Status LED +function _i2c_sys_led { + local value=0 + local mask=${BIT_MASK[0]} + + if [ "${COLOR_LED}" == "green" ]; then + value=0xFF + elif [ "${COLOR_LED}" == "amber" ]; then + value=0x00 + else + echo "Invalid Parameters ${COLOR_LED}, Exit!!!" + _help + exit ${FALSE} + fi + + _i2c_set_led $value $mask +} + +#Set FAN LED +function _i2c_fan_led { + local value=0 + local mask=${BIT_MASK[2]} + + if [ "${COLOR_LED}" == "green" ]; then + value=0x00 + elif [ "${COLOR_LED}" == "amber" ]; then + value=0xFF + else + echo "Invalid Parameters ${COLOR_LED}, Exit!!!" + _help + exit ${FALSE} + fi + + _i2c_set_led $value $mask +} + +#Set PSU1 LED +function _i2c_psu1_led { + local value=0 + local mask=${BIT_MASK[3]} + + if [ "${COLOR_LED}" == "green" ]; then + value=0x00 + elif [ "${COLOR_LED}" == "amber" ]; then + value=0xFF + else + echo "Invalid Parameters ${COLOR_LED}, Exit!!!" + _help + exit ${FALSE} + fi + + _i2c_set_led $value $mask +} + +#Set PSU2 LED +function _i2c_psu2_led { + local reg=${REG_OUT_0} + local value=0 + local mask=${BIT_MASK[4]} + + if [ "${COLOR_LED}" == "green" ]; then + value=0x00 + elif [ "${COLOR_LED}" == "amber" ]; then + value=0xFF + else + echo "Invalid Parameters ${COLOR_LED}, Exit!!!" + _help + exit ${FALSE} + fi + + _i2c_set_led $value $mask +} + +#Set LEDs in LED Board +function _i2c_set_led { + local value=$1 + local mask=$2 + local reg=${REG_OUT_0} + local i2c_bus=$I2C_BUS_LED_BOARD + local i2c_addr=$I2C_ADDR_LED_BOARD + + _i2c_set $i2c_bus $i2c_addr $reg $mask $value +} + +#Reset all system leds +function _i2c_reset_led { + local mask=0xFF + local value=$((2#00000011)) + local reg=${REG_OUT_0} + local i2c_bus=$I2C_BUS_LED_BOARD + local i2c_addr=$I2C_ADDR_LED_BOARD + + _i2c_set $i2c_bus $i2c_addr $reg $mask $value +} + +#Get Mother Board Version and Type +function _i2c_board_type_get { + echo "=========================================================" + echo "# Description: I2C MB Board Type Get" + echo "=========================================================" + local i2c_bus=${I2C_BUS_ID_GPIO} + local i2c_addr=${I2C_ADDR_ID_GPIO} + local reg=${REG_IN_1} + local value=0 + + value=$(_i2c_get $i2c_bus $i2c_addr $reg) + + #Bit 0-1 + boardBuildRev=$((value & 0x03)) + #Bit 2-3 + boardHwRev=$((value >> 2 & 0x03)) + #Bit 4-7 + boardId=$((value>>4)) + printf "[MB BOARD_ID] = 0x%02x, [HW Rev] = %d, [Build Rev] = %d\n" $boardId $boardHwRev $boardBuildRev +} + +#Get Board Version and Type from Dummy BMC Board +function _i2c_bmc_board_type_get { + echo "=========================================================" + echo "# Description: I2C BMC Board Type Get" + echo "=========================================================" + + local i2c_bus=${I2C_BUS_BMC_BOARD_TYPE} + local i2c_addr=${I2C_ADDR_BMC_BOARD_TYPE} + local reg=${REG_IN_1} + local value=0 + + value=$(_i2c_get $i2c_bus $i2c_addr $reg) + + #Bit 0-1 + boardBuildRev=$((($value) & 0x03)) + #Bit 2-3 + boardHwRev=$((($value) >> 2 & 0x03)) + #Bit 4-7 + boardId=$((($value) >> 4)) + printf "[BMC BOARD_ID] = 0x%02x, [HW Rev] = %d, [Build Rev] = %d\n" $boardId $boardHwRev $boardBuildRev +} + +#Get CPLD Version +function _i2c_cpld_version { + echo "=========================================================" + echo "# Description: CPLD Version" + echo "=========================================================" + cat ${PATH_SYS_CPLD}/cpld_version +} + +#Get PSU Status +function _i2c_psu_status { + local psu_abs="" + + psu1PwGood=`cat ${PATH_SYSFS_PSU1}/psu_pg` + psu_abs=`cat ${PATH_SYSFS_PSU1}/psu_abs` + if [ "$psu_abs" == "0" ]; then + psu1Exist=1 + else + psu1Exist=0 + fi + + psu2PwGood=`cat ${PATH_SYSFS_PSU2}/psu_pg` + psu_abs=`cat ${PATH_SYSFS_PSU2}/psu_abs` + if [ "$psu_abs" == "0" ]; then + psu2Exist=1 + else + psu2Exist=0 + fi + + printf "PSU1 Exist:%x PSU1 PW Good:%d\n" $psu1Exist $psu1PwGood + printf "PSU2 Exist:%d PSU2 PW Good:%d\n" $psu2Exist $psu2PwGood +} + +#Set 10G Mux to CPU or Front Panel +function _i2c_10g_mux { + + echo "=========================================================" + echo "# Description: 10G Mux" + echo "=========================================================" + + local target=${TARGET_10G_MUX} + local i2c_bus=${I2C_BUS_10GMUX} + local i2c_addr=${I2C_ADDR_10GMUX} + local reg=0 + local mask=0xff + local value=0 + local file_10g_mux="${PATH_SYS_CPLD}/cpld_10g_mux" + + #get current 10g mux register value on CPLD + value=`cat ${file_10g_mux}` + + if [ "${target}" == "cpu" ]; then + #Set XE0: slave address access + _i2c_set $i2c_bus $i2c_addr 0x06 $mask 0x18 + #Set XE0: CH4 D_IN0-S_OUTA0 EQ + _i2c_set $i2c_bus $i2c_addr 0x2c $mask 0x00 + #Set XE0: CH5 NC-S_OUTB0 DEM + _i2c_set $i2c_bus $i2c_addr 0x35 $mask 0x80 + #Set XE0: CH5 NC-S_OUTB0 VOD + _i2c_set $i2c_bus $i2c_addr 0x34 $mask 0xab + #Set XE0: CH1 D_OUT0-S_INB0 EQ + _i2c_set $i2c_bus $i2c_addr 0x16 $mask 0x01 + #Set XE0: CH1 D_OUT0-S_INB0 DEM + _i2c_set $i2c_bus $i2c_addr 0x18 $mask 0x80 + #Set XE0: CH1 D_OUT0-S_INB0 VOD + _i2c_set $i2c_bus $i2c_addr 0x17 $mask 0xab + #Set XE1: CH6 D_IN1-S_OUTA1 EQ + _i2c_set $i2c_bus $i2c_addr 0x3a $mask 0x00 + #Set XE1: CH7 NC-S_OUTB1 EQ + _i2c_set $i2c_bus $i2c_addr 0x41 $mask 0x00 + #Set XE1: CH7 NC-S_OUTB1 DEM + _i2c_set $i2c_bus $i2c_addr 0x43 $mask 0x80 + #Set XE1: CH7 NC-S_OUTB1 VOD + _i2c_set $i2c_bus $i2c_addr 0x42 $mask 0xab + #Set XE1: CH3 D_OUT1-S_INB1 EQ + _i2c_set $i2c_bus $i2c_addr 0x24 $mask 0x01 + #Set XE1: CH3 D_OUT1-S_INB1 DEM + _i2c_set $i2c_bus $i2c_addr 0x26 $mask 0x80 + #Set XE1: CH3 D_OUT1-S_INB1 VOD + _i2c_set $i2c_bus $i2c_addr 0x25 $mask 0xab + #Enable auto negotiation of XE ports + eval "bcmcmd 'port xe0,xe1 an=1 if=kr en=1'" + #delay 1 sec + sleep 1 + + #switch 10G MUX to cpu on CPLD + value=$(( value & 0xf3 )) + echo "$(printf "%x" ${value})" > ${file_10g_mux} + + echo "Switch 10G Mux to [CPU]" + + elif [ "${COLOR_LED}" == "fp" ]; then + #Set XE0: slave address access + _i2c_set $i2c_bus $i2c_addr 0x06 $mask 0x18 + #Set XE0: CH4 D_IN0-S_OUTA0 EQ + _i2c_set $i2c_bus $i2c_addr 0x2c $mask 0x00 + #Set XE0: CH4 D_IN0-S_OUTA0 DEM + _i2c_set $i2c_bus $i2c_addr 0x2e $mask 0x80 + #Set XE0: CH4 D_IN0-S_OUTA0 VOD + _i2c_set $i2c_bus $i2c_addr 0x2d $mask 0xab + #Set XE0: CH0 NC-S_INA0 EQ + _i2c_set $i2c_bus $i2c_addr 0x0f $mask 0x00 + #Set XE0: CH1 D_OUT0-S_INB0 DEM + _i2c_set $i2c_bus $i2c_addr 0x18 $mask 0x80 + #Set XE0: CH1 D_OUT0-S_INB0 VOD + _i2c_set $i2c_bus $i2c_addr 0x17 $mask 0xab + #Set XE1: CH6 D_IN1-S_OUTA1 EQ + _i2c_set $i2c_bus $i2c_addr 0x3a $mask 0x00 + #Set XE1: CH6 D_IN1-S_OUTA1 DEM + _i2c_set $i2c_bus $i2c_addr 0x3c $mask 0x80 + #Set XE1: CH6 D_IN1-S_OUTA1 VOD + _i2c_set $i2c_bus $i2c_addr 0x3b $mask 0xab + #Set XE1: CH2 NC-S_INA1 EQ + _i2c_set $i2c_bus $i2c_addr 0x1d $mask 0x00 + #Set XE1: CH3 D_OUT1-S_INB1 DEM + _i2c_set $i2c_bus $i2c_addr 0x26 $mask 0x80 + #Set XE1: CH3 D_OUT1-S_INB1 VOD + _i2c_set $i2c_bus $i2c_addr 0x25 $mask 0xab + #Enable auto negotiation of XE ports + eval "bcmcmd 'port xe0,xe1 an=0 if=kr en=1'" + #delay 1 sec + sleep 1 + + #switch 10G MUX to front panel on CPLD + value=$(( value | 0x0c )) + echo "$(printf "%x" ${value})" > ${file_10g_mux} + + echo "Switch 10G Mux to [Front Panel]" + else + echo "invalid target, please set target to cpu/fp" + fi +} + +#Increase read socket buffer for CoPP Test +function _config_rmem { + echo "109430400" > /proc/sys/net/core/rmem_max +} + +#Main Function +function _main { + start_time_str=`date` + start_time_sec=$(date +%s) + + if [ "${EXEC_FUNC}" == "help" ]; then + _help + elif [ "${EXEC_FUNC}" == "i2c_init" ]; then + _i2c_init + elif [ "${EXEC_FUNC}" == "i2c_deinit" ]; then + _i2c_deinit + elif [ "${EXEC_FUNC}" == "i2c_temp_init" ]; then + _i2c_temp_init + elif [ "${EXEC_FUNC}" == "i2c_fan_init" ]; then + _i2c_fan_init + elif [ "${EXEC_FUNC}" == "i2c_volmon_init" ]; then + _i2c_volmon_init + elif [ "${EXEC_FUNC}" == "i2c_io_exp_init" ]; then + _i2c_io_exp_init + elif [ "${EXEC_FUNC}" == "i2c_led_test" ]; then + _i2c_led_test + elif [ "${EXEC_FUNC}" == "i2c_mb_eeprom_get" ]; then + _i2c_mb_eeprom_get + elif [ "${EXEC_FUNC}" == "i2c_cpu_eeprom_get" ]; then + _i2c_cpu_eeprom_get + elif [ "${EXEC_FUNC}" == "i2c_psu_eeprom_get" ]; then + _i2c_psu_eeprom_get + elif [ "${EXEC_FUNC}" == "i2c_qsfp_eeprom_get" ]; then + _i2c_qsfp_eeprom_get + elif [ "${EXEC_FUNC}" == "i2c_qsfp_eeprom_init" ]; then + _i2c_qsfp_eeprom_init ${QSFP_INIT_ACTION} + elif [ "${EXEC_FUNC}" == "i2c_mb_eeprom_init" ]; then + _i2c_mb_eeprom_init ${MB_EEPROM_ACTION} + elif [ "${EXEC_FUNC}" == "i2c_cpu_eeprom_init" ]; then + _i2c_cpu_eeprom_init ${MB_EEPROM_ACTION} + elif [ "${EXEC_FUNC}" == "i2c_qsfp_status_get" ]; then + _i2c_qsfp_status_get + elif [ "${EXEC_FUNC}" == "i2c_qsfp_type_get" ]; then + _i2c_qsfp_type_get + elif [ "${EXEC_FUNC}" == "i2c_qsfp_signal_get" ]; then + _i2c_qsfp_signal_get ${QSFP_PORT} ${QSFP_ACTION} + elif [ "${EXEC_FUNC}" == "i2c_qsfp_signal_set" ]; then + _i2c_qsfp_signal_set ${QSFP_PORT} ${QSFP_ACTION} ${QSFP_VALUE} + elif [ "${EXEC_FUNC}" == "i2c_led_psu_status_set" ]; then + _i2c_led_psu_status_set + elif [ "${EXEC_FUNC}" == "i2c_led_fan_status_set" ]; then + _i2c_led_fan_status_set + elif [ "${EXEC_FUNC}" == "i2c_led_fan_tray_status_set" ]; then + _i2c_led_fan_tray_status_set + elif [ "${EXEC_FUNC}" == "i2c_led_fan_tray_test" ]; then + _i2c_led_fan_tray_test + elif [ "${EXEC_FUNC}" == "i2c_sys_led" ]; then + _i2c_sys_led + elif [ "${EXEC_FUNC}" == "i2c_fan_led" ]; then + _i2c_fan_led + elif [ "${EXEC_FUNC}" == "i2c_fan_tray_led" ]; then + _i2c_fan_tray_led + elif [ "${EXEC_FUNC}" == "i2c_psu1_led" ]; then + _i2c_psu1_led + elif [ "${EXEC_FUNC}" == "i2c_psu2_led" ]; then + _i2c_psu2_led + elif [ "${EXEC_FUNC}" == "i2c_board_type_get" ]; then + _i2c_board_type_get + elif [ "${EXEC_FUNC}" == "i2c_bmc_board_type_get" ]; then + _i2c_bmc_board_type_get + elif [ "${EXEC_FUNC}" == "i2c_cpld_version" ]; then + _i2c_cpld_version + elif [ "${EXEC_FUNC}" == "i2c_psu_status" ]; then + _i2c_psu_status + elif [ "${EXEC_FUNC}" == "i2c_test_all" ]; then + _i2c_deinit + _i2c_init + _i2c_led_test + _i2c_psu_eeprom_get + _i2c_mb_eeprom_get + _i2c_cpu_eeprom_get + _i2c_board_type_get + _i2c_bmc_board_type_get + _i2c_cpld_version + _i2c_psu_status + elif [ "${EXEC_FUNC}" == "i2c_10g_mux" ]; then + _i2c_10g_mux + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + end_time_str=`date` + end_time_sec=$(date +%s) + diff_time=$[ ${end_time_sec} - ${start_time_sec} ] + echo "------------------------------" + echo "Total Execution Time: ${diff_time} sec" + + echo "DONE" +} + +_main diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_monitor.sh new file mode 100755 index 000000000000..51c49c1152f5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_monitor.sh @@ -0,0 +1,104 @@ +#!/bin/bash +# Copyright (C) 2017 Ingrasys, 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 3 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, see . + +INTERVAL=3 +I2C_UTILS="/usr/sbin/i2c_utils.sh" +QSFP_SI_SCRIPT="/usr/sbin/qsfp_si_cfg.sh" +QSFP_ARRAY=(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \ + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) + +#QSFP SI monitor +function _qsfp_si_monitor { + local i + local status + for i in {0..63}; + do + status=`${I2C_UTILS} i2c_qsfp_status_get $(expr $i + 1) | egrep '^status=.*$' | sed -e 's/status=//g'` + if [ "${status}" == "1" ]; then + _qsfp_type_check $i + fi + done +} + +#QSFP type +function _qsfp_type_check { + local port=$1 + local qsfp_type=`${I2C_UTILS} i2c_qsfp_type_get $(expr $port + 1) ` + local identifier=`echo "$qsfp_type" | egrep -o 'identifier = .*$' | sed -e 's/identifier = //g'` + if [ "${identifier}" == "11" ]; then + connector=`echo "$qsfp_type" | egrep -o 'connector = .*$' | sed -e 's/connector = //g'` + case ${connector} in + 21|23) + #DAC + if [ "${QSFP_ARRAY[$port]}" != "${connector}" ]; then + echo "Change Port $(expr $port + 1) to DAC" + QSFP_ARRAY[$port]=${connector} + ${QSFP_SI_SCRIPT} dac $port >/dev/null + fi + ;; + *) + #Optical + if [ "${QSFP_ARRAY[$port]}" != "${connector}" ]; then + echo "Change Port $(expr $port + 1) to Optical" + QSFP_ARRAY[$port]=${connector} + ${QSFP_SI_SCRIPT} optical $port >/dev/null + fi + ;; + esac + fi +} + +#Docker exist check +function _docker_swss_check { + while true + do + # Check if syncd starts + result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + if [ "$result" == "3" ]; then + return + fi + sleep $INTERVAL + done +} + +#Docker exist check +function _qsfp_si_cfg_script_check { + + if [ -f ${QSFP_SI_SCRIPT} ] && [ -x ${QSFP_SI_SCRIPT} ]; then + echo "SI Script exists. Start monitor." + return + else + echo "SI Script not exist. Exit monitor." + exit + fi +} + +# main function +function _main { + #Check SI Script + _qsfp_si_cfg_script_check + #Check docker swss is running + _docker_swss_check + while true + do + _qsfp_si_monitor + # Sleep while still handling signals + sleep $INTERVAL & + wait $! + done +} + +_main diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_si_cfg.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_si_cfg.sh new file mode 100755 index 000000000000..ba59c50ca7bf --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_si_cfg.sh @@ -0,0 +1,230 @@ +#!/bin/bash +# Copyright (C) 2017 Ingrasys, 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 3 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, see . + +VERSION="1.0.0" +TRUE=200 +FALSE=404 + +TYPE=${1} +PORT=${2} + +#FIXME update SI values +#QSFP Optical +function _qsfp_optical_si_set { + local idx=0 + #FIXME + local si=(11 68 13 15 68 15 11 68 9 11 68 13 + 11 68 17 11 68 13 13 68 11 11 68 15 + 11 68 13 11 68 17 11 68 17 13 68 13 + 11 68 15 11 68 9 11 68 9 11 68 7 + 9 68 13 13 68 7 11 68 7 11 68 11 + 11 68 13 11 68 13 9 68 7 11 68 11 + 11 68 9 11 68 15 11 68 9 11 68 9 + 11 68 9 11 68 7 11 68 9 11 68 9 + 13 68 9 13 68 13 13 68 7 13 68 11 + 13 68 5 13 68 11 13 68 5 13 68 11 + + 11 68 3 11 68 9 11 68 5 11 68 13 + 11 68 9 11 68 9 11 68 11 13 68 5 + 13 68 3 11 68 7 11 68 5 11 68 9 + 11 68 9 13 68 9 13 68 1 11 68 11 + 5 68 1 11 68 7 11 68 1 13 68 3 + 11 68 5 11 68 3 11 68 7 11 68 3 + 11 68 3 13 68 11 13 68 1 13 68 3 + 11 68 1 13 68 1 13 68 1 11 68 7 + 11 68 1 11 68 5 11 68 1 9 68 5 + 5 68 1 13 68 1 11 68 5 11 68 3 + + 11 68 1 11 68 11 11 68 1 13 68 7 + 13 68 1 15 68 1 11 68 1 13 68 7 + 13 68 1 11 68 5 11 68 1 11 68 1 + 11 68 5 13 68 3 11 68 5 9 68 1 + 11 68 5 13 68 5 13 68 1 11 68 9 + 13 68 1 11 68 13 13 68 1 11 68 7 + 11 68 1 11 68 1 9 68 1 11 68 1 + 11 68 1 11 68 1 11 68 5 11 68 1 + 13 68 1 11 68 11 11 68 1 11 68 1 + 11 68 1 11 68 15 11 68 1 13 68 5 + + 11 68 1 11 68 1 9 68 1 13 68 1 + 11 68 1 11 68 1 9 68 1 11 68 1 + 11 68 1 13 68 3 11 68 1 13 68 1 + 11 68 1 13 68 1 11 68 1 11 68 13 + 11 68 1 11 68 1 11 68 1 11 68 1 + 11 68 11 11 68 1 13 68 1 11 68 1 + 11 68 1 11 68 9 11 68 1 11 68 7 + 11 68 1 13 68 1 13 68 1 11 68 1 + 11 68 1 11 68 5 11 68 1 13 68 3 + 11 68 3 9 68 1 11 68 3 11 68 1 + + 11 68 7 11 68 9 11 68 1 11 68 9 + 11 68 3 11 68 15 11 68 3 9 68 9 + 9 68 1 11 68 3 11 68 1 11 68 5 + 11 68 5 5 68 5 11 68 5 11 68 1 + 13 68 5 13 68 5 11 68 1 11 68 9 + 11 68 1 11 68 1 11 68 1 13 68 7 + 11 68 1 11 68 5 11 68 1 11 68 3 + 11 68 5 11 68 1 11 68 5 11 68 1 + 11 68 3 11 68 7 11 68 3 11 68 9 + 11 68 1 13 68 7 11 68 1 9 68 9 + + 13 68 1 11 68 5 11 68 3 13 68 5 + 11 68 7 11 68 11 13 68 5 9 68 5 + 11 68 5 11 68 13 13 68 7 11 68 13 + 11 68 7 11 68 11 11 68 5 11 68 11 + 11 68 11 11 68 11 11 68 7 11 68 11 + 11 68 13 11 68 11 11 68 9 15 68 9 + 11 68 11 11 68 5 11 68 7 13 68 11 + 11 68 9 13 68 17 11 68 7 11 68 13 + 11 68 11 11 68 17 11 68 13 11 68 15 + 13 68 9 13 68 11 11 68 11 13 68 7 + + 11 68 13 13 68 9 11 68 9 11 68 9 + 11 68 19 11 68 15 11 68 9 11 68 11 + 13 68 13 13 68 17 13 68 11 11 68 11 + 13 68 9 13 68 13 11 68 11 11 68 9) + + idx=$(( PORT * 12 )) + #FIXEME + #for j in {0..3} + #do + # bcmcmd "phy ce${PORT} CL93N72_UT_CTL2r.${j} CL93N72_TXFIR_POST=${si[idx++]}; phy ce${PORT} CL93N72_UT_CTL3r.${j} CL93N72_TXFIR_MAIN=${si[idx++]}; phy ce${PORT} CL93N72_UT_CTL2r.${j} CL93N72_TXFIR_PRE=${si[idx++]};" + #done +} + +function _qsfp_dac_si_set { + local idx=0 + # each port has 4 lanes, each lane has 3 SI values (post,main,pre), total 4*3=12 + local port_si=12 + + #si[0]: txfir_post for port0 lane0 + #si[1]: txfir_main for port0 lane0 + #si[2]: txfir_pre for port0 lane0 + + #si[3]: txfir_post for port0 lane1 + #si[4]: txfir_main for port0 lane1 + #si[5]: txfir_pre for port0 lane1 + + local si=(11 68 13 15 68 15 11 68 9 11 68 13 + 11 68 17 11 68 13 13 68 11 11 68 15 + 11 68 13 11 68 17 11 68 17 13 68 13 + 11 68 15 11 68 9 11 68 9 11 68 7 + 9 68 13 13 68 7 11 68 7 11 68 11 + 11 68 13 11 68 13 9 68 7 11 68 11 + 11 68 9 11 68 15 11 68 9 11 68 9 + 11 68 9 11 68 7 11 68 9 11 68 9 + 13 68 9 13 68 13 13 68 7 13 68 11 + 13 68 5 13 68 11 13 68 5 13 68 11 + + 11 68 3 11 68 9 11 68 5 11 68 13 + 11 68 9 11 68 9 11 68 11 13 68 5 + 13 68 3 11 68 7 11 68 5 11 68 9 + 11 68 9 13 68 9 13 68 1 11 68 11 + 5 68 1 11 68 7 11 68 1 13 68 3 + 11 68 5 11 68 3 11 68 7 11 68 3 + 11 68 3 13 68 11 13 68 1 13 68 3 + 11 68 1 13 68 1 13 68 1 11 68 7 + 11 68 1 11 68 5 11 68 1 9 68 5 + 5 68 1 13 68 1 11 68 5 11 68 3 + + 11 68 1 11 68 11 11 68 1 13 68 7 + 13 68 1 15 68 1 11 68 1 13 68 7 + 13 68 1 11 68 5 11 68 1 11 68 1 + 11 68 5 13 68 3 11 68 5 9 68 1 + 11 68 5 13 68 5 13 68 1 11 68 9 + 13 68 1 11 68 13 13 68 1 11 68 7 + 11 68 1 11 68 1 9 68 1 11 68 1 + 11 68 1 11 68 1 11 68 5 11 68 1 + 13 68 1 11 68 11 11 68 1 11 68 1 + 11 68 1 11 68 15 11 68 1 13 68 5 + + 11 68 1 11 68 1 9 68 1 13 68 1 + 11 68 1 11 68 1 9 68 1 11 68 1 + 11 68 1 13 68 3 11 68 1 13 68 1 + 11 68 1 13 68 1 11 68 1 11 68 13 + 11 68 1 11 68 1 11 68 1 11 68 1 + 11 68 11 11 68 1 13 68 1 11 68 1 + 11 68 1 11 68 9 11 68 1 11 68 7 + 11 68 1 13 68 1 13 68 1 11 68 1 + 11 68 1 11 68 5 11 68 1 13 68 3 + 11 68 3 9 68 1 11 68 3 11 68 1 + + 11 68 7 11 68 9 11 68 1 11 68 9 + 11 68 3 11 68 15 11 68 3 9 68 9 + 9 68 1 11 68 3 11 68 1 11 68 5 + 11 68 5 5 68 5 11 68 5 11 68 1 + 13 68 5 13 68 5 11 68 1 11 68 9 + 11 68 1 11 68 1 11 68 1 13 68 7 + 11 68 1 11 68 5 11 68 1 11 68 3 + 11 68 5 11 68 1 11 68 5 11 68 1 + 11 68 3 11 68 7 11 68 3 11 68 9 + 11 68 1 13 68 7 11 68 1 9 68 9 + + 13 68 1 11 68 5 11 68 3 13 68 5 + 11 68 7 11 68 11 13 68 5 9 68 5 + 11 68 5 11 68 13 13 68 7 11 68 13 + 11 68 7 11 68 11 11 68 5 11 68 11 + 11 68 11 11 68 11 11 68 7 11 68 11 + 11 68 13 11 68 11 11 68 9 15 68 9 + 11 68 11 11 68 5 11 68 7 13 68 11 + 11 68 9 13 68 17 11 68 7 11 68 13 + 11 68 11 11 68 17 11 68 13 11 68 15 + 13 68 9 13 68 11 11 68 11 13 68 7 + + 11 68 13 13 68 9 11 68 9 11 68 9 + 11 68 19 11 68 15 11 68 9 11 68 11 + 13 68 13 13 68 17 13 68 11 11 68 11 + 13 68 9 13 68 13 11 68 11 11 68 9) + + # get first si index for this port + idx=$(( PORT * port_si )) + + # loop for 4 lanes + for j in {0..3} + do + bcmcmd "phy ce${PORT} CL93N72_UT_CTL2r.${j} CL93N72_TXFIR_POST=${si[idx++]}; phy ce${PORT} CL93N72_UT_CTL3r.${j} CL93N72_TXFIR_MAIN=${si[idx++]}; phy ce${PORT} CL93N72_UT_CTL2r.${j} CL93N72_TXFIR_PRE=${si[idx++]};" + done +} + +# Help usage function +function _help { + echo "=========================================================" + echo "# Description: Help Function" + echo "=========================================================" + echo "----------------------------------------------------" + echo "EX : ${0} help" + echo " : ${0} optical [0-63]" + echo " : ${0} dac [0-63]" + echo "----------------------------------------------------" +} + +#Main Function +function _main { + + if [ "${TYPE}" == "help" ]; then + _help + elif [ "${TYPE}" == "optical" ]; then + _qsfp_optical_si_set + elif [ "${TYPE}" == "dac" ]; then + _qsfp_dac_si_set + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi +} + +_main diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/s9200_64x_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/s9200_64x_monitor.sh new file mode 100755 index 000000000000..974da6d5001f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/s9200_64x_monitor.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# Copyright (C) 2016 Ingrasys, 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 3 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, see . + +INTERVAL=5 +I2C_UTILS="/usr/sbin/i2c_utils.sh" + + +# LED status monitor +function _led_monitor { + ${I2C_UTILS} i2c_led_fan_status_set >/dev/null + ${I2C_UTILS} i2c_led_psu_status_set >/dev/null + ${I2C_UTILS} i2c_led_fan_tray_status_set >/dev/null +} + +# main function +function _main { + while true + do + _led_monitor + # Sleep while still handling signals + sleep $INTERVAL & + wait $! + done +} + +_main \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-mitac b/platform/broadcom/sonic-platform-modules-mitac deleted file mode 160000 index 5b1ce26b7688..000000000000 --- a/platform/broadcom/sonic-platform-modules-mitac +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 5b1ce26b76880979de5bbbb54140a750b2809367 diff --git a/platform/broadcom/sonic-platform-modules-mitac/.gitignore b/platform/broadcom/sonic-platform-modules-mitac/.gitignore new file mode 100644 index 000000000000..38e72f05332d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/.gitignore @@ -0,0 +1,17 @@ +# Build file +ly1200-32x/modules/*.mod.c +ly1200-32x/modules/*.mod.o +ly1200-32x/modules/*.o +ly1200-32x/modules/*.ko +ly1200-32x/modules/*.cmd +ly1200-32x/modules/Module.symvers +ly1200-32x/modules/modules.order +ly1200-32x/modules/.tmp_versions + +debian/sonic-platform-mitac-ly1200-32x/ +debian/sonic-platform-mitac-ly1200-32x.debhelper.log +debian/sonic-platform-mitac-ly1200-32x.postinst.debhelper +debian/sonic-platform-mitac-ly1200-32x.postrm.debhelper +debian/sonic-platform-mitac-ly1200-32x.prerm.debhelper +debian/sonic-platform-mitac-ly1200-32x.substvars +debian/files diff --git a/platform/broadcom/sonic-platform-modules-mitac/LICENSE b/platform/broadcom/sonic-platform-modules-mitac/LICENSE new file mode 100644 index 000000000000..c07c63913aeb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/LICENSE @@ -0,0 +1,16 @@ +Copyright (C) 2016 Microsoft, Inc +Copyright (C) 2018 MiTAC Technology Corporation + +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/broadcom/sonic-platform-modules-mitac/README.md b/platform/broadcom/sonic-platform-modules-mitac/README.md new file mode 100644 index 000000000000..d7d47a58debf --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/README.md @@ -0,0 +1 @@ +platform drivers of MiTAC products for the SONiC project diff --git a/platform/broadcom/sonic-platform-modules-mitac/debian/changelog b/platform/broadcom/sonic-platform-modules-mitac/debian/changelog new file mode 100644 index 000000000000..592bb3a71134 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/debian/changelog @@ -0,0 +1,5 @@ +sonic-mitac-platform-modules (1.0) unstable; urgency=low + + * Initial release + + -- MiTAC Network Thu, 01 Sep 2017 11:26:38 +0800 diff --git a/platform/broadcom/sonic-platform-modules-mitac/debian/compat b/platform/broadcom/sonic-platform-modules-mitac/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/debian/compat @@ -0,0 +1 @@ +9 diff --git a/platform/broadcom/sonic-platform-modules-mitac/debian/control b/platform/broadcom/sonic-platform-modules-mitac/debian/control new file mode 100644 index 000000000000..8e20f8524d74 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/debian/control @@ -0,0 +1,12 @@ +Source: sonic-mitac-platform-modules +Section: main +Priority: extra +Maintainer: MiTAC network +Build-Depends: debhelper (>= 8.0.0), bzip2 +Standards-Version: 3.9.3 + +Package: sonic-platform-mitac-ly1200-32x +Architecture: amd64 +Depends: linux-image-3.16.0-5-amd64 +Description: kernel modules for platform devices such as fan, led, sfp + diff --git a/platform/broadcom/sonic-platform-modules-mitac/debian/rules b/platform/broadcom/sonic-platform-modules-mitac/debian/rules new file mode 100755 index 000000000000..7f9f99827d21 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/debian/rules @@ -0,0 +1,41 @@ +#!/usr/bin/make -f + +export INSTALL_MOD_DIR:=extra + +PACKAGE_PRE_NAME := sonic-platform-mitac +KVERSION ?= $(shell uname -r) +KERNEL_SRC := /lib/modules/$(KVERSION) +MOD_SRC_DIR:= $(shell pwd) +MODULE_DIRS:= ly1200-32x + +%: + dh $@ + +override_dh_auto_build: + (for mod in $(MODULE_DIRS); do \ + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ + done) + +override_dh_auto_install: + (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}/usr/local/bin;\ + cp $(MOD_SRC_DIR)/$${mod}/modules/*.ko \ + debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + mkdir -p debian/$(PACKAGE_PRE_NAME)-$${mod}/opt; \ + cp -rfL $(MOD_SRC_DIR)/$${mod}/opt/* \ + debian/$(PACKAGE_PRE_NAME)-$${mod}/opt; \ + mkdir -p debian/$(PACKAGE_PRE_NAME)-$${mod}/etc/init.d; \ + cp -rfL $(MOD_SRC_DIR)/$${mod}/etc/* \ + debian/$(PACKAGE_PRE_NAME)-$${mod}/etc; \ + done) + +override_dh_usrlocal: + +override_dh_clean: + dh_clean + (for mod in $(MODULE_DIRS); do \ + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules clean; \ + done) + diff --git a/platform/broadcom/sonic-platform-modules-mitac/debian/sonic-platform-mitac-ly1200-32x.init b/platform/broadcom/sonic-platform-modules-mitac/debian/sonic-platform-mitac-ly1200-32x.init new file mode 100644 index 000000000000..819b0287e8c3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/debian/sonic-platform-mitac-ly1200-32x.init @@ -0,0 +1,56 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup ly1200-32x board. +### END INIT INFO + +case "$1" in +start) + eval sonic_version=$(cat /etc/sonic/sonic_version.yml | grep build_version | cut -f2 -d" ") + if [ -f /host/image-$sonic_version/platform/firsttime ]; then + update-rc.d xcvr_servd defaults >/dev/null + fi + + echo -n "Setting up board... " + + echo 0 > /proc/sys/kernel/perf_cpu_time_max_percent + + /etc/init.d/gpe start + /etc/init.d/i2c_init start + /etc/init.d/sys_polld start + /opt/script/start_watchdog.sh & + /opt/script/start_service.sh & + echo "done." + ;; + +stop) + echo -n "cleaning... " + + /etc/init.d/gpe stop + /etc/init.d/i2c_init stop + /etc/init.d/xcvr_servd stop + /etc/init.d/sys_servd stop + /etc/init.d/sys_polld stop + + echo "done." + + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/sonic-platform-mitac-ly1200-32x.init {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-mitac/debian/sonic-platform-mitac-ly1200-32x.upstart b/platform/broadcom/sonic-platform-modules-mitac/debian/sonic-platform-mitac-ly1200-32x.upstart new file mode 100644 index 000000000000..39533b8226af --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/debian/sonic-platform-mitac-ly1200-32x.upstart @@ -0,0 +1,5 @@ +description "SONiC platform service" + +respawn + +exec /etc/init.d/sonic-platform-mitac-ly1200-32x start diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/etc/init.d/fan-ctrld b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/etc/init.d/fan-ctrld new file mode 100755 index 000000000000..936f01e8b640 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/etc/init.d/fan-ctrld @@ -0,0 +1,35 @@ +#!/bin/bash +### BEGIN INIT INFO +# Provides: fan-ctrld +# Required-Start: +# Required-Stop: +# Default-Start: rc.local +# Default-Stop: +# Short-Description: Daemon fan-ctrld +### END INIT INFO + +N=/etc/init.d/fan-ctrld +D_PATH=/opt/fan-ctrl/fan-ctrl + +set -e + +stop_fan_ctrld () { + pkill -f $D_PATH +} + +case "$1" in + start) + $D_PATH & + ;; + stop) + stop_fan_ctrld + ;; + reload|restart|force-reload) + ;; + *) + echo "Usage: $N {start}" >&2 + exit 1 + ;; +esac + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/etc/init.d/gpe b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/etc/init.d/gpe new file mode 100755 index 000000000000..c326442db047 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/etc/init.d/gpe @@ -0,0 +1,39 @@ +#! /bin/bash +### BEGIN INIT INFO +# Provides: gpe +# Required-Start: +# Required-Stop: +# Default-Start: rc.local +# Default-Stop: +# Short-Description: Daemon gpe +### END INIT INFO + +# Load kernel modules +load_module () { + if [ `lsmod | grep -c "gpe "` -eq 0 ]; then + insmod /lib/modules/`uname -r`/extra/mitac_ly1200_32x_gpe.ko + fi +} + +remove_module () { + rmmod mitac-ly1200-32x_gpe +} + +case "$1" in + start) + load_module + ;; + stop) + remove_module + ;; + reload|restart|force-reload) + remove_module + load_module + ;; + *) + echo "Usage: $N {start|stop|reload|restart|force-reload}" >&2 + exit 1 + ;; +esac + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/etc/init.d/i2c_init b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/etc/init.d/i2c_init new file mode 100755 index 000000000000..1d0a94cbb4e6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/etc/init.d/i2c_init @@ -0,0 +1,231 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board-i2c +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup ly1200-32x board. +### END INIT INFO + +I2C_BUS_RM_ALL=0 +I2C_I801_RM_PRINT=0 +I2C_ISMT_RM_PRINT=0 +I2C_I801_INS_PRINT=0 +I2C_ISMT_INS_PRINT=0 +I2C_I801_RM_RETRY=0 +I2C_ISMT_RM_RETRY=0 +I2C_I801_INS_RETRY=0 +I2C_ISMT_INS_RETRY=0 +RETRY=3 + +# process name/id +DAEMON_NAME=`basename $0` +DAEMON_PID="$$" + +# default log file +DEF_LOG_FILE="/var/log/syslog" + +#/* +#* FEATURE: +#* log_msg +#* PURPOSE: +#* log message +#* PARAMETERS: +#* msg (IN) message +#* RETURNS: +#* +#*/ +function log_msg() { + local msg=$1 + + echo -e "`date +"%b %_d %T"` `hostname` $DAEMON_NAME[$DAEMON_PID]: ${msg}" >> ${DEF_LOG_FILE} +} + + +# Load kernel modules +load_modules () { + while [ 1 ] + do + if [ `lsmod | grep -c "i2c_i801 "` -eq 1 ] && [ `lsmod | grep -c "i2c_ismt "` -eq 1 ]; then + log_msg "The kernel module i801 and ismt was insert." + break; + fi + if [ $I2C_BUS_RM_ALL -eq 0 ]; then + I2C_BUS_RM_ALL=1 + log_msg "Wait for i2c_i801 and i2c_ismt module insert." + fi + sleep 1 + done + if [ $I2C_BUS_RM_ALL -eq 1 ]; then + log_msg "i2c_i801 and i2c_ismt auto insert success." + fi + #----------remove i801 start--------------------- + if [ `lsmod | grep -c "i2c_i801 "` -eq 1 ]; then + rmmod i2c_i801 + while [ `lsmod | grep -c "i2c_i801 "` -eq 1 ] + do + if [ $I2C_I801_RM_PRINT -eq 0 ]; then + I2C_I801_RM_PRINT=1 + log_msg "Wait for i2c_i801 remove." + fi + if [ $I2C_I801_RM_RETRY -lt $RETRY ];then + I2C_I801_RM_RETRY=$((I2C_I801_RM_RETRY + 1)) + else + break + fi + sleep 1 + done + if [ $I2C_I801_RM_PRINT -eq 1 ]; then + log_msg "i2c_i801 remove success." + fi + fi + #----------remove i801 end------------------------ + + + #----------remove ismt start---------------------- + if [ `lsmod | grep -c "i2c_ismt "` -eq 1 ]; then + rmmod i2c_ismt + while [ `lsmod | grep -c "i2c_ismt "` -eq 1 ] + do + if [ $I2C_ISMT_RM_PRINT -eq 0 ]; then + I2C_ISMT_RM_PRINT=1 + log_msg "Wait for i2c_ismt remove." + fi + if [ $I2C_ISMT_RM_RETRY -lt $RETRY ];then + I2C_ISMT_RM_RETRY=$((I2C_ISMT_RM_RETRY + 1)) + else + break + fi + sleep 1 + done + if [ $I2C_ISMT_RM_PRINT -eq 1 ]; then + log_msg "i2c_ismt remove success." + fi + fi + #----------remove ismt end------------------------ + + #----------insert i801 start---------------------- + insmod /lib/modules/`uname -r`/kernel/drivers/i2c/busses/i2c-i801.ko + while [ `lsmod | grep -c "i2c_i801 "` -eq 0 ] + do + if [ $I2C_I801_INS_PRINT -eq 0 ]; then + I2C_I801_INS_PRINT=1 + log_msg "Wait for i2c_i801 insert." + fi + if [ $I2C_I801_INS_RETRY -lt $RETRY ];then + I2C_I801_INS_RETRY=$((I2C_I801_INS_RETRY + 1)) + else + break + fi + sleep 1 + done + if [ $I2C_I801_INS_PRINT -eq 1 ]; then + log_msg "i2c_i801 insert success." + fi + #----------insert i801 end------------------------ + + #----------insert ismt start---------------------- + insmod /lib/modules/`uname -r`/kernel/drivers/i2c/busses/i2c-ismt.ko + while [ `lsmod | grep -c "i2c_ismt "` -eq 0 ] + do + if [ $I2C_ISMT_INS_PRINT -eq 0 ]; then + I2C_ISMT_INS_PRINT=1 + log_msg "Wait for i2c_ismt insert." + fi + if [ $I2C_ISMT_INS_RETRY -lt $RETRY ];then + I2C_ISMT_INS_RETRY=$((I2C_ISMT_INS_RETRY + 1)) + else + break + fi + sleep 1 + done + if [ $I2C_ISMT_INS_PRINT -eq 1 ]; then + log_msg "i2c_ismt insert success." + fi + #----------insert ismt start------------------------ + if [ `lsmod | grep -c "at24 "` -eq 0 ]; then + insmod /lib/modules/`uname -r`/kernel/drivers/misc/eeprom/at24.ko + fi + if [ `lsmod | grep -c "i2c_mux "` -eq 0 ]; then + insmod /lib/modules/`uname -r`/kernel/drivers/i2c/i2c-mux.ko + fi + if [ `lsmod | grep -c "i2c_mux_pca954x "` -eq 0 ]; then + insmod /lib/modules/`uname -r`/kernel/drivers/i2c/muxes/i2c-mux-pca954x.ko + fi + if [ `lsmod | grep -c "lm75 "` -eq 0 ]; then + insmod /lib/modules/`uname -r`/kernel/drivers/hwmon/lm75.ko + fi + if [ `lsmod | grep -c "max31790 "` -eq 0 ]; then + insmod /lib/modules/`uname -r`/kernel/drivers/hwmon/max31790.ko + fi + if [ `lsmod | grep -c "sff_8436_eeprom "` -eq 0 ]; then + insmod /lib/modules/`uname -r`/kernel/drivers/misc/eeprom/sff_8436_eeprom.ko + fi + if [ `lsmod | grep -c "mitac_ly1200_32x_fse000 "` -eq 0 ]; then + insmod /lib/modules/`uname -r`/extra/mitac_ly1200_32x_fse000.ko + fi + if [ `lsmod | grep -c "mitac_ly1200_32x_system_cpld "` -eq 0 ]; then + insmod /lib/modules/`uname -r`/extra/mitac_ly1200_32x_system_cpld.ko + fi + if [ `lsmod | grep -c "mitac_ly1200_32x_master_cpld "` -eq 0 ]; then + insmod /lib/modules/`uname -r`/extra/mitac_ly1200_32x_master_cpld.ko + fi + if [ `lsmod | grep -c "mitac_ly1200_32x_slave_cpld "` -eq 0 ]; then + insmod /lib/modules/`uname -r`/extra/mitac_ly1200_32x_slave_cpld.ko + fi + if [ `lsmod | grep -c "mitac_ly1200_32x_cb_i2c "` -eq 0 ]; then + insmod /lib/modules/`uname -r`/extra/mitac_ly1200_32x_cb_i2c.ko + fi + if [ `lsmod | grep -c "mitac_ly1200_32x_sb_i2c "` -eq 0 ]; then + insmod /lib/modules/`uname -r`/extra/mitac_ly1200_32x_sb_i2c.ko + fi + if [ `lsmod | grep -c "mitac_ly1200_32x_pb_i2c "` -eq 0 ]; then + insmod /lib/modules/`uname -r`/extra/mitac_ly1200_32x_pb_i2c.ko + fi + if [ `lsmod | grep -c "mitac_ly1200_32x_fb_i2c "` -eq 0 ]; then + insmod /lib/modules/`uname -r`/extra/mitac_ly1200_32x_fb_i2c.ko + fi + if [ `lsmod | grep -c "mitac_ly1200_32x_fb_module_i2c "` -eq 0 ]; then + insmod /lib/modules/`uname -r`/extra/mitac_ly1200_32x_fb_module_i2c.ko + fi +} + +# Load i2c_dev modules +load_i2c_dev_modules () { + if [ `lsmod | grep -c "i2c_dev "` -eq 0 ]; then + modprobe i2c_dev + fi +} + +case "$1" in +start) + echo -n "Setting up board... " + depmod -a + load_i2c_dev_modules + load_modules + echo "done." + ;; + +stop) + echo -n "cleaning... " + + + echo "done." + + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/i2c_init {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/etc/init.d/sys_polld b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/etc/init.d/sys_polld new file mode 100755 index 000000000000..1df43346f257 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/etc/init.d/sys_polld @@ -0,0 +1,48 @@ +#!/bin/bash +### BEGIN INIT INFO +# Provides: sys-polld +# Required-Start: +# Required-Stop: +# Default-Start: rc.local +# Default-Stop: +# Short-Description: Daemon sys-polld +### END INIT INFO + +N=/etc/init.d/sys-polld +D_PATH=/opt/system-check/system-check.sh + +set -e + +stop_syspolld () { + local GCOUNT=`ps aux | grep -c "$D_PATH"` + local KILL_COUNT=0 + + while [ $GCOUNT -gt 1 ] + do + local ID=`ps aux | grep "$D_PATH" | head -n 1 | awk -F' ' '{print $2}'` + kill -15 $ID + GCOUNT=`ps aux | grep -c "$D_PATH"` + KILL_COUNT=`expr $KILL_COUNT + 1` + if [ $KILL_COUNT -eq 100 ]; then + echo "Error: kill sys-polld $KILL_COUNT times. stop kill process." + GCOUNT=0 + fi + done +} + +case "$1" in + start) + $D_PATH & + ;; + stop) + stop_syspolld + ;; + reload|restart|force-reload) + ;; + *) + echo "Usage: $N {start}" >&2 + exit 1 + ;; +esac + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/etc/init.d/sys_servd b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/etc/init.d/sys_servd new file mode 100755 index 000000000000..09ee087d5db0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/etc/init.d/sys_servd @@ -0,0 +1,28 @@ +#!/bin/sh +### BEGIN INIT INFO +# Provides: sys-servd +# Required-Start: $remote_fs $syslog +# Required-Stop: $remote_fs $syslog +# Default-Start: rc.local +# Default-Stop: 0 1 6 +# Short-Description: Daemon sys-servd +### END INIT INFO + +# Author: Eddy Weng + +DESC="Service script for /opt/sys-serv/sys-servd" +DAEMON=/opt/sys-serv/sys-servd + +case "$1" in + start) + start-stop-daemon --start --exec $DAEMON + ;; + stop) + start-stop-daemon --stop --name sys-servd + ;; + *) + exit 1 + ;; +esac + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/etc/init.d/xcvr_servd b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/etc/init.d/xcvr_servd new file mode 100755 index 000000000000..1558614fd43c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/etc/init.d/xcvr_servd @@ -0,0 +1,28 @@ +#!/bin/sh +### BEGIN INIT INFO +# Provides: xcvr-servd +# Required-Start: $remote_fs $syslog +# Required-Stop: $remote_fs $syslog +# Default-Start: rc.local +# Default-Stop: 0 1 6 +# Short-Description: Daemon xcvr-servd +### END INIT INFO + +# Author: Yencheng Lin + +DESC="Service script for /opt/xcvr-serv/xcvr-servd" +DAEMON=/opt/xcvr-serv/xcvr-servd + +case "$1" in + start) + start-stop-daemon --start --exec $DAEMON + ;; + stop) + start-stop-daemon --stop --name xcvr-servd + ;; + *) + exit 1 + ;; +esac + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/Makefile b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/Makefile new file mode 100644 index 000000000000..fc3f88de8eb3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/Makefile @@ -0,0 +1,5 @@ +obj-m:=mitac_ly1200_32x_fb_i2c.o mitac_ly1200_32x_fse000.o \ +mitac_ly1200_32x_master_cpld.o mitac_ly1200_32x_sb_i2c.o \ +mitac_ly1200_32x_system_cpld.o mitac_ly1200_32x_cb_i2c.o \ +mitac_ly1200_32x_fb_module_i2c.o mitac_ly1200_32x_gpe.o \ +mitac_ly1200_32x_pb_i2c.o mitac_ly1200_32x_slave_cpld.o diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/bms_i2c.h b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/bms_i2c.h new file mode 100644 index 000000000000..dd63607f39c7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/bms_i2c.h @@ -0,0 +1,26 @@ +#ifndef _BMS_I2C_H_ +#define _BMS_I2C_H_ + +const char *bms_i2c_adapter_names[] = { + "SMBus I801 adapter", + "SMBus iSMT adapter", +}; + +enum i2c_adapter_type { + I2C_ADAPTER_I801 = 0, + I2C_ADAPTER_ISMT, +}; + +enum bms_module_switch_bus { + I2C_STAGE1_MUX_CHAN0 = 0, + I2C_STAGE1_MUX_CHAN1, + I2C_STAGE1_MUX_CHAN2, + I2C_STAGE1_MUX_CHAN3, + I2C_STAGE1_MUX_CHAN4, + I2C_STAGE1_MUX_CHAN5, + I2C_STAGE1_MUX_CHAN6, + I2C_STAGE1_MUX_CHAN7, +}; + +#endif /* _BMS_I2C_H_ */ + diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/master_cpld_reg.h b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/master_cpld_reg.h new file mode 100644 index 000000000000..dfdc89dbe57d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/master_cpld_reg.h @@ -0,0 +1,275 @@ +#ifndef __MASTER_CPLD_REG +#define __MASTER_CPLD_REG + +static int master_cpld_raw_read(struct device *dev, struct device_attribute *attr, char *buf, + int reg_offset, int reg_width, int fld_shift, int fld_width, int fld_mask, char* reg_name); +static int master_cpld_raw_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count, + int reg_offset, int reg_width, int fld_shift, int fld_width, int fld_mask, char* reg_name); + +/* generic CPLD read function */ +#define FLD_RAW_RD_FUNC(_reg, _fld, _wdh) static ssize_t \ +master_cpld_##_fld##_raw_read(struct device *dev, struct device_attribute *attr, char *buf) { \ + return master_cpld_raw_read(dev, attr, buf, _reg##_offset, _reg##_width, _fld##_shift, _fld##_width, _fld##_mask, #_reg); \ +} + +/* generic CPLD write function */ +#define FLD_RAW_WR_FUNC(_reg, _fld, _wdh) static ssize_t \ +master_cpld_##_fld##_raw_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { \ + return master_cpld_raw_write(dev, attr, buf, count, _reg##_offset, _reg##_width, _fld##_shift, _fld##_width, _fld##_mask, #_reg); \ +} + +/* CPLD register definition macros */ +#define REG_DEF(_reg, _off, _wdh) \ +static unsigned int _reg##_offset = (unsigned int)(_off); \ +static unsigned int _reg##_width = (unsigned int)(_wdh); + +/* CPLD register field definition macros, with generic read/write function */ +#define FLD_RAW_RO_DEF(_reg, _fld, _sft, _wdh) \ +static unsigned int _fld##_shift = (unsigned int)(_sft); \ +static unsigned int _fld##_width = (unsigned int)(_wdh); \ +static unsigned int _fld##_mask = ((((unsigned int)1) << (_wdh)) - 1); \ +FLD_RAW_RD_FUNC(_reg, _fld, _wdh) + +#define FLD_RAW_RW_DEF(_reg, _fld, _sft, _wdh) \ +static unsigned int _fld##_shift = (unsigned int)(_sft); \ +static unsigned int _fld##_width = (unsigned int)(_wdh); \ +static unsigned int _fld##_mask = ((((unsigned int)1) << (_wdh)) - 1); \ +FLD_RAW_RD_FUNC(_reg, _fld, _wdh) FLD_RAW_WR_FUNC(_reg, _fld, _wdh) + +/* declare master CPLD registers */ +/* register name offset width */ +/* --------------------------------------- ------- ----- */ +REG_DEF( mstr_cpld_rev, 0x00, 8) +REG_DEF( mstr_cpld_gpr, 0x01, 8) +REG_DEF( mb_brd_rev_type, 0x02, 8) +REG_DEF( mstr_srr, 0x03, 8) +REG_DEF( eeprom_wp, 0x04, 8) +REG_DEF( mstr_irq, 0x05, 8) +REG_DEF( system_led, 0x06, 8) +REG_DEF( fan_tray_3_1_led, 0x07, 8) +REG_DEF( fan_tray_6_4_led, 0x08, 8) +REG_DEF( fan_tray_status, 0x09, 8) +REG_DEF( fan_type_status, 0x0A, 8) +REG_DEF( psu_en_status, 0x0B, 8) +REG_DEF( mb_pwr_en_status, 0x0C, 8) +REG_DEF( mb_pwr_status, 0x0D, 8) + +REG_DEF( zqsfp28_present_8_1_status, 0x10, 8) +REG_DEF( zqsfp28_present_16_9_status, 0x11, 8) +REG_DEF( zqsfp28_rst_8_1, 0x12, 8) +REG_DEF( zqsfp28_rst_16_9, 0x13, 8) +REG_DEF( zqsfp28_modsel_8_1, 0x14, 8) +REG_DEF( zqsfp28_modsel_16_9, 0x15, 8) +REG_DEF( zqsfp28_lpmode_8_1, 0x16, 8) +REG_DEF( zqsfp28_lpmode_16_9, 0x17, 8) +REG_DEF( zqsfp28_irq_8_1_status, 0x18, 8) +REG_DEF( zqsfp28_irq_16_9_status, 0x19, 8) +REG_DEF( zqsfp28_irq_msk_8_1_status, 0x1A, 8) +REG_DEF( zqsfp28_irq_msk_16_9_status, 0x1B, 8) + + +/* declare master CPLD register's fields */ +/* register name field name shift width */ +/* ---------------------- ---------------- ------ ----- */ +FLD_RAW_RO_DEF( mstr_cpld_rev, mjr_rev, 4, 4) +FLD_RAW_RO_DEF( mstr_cpld_rev, mnr_rev, 0, 4) + +FLD_RAW_RW_DEF( mstr_cpld_gpr, scrtch_reg, 0, 8) + +FLD_RAW_RO_DEF( mb_brd_rev_type, brd_rev, 4, 4) +FLD_RAW_RO_DEF( mb_brd_rev_type, brd_type, 0, 4) + +FLD_RAW_RW_DEF( mstr_srr, mb_rst, 2, 1) +FLD_RAW_RW_DEF( mstr_srr, npu_rst, 1, 1) +FLD_RAW_RW_DEF( mstr_srr, mgmt_phy_rst, 0, 1) + +FLD_RAW_RW_DEF( eeprom_wp, mb_eeprom_wp, 2, 1) +FLD_RAW_RW_DEF( eeprom_wp, cpld_spi_wp, 1, 1) +FLD_RAW_RW_DEF( eeprom_wp, fan_eeprom_wp, 0, 1) + +FLD_RAW_RW_DEF( mstr_irq, ps2_int_msk, 7, 1) +FLD_RAW_RW_DEF( mstr_irq, ps1_int_msk, 6, 1) +FLD_RAW_RW_DEF( mstr_irq, usb_fault_msk, 5, 1) +FLD_RAW_RW_DEF( mstr_irq, pcie_int_msk, 4, 1) +FLD_RAW_RW_DEF( mstr_irq, fan_alert_int_msk, 3, 1) +FLD_RAW_RO_DEF( mstr_irq, usb_fault, 2, 1) +FLD_RAW_RO_DEF( mstr_irq, pcie_int, 1, 1) +FLD_RAW_RO_DEF( mstr_irq, fan_alert_int, 0, 1) + +FLD_RAW_RW_DEF( system_led, system_led_fld, 6, 2) +FLD_RAW_RW_DEF( system_led, power_led, 4, 2) +FLD_RAW_RW_DEF( system_led, fan_led, 2, 2) +FLD_RAW_RW_DEF( system_led, locate_led, 1, 1) + +FLD_RAW_RW_DEF( fan_tray_3_1_led, led_test, 6, 2) +FLD_RAW_RW_DEF( fan_tray_3_1_led, fan_tray3_led, 4, 2) +FLD_RAW_RW_DEF( fan_tray_3_1_led, fan_tray2_led, 2, 2) +FLD_RAW_RW_DEF( fan_tray_3_1_led, fan_tray1_led, 0, 2) + +FLD_RAW_RW_DEF( fan_tray_6_4_led, fan_tray6_led, 4, 2) +FLD_RAW_RW_DEF( fan_tray_6_4_led, fan_tray5_led, 2, 2) +FLD_RAW_RW_DEF( fan_tray_6_4_led, fan_tray4_led, 0, 2) + +FLD_RAW_RO_DEF( fan_tray_status, fan_tray6_present, 5, 1) +FLD_RAW_RO_DEF( fan_tray_status, fan_tray5_present, 4, 1) +FLD_RAW_RO_DEF( fan_tray_status, fan_tray4_present, 3, 1) +FLD_RAW_RO_DEF( fan_tray_status, fan_tray3_present, 2, 1) +FLD_RAW_RO_DEF( fan_tray_status, fan_tray2_present, 1, 1) +FLD_RAW_RO_DEF( fan_tray_status, fan_tray1_present, 0, 1) + +FLD_RAW_RO_DEF( fan_type_status, fan_type6, 5, 1) +FLD_RAW_RO_DEF( fan_type_status, fan_type5, 4, 1) +FLD_RAW_RO_DEF( fan_type_status, fan_type4, 3, 1) +FLD_RAW_RO_DEF( fan_type_status, fan_type3, 2, 1) +FLD_RAW_RO_DEF( fan_type_status, fan_type2, 1, 1) +FLD_RAW_RO_DEF( fan_type_status, fan_type1, 0, 1) + +FLD_RAW_RO_DEF( psu_en_status, ps1_ps, 7, 1) +FLD_RAW_RO_DEF( psu_en_status, ps1_pg, 6, 1) +FLD_RAW_RO_DEF( psu_en_status, ps1_int, 5, 1) +FLD_RAW_RW_DEF( psu_en_status, ps1_on, 4, 1) +FLD_RAW_RO_DEF( psu_en_status, ps2_ps, 3, 1) +FLD_RAW_RO_DEF( psu_en_status, ps2_pg, 2, 1) +FLD_RAW_RO_DEF( psu_en_status, ps2_int, 1, 1) +FLD_RAW_RW_DEF( psu_en_status, ps2_on, 0, 1) + +FLD_RAW_RW_DEF( mb_pwr_en_status, usb1_vbus_en, 7, 1) +FLD_RAW_RO_DEF( mb_pwr_en_status, v5p0_en, 5, 1) +FLD_RAW_RO_DEF( mb_pwr_en_status, v3p3_en, 4, 1) +FLD_RAW_RO_DEF( mb_pwr_en_status, vcc_1v8_en, 3, 1) +FLD_RAW_RO_DEF( mb_pwr_en_status, mac_avs1v_en, 2, 1) +FLD_RAW_RO_DEF( mb_pwr_en_status, mac1v_en, 1, 1) +FLD_RAW_RO_DEF( mb_pwr_en_status, vcc_1v25_en, 0, 1) + +FLD_RAW_RO_DEF( mb_pwr_status, vcc_3p3_cpld, 6, 1) +FLD_RAW_RO_DEF( mb_pwr_status, vcc5v_pg, 5, 1) +FLD_RAW_RO_DEF( mb_pwr_status, vcc3v3_pg, 4, 1) +FLD_RAW_RO_DEF( mb_pwr_status, vcc_1v8_pg, 3, 1) +FLD_RAW_RO_DEF( mb_pwr_status, mac_avs1v_pg, 2, 1) +FLD_RAW_RO_DEF( mb_pwr_status, mac1v_pg, 1, 1) +FLD_RAW_RO_DEF( mb_pwr_status, vcc_1v25_pg, 0, 1) + +FLD_RAW_RO_DEF( zqsfp28_present_8_1_status, port8_present, 7, 1) +FLD_RAW_RO_DEF( zqsfp28_present_8_1_status, port7_present, 6, 1) +FLD_RAW_RO_DEF( zqsfp28_present_8_1_status, port6_present, 5, 1) +FLD_RAW_RO_DEF( zqsfp28_present_8_1_status, port5_present, 4, 1) +FLD_RAW_RO_DEF( zqsfp28_present_8_1_status, port4_present, 3, 1) +FLD_RAW_RO_DEF( zqsfp28_present_8_1_status, port3_present, 2, 1) +FLD_RAW_RO_DEF( zqsfp28_present_8_1_status, port2_present, 1, 1) +FLD_RAW_RO_DEF( zqsfp28_present_8_1_status, port1_present, 0, 1) + +FLD_RAW_RO_DEF( zqsfp28_present_16_9_status,port16_present, 7, 1) +FLD_RAW_RO_DEF( zqsfp28_present_16_9_status,port15_present, 6, 1) +FLD_RAW_RO_DEF( zqsfp28_present_16_9_status,port14_present, 5, 1) +FLD_RAW_RO_DEF( zqsfp28_present_16_9_status,port13_present, 4, 1) +FLD_RAW_RO_DEF( zqsfp28_present_16_9_status,port12_present, 3, 1) +FLD_RAW_RO_DEF( zqsfp28_present_16_9_status,port11_present, 2, 1) +FLD_RAW_RO_DEF( zqsfp28_present_16_9_status,port10_present, 1, 1) +FLD_RAW_RO_DEF( zqsfp28_present_16_9_status,port9_present, 0, 1) + +FLD_RAW_RW_DEF( zqsfp28_rst_8_1, port8_rst, 7, 1) +FLD_RAW_RW_DEF( zqsfp28_rst_8_1, port7_rst, 6, 1) +FLD_RAW_RW_DEF( zqsfp28_rst_8_1, port6_rst, 5, 1) +FLD_RAW_RW_DEF( zqsfp28_rst_8_1, port5_rst, 4, 1) +FLD_RAW_RW_DEF( zqsfp28_rst_8_1, port4_rst, 3, 1) +FLD_RAW_RW_DEF( zqsfp28_rst_8_1, port3_rst, 2, 1) +FLD_RAW_RW_DEF( zqsfp28_rst_8_1, port2_rst, 1, 1) +FLD_RAW_RW_DEF( zqsfp28_rst_8_1, port1_rst, 0, 1) + +FLD_RAW_RW_DEF( zqsfp28_rst_16_9, port16_rst, 7, 1) +FLD_RAW_RW_DEF( zqsfp28_rst_16_9, port15_rst, 6, 1) +FLD_RAW_RW_DEF( zqsfp28_rst_16_9, port14_rst, 5, 1) +FLD_RAW_RW_DEF( zqsfp28_rst_16_9, port13_rst, 4, 1) +FLD_RAW_RW_DEF( zqsfp28_rst_16_9, port12_rst, 3, 1) +FLD_RAW_RW_DEF( zqsfp28_rst_16_9, port11_rst, 2, 1) +FLD_RAW_RW_DEF( zqsfp28_rst_16_9, port10_rst, 1, 1) +FLD_RAW_RW_DEF( zqsfp28_rst_16_9, port9_rst, 0, 1) + +FLD_RAW_RW_DEF( zqsfp28_modsel_8_1, port8_modsel, 7, 1) +FLD_RAW_RW_DEF( zqsfp28_modsel_8_1, port7_modsel, 6, 1) +FLD_RAW_RW_DEF( zqsfp28_modsel_8_1, port6_modsel, 5, 1) +FLD_RAW_RW_DEF( zqsfp28_modsel_8_1, port5_modsel, 4, 1) +FLD_RAW_RW_DEF( zqsfp28_modsel_8_1, port4_modsel, 3, 1) +FLD_RAW_RW_DEF( zqsfp28_modsel_8_1, port3_modsel, 2, 1) +FLD_RAW_RW_DEF( zqsfp28_modsel_8_1, port2_modsel, 1, 1) +FLD_RAW_RW_DEF( zqsfp28_modsel_8_1, port1_modsel, 0, 1) + +FLD_RAW_RW_DEF( zqsfp28_modsel_16_9, port16_modsel, 7, 1) +FLD_RAW_RW_DEF( zqsfp28_modsel_16_9, port15_modsel, 6, 1) +FLD_RAW_RW_DEF( zqsfp28_modsel_16_9, port14_modsel, 5, 1) +FLD_RAW_RW_DEF( zqsfp28_modsel_16_9, port13_modsel, 4, 1) +FLD_RAW_RW_DEF( zqsfp28_modsel_16_9, port12_modsel, 3, 1) +FLD_RAW_RW_DEF( zqsfp28_modsel_16_9, port11_modsel, 2, 1) +FLD_RAW_RW_DEF( zqsfp28_modsel_16_9, port10_modsel, 1, 1) +FLD_RAW_RW_DEF( zqsfp28_modsel_16_9, port9_modsel, 0, 1) + +FLD_RAW_RW_DEF( zqsfp28_lpmode_8_1, port8_lpmode, 7, 1) +FLD_RAW_RW_DEF( zqsfp28_lpmode_8_1, port7_lpmode, 6, 1) +FLD_RAW_RW_DEF( zqsfp28_lpmode_8_1, port6_lpmode, 5, 1) +FLD_RAW_RW_DEF( zqsfp28_lpmode_8_1, port5_lpmode, 4, 1) +FLD_RAW_RW_DEF( zqsfp28_lpmode_8_1, port4_lpmode, 3, 1) +FLD_RAW_RW_DEF( zqsfp28_lpmode_8_1, port3_lpmode, 2, 1) +FLD_RAW_RW_DEF( zqsfp28_lpmode_8_1, port2_lpmode, 1, 1) +FLD_RAW_RW_DEF( zqsfp28_lpmode_8_1, port1_lpmode, 0, 1) + +FLD_RAW_RW_DEF( zqsfp28_lpmode_16_9, port16_lpmode, 7, 1) +FLD_RAW_RW_DEF( zqsfp28_lpmode_16_9, port15_lpmode, 6, 1) +FLD_RAW_RW_DEF( zqsfp28_lpmode_16_9, port14_lpmode, 5, 1) +FLD_RAW_RW_DEF( zqsfp28_lpmode_16_9, port13_lpmode, 4, 1) +FLD_RAW_RW_DEF( zqsfp28_lpmode_16_9, port12_lpmode, 3, 1) +FLD_RAW_RW_DEF( zqsfp28_lpmode_16_9, port11_lpmode, 2, 1) +FLD_RAW_RW_DEF( zqsfp28_lpmode_16_9, port10_lpmode, 1, 1) +FLD_RAW_RW_DEF( zqsfp28_lpmode_16_9, port9_lpmode, 0, 1) + +FLD_RAW_RO_DEF( zqsfp28_irq_8_1_status, port8_irq_status, 7, 1) +FLD_RAW_RO_DEF( zqsfp28_irq_8_1_status, port7_irq_status, 6, 1) +FLD_RAW_RO_DEF( zqsfp28_irq_8_1_status, port6_irq_status, 5, 1) +FLD_RAW_RO_DEF( zqsfp28_irq_8_1_status, port5_irq_status, 4, 1) +FLD_RAW_RO_DEF( zqsfp28_irq_8_1_status, port4_irq_status, 3, 1) +FLD_RAW_RO_DEF( zqsfp28_irq_8_1_status, port3_irq_status, 2, 1) +FLD_RAW_RO_DEF( zqsfp28_irq_8_1_status, port2_irq_status, 1, 1) +FLD_RAW_RO_DEF( zqsfp28_irq_8_1_status, port1_irq_status, 0, 1) + +FLD_RAW_RO_DEF( zqsfp28_irq_16_9_status, port16_irq_status, 7, 1) +FLD_RAW_RO_DEF( zqsfp28_irq_16_9_status, port15_irq_status, 6, 1) +FLD_RAW_RO_DEF( zqsfp28_irq_16_9_status, port14_irq_status, 5, 1) +FLD_RAW_RO_DEF( zqsfp28_irq_16_9_status, port13_irq_status, 4, 1) +FLD_RAW_RO_DEF( zqsfp28_irq_16_9_status, port12_irq_status, 3, 1) +FLD_RAW_RO_DEF( zqsfp28_irq_16_9_status, port11_irq_status, 2, 1) +FLD_RAW_RO_DEF( zqsfp28_irq_16_9_status, port10_irq_status, 1, 1) +FLD_RAW_RO_DEF( zqsfp28_irq_16_9_status, port9_irq_status, 0, 1) + +FLD_RAW_RW_DEF( zqsfp28_irq_msk_8_1_status, port8_irq_msk, 7, 1) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_8_1_status, port7_irq_msk, 6, 1) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_8_1_status, port6_irq_msk, 5, 1) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_8_1_status, port5_irq_msk, 4, 1) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_8_1_status, port4_irq_msk, 3, 1) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_8_1_status, port3_irq_msk, 2, 1) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_8_1_status, port2_irq_msk, 1, 1) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_8_1_status, port1_irq_msk, 0, 1) + +FLD_RAW_RW_DEF( zqsfp28_irq_msk_16_9_status,port16_irq_msk, 7, 1) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_16_9_status,port15_irq_msk, 6, 1) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_16_9_status,port14_irq_msk, 5, 1) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_16_9_status,port13_irq_msk, 4, 1) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_16_9_status,port12_irq_msk, 3, 1) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_16_9_status,port11_irq_msk, 2, 1) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_16_9_status,port10_irq_msk, 1, 1) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_16_9_status,port9_irq_msk, 0, 1) + +FLD_RAW_RO_DEF( zqsfp28_present_8_1_status, port_1_8_present, 0, 8) +FLD_RAW_RO_DEF( zqsfp28_present_16_9_status,port_9_16_present, 0, 8) +FLD_RAW_RW_DEF( zqsfp28_rst_8_1, port_1_8_rst, 0, 8) +FLD_RAW_RW_DEF( zqsfp28_rst_16_9, port_9_16_rst, 0, 8) +FLD_RAW_RW_DEF( zqsfp28_modsel_8_1, port_1_8_modsel, 0, 8) +FLD_RAW_RW_DEF( zqsfp28_modsel_16_9, port_9_16_modsel, 0, 8) +FLD_RAW_RO_DEF( zqsfp28_irq_8_1_status, port_1_8_irq_status, 0, 8) +FLD_RAW_RO_DEF( zqsfp28_irq_16_9_status, port_9_16_irq_status,0, 8) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_8_1_status, port_1_8_irq_msk, 0, 8) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_16_9_status,port_9_16_irq_msk, 0, 8) +FLD_RAW_RW_DEF( zqsfp28_lpmode_8_1, port_1_8_lpmode, 0, 8) +FLD_RAW_RW_DEF( zqsfp28_lpmode_16_9, port_9_16_lpmode, 0, 8) + +FLD_RAW_RO_DEF( fan_tray_status, fan_tray1_6_present, 0, 8) +FLD_RAW_RO_DEF( psu_en_status, psu_en_status_fld, 0, 8) +#endif /* __MASTER_CPLD_REG */ diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/master_cpld_sysfs.h b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/master_cpld_sysfs.h new file mode 100644 index 000000000000..e851ca5fb487 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/master_cpld_sysfs.h @@ -0,0 +1,226 @@ +#ifndef __MASTER_CPLD_SYSFS +#define __MASTER_CPLD_SYSFS + +/* generic CPLD sysfs file definition macros */ +#define SYSFS_RAW_RO_ATTR_DEF(field) \ +struct device_attribute field \ + = __ATTR(field, S_IRUGO, master_cpld_##field##_raw_read, NULL); + +#define SYSFS_RAW_RW_ATTR_DEF(field) \ +struct device_attribute field \ + = __ATTR(field, S_IRUGO | S_IWUGO, master_cpld_##field##_raw_read, master_cpld_##field##_raw_write); + +#define SYSFS_MISC_RO_ATTR_DEF(field, _read) \ +struct device_attribute field \ + = __ATTR(field, S_IRUGO, _read, NULL); + +#define SYSFS_MISC_RW_ATTR_DEF(field, _read, _write) \ +struct device_attribute field \ + = __ATTR(field, S_IRUGO | S_IWUGO, _read, _write); + +#define SYSFS_ATTR_PTR(field) \ +&field.attr + +/* declare master CPLD file system */ +SYSFS_RAW_RO_ATTR_DEF(mjr_rev) +SYSFS_RAW_RO_ATTR_DEF(mnr_rev) + +SYSFS_RAW_RW_ATTR_DEF(scrtch_reg) + +SYSFS_RAW_RO_ATTR_DEF(brd_rev) +SYSFS_RAW_RO_ATTR_DEF(brd_type) + +SYSFS_RAW_RW_ATTR_DEF(mb_rst) +SYSFS_RAW_RW_ATTR_DEF(npu_rst) +SYSFS_RAW_RW_ATTR_DEF(mgmt_phy_rst) + +SYSFS_RAW_RW_ATTR_DEF(mb_eeprom_wp) +SYSFS_RAW_RW_ATTR_DEF(cpld_spi_wp) +SYSFS_RAW_RW_ATTR_DEF(fan_eeprom_wp) + +SYSFS_RAW_RW_ATTR_DEF(ps2_int_msk) +SYSFS_RAW_RW_ATTR_DEF(ps1_int_msk) +SYSFS_RAW_RW_ATTR_DEF(usb_fault_msk) +SYSFS_RAW_RW_ATTR_DEF(pcie_int_msk) +SYSFS_RAW_RW_ATTR_DEF(fan_alert_int_msk) +SYSFS_RAW_RO_ATTR_DEF(usb_fault) +SYSFS_RAW_RO_ATTR_DEF(pcie_int) +SYSFS_RAW_RO_ATTR_DEF(fan_alert_int) + +SYSFS_RAW_RW_ATTR_DEF(system_led_fld) +SYSFS_RAW_RW_ATTR_DEF(power_led) +SYSFS_RAW_RW_ATTR_DEF(fan_led) +SYSFS_RAW_RW_ATTR_DEF(locate_led) + +SYSFS_RAW_RW_ATTR_DEF(led_test) +SYSFS_RAW_RW_ATTR_DEF(fan_tray3_led) +SYSFS_RAW_RW_ATTR_DEF(fan_tray2_led) +SYSFS_RAW_RW_ATTR_DEF(fan_tray1_led) + +SYSFS_RAW_RW_ATTR_DEF(fan_tray6_led) +SYSFS_RAW_RW_ATTR_DEF(fan_tray5_led) +SYSFS_RAW_RW_ATTR_DEF(fan_tray4_led) + +SYSFS_RAW_RO_ATTR_DEF(fan_tray6_present) +SYSFS_RAW_RO_ATTR_DEF(fan_tray5_present) +SYSFS_RAW_RO_ATTR_DEF(fan_tray4_present) +SYSFS_RAW_RO_ATTR_DEF(fan_tray3_present) +SYSFS_RAW_RO_ATTR_DEF(fan_tray2_present) +SYSFS_RAW_RO_ATTR_DEF(fan_tray1_present) + +SYSFS_RAW_RO_ATTR_DEF(fan_type6) +SYSFS_RAW_RO_ATTR_DEF(fan_type5) +SYSFS_RAW_RO_ATTR_DEF(fan_type4) +SYSFS_RAW_RO_ATTR_DEF(fan_type3) +SYSFS_RAW_RO_ATTR_DEF(fan_type2) +SYSFS_RAW_RO_ATTR_DEF(fan_type1) + +SYSFS_RAW_RO_ATTR_DEF(ps1_ps) +SYSFS_RAW_RO_ATTR_DEF(ps1_pg) +SYSFS_RAW_RO_ATTR_DEF(ps1_int) +SYSFS_RAW_RW_ATTR_DEF(ps1_on) +SYSFS_RAW_RO_ATTR_DEF(ps2_ps) +SYSFS_RAW_RO_ATTR_DEF(ps2_pg) +SYSFS_RAW_RO_ATTR_DEF(ps2_int) +SYSFS_RAW_RW_ATTR_DEF(ps2_on) + +SYSFS_RAW_RW_ATTR_DEF(usb1_vbus_en) +SYSFS_RAW_RO_ATTR_DEF(v5p0_en) +SYSFS_RAW_RO_ATTR_DEF(v3p3_en) +SYSFS_RAW_RO_ATTR_DEF(vcc_1v8_en) +SYSFS_RAW_RO_ATTR_DEF(mac_avs1v_en) +SYSFS_RAW_RO_ATTR_DEF(mac1v_en) +SYSFS_RAW_RO_ATTR_DEF(vcc_1v25_en) + +SYSFS_RAW_RO_ATTR_DEF(vcc_3p3_cpld) +SYSFS_RAW_RO_ATTR_DEF(vcc5v_pg) +SYSFS_RAW_RO_ATTR_DEF(vcc3v3_pg) +SYSFS_RAW_RO_ATTR_DEF(vcc_1v8_pg) +SYSFS_RAW_RO_ATTR_DEF(mac_avs1v_pg) +SYSFS_RAW_RO_ATTR_DEF(mac1v_pg) +SYSFS_RAW_RO_ATTR_DEF(vcc_1v25_pg) + +SYSFS_RAW_RO_ATTR_DEF(port8_present) +SYSFS_RAW_RO_ATTR_DEF(port7_present) +SYSFS_RAW_RO_ATTR_DEF(port6_present) +SYSFS_RAW_RO_ATTR_DEF(port5_present) +SYSFS_RAW_RO_ATTR_DEF(port4_present) +SYSFS_RAW_RO_ATTR_DEF(port3_present) +SYSFS_RAW_RO_ATTR_DEF(port2_present) +SYSFS_RAW_RO_ATTR_DEF(port1_present) + +SYSFS_RAW_RO_ATTR_DEF(port16_present) +SYSFS_RAW_RO_ATTR_DEF(port15_present) +SYSFS_RAW_RO_ATTR_DEF(port14_present) +SYSFS_RAW_RO_ATTR_DEF(port13_present) +SYSFS_RAW_RO_ATTR_DEF(port12_present) +SYSFS_RAW_RO_ATTR_DEF(port11_present) +SYSFS_RAW_RO_ATTR_DEF(port10_present) +SYSFS_RAW_RO_ATTR_DEF(port9_present) + +SYSFS_RAW_RW_ATTR_DEF(port8_rst) +SYSFS_RAW_RW_ATTR_DEF(port7_rst) +SYSFS_RAW_RW_ATTR_DEF(port6_rst) +SYSFS_RAW_RW_ATTR_DEF(port5_rst) +SYSFS_RAW_RW_ATTR_DEF(port4_rst) +SYSFS_RAW_RW_ATTR_DEF(port3_rst) +SYSFS_RAW_RW_ATTR_DEF(port2_rst) +SYSFS_RAW_RW_ATTR_DEF(port1_rst) + +SYSFS_RAW_RW_ATTR_DEF(port16_rst) +SYSFS_RAW_RW_ATTR_DEF(port15_rst) +SYSFS_RAW_RW_ATTR_DEF(port14_rst) +SYSFS_RAW_RW_ATTR_DEF(port13_rst) +SYSFS_RAW_RW_ATTR_DEF(port12_rst) +SYSFS_RAW_RW_ATTR_DEF(port11_rst) +SYSFS_RAW_RW_ATTR_DEF(port10_rst) +SYSFS_RAW_RW_ATTR_DEF(port9_rst) + +SYSFS_RAW_RW_ATTR_DEF(port8_modsel) +SYSFS_RAW_RW_ATTR_DEF(port7_modsel) +SYSFS_RAW_RW_ATTR_DEF(port6_modsel) +SYSFS_RAW_RW_ATTR_DEF(port5_modsel) +SYSFS_RAW_RW_ATTR_DEF(port4_modsel) +SYSFS_RAW_RW_ATTR_DEF(port3_modsel) +SYSFS_RAW_RW_ATTR_DEF(port2_modsel) +SYSFS_RAW_RW_ATTR_DEF(port1_modsel) + +SYSFS_RAW_RW_ATTR_DEF(port16_modsel) +SYSFS_RAW_RW_ATTR_DEF(port15_modsel) +SYSFS_RAW_RW_ATTR_DEF(port14_modsel) +SYSFS_RAW_RW_ATTR_DEF(port13_modsel) +SYSFS_RAW_RW_ATTR_DEF(port12_modsel) +SYSFS_RAW_RW_ATTR_DEF(port11_modsel) +SYSFS_RAW_RW_ATTR_DEF(port10_modsel) +SYSFS_RAW_RW_ATTR_DEF(port9_modsel) + +SYSFS_RAW_RW_ATTR_DEF(port8_lpmode) +SYSFS_RAW_RW_ATTR_DEF(port7_lpmode) +SYSFS_RAW_RW_ATTR_DEF(port6_lpmode) +SYSFS_RAW_RW_ATTR_DEF(port5_lpmode) +SYSFS_RAW_RW_ATTR_DEF(port4_lpmode) +SYSFS_RAW_RW_ATTR_DEF(port3_lpmode) +SYSFS_RAW_RW_ATTR_DEF(port2_lpmode) +SYSFS_RAW_RW_ATTR_DEF(port1_lpmode) + +SYSFS_RAW_RW_ATTR_DEF(port16_lpmode) +SYSFS_RAW_RW_ATTR_DEF(port15_lpmode) +SYSFS_RAW_RW_ATTR_DEF(port14_lpmode) +SYSFS_RAW_RW_ATTR_DEF(port13_lpmode) +SYSFS_RAW_RW_ATTR_DEF(port12_lpmode) +SYSFS_RAW_RW_ATTR_DEF(port11_lpmode) +SYSFS_RAW_RW_ATTR_DEF(port10_lpmode) +SYSFS_RAW_RW_ATTR_DEF(port9_lpmode) + +SYSFS_RAW_RO_ATTR_DEF(port8_irq_status) +SYSFS_RAW_RO_ATTR_DEF(port7_irq_status) +SYSFS_RAW_RO_ATTR_DEF(port6_irq_status) +SYSFS_RAW_RO_ATTR_DEF(port5_irq_status) +SYSFS_RAW_RO_ATTR_DEF(port4_irq_status) +SYSFS_RAW_RO_ATTR_DEF(port3_irq_status) +SYSFS_RAW_RO_ATTR_DEF(port2_irq_status) +SYSFS_RAW_RO_ATTR_DEF(port1_irq_status) + +SYSFS_RAW_RO_ATTR_DEF(port16_irq_status) +SYSFS_RAW_RO_ATTR_DEF(port15_irq_status) +SYSFS_RAW_RO_ATTR_DEF(port14_irq_status) +SYSFS_RAW_RO_ATTR_DEF(port13_irq_status) +SYSFS_RAW_RO_ATTR_DEF(port12_irq_status) +SYSFS_RAW_RO_ATTR_DEF(port11_irq_status) +SYSFS_RAW_RO_ATTR_DEF(port10_irq_status) +SYSFS_RAW_RO_ATTR_DEF(port9_irq_status) + +SYSFS_RAW_RW_ATTR_DEF(port8_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port7_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port6_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port5_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port4_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port3_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port2_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port1_irq_msk) + +SYSFS_RAW_RW_ATTR_DEF(port16_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port15_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port14_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port13_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port12_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port11_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port10_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port9_irq_msk) + +SYSFS_RAW_RO_ATTR_DEF(port_1_8_present) +SYSFS_RAW_RO_ATTR_DEF(port_9_16_present) +SYSFS_RAW_RW_ATTR_DEF(port_1_8_rst) +SYSFS_RAW_RW_ATTR_DEF(port_9_16_rst) +SYSFS_RAW_RW_ATTR_DEF(port_1_8_modsel) +SYSFS_RAW_RW_ATTR_DEF(port_9_16_modsel) +SYSFS_RAW_RO_ATTR_DEF(port_1_8_irq_status) +SYSFS_RAW_RO_ATTR_DEF(port_9_16_irq_status) +SYSFS_RAW_RW_ATTR_DEF(port_1_8_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port_9_16_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port_1_8_lpmode) +SYSFS_RAW_RW_ATTR_DEF(port_9_16_lpmode) + +SYSFS_RAW_RO_ATTR_DEF(fan_tray1_6_present) +SYSFS_RAW_RO_ATTR_DEF(psu_en_status_fld) +#endif /* __MASTER_CPLD_SYSFS */ diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_cb_i2c.c b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_cb_i2c.c new file mode 100644 index 000000000000..11fffe251785 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_cb_i2c.c @@ -0,0 +1,163 @@ +#include +#include +#include +#include "bms_i2c.h" + +#define BMS_CB_I2C_CLIENT_NUM 5 +#define BMS_CB_ADAPTER_BASE 0 + +static struct i2c_client *bms_cb_clients[BMS_CB_I2C_CLIENT_NUM] = {NULL}; +static int bms_cb_client_index = 0; + +static int __init __find_i2c_adap(struct device *dev, void *data) +{ + const char *name = data; + static const char *prefix = "i2c-"; + struct i2c_adapter *adapter; + + if (strncmp(dev_name(dev), prefix, strlen(prefix)) != 0) + { + return 0; + } + adapter = to_i2c_adapter(dev); + + return (strncmp(adapter->name, name, strlen(name)) == 0); +} + +static int __init find_i2c_adapter_num(enum i2c_adapter_type type) +{ + struct device *dev = NULL; + struct i2c_adapter *adapter; + const char *name = bms_i2c_adapter_names[type]; + + /* find the adapter by name */ + dev = bus_find_device(&i2c_bus_type, NULL, (void *)name, + __find_i2c_adap); + if (!dev) { + pr_err("%s: i2c adapter %s not found on system.\n", + __func__, name); + return -ENODEV; + } + adapter = to_i2c_adapter(dev); + + return adapter->nr; +} + + +static __init struct i2c_client *bms_cb_setup_spd( + struct i2c_adapter *adap, int addr) +{ + struct i2c_board_info info_spd = { + I2C_BOARD_INFO("spd", addr), + }; + + return i2c_new_device(adap, &info_spd); +} + + +static __init struct i2c_client *bms_cb_setup_eeprom_24c02( + struct i2c_adapter *adap, int addr) +{ + struct i2c_board_info info_spd = { + I2C_BOARD_INFO("24c02", addr), + }; + + return i2c_new_device(adap, &info_spd); +} + +static __init struct i2c_client *bms_cb_setup_tmp75( + struct i2c_adapter *adap, int addr) +{ + struct i2c_board_info info_spd = { + I2C_BOARD_INFO("tmp75", addr), + }; + + return i2c_new_device(adap, &info_spd); +} + +static __init struct i2c_client *bms_cb_setup_system_cpld(struct i2c_adapter *adap) +{ + struct i2c_board_info info = { + I2C_BOARD_INFO("system_cpld", 0x31), + }; + + return i2c_new_device(adap, &info); +} + +static int __init bms_cb_setup_devices_i801(void) +{ + struct i2c_adapter *adap; + int adap_num = find_i2c_adapter_num(I2C_ADAPTER_I801); + + if (adap_num < 0) + return adap_num; + + adap = i2c_get_adapter(adap_num); + if (!adap) { + pr_err("%s failed to get i2c adap %d.\n", __func__, adap_num); + goto exit; + } + + bms_cb_clients[bms_cb_client_index++] = bms_cb_setup_spd(adap, 0x50); + bms_cb_clients[bms_cb_client_index++] = bms_cb_setup_spd(adap, 0x52); + bms_cb_clients[bms_cb_client_index++] = bms_cb_setup_tmp75(adap, 0x4e); + +exit: + return 0; +} + +static int __init bms_cb_setup_devices_ismt(void) +{ + struct i2c_adapter *adap; + int adap_num = find_i2c_adapter_num(I2C_ADAPTER_ISMT); + + if (adap_num < 0) + return adap_num; + + adap = i2c_get_adapter(adap_num); + if (!adap) { + pr_err("%s failed to get i2c adap %d.\n", __func__, adap_num); + return 0; + } + + bms_cb_clients[bms_cb_client_index++] = bms_cb_setup_system_cpld(adap); + bms_cb_clients[bms_cb_client_index++] = bms_cb_setup_eeprom_24c02(adap, 0x56); + return 0; +} + +static int __init bms_cb_i2c_init(void) +{ + /* Initial bms_cb_slients array. */ + memset(bms_cb_clients, 0x0, BMS_CB_I2C_CLIENT_NUM); + + bms_cb_setup_devices_i801(); + mdelay(200); + bms_cb_setup_devices_ismt(); + + return 0; +} + + +static void __exit bms_cb_i2c_exit(void){ + int i; + + for (i=(bms_cb_client_index-1); i>=0; i--) { + if (bms_cb_clients[i]) { + i2c_unregister_device(bms_cb_clients[i]); + bms_cb_clients[i] = NULL; + } + } + + bms_cb_client_index = 0; + +} + + +module_init(bms_cb_i2c_init); +module_exit(bms_cb_i2c_exit); + + +MODULE_DESCRIPTION("mitac_ly1200_32x_cb_i2c driver"); +MODULE_AUTHOR("Eddy Weng "); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_fb_i2c.c b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_fb_i2c.c new file mode 100644 index 000000000000..d228bc481279 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_fb_i2c.c @@ -0,0 +1,153 @@ +#include +#include +#include "bms_i2c.h" + +#define BMS_FB_I2C_CLIENT_NUM 3 + + +static struct i2c_client *bms_fb_clients[BMS_FB_I2C_CLIENT_NUM] = {NULL}; +static int bms_fb_client_index = 0; + +static int __init __find_i2c_adap(struct device *dev, void *data) +{ + const char *name = data; + static const char *prefix = "i2c-"; + struct i2c_adapter *adapter; + + if (strncmp(dev_name(dev), prefix, strlen(prefix)) != 0) + { + return 0; + } + adapter = to_i2c_adapter(dev); + + return (strncmp(adapter->name, name, strlen(name)) == 0); +} + +static int __init find_i2c_adapter_num(enum i2c_adapter_type type) +{ + struct device *dev = NULL; + struct i2c_adapter *adapter; + const char *name = bms_i2c_adapter_names[type]; + + /* find the adapter by name */ + dev = bus_find_device(&i2c_bus_type, NULL, (void *)name, + __find_i2c_adap); + if (!dev) { + pr_err("%s: i2c adapter %s not found on system.\n", + __func__, name); + return -ENODEV; + } + adapter = to_i2c_adapter(dev); + + return adapter->nr; +} + +static int __init find_i2c_mux_adapter_num(int parent_num, int num) +{ + struct device *dev = NULL; + struct i2c_adapter *adapter; + char name[48]; + + snprintf(name, sizeof(name), "i2c-%d-mux (chan_id %d)", + parent_num, num); + /* find the adapter by name */ + dev = bus_find_device(&i2c_bus_type, NULL, (void *)name, + __find_i2c_adap); + if (!dev) { + pr_err("%s: i2c adapter %s not found on system.\n", + __func__, name); + return -ENODEV; + } + adapter = to_i2c_adapter(dev); + + return adapter->nr; +} + +static __init struct i2c_client *bms_fb_setup_tmp75( + struct i2c_adapter *adap, int addr) +{ + struct i2c_board_info info_spd = { + I2C_BOARD_INFO("tmp75", addr), + }; + + return i2c_new_device(adap, &info_spd); +} + +static __init struct i2c_client *bms_fb_setup_max31790( + struct i2c_adapter *adap, int addr) +{ + struct i2c_board_info info_spd = { + I2C_BOARD_INFO("max31790", addr), + }; + + return i2c_new_device(adap, &info_spd); +} + +static int __init bms_fb_setup_devices(void) +{ + struct i2c_adapter *adap; + int adap_num; + int parent_num; + + parent_num = find_i2c_adapter_num(I2C_ADAPTER_ISMT); + if (parent_num < 0) + return parent_num; + + /* Mux chan1 steup */ + adap_num = find_i2c_mux_adapter_num(parent_num, I2C_STAGE1_MUX_CHAN1); + if (adap_num >= 0){ + adap = i2c_get_adapter(adap_num); + if(adap) { + bms_fb_clients[bms_fb_client_index++] = bms_fb_setup_max31790(adap, 0x20); + bms_fb_clients[bms_fb_client_index++] = bms_fb_setup_max31790(adap, 0x23); + }else{ + pr_err("%s failed to get i2c adap %d.\n", __func__, adap_num); + } + }else{ + pr_err("%s failed to find i2c mux adap number %d.\n", __func__, I2C_STAGE1_MUX_CHAN1); + } + + adap_num = find_i2c_mux_adapter_num(parent_num, I2C_STAGE1_MUX_CHAN2); + if (adap_num >= 0){ + adap = i2c_get_adapter(adap_num); + if(adap) { + bms_fb_clients[bms_fb_client_index++] = bms_fb_setup_tmp75(adap, 0x4d); + }else{ + pr_err("%s failed to get i2c adap %d.\n", __func__, adap_num); + } + }else{ + pr_err("%s failed to find i2c mux adap number %d.\n", __func__, I2C_STAGE1_MUX_CHAN2); + } + + return 0; +} + +static int __init bms_fb_i2c_init(void) +{ + bms_fb_setup_devices(); + + return 0; +} + +static void __exit bms_fb_i2c_exit(void){ + int i; + + for (i=(bms_fb_client_index-1); i>=0; i--) { + if (bms_fb_clients[i]) { + i2c_unregister_device(bms_fb_clients[i]); + bms_fb_clients[i] = NULL; + } + } + + bms_fb_client_index = 0; + +} + +module_init(bms_fb_i2c_init); +module_exit(bms_fb_i2c_exit); + + +MODULE_DESCRIPTION("mitac_ly1200_32x_fb_i2c driver"); +MODULE_AUTHOR("Eddy Weng "); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_fb_module_i2c.c b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_fb_module_i2c.c new file mode 100644 index 000000000000..174dba197217 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_fb_module_i2c.c @@ -0,0 +1,138 @@ +#include +#include +#include "bms_i2c.h" + +#define BMS_FB_MODULE_I2C_CLIENT_NUM 6 + +static struct i2c_client *bms_fb_module_clients[BMS_FB_MODULE_I2C_CLIENT_NUM] = {NULL}; +static int bms_fb_module_client_index = 0; + +static int __init __find_i2c_adap(struct device *dev, void *data) +{ + const char *name = data; + static const char *prefix = "i2c-"; + struct i2c_adapter *adapter; + + if (strncmp(dev_name(dev), prefix, strlen(prefix)) != 0) + { + return 0; + } + adapter = to_i2c_adapter(dev); + + return (strncmp(adapter->name, name, strlen(name)) == 0); +} + +static int __init find_i2c_adapter_num(enum i2c_adapter_type type) +{ + struct device *dev = NULL; + struct i2c_adapter *adapter; + const char *name = bms_i2c_adapter_names[type]; + + /* find the adapter by name */ + dev = bus_find_device(&i2c_bus_type, NULL, (void *)name, + __find_i2c_adap); + if (!dev) { + pr_err("%s: i2c adapter %s not found on system.\n", + __func__, name); + return -ENODEV; + } + adapter = to_i2c_adapter(dev); + + return adapter->nr; +} + +static int __init find_i2c_mux_adapter_num(int parent_num, int num) +{ + struct device *dev = NULL; + struct i2c_adapter *adapter; + char name[48]; + + snprintf(name, sizeof(name), "i2c-%d-mux (chan_id %d)", + parent_num, num); + /* find the adapter by name */ + dev = bus_find_device(&i2c_bus_type, NULL, (void *)name, + __find_i2c_adap); + if (!dev) { + pr_err("%s: i2c adapter %s not found on system.\n", + __func__, name); + return -ENODEV; + } + adapter = to_i2c_adapter(dev); + + return adapter->nr; +} + + +static __init struct i2c_client *bms_fb_module_setup_eeprom_24c02( + struct i2c_adapter *adap, int addr) +{ + struct i2c_board_info info_spd = { + I2C_BOARD_INFO("24c02", addr), + }; + + return i2c_new_device(adap, &info_spd); +} + +static int __init bms_fb_module_setup_devices(void) +{ + struct i2c_adapter *adap; + int adap_num; + int parent_num; + + parent_num = find_i2c_adapter_num(I2C_ADAPTER_ISMT); + if (parent_num < 0) + return parent_num; + + adap_num = find_i2c_mux_adapter_num(parent_num, I2C_STAGE1_MUX_CHAN1); + if (adap_num < 0) + return adap_num; + + adap = i2c_get_adapter(adap_num); + if (!adap) { + pr_err("%s failed to get i2c adap %d.\n", __func__, adap_num); + goto exit; + } + + bms_fb_module_clients[bms_fb_module_client_index++] = bms_fb_module_setup_eeprom_24c02(adap, 0x50); + bms_fb_module_clients[bms_fb_module_client_index++] = bms_fb_module_setup_eeprom_24c02(adap, 0x51); + bms_fb_module_clients[bms_fb_module_client_index++] = bms_fb_module_setup_eeprom_24c02(adap, 0x52); + bms_fb_module_clients[bms_fb_module_client_index++] = bms_fb_module_setup_eeprom_24c02(adap, 0x53); + bms_fb_module_clients[bms_fb_module_client_index++] = bms_fb_module_setup_eeprom_24c02(adap, 0x54); + bms_fb_module_clients[bms_fb_module_client_index++] = bms_fb_module_setup_eeprom_24c02(adap, 0x55); + +exit: + return 0; +} + +static int __init bms_fb_module_i2c_init(void) +{ + /* Initial bms_sb_slients array. */ + memset(bms_fb_module_clients, 0x0, BMS_FB_MODULE_I2C_CLIENT_NUM); + + bms_fb_module_setup_devices(); + + return 0; +} + +static void __exit bms_fb_module_i2c_exit(void){ + int i; + + for (i=(bms_fb_module_client_index-1); i>=0; i--) { + if (bms_fb_module_clients[i]) { + i2c_unregister_device(bms_fb_module_clients[i]); + bms_fb_module_clients[i] = NULL; + } + } + + bms_fb_module_client_index = 0; + +} + +module_init(bms_fb_module_i2c_init); +module_exit(bms_fb_module_i2c_exit); + + +MODULE_DESCRIPTION("mitac_ly1200_32x_fb_module_i2c driver"); +MODULE_AUTHOR("Eddy Weng "); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_fse000.c b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_fse000.c new file mode 100644 index 000000000000..362821706857 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_fse000.c @@ -0,0 +1,1787 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pmbus.h" +#include + +/* + * Number of additional attribute pointers to allocate + * with each call to krealloc + */ +#define PMBUS_ATTR_ALLOC_SIZE 32 + +/* + * Index into status register array, per status register group + */ +#define PB_STATUS_BASE 0 +#define PB_STATUS_VOUT_BASE (PB_STATUS_BASE + PMBUS_PAGES) +#define PB_STATUS_IOUT_BASE (PB_STATUS_VOUT_BASE + PMBUS_PAGES) +#define PB_STATUS_FAN_BASE (PB_STATUS_IOUT_BASE + PMBUS_PAGES) +#define PB_STATUS_FAN34_BASE (PB_STATUS_FAN_BASE + PMBUS_PAGES) +#define PB_STATUS_TEMP_BASE (PB_STATUS_FAN34_BASE + PMBUS_PAGES) +#define PB_STATUS_INPUT_BASE (PB_STATUS_TEMP_BASE + PMBUS_PAGES) +#define PB_STATUS_VMON_BASE (PB_STATUS_INPUT_BASE + 1) + +#define PB_NUM_STATUS_REG (PB_STATUS_VMON_BASE + 1) + +#define PMBUS_NAME_SIZE 24 +#define PMBUS_BLOCK_READ_SIZE 32 + +struct pmbus_sensor { + struct pmbus_sensor *next; + char name[PMBUS_NAME_SIZE]; /* sysfs sensor name */ + struct device_attribute attribute; + u8 page; /* page number */ + u16 reg; /* register */ + enum pmbus_sensor_classes class; /* sensor class */ + bool update; /* runtime sensor update needed */ + int data; /* Sensor data. + Negative if there was a read error */ +}; +#define to_pmbus_sensor(_attr) \ + container_of(_attr, struct pmbus_sensor, attribute) + +struct pmbus_st { + char name[PMBUS_NAME_SIZE]; /* sysfs boolean name */ + struct sensor_device_attribute attribute; + u16 base; +}; +#define to_pmbus_status(_attr) \ + container_of(_attr, struct pmbus_st, attribute) + +struct pmbus_mfr { + struct pmbus_mfr *next; + char name[PMBUS_NAME_SIZE]; /* sysfs sensor name */ + struct device_attribute attribute; + u8 page; /* page number */ + u16 reg; /* register */ + int data; /* Sensor data. + Negative if there was a read error */ + char data_buf[PMBUS_BLOCK_READ_SIZE]; +}; +#define to_pmbus_mfr(_attr) \ + container_of(_attr, struct pmbus_mfr, attribute) + +struct pmbus_boolean { + char name[PMBUS_NAME_SIZE]; /* sysfs boolean name */ + struct sensor_device_attribute attribute; + struct pmbus_sensor *s1; + struct pmbus_sensor *s2; +}; +#define to_pmbus_boolean(_attr) \ + container_of(_attr, struct pmbus_boolean, attribute) + +struct pmbus_label { + char name[PMBUS_NAME_SIZE]; /* sysfs label name */ + struct device_attribute attribute; + char label[PMBUS_NAME_SIZE]; /* label */ +}; +#define to_pmbus_label(_attr) \ + container_of(_attr, struct pmbus_label, attribute) + +struct pmbus_data { + struct device *dev; + struct device *hwmon_dev; + + u32 flags; /* from platform data */ + + int exponent[PMBUS_PAGES]; + /* linear mode: exponent for output voltages */ + + const struct pmbus_driver_info *info; + + int max_attributes; + int num_attributes; + struct attribute_group group; + const struct attribute_group *groups[2]; + + struct pmbus_sensor *sensors; + struct pmbus_mfr *mfr; + + struct mutex update_lock; + bool valid; + unsigned long last_updated; /* in jiffies */ + + /* + * A single status register covers multiple attributes, + * so we keep them all together. + */ + u8 status[PB_NUM_STATUS_REG]; + u8 status_register; + + u8 currpage; +}; + +void pmbus_clear_cache(struct i2c_client *client) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + + data->valid = false; +} + +int pmbus_set_page(struct i2c_client *client, u8 page) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + int rv = 0; + int newpage; + + if (page != data->currpage) { + rv = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page); + newpage = i2c_smbus_read_byte_data(client, PMBUS_PAGE); + if (newpage != page) + rv = -EIO; + else + data->currpage = page; + } + return rv; +} + +int pmbus_write_byte(struct i2c_client *client, int page, u8 value) +{ + int rv; + + if (page >= 0) { + rv = pmbus_set_page(client, page); + if (rv < 0) + return rv; + } + + return i2c_smbus_write_byte(client, value); +} + +/* + * _pmbus_write_byte() is similar to pmbus_write_byte(), but checks if + * a device specific mapping function exists and calls it if necessary. + */ +static int _pmbus_write_byte(struct i2c_client *client, int page, u8 value) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + const struct pmbus_driver_info *info = data->info; + int status; + + if (info->write_byte) { + status = info->write_byte(client, page, value); + if (status != -ENODATA) + return status; + } + return pmbus_write_byte(client, page, value); +} + +int pmbus_write_word_data(struct i2c_client *client, u8 page, u8 reg, u16 word) +{ + int rv; + + rv = pmbus_set_page(client, page); + if (rv < 0) + return rv; + + return i2c_smbus_write_word_data(client, reg, word); +} + +/* + * _pmbus_write_word_data() is similar to pmbus_write_word_data(), but checks if + * a device specific mapping function exists and calls it if necessary. + */ +static int _pmbus_write_word_data(struct i2c_client *client, int page, int reg, + u16 word) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + const struct pmbus_driver_info *info = data->info; + int status; + + if (info->write_word_data) { + status = info->write_word_data(client, page, reg, word); + if (status != -ENODATA) + return status; + } + if (reg >= PMBUS_VIRT_BASE) + return -ENXIO; + return pmbus_write_word_data(client, page, reg, word); +} + +int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg) +{ + int rv; + + rv = pmbus_set_page(client, page); + if (rv < 0) + return rv; + + return i2c_smbus_read_word_data(client, reg); +} + +int pmbus_read_block_data(struct i2c_client *client, u8 reg, u8* value) +{ + return i2c_smbus_read_block_data(client, reg, value); +} + +static int _pmbus_read_block_data(struct i2c_client *client, int page, int reg, u8* value) +{ + int rv; + + rv = pmbus_set_page(client, page); + if (rv < 0) + return rv; + return pmbus_read_block_data(client, reg, value); +} + +/* + * _pmbus_read_word_data() is similar to pmbus_read_word_data(), but checks if + * a device specific mapping function exists and calls it if necessary. + */ +static int _pmbus_read_word_data(struct i2c_client *client, int page, int reg) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + const struct pmbus_driver_info *info = data->info; + int status; + + if (info->read_word_data) { + status = info->read_word_data(client, page, reg); + if (status != -ENODATA) + return status; + } + if (reg >= PMBUS_VIRT_BASE) + return -ENXIO; + return pmbus_read_word_data(client, page, reg); +} + +int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg) +{ + int rv; + + if (page >= 0) { + rv = pmbus_set_page(client, page); + if (rv < 0) + return rv; + } + + return i2c_smbus_read_byte_data(client, reg); +} + +/* + * _pmbus_read_byte_data() is similar to pmbus_read_byte_data(), but checks if + * a device specific mapping function exists and calls it if necessary. + */ +static int _pmbus_read_byte_data(struct i2c_client *client, int page, int reg) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + const struct pmbus_driver_info *info = data->info; + int status; + + if (info->read_byte_data) { + status = info->read_byte_data(client, page, reg); + if (status != -ENODATA) + return status; + } + return pmbus_read_byte_data(client, page, reg); +} + +static void pmbus_clear_fault_page(struct i2c_client *client, int page) +{ + _pmbus_write_byte(client, page, PMBUS_CLEAR_FAULTS); +} + +void pmbus_clear_faults(struct i2c_client *client) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + int i; + + for (i = 0; i < data->info->pages; i++) + pmbus_clear_fault_page(client, i); +} + +static int pmbus_check_status_cml(struct i2c_client *client) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + int status, status2; + + status = _pmbus_read_byte_data(client, -1, data->status_register); + if (status < 0 || (status & PB_STATUS_CML)) { + status2 = _pmbus_read_byte_data(client, -1, PMBUS_STATUS_CML); + if (status2 < 0 || (status2 & PB_CML_FAULT_INVALID_COMMAND)) + return -EIO; + } + return 0; +} + +static bool pmbus_check_register(struct i2c_client *client, + int (*func)(struct i2c_client *client, + int page, int reg), + int page, int reg) +{ + int rv; + struct pmbus_data *data = i2c_get_clientdata(client); + + rv = func(client, page, reg); + if (rv >= 0 && !(data->flags & PMBUS_SKIP_STATUS_CHECK)) + rv = pmbus_check_status_cml(client); + pmbus_clear_fault_page(client, -1); + return rv >= 0; +} + +bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg) +{ + return pmbus_check_register(client, _pmbus_read_byte_data, page, reg); +} + +bool pmbus_check_word_register(struct i2c_client *client, int page, int reg) +{ + return pmbus_check_register(client, _pmbus_read_word_data, page, reg); +} + +const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client *client) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + + return data->info; +} + +static struct _pmbus_status { + u32 func; + u16 base; + u16 reg; +} pmbus_status[] = { + { PMBUS_HAVE_STATUS_VOUT, PB_STATUS_VOUT_BASE, PMBUS_STATUS_VOUT }, + { PMBUS_HAVE_STATUS_IOUT, PB_STATUS_IOUT_BASE, PMBUS_STATUS_IOUT }, + { PMBUS_HAVE_STATUS_TEMP, PB_STATUS_TEMP_BASE, + PMBUS_STATUS_TEMPERATURE }, + { PMBUS_HAVE_STATUS_FAN12, PB_STATUS_FAN_BASE, PMBUS_STATUS_FAN_12 }, + { PMBUS_HAVE_STATUS_FAN34, PB_STATUS_FAN34_BASE, PMBUS_STATUS_FAN_34 }, +}; + +static struct _pmbus_status_reg { + char name[PMBUS_NAME_SIZE]; + u16 base; + u8 offset; +} pmbus_status_reg[] = { + { "vout_ov_fault", PB_STATUS_VOUT_BASE, PB_VOLTAGE_UV_FAULT}, + { "vout_uv_fault", PB_STATUS_VOUT_BASE, PB_VOLTAGE_OV_FAULT}, + { "ot_fault", PB_STATUS_TEMP_BASE, PB_TEMP_OT_FAULT}, + { "ot_warning", PB_STATUS_TEMP_BASE, PB_TEMP_OT_WARNING}, + { "vin_uv_warning", PB_STATUS_INPUT_BASE, PB_VOLTAGE_UV_WARNING}, + { "vin_uv_fault", PB_STATUS_INPUT_BASE, PB_VOLTAGE_UV_FAULT}, +}; + +static struct _pmbus_mfr_reg { + char name[PMBUS_NAME_SIZE]; + u16 reg; +} pmbus_mfr_reg[] = { + { "mfr_id", PMBUS_MFR_ID}, + { "mfr_model", PMBUS_MFR_MODEL}, + { "mfr_revision", PMBUS_MFR_REVISION}, + { "mfr_location", PMBUS_MFR_LOCATION}, + { "mfr_date", PMBUS_MFR_DATE}, + { "mfr_serial", PMBUS_MFR_SERIAL}, +}; + +static struct pmbus_data *pmbus_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev->parent); + struct pmbus_data *data = i2c_get_clientdata(client); + const struct pmbus_driver_info *info = data->info; + struct pmbus_sensor *sensor; + struct pmbus_mfr *mfr; + + mutex_lock(&data->update_lock); + if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { + int i, j; + + for (i = 0; i < info->pages; i++) { + data->status[PB_STATUS_BASE + i] + = _pmbus_read_byte_data(client, i, + data->status_register); + for (j = 0; j < ARRAY_SIZE(pmbus_status); j++) { + struct _pmbus_status *s = &pmbus_status[j]; + + if (!(info->func[i] & s->func)) + continue; + data->status[s->base + i] + = _pmbus_read_byte_data(client, i, + s->reg); + } + } + + if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) + data->status[PB_STATUS_INPUT_BASE] + = _pmbus_read_byte_data(client, 0, + PMBUS_STATUS_INPUT); + + if (info->func[0] & PMBUS_HAVE_STATUS_VMON) + data->status[PB_STATUS_VMON_BASE] + = _pmbus_read_byte_data(client, 0, + PMBUS_VIRT_STATUS_VMON); + + for (sensor = data->sensors; sensor; sensor = sensor->next) { + if (!data->valid || sensor->update) + sensor->data + = _pmbus_read_word_data(client, + sensor->page, + sensor->reg); + } + + /* read mfg data */ + for (mfr = data->mfr; mfr; mfr = mfr->next) { + mfr->data = _pmbus_read_block_data(client, mfr->page, mfr->reg, mfr->data_buf); + } + + pmbus_clear_faults(client); + data->last_updated = jiffies; + data->valid = 1; + } + mutex_unlock(&data->update_lock); + return data; +} + +/* + * Convert linear sensor values to milli- or micro-units + * depending on sensor type. + */ +static long pmbus_reg2data_linear(struct pmbus_data *data, + struct pmbus_sensor *sensor) +{ + s16 exponent; + s32 mantissa; + long val; + + if (sensor->class == PSC_VOLTAGE_OUT) { /* LINEAR16 */ + exponent = data->exponent[sensor->page]; + mantissa = (u16) sensor->data; + } else { /* LINEAR11 */ + exponent = ((s16)sensor->data) >> 11; + mantissa = ((s16)((sensor->data & 0x7ff) << 5)) >> 5; + } + + val = mantissa; + + /* scale result to milli-units for all sensors except fans */ + if (sensor->class != PSC_FAN) + val = val * 1000L; + + /* scale result to micro-units for power sensors */ + if (sensor->class == PSC_POWER) + val = val * 1000L; + + if (exponent >= 0) + val <<= exponent; + else + val >>= -exponent; + + return val; +} + +/* + * Convert direct sensor values to milli- or micro-units + * depending on sensor type. + */ +static long pmbus_reg2data_direct(struct pmbus_data *data, + struct pmbus_sensor *sensor) +{ + long val = (s16) sensor->data; + long m, b, R; + + m = data->info->m[sensor->class]; + b = data->info->b[sensor->class]; + R = data->info->R[sensor->class]; + + if (m == 0) + return 0; + + /* X = 1/m * (Y * 10^-R - b) */ + R = -R; + /* scale result to milli-units for everything but fans */ + if (sensor->class != PSC_FAN) { + R += 3; + b *= 1000; + } + + /* scale result to micro-units for power sensors */ + if (sensor->class == PSC_POWER) { + R += 3; + b *= 1000; + } + + while (R > 0) { + val *= 10; + R--; + } + while (R < 0) { + val = DIV_ROUND_CLOSEST(val, 10); + R++; + } + + return (val - b) / m; +} + +/* + * Convert VID sensor values to milli- or micro-units + * depending on sensor type. + * We currently only support VR11. + */ +static long pmbus_reg2data_vid(struct pmbus_data *data, + struct pmbus_sensor *sensor) +{ + long val = sensor->data; + + if (val < 0x02 || val > 0xb2) + return 0; + return DIV_ROUND_CLOSEST(160000 - (val - 2) * 625, 100); +} + +static long pmbus_reg2data(struct pmbus_data *data, struct pmbus_sensor *sensor) +{ + long val; + + switch (data->info->format[sensor->class]) { + case direct: + val = pmbus_reg2data_direct(data, sensor); + break; + case vid: + val = pmbus_reg2data_vid(data, sensor); + break; + case linear: + default: + val = pmbus_reg2data_linear(data, sensor); + break; + } + return val; +} + +#define MAX_MANTISSA (1023 * 1000) +#define MIN_MANTISSA (511 * 1000) + +static u16 pmbus_data2reg_linear(struct pmbus_data *data, + struct pmbus_sensor *sensor, long val) +{ + s16 exponent = 0, mantissa; + bool negative = false; + + /* simple case */ + if (val == 0) + return 0; + + if (sensor->class == PSC_VOLTAGE_OUT) { + /* LINEAR16 does not support negative voltages */ + if (val < 0) + return 0; + + /* + * For a static exponents, we don't have a choice + * but to adjust the value to it. + */ + if (data->exponent[sensor->page] < 0) + val <<= -data->exponent[sensor->page]; + else + val >>= data->exponent[sensor->page]; + val = DIV_ROUND_CLOSEST(val, 1000); + return val & 0xffff; + } + + if (val < 0) { + negative = true; + val = -val; + } + + /* Power is in uW. Convert to mW before converting. */ + if (sensor->class == PSC_POWER) + val = DIV_ROUND_CLOSEST(val, 1000L); + + /* + * For simplicity, convert fan data to milli-units + * before calculating the exponent. + */ + if (sensor->class == PSC_FAN) + val = val * 1000; + + /* Reduce large mantissa until it fits into 10 bit */ + while (val >= MAX_MANTISSA && exponent < 15) { + exponent++; + val >>= 1; + } + /* Increase small mantissa to improve precision */ + while (val < MIN_MANTISSA && exponent > -15) { + exponent--; + val <<= 1; + } + + /* Convert mantissa from milli-units to units */ + mantissa = DIV_ROUND_CLOSEST(val, 1000); + + /* Ensure that resulting number is within range */ + if (mantissa > 0x3ff) + mantissa = 0x3ff; + + /* restore sign */ + if (negative) + mantissa = -mantissa; + + /* Convert to 5 bit exponent, 11 bit mantissa */ + return (mantissa & 0x7ff) | ((exponent << 11) & 0xf800); +} + +static u16 pmbus_data2reg_direct(struct pmbus_data *data, + struct pmbus_sensor *sensor, long val) +{ + long m, b, R; + + m = data->info->m[sensor->class]; + b = data->info->b[sensor->class]; + R = data->info->R[sensor->class]; + + /* Power is in uW. Adjust R and b. */ + if (sensor->class == PSC_POWER) { + R -= 3; + b *= 1000; + } + + /* Calculate Y = (m * X + b) * 10^R */ + if (sensor->class != PSC_FAN) { + R -= 3; /* Adjust R and b for data in milli-units */ + b *= 1000; + } + val = val * m + b; + + while (R > 0) { + val *= 10; + R--; + } + while (R < 0) { + val = DIV_ROUND_CLOSEST(val, 10); + R++; + } + + return val; +} + +static u16 pmbus_data2reg_vid(struct pmbus_data *data, + struct pmbus_sensor *sensor, long val) +{ + val = clamp_val(val, 500, 1600); + + return 2 + DIV_ROUND_CLOSEST((1600 - val) * 100, 625); +} + +static u16 pmbus_data2reg(struct pmbus_data *data, + struct pmbus_sensor *sensor, long val) +{ + u16 regval; + + switch (data->info->format[sensor->class]) { + case direct: + regval = pmbus_data2reg_direct(data, sensor, val); + break; + case vid: + regval = pmbus_data2reg_vid(data, sensor, val); + break; + case linear: + default: + regval = pmbus_data2reg_linear(data, sensor, val); + break; + } + return regval; +} + +/* + * Return boolean calculated from converted data. + * defines a status register index and mask. + * The mask is in the lower 8 bits, the register index is in bits 8..23. + * + * The associated pmbus_boolean structure contains optional pointers to two + * sensor attributes. If specified, those attributes are compared against each + * other to determine if a limit has been exceeded. + * + * If the sensor attribute pointers are NULL, the function returns true if + * (status[reg] & mask) is true. + * + * If sensor attribute pointers are provided, a comparison against a specified + * limit has to be performed to determine the boolean result. + * In this case, the function returns true if v1 >= v2 (where v1 and v2 are + * sensor values referenced by sensor attribute pointers s1 and s2). + * + * To determine if an object exceeds upper limits, specify = . + * To determine if an object exceeds lower limits, specify = . + * + * If a negative value is stored in any of the referenced registers, this value + * reflects an error code which will be returned. + */ +static int pmbus_get_boolean(struct pmbus_data *data, struct pmbus_boolean *b, + int index) +{ + struct pmbus_sensor *s1 = b->s1; + struct pmbus_sensor *s2 = b->s2; + u16 reg = (index >> 8) & 0xffff; + u8 mask = index & 0xff; + int ret, status; + u8 regval; + + status = data->status[reg]; + if (status < 0) + return status; + + regval = status & mask; + if (!s1 && !s2) { + ret = !!regval; + } else if (!s1 || !s2) { + WARN(1, "Bad boolean descriptor %p: s1=%p, s2=%p\n", b, s1, s2); + return 0; + } else { + long v1, v2; + + if (s1->data < 0) + return s1->data; + if (s2->data < 0) + return s2->data; + + v1 = pmbus_reg2data(data, s1); + v2 = pmbus_reg2data(data, s2); + ret = !!(regval && v1 >= v2); + } + return ret; +} + +static ssize_t pmbus_show_boolean(struct device *dev, + struct device_attribute *da, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct pmbus_boolean *boolean = to_pmbus_boolean(attr); + struct pmbus_data *data = pmbus_update_device(dev); + int val; + + val = pmbus_get_boolean(data, boolean, attr->index); + if (val < 0) + return val; + return snprintf(buf, PAGE_SIZE, "%d\n", val); +} + +static ssize_t pmbus_show_sensor(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct pmbus_data *data = pmbus_update_device(dev); + struct pmbus_sensor *sensor = to_pmbus_sensor(devattr); + + if (sensor->data < 0) + return sensor->data; + + return snprintf(buf, PAGE_SIZE, "%ld\n", pmbus_reg2data(data, sensor)); +} + +static ssize_t pmbus_show_status(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct pmbus_st *status = to_pmbus_status(attr); + struct pmbus_data *data = pmbus_update_device(dev); + + return snprintf(buf, PAGE_SIZE, "%u\n", !!(data->status[status->base] & attr->index)); +} + +static ssize_t pmbus_show_mfr(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct pmbus_mfr *mfr; + + pmbus_update_device(dev); + mfr = to_pmbus_mfr(devattr); + + if (mfr->data < 0) + return mfr->data; + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(3,16,49) + /* mfr->data[0] is data length, we don't want show data length when show command */ + return snprintf(buf, PAGE_SIZE, "%s\n", &mfr->data_buf[1]); +#else + return snprintf(buf, PAGE_SIZE, "%s\n", &mfr->data_buf); +#endif +} + +static ssize_t pmbus_set_sensor(struct device *dev, + struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev->parent); + struct pmbus_data *data = i2c_get_clientdata(client); + struct pmbus_sensor *sensor = to_pmbus_sensor(devattr); + ssize_t rv = count; + long val = 0; + int ret; + u16 regval; + + if (kstrtol(buf, 10, &val) < 0) + return -EINVAL; + + mutex_lock(&data->update_lock); + regval = pmbus_data2reg(data, sensor, val); + ret = _pmbus_write_word_data(client, sensor->page, sensor->reg, regval); + if (ret < 0) + rv = ret; + else + sensor->data = regval; + mutex_unlock(&data->update_lock); + return rv; +} + +static ssize_t pmbus_show_label(struct device *dev, + struct device_attribute *da, char *buf) +{ + struct pmbus_label *label = to_pmbus_label(da); + + return snprintf(buf, PAGE_SIZE, "%s\n", label->label); +} + +static int pmbus_add_attribute(struct pmbus_data *data, struct attribute *attr) +{ + if (data->num_attributes >= data->max_attributes - 1) { + int new_max_attrs = data->max_attributes + PMBUS_ATTR_ALLOC_SIZE; + void *new_attrs = krealloc(data->group.attrs, + new_max_attrs * sizeof(void *), + GFP_KERNEL); + if (!new_attrs) + return -ENOMEM; + data->group.attrs = new_attrs; + data->max_attributes = new_max_attrs; + } + + data->group.attrs[data->num_attributes++] = attr; + data->group.attrs[data->num_attributes] = NULL; + return 0; +} + +static void pmbus_dev_attr_init(struct device_attribute *dev_attr, + const char *name, + umode_t mode, + ssize_t (*show)(struct device *dev, + struct device_attribute *attr, + char *buf), + ssize_t (*store)(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count)) +{ + sysfs_attr_init(&dev_attr->attr); + dev_attr->attr.name = name; + dev_attr->attr.mode = mode; + dev_attr->show = show; + dev_attr->store = store; +} + +static void pmbus_attr_init(struct sensor_device_attribute *a, + const char *name, + umode_t mode, + ssize_t (*show)(struct device *dev, + struct device_attribute *attr, + char *buf), + ssize_t (*store)(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count), + int idx) +{ + pmbus_dev_attr_init(&a->dev_attr, name, mode, show, store); + a->index = idx; +} + +static int pmbus_add_boolean(struct pmbus_data *data, + const char *name, const char *type, int seq, + struct pmbus_sensor *s1, + struct pmbus_sensor *s2, + u16 reg, u8 mask) +{ + struct pmbus_boolean *boolean; + struct sensor_device_attribute *a; + + boolean = devm_kzalloc(data->dev, sizeof(*boolean), GFP_KERNEL); + if (!boolean) + return -ENOMEM; + + a = &boolean->attribute; + + snprintf(boolean->name, sizeof(boolean->name), "%s%d_%s", + name, seq, type); + boolean->s1 = s1; + boolean->s2 = s2; + pmbus_attr_init(a, boolean->name, S_IRUGO, pmbus_show_boolean, NULL, + (reg << 8) | mask); + + return pmbus_add_attribute(data, &a->dev_attr.attr); +} + +static struct pmbus_sensor *pmbus_add_sensor(struct pmbus_data *data, + const char *name, const char *type, + int seq, int page, int reg, + enum pmbus_sensor_classes class, + bool update, bool readonly) +{ + struct pmbus_sensor *sensor; + struct device_attribute *a; + + sensor = devm_kzalloc(data->dev, sizeof(*sensor), GFP_KERNEL); + if (!sensor) + return NULL; + a = &sensor->attribute; + + snprintf(sensor->name, sizeof(sensor->name), "%s%d_%s", + name, seq, type); + sensor->page = page; + sensor->reg = reg; + sensor->class = class; + sensor->update = update; + pmbus_dev_attr_init(a, sensor->name, + readonly ? S_IRUGO : S_IRUGO | S_IWUSR, + pmbus_show_sensor, pmbus_set_sensor); + + if (pmbus_add_attribute(data, &a->attr)) + return NULL; + + sensor->next = data->sensors; + data->sensors = sensor; + + return sensor; +} + +static int pmbus_add_status(struct pmbus_data *data, + const char *name, u16 base, + u8 offset) +{ + struct pmbus_st *status; + struct sensor_device_attribute *a; + + status = devm_kzalloc(data->dev, sizeof(*status), GFP_KERNEL); + if (!status) + return -ENOMEM; + + a = &status->attribute; + + snprintf(status->name, sizeof(status->name), "%s", name); + + status->base = base; + + pmbus_attr_init(a, status->name, S_IRUGO, + pmbus_show_status, NULL, offset); + + return pmbus_add_attribute(data, &a->dev_attr.attr); +} + +static struct pmbus_mfr *pmbus_add_mfr(struct pmbus_data *data, + const char *name, + int page, int reg) +{ + struct pmbus_mfr *mfr; + struct device_attribute *a; + + mfr = devm_kzalloc(data->dev, sizeof(*mfr), GFP_KERNEL); + if (!mfr) + return NULL; + a = &mfr->attribute; + + snprintf(mfr->name, sizeof(mfr->name), "%s", name); + mfr->page = page; + mfr->reg = reg; + pmbus_dev_attr_init(a, mfr->name, S_IRUGO, + pmbus_show_mfr, NULL); + + if (pmbus_add_attribute(data, &a->attr)) + return NULL; + + mfr->next = data->mfr; + data->mfr = mfr; + + return mfr; +} + +static int pmbus_add_label(struct pmbus_data *data, + const char *name, int seq, + const char *lstring, int index) +{ + struct pmbus_label *label; + struct device_attribute *a; + + label = devm_kzalloc(data->dev, sizeof(*label), GFP_KERNEL); + if (!label) + return -ENOMEM; + + a = &label->attribute; + + snprintf(label->name, sizeof(label->name), "%s%d_label", name, seq); + if (!index) + strncpy(label->label, lstring, sizeof(label->label) - 1); + else + snprintf(label->label, sizeof(label->label), "%s%d", lstring, + index); + + pmbus_dev_attr_init(a, label->name, S_IRUGO, pmbus_show_label, NULL); + return pmbus_add_attribute(data, &a->attr); +} + +/* + * Search for attributes. Allocate sensors, booleans, and labels as needed. + */ + +/* + * The pmbus_limit_attr structure describes a single limit attribute + * and its associated alarm attribute. + */ +struct pmbus_limit_attr { + u16 reg; /* Limit register */ + u16 sbit; /* Alarm attribute status bit */ + bool update; /* True if register needs updates */ + bool low; /* True if low limit; for limits with compare + functions only */ + const char *attr; /* Attribute name */ + const char *alarm; /* Alarm attribute name */ +}; + +/* + * The pmbus_sensor_attr structure describes one sensor attribute. This + * description includes a reference to the associated limit attributes. + */ +struct pmbus_sensor_attr { + u16 reg; /* sensor register */ + u8 gbit; /* generic status bit */ + u8 nlimit; /* # of limit registers */ + enum pmbus_sensor_classes class;/* sensor class */ + const char *label; /* sensor label */ + bool paged; /* true if paged sensor */ + bool update; /* true if update needed */ + bool compare; /* true if compare function needed */ + u32 func; /* sensor mask */ + u32 sfunc; /* sensor status mask */ + int sbase; /* status base register */ + const struct pmbus_limit_attr *limit;/* limit registers */ +}; + +/* + * Add a set of limit attributes and, if supported, the associated + * alarm attributes. + * returns 0 if no alarm register found, 1 if an alarm register was found, + * < 0 on errors. + */ +static int pmbus_add_limit_attrs(struct i2c_client *client, + struct pmbus_data *data, + const struct pmbus_driver_info *info, + const char *name, int index, int page, + struct pmbus_sensor *base, + const struct pmbus_sensor_attr *attr) +{ + const struct pmbus_limit_attr *l = attr->limit; + int nlimit = attr->nlimit; + int have_alarm = 0; + int i, ret; + struct pmbus_sensor *curr; + + for (i = 0; i < nlimit; i++) { + if (pmbus_check_word_register(client, page, l->reg)) { + curr = pmbus_add_sensor(data, name, l->attr, index, + page, l->reg, attr->class, + attr->update || l->update, + false); + if (!curr) + return -ENOMEM; + if (l->sbit && (info->func[page] & attr->sfunc)) { + ret = pmbus_add_boolean(data, name, + l->alarm, index, + attr->compare ? l->low ? curr : base + : NULL, + attr->compare ? l->low ? base : curr + : NULL, + attr->sbase + page, l->sbit); + if (ret) + return ret; + have_alarm = 1; + } + } + l++; + } + return have_alarm; +} + +static int pmbus_add_sensor_attrs_one(struct i2c_client *client, + struct pmbus_data *data, + const struct pmbus_driver_info *info, + const char *name, + int index, int page, + const struct pmbus_sensor_attr *attr) +{ + struct pmbus_sensor *base; + int ret; + + if (attr->label) { + ret = pmbus_add_label(data, name, index, attr->label, + attr->paged ? page + 1 : 0); + if (ret) + return ret; + } + base = pmbus_add_sensor(data, name, "input", index, page, attr->reg, + attr->class, true, true); + if (!base) + return -ENOMEM; + if (attr->sfunc) { + ret = pmbus_add_limit_attrs(client, data, info, name, + index, page, base, attr); + if (ret < 0) + return ret; + /* + * Add generic alarm attribute only if there are no individual + * alarm attributes, if there is a global alarm bit, and if + * the generic status register for this page is accessible. + */ + if (!ret && attr->gbit && + pmbus_check_byte_register(client, page, + data->status_register)) { + ret = pmbus_add_boolean(data, name, "alarm", index, + NULL, NULL, + PB_STATUS_BASE + page, + attr->gbit); + if (ret) + return ret; + } + } + return 0; +} + +static int pmbus_add_sensor_attrs(struct i2c_client *client, + struct pmbus_data *data, + const char *name, + const struct pmbus_sensor_attr *attrs, + int nattrs) +{ + const struct pmbus_driver_info *info = data->info; + int index, i; + int ret; + + index = 1; + for (i = 0; i < nattrs; i++) { + int page, pages; + + pages = attrs->paged ? info->pages : 1; + for (page = 0; page < pages; page++) { + if (!(info->func[page] & attrs->func)) + continue; + ret = pmbus_add_sensor_attrs_one(client, data, info, + name, index, page, + attrs); + if (ret) + return ret; + index++; + } + attrs++; + } + return 0; +} + +static const struct pmbus_sensor_attr voltage_attributes[] = { + { + .reg = PMBUS_READ_VOUT, + .class = PSC_VOLTAGE_OUT, + .label = "vout", + .paged = true, + .func = PMBUS_HAVE_VOUT, + .sfunc = PMBUS_HAVE_STATUS_VOUT, + .sbase = PB_STATUS_VOUT_BASE, + .gbit = PB_STATUS_VOUT_OV, + } +}; + +static const struct pmbus_limit_attr iout_limit_attrs[] = { + { + .reg = PMBUS_IOUT_OC_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_IOUT_OC_WARNING, + }, { + .reg = PMBUS_IOUT_OC_FAULT_LIMIT, + .attr = "crit", + .alarm = "crit_alarm", + .sbit = PB_IOUT_OC_FAULT, + } +}; + +static const struct pmbus_sensor_attr current_attributes[] = { + { + .reg = PMBUS_READ_IIN, + .class = PSC_CURRENT_IN, + .label = "iin", + .func = PMBUS_HAVE_IIN, + .sfunc = PMBUS_HAVE_STATUS_INPUT, + .sbase = PB_STATUS_INPUT_BASE, + }, { + .reg = PMBUS_READ_IOUT, + .class = PSC_CURRENT_OUT, + .label = "iout", + .paged = true, + .func = PMBUS_HAVE_IOUT, + .sfunc = PMBUS_HAVE_STATUS_IOUT, + .sbase = PB_STATUS_IOUT_BASE, + .gbit = PB_STATUS_IOUT_OC, + .limit = iout_limit_attrs, + .nlimit = ARRAY_SIZE(iout_limit_attrs), + } +}; + +/* Temperature atributes */ +static const struct pmbus_limit_attr temp_limit_attrs[] = { + { + .reg = PMBUS_OT_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_TEMP_OT_WARNING, + } +}; + +static const struct pmbus_limit_attr temp_limit_attrs2[] = { + { + .reg = PMBUS_OT_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_TEMP_OT_WARNING, + } +}; + +static const struct pmbus_limit_attr temp_limit_attrs3[] = { + { + .reg = PMBUS_OT_WARN_LIMIT, + .attr = "max", + .alarm = "max_alarm", + .sbit = PB_TEMP_OT_WARNING, + } +}; + +static const struct pmbus_sensor_attr temp_attributes[] = { + { + .reg = PMBUS_READ_TEMPERATURE_1, + .class = PSC_TEMPERATURE, + .paged = true, + .update = true, + .compare = true, + .func = PMBUS_HAVE_TEMP, + .sfunc = PMBUS_HAVE_STATUS_TEMP, + .sbase = PB_STATUS_TEMP_BASE, + .gbit = PB_STATUS_TEMPERATURE, + .limit = temp_limit_attrs, + .nlimit = ARRAY_SIZE(temp_limit_attrs), + }, { + .reg = PMBUS_READ_TEMPERATURE_2, + .class = PSC_TEMPERATURE, + .paged = true, + .update = true, + .compare = true, + .func = PMBUS_HAVE_TEMP2, + .sfunc = PMBUS_HAVE_STATUS_TEMP, + .sbase = PB_STATUS_TEMP_BASE, + .gbit = PB_STATUS_TEMPERATURE, + .limit = temp_limit_attrs2, + .nlimit = ARRAY_SIZE(temp_limit_attrs2), + }, { + .reg = PMBUS_READ_TEMPERATURE_3, + .class = PSC_TEMPERATURE, + .paged = true, + .update = true, + .compare = true, + .func = PMBUS_HAVE_TEMP3, + .sfunc = PMBUS_HAVE_STATUS_TEMP, + .sbase = PB_STATUS_TEMP_BASE, + .gbit = PB_STATUS_TEMPERATURE, + .limit = temp_limit_attrs3, + .nlimit = ARRAY_SIZE(temp_limit_attrs3), + } +}; + +static const int pmbus_fan_registers[] = { + PMBUS_READ_FAN_SPEED_1, +}; + +static const int pmbus_fan_config_registers[] = { + PMBUS_FAN_CONFIG_12, +}; + +static const int pmbus_fan_status_registers[] = { + PMBUS_STATUS_FAN_12, +}; + +static const u32 pmbus_fan_flags[] = { + PMBUS_HAVE_FAN12, +}; + +static const u32 pmbus_fan_status_flags[] = { + PMBUS_HAVE_STATUS_FAN12, +}; + +/* Fans */ +static int pmbus_add_fan_attributes(struct i2c_client *client, + struct pmbus_data *data) +{ + const struct pmbus_driver_info *info = data->info; + int index = 1; + int page; + int ret; + + for (page = 0; page < info->pages; page++) { + int f; + + for (f = 0; f < ARRAY_SIZE(pmbus_fan_registers); f++) { + int regval; + + if (!(info->func[page] & pmbus_fan_flags[f])) + break; + + if (!pmbus_check_word_register(client, page, + pmbus_fan_registers[f])) + break; + + /* + * Skip fan if not installed. + * Each fan configuration register covers multiple fans, + * so we have to do some magic. + */ + regval = _pmbus_read_byte_data(client, page, + pmbus_fan_config_registers[f]); + if (regval < 0 || + (!(regval & (PB_FAN_1_INSTALLED >> ((f & 1) * 4))))) + continue; + + if (pmbus_add_sensor(data, "fan", "input", index, + page, pmbus_fan_registers[f], + PSC_FAN, true, true) == NULL) + return -ENOMEM; + + /* + * Each fan status register covers multiple fans, + * so we have to do some magic. + */ + if ((info->func[page] & pmbus_fan_status_flags[f]) && + pmbus_check_byte_register(client, + page, pmbus_fan_status_registers[f])) { + int base; + + if (f > 1) /* fan 3, 4 */ + base = PB_STATUS_FAN34_BASE + page; + else + base = PB_STATUS_FAN_BASE + page; + ret = pmbus_add_boolean(data, "fan", + "alarm", index, NULL, NULL, base, + PB_FAN_FAN1_WARNING >> (f & 1)); + if (ret) + return ret; + ret = pmbus_add_boolean(data, "fan", + "fault", index, NULL, NULL, base, + PB_FAN_FAN1_FAULT >> (f & 1)); + if (ret) + return ret; + } + index++; + } + } + return 0; +} + +/* mfr items */ +static int pmbus_add_mfr_attributes(struct i2c_client *client, + struct pmbus_data *data) +{ + int page = 0; + int i; + + for(i = 0; i < ARRAY_SIZE(pmbus_mfr_reg);i++){ + + if (pmbus_add_mfr(data, pmbus_mfr_reg[i].name, page, pmbus_mfr_reg[i].reg) == NULL){ + return -ENOMEM; + } + } + + return 0; +} + +/* status items */ +static int pmbus_add_status_attributes(struct i2c_client *client, + struct pmbus_data *data) +{ + int i; + + for(i = 0; i < ARRAY_SIZE(pmbus_status_reg);i++){ + if (pmbus_add_status(data, pmbus_status_reg[i].name, pmbus_status_reg[i].base, pmbus_status_reg[i].offset)){ + return -ENOMEM; + } + } + + return 0; +} + +static int pmbus_find_attributes(struct i2c_client *client, + struct pmbus_data *data) +{ + int ret; + + /* Voltage sensors */ + ret = pmbus_add_sensor_attrs(client, data, "in", voltage_attributes, + ARRAY_SIZE(voltage_attributes)); + if (ret) + return ret; + + /* Current sensors */ + ret = pmbus_add_sensor_attrs(client, data, "curr", current_attributes, + ARRAY_SIZE(current_attributes)); + if (ret) + return ret; + + /* Temperature sensors */ + ret = pmbus_add_sensor_attrs(client, data, "temp", temp_attributes, + ARRAY_SIZE(temp_attributes)); + if (ret) + return ret; + + /* Fans */ + ret = pmbus_add_fan_attributes(client, data); + if (ret) + return ret; + + /* mfr data */ + ret = pmbus_add_mfr_attributes(client, data); + if (ret) + return ret; + + /* status data */ + ret = pmbus_add_status_attributes(client, data); + return ret; +} + +/* + * Identify chip parameters. + * This function is called for all chips. + */ +static int pmbus_identify_common(struct i2c_client *client, + struct pmbus_data *data, int page) +{ + int vout_mode = -1; + + if (pmbus_check_byte_register(client, page, PMBUS_VOUT_MODE)) + vout_mode = _pmbus_read_byte_data(client, page, + PMBUS_VOUT_MODE); + if (vout_mode >= 0 && vout_mode != 0xff) { + /* + * Not all chips support the VOUT_MODE command, + * so a failure to read it is not an error. + */ + switch (vout_mode >> 5) { + case 0: /* linear mode */ + if (data->info->format[PSC_VOLTAGE_OUT] != linear) + return -ENODEV; + + data->exponent[page] = ((s8)(vout_mode << 3)) >> 3; + break; + case 1: /* VID mode */ + if (data->info->format[PSC_VOLTAGE_OUT] != vid) + return -ENODEV; + break; + case 2: /* direct mode */ + if (data->info->format[PSC_VOLTAGE_OUT] != direct) + return -ENODEV; + break; + default: + return -ENODEV; + } + } + + pmbus_clear_fault_page(client, page); + return 0; +} + +static int pmbus_init_common(struct i2c_client *client, struct pmbus_data *data, + struct pmbus_driver_info *info) +{ + struct device *dev = &client->dev; + int page, ret; + + /* + * Some PMBus chips don't support PMBUS_STATUS_BYTE, so try + * to use PMBUS_STATUS_WORD instead if that is the case. + * Bail out if both registers are not supported. + */ + data->status_register = PMBUS_STATUS_BYTE; + ret = i2c_smbus_read_byte_data(client, PMBUS_STATUS_BYTE); + if (ret < 0 || ret == 0xff) { + data->status_register = PMBUS_STATUS_WORD; + ret = i2c_smbus_read_word_data(client, PMBUS_STATUS_WORD); + if (ret < 0 || ret == 0xffff) { + dev_err(dev, "PMBus status register not found\n"); + return -ENODEV; + } + } + + pmbus_clear_faults(client); + + if (info->identify) { + ret = (*info->identify)(client, info); + if (ret < 0) { + dev_err(dev, "Chip identification failed\n"); + return ret; + } + } + + if (info->pages <= 0 || info->pages > PMBUS_PAGES) { + dev_err(dev, "Bad number of PMBus pages: %d\n", info->pages); + return -ENODEV; + } + + /* Current only using page 1 in BMS project */ + info->pages = 1; + + for (page = 0; page < info->pages; page++) { + ret = pmbus_identify_common(client, data, page); + if (ret < 0) { + dev_err(dev, "Failed to identify chip capabilities\n"); + return ret; + } + } + return 0; +} + +int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, + struct pmbus_driver_info *info) +{ + struct device *dev = &client->dev; + const struct pmbus_platform_data *pdata = dev_get_platdata(dev); + struct pmbus_data *data; + int ret; + + if (!info) + return -ENODEV; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE + | I2C_FUNC_SMBUS_BYTE_DATA + | I2C_FUNC_SMBUS_WORD_DATA)) + return -ENODEV; + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->dev = dev; + + if (pdata) + data->flags = pdata->flags; + data->info = info; + + ret = pmbus_init_common(client, data, info); + if (ret < 0) + return ret; + + ret = pmbus_find_attributes(client, data); + if (ret) + goto out_kfree; + + /* + * If there are no attributes, something is wrong. + * Bail out instead of trying to register nothing. + */ + if (!data->num_attributes) { + dev_err(dev, "No attributes found\n"); + ret = -ENODEV; + goto out_kfree; + } + + data->groups[0] = &data->group; + data->hwmon_dev = hwmon_device_register_with_groups(dev, client->name, + data, data->groups); + if (IS_ERR(data->hwmon_dev)) { + ret = PTR_ERR(data->hwmon_dev); + dev_err(dev, "Failed to register hwmon device\n"); + goto out_kfree; + } + return 0; + +out_kfree: + kfree(data->group.attrs); + return ret; +} + +int pmbus_do_remove(struct i2c_client *client) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + kfree(data->group.attrs); + return 0; +} + + +/* + * Find sensor groups and status registers on each page. + */ +static void pmbus_find_sensor_groups(struct i2c_client *client, + struct pmbus_driver_info *info) +{ + int page; + + /* Sensors detected on page 0 only */ + if (pmbus_check_word_register(client, 0, PMBUS_READ_VIN)) + info->func[0] |= PMBUS_HAVE_VIN; + if (pmbus_check_word_register(client, 0, PMBUS_READ_VCAP)) + info->func[0] |= PMBUS_HAVE_VCAP; + if (pmbus_check_word_register(client, 0, PMBUS_READ_IIN)) + info->func[0] |= PMBUS_HAVE_IIN; + if (pmbus_check_word_register(client, 0, PMBUS_READ_PIN)) + info->func[0] |= PMBUS_HAVE_PIN; + if (info->func[0] + && pmbus_check_byte_register(client, 0, PMBUS_STATUS_INPUT)) + info->func[0] |= PMBUS_HAVE_STATUS_INPUT; + if (pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_12) && + pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_1)) { + info->func[0] |= PMBUS_HAVE_FAN12; + if (pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_12)) + info->func[0] |= PMBUS_HAVE_STATUS_FAN12; + } + if (pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_34) && + pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_3)) { + info->func[0] |= PMBUS_HAVE_FAN34; + if (pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_34)) + info->func[0] |= PMBUS_HAVE_STATUS_FAN34; + } + if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_1)) + info->func[0] |= PMBUS_HAVE_TEMP; + if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_2)) + info->func[0] |= PMBUS_HAVE_TEMP2; + if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_3)) + info->func[0] |= PMBUS_HAVE_TEMP3; + if (info->func[0] & (PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 + | PMBUS_HAVE_TEMP3) + && pmbus_check_byte_register(client, 0, + PMBUS_STATUS_TEMPERATURE)) + info->func[0] |= PMBUS_HAVE_STATUS_TEMP; + + /* Sensors detected on all pages */ + for (page = 0; page < info->pages; page++) { + if (pmbus_check_word_register(client, page, PMBUS_READ_VOUT)) { + info->func[page] |= PMBUS_HAVE_VOUT; + if (pmbus_check_byte_register(client, page, + PMBUS_STATUS_VOUT)) + info->func[page] |= PMBUS_HAVE_STATUS_VOUT; + } + if (pmbus_check_word_register(client, page, PMBUS_READ_IOUT)) { + info->func[page] |= PMBUS_HAVE_IOUT; + if (pmbus_check_byte_register(client, 0, + PMBUS_STATUS_IOUT)) + info->func[page] |= PMBUS_HAVE_STATUS_IOUT; + } + if (pmbus_check_word_register(client, page, PMBUS_READ_POUT)) + info->func[page] |= PMBUS_HAVE_POUT; + } +} + +/* + * Identify chip parameters. + */ +static int pmbus_identify(struct i2c_client *client, + struct pmbus_driver_info *info) +{ + int ret = 0; + + if (!info->pages) { + /* + * Check if the PAGE command is supported. If it is, + * keep setting the page number until it fails or until the + * maximum number of pages has been reached. Assume that + * this is the number of pages supported by the chip. + */ + if (pmbus_check_byte_register(client, 0, PMBUS_PAGE)) { + int page; + + for (page = 1; page < PMBUS_PAGES; page++) { + if (pmbus_set_page(client, page) < 0) + break; + } + pmbus_set_page(client, 0); + info->pages = page; + } else { + info->pages = 1; + } + } + + if (pmbus_check_byte_register(client, 0, PMBUS_VOUT_MODE)) { + int vout_mode; + + vout_mode = pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE); + if (vout_mode >= 0 && vout_mode != 0xff) { + switch (vout_mode >> 5) { + case 0: + break; + case 1: + info->format[PSC_VOLTAGE_OUT] = vid; + break; + case 2: + info->format[PSC_VOLTAGE_OUT] = direct; + break; + default: + ret = -ENODEV; + goto abort; + } + } + } + + /* + * We should check if the COEFFICIENTS register is supported. + * If it is, and the chip is configured for direct mode, we can read + * the coefficients from the chip, one set per group of sensor + * registers. + * + * To do this, we will need access to a chip which actually supports the + * COEFFICIENTS command, since the command is too complex to implement + * without testing it. Until then, abort if a chip configured for direct + * mode was detected. + */ + if (info->format[PSC_VOLTAGE_OUT] == direct) { + ret = -ENODEV; + goto abort; + } + + /* Try to find sensor groups */ + pmbus_find_sensor_groups(client, info); +abort: + return ret; +} + +static int pmbus_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct pmbus_driver_info *info; + + info = devm_kzalloc(&client->dev, sizeof(struct pmbus_driver_info), + GFP_KERNEL); + if (!info) + return -ENOMEM; + + info->pages = id->driver_data; + info->identify = pmbus_identify; + + return pmbus_do_probe(client, id, info); +} + +/* + * Use driver_data to set the number of pages supported by the chip. + */ +static const struct i2c_device_id pmbus_id[] = { + {"fse000", 0}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, pmbus_id); + +/* This is the driver that will be inserted */ +static struct i2c_driver pmbus_driver = { + .driver = { + .name = "fse000", + }, + .probe = pmbus_probe, + .remove = pmbus_do_remove, + .id_table = pmbus_id, +}; + +module_i2c_driver(pmbus_driver); + +MODULE_DESCRIPTION("mitac_ly1200_32x_fse000 driver"); +MODULE_AUTHOR("Eddy Weng "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_gpe.c b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_gpe.c new file mode 100644 index 000000000000..3ced2b0a399b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_gpe.c @@ -0,0 +1,93 @@ +#include +#include + +#define BMS_GPE_CLASS "bms_acpi" +#define BMS_GPE_DRIVER_NAME "bms_gpe" +#define BMS_GPE_DEVICE_NAME "bms_acpi_gpe" + +static int bms_gpe[] = {0x01, 0x02, 0x47}; +static int bms_gpe_num = sizeof(bms_gpe) / sizeof(bms_gpe[0]); + +static u32 bms_gpe_handler(acpi_handle handle, u32 gpe_num, void *context) +{ + struct acpi_device *device = context; + + acpi_bus_generate_netlink_event(device->pnp.device_class,dev_name(&device->dev), + gpe_num, 0); + return ACPI_INTERRUPT_HANDLED; /* GPE will be disable afterward */ +} + +static int bms_gpe_add(struct acpi_device *device) +{ + acpi_status status; + int i = 0; + char info_str[60] = { 0 }; + char temp[6] = { 0 }; + + if (!device) { + printk("No device of BMS GPE\n"); + return -EINVAL; + } + + strcpy(acpi_device_name(device), BMS_GPE_DEVICE_NAME); + strcpy(acpi_device_class(device), BMS_GPE_CLASS); + + strncat(info_str, "Initialized GPE list = ", 23); + for (i = 0; i < bms_gpe_num; i++) { + status = acpi_install_gpe_handler(NULL, bms_gpe[i], + ACPI_GPE_LEVEL_TRIGGERED, + &bms_gpe_handler, device); + if (status != AE_OK) { + printk("Fail to claim BMS GPE%X (code:0x%X)\n",bms_gpe[i],status); + return -EINVAL; + } + snprintf(temp, sizeof(temp), "0x%.2X ", bms_gpe[i]); + strncat(info_str, temp, 6); + } + + dev_info(&device->dev, "%s.\n", info_str); + + return 0; +} + +static int bms_gpe_remove(struct acpi_device *device) +{ + int i = 0; + for (i = 0; i < bms_gpe_num; i++) { + acpi_remove_gpe_handler(NULL, bms_gpe[i], &bms_gpe_handler); + } + return 0; +} + +static const struct acpi_device_id bms_acpi_device_ids[] = { + { "PNP0C01", 0 }, + { /* END OF LIST */ } +}; + +static struct acpi_driver bms_gpe_driver = { + .name = BMS_GPE_DRIVER_NAME, + .class = BMS_GPE_CLASS, + .ids = bms_acpi_device_ids, + .ops = { + .add = bms_gpe_add, + .remove = bms_gpe_remove, + }, +}; + +static int __init bms_gpe_init(void) +{ + printk(KERN_INFO "%s: init.\n", __FUNCTION__); + return acpi_bus_register_driver(&bms_gpe_driver); +} + +static void __exit bms_gpe_exit(void) +{ + printk(KERN_INFO "%s: exit.\n", __FUNCTION__); + acpi_bus_unregister_driver(&bms_gpe_driver); +} + +module_init(bms_gpe_init); +module_exit(bms_gpe_exit); +MODULE_AUTHOR("Yencheng Lin "); +MODULE_DESCRIPTION("mitac_ly1200_32x_gpe driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_master_cpld.c b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_master_cpld.c new file mode 100644 index 000000000000..921a2ea424a3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_master_cpld.c @@ -0,0 +1,503 @@ +#include +#include + +#include "master_cpld_reg.h" +#include "master_cpld_sysfs.h" + +static int debug_flag = 0; + +struct master_cpld_data { + struct mutex lock; + + struct i2c_client *client; + struct device_attribute bin; +}; + + +static const struct i2c_device_id master_cpld_ids[] = { + { "master_cpld", 0 }, + { /* END OF LIST */ } +}; +MODULE_DEVICE_TABLE(i2c, master_cpld_ids); + +static int master_cpld_raw_read(struct device *dev, struct device_attribute *attr, char *buf, + int reg_offset, int reg_width, int fld_shift, int fld_width, int fld_mask, char* reg_name){ + unsigned int reg_val = 0, fld_val; + static int debug_flag; + struct master_cpld_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + int err; + + if (reg_width != 8){ + printk("%s: Register table width setting failed.\n", reg_name); + return -EINVAL; + } + mutex_lock(&data->lock); + if ((err = i2c_smbus_read_byte_data(client, (u8)reg_offset)) < 0) { + /* CPLD read error condition */; + mutex_unlock(&data->lock); + printk("%s: i2c read failed, error code = %d.\n", reg_name, err); + return err; + } + reg_val = err; + if (debug_flag) { + printk("%s: reg_offset = %d, width = %d, cur value = 0x%x.\n", reg_name, reg_offset, reg_width, reg_val); + } + mutex_unlock(&data->lock); + if (fld_width == reg_width) {fld_val = reg_val & fld_mask;} + else {fld_val = (reg_val >> fld_shift) & fld_mask;} + return sprintf(buf, "0x%x\n", fld_val); +} + +static int master_cpld_raw_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count, + int reg_offset, int reg_width, int fld_shift, int fld_width, int fld_mask, char* reg_name){ + int ret_code; + unsigned int reg_val, fld_val; + unsigned long val; + static int debug_flag; + struct master_cpld_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + if (reg_width != 8){ + printk("%s: Register table width setting failed.\n", reg_name); + return -EINVAL; + } + /* Parse buf and store to fld_val */ + if ((ret_code = kstrtoul(buf, 16, &val))){ + printk("%s: Conversion value = %s failed, errno = %d.\n", reg_name, buf, ret_code); + return ret_code; + } + fld_val = (unsigned int)val; + mutex_lock(&data->lock); + if ((ret_code = i2c_smbus_read_byte_data(client, (u8)reg_offset)) < 0) { + /* Handle CPLD read error condition */; + mutex_unlock(&data->lock); + printk("%s: i2c read failed, error code = %d.\n", reg_name, ret_code); + return ret_code; + } + reg_val = ret_code; + if (debug_flag) { + printk("%s: offset = %d, width = %d, cur value = 0x%x.\n", reg_name, reg_offset, reg_width, reg_val); + } + if (fld_width == reg_width) {reg_val = fld_val & fld_mask;} + else {reg_val = (reg_val & ~(fld_mask << fld_shift)) | + ((fld_val & (fld_mask)) << fld_shift);} + if ((ret_code = i2c_smbus_write_byte_data(client, (u8)reg_offset, (u8)reg_val)) != 0) { + /* Handle CPLD write error condition */; + mutex_unlock(&data->lock); + printk("%s: i2c write failed, error code = %d.\n", reg_name, ret_code); + return ret_code; + } + else if (debug_flag) { + printk("%s: offset = %d, width = %d, new value = 0x%x.\n", reg_name, reg_offset, reg_width, reg_val); + } + mutex_unlock(&data->lock); + return count; +} + +/*--------------------special file for debug---------------------- */ +static ssize_t master_cpld_debug_read(struct device *dev, struct device_attribute *attr, + char *buf){ + + return sprintf(buf, "%d\n", debug_flag); +} + + +static ssize_t master_cpld_debug_write(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + int temp; + int error; + + error = kstrtoint(buf, 10, &temp); + if (error){ + printk(KERN_INFO "%s: Conversion value = %s failed.\n", __FUNCTION__, buf); + return count; + } + debug_flag = temp; + + if(debug_flag) + printk("%s, debug_flag = %d\n", __FUNCTION__, debug_flag); + + return count; +} +SYSFS_MISC_RW_ATTR_DEF(debug, master_cpld_debug_read, master_cpld_debug_write) + + + + +/* ----------------define port group---------------------------- */ +static struct attribute *port1_attributes[] = { + SYSFS_ATTR_PTR(port1_present), /* register: zqsfp28_present_8_1_status */ + SYSFS_ATTR_PTR(port1_rst), /* register: zqsfp28_rst_8_1 */ + SYSFS_ATTR_PTR(port1_modsel), /* register: zqsfp28_modsel_8_1 */ + SYSFS_ATTR_PTR(port1_lpmode), /* register: zqsfp28_lpmode_8_1 */ + SYSFS_ATTR_PTR(port1_irq_status), /* register: zqsfp28_irq_8_1_status */ + SYSFS_ATTR_PTR(port1_irq_msk), /* register: zqsfp28_irq_msk_8_1_status */ + NULL +}; + + +static struct attribute *port2_attributes[] = { + SYSFS_ATTR_PTR(port2_present), /* register: zqsfp28_present_8_1_status */ + SYSFS_ATTR_PTR(port2_rst), /* register: zqsfp28_rst_8_1 */ + SYSFS_ATTR_PTR(port2_modsel), /* register: zqsfp28_modsel_8_1 */ + SYSFS_ATTR_PTR(port2_lpmode), /* register: zqsfp28_lpmode_8_1 */ + SYSFS_ATTR_PTR(port2_irq_status), /* register: zqsfp28_irq_8_1_status */ + SYSFS_ATTR_PTR(port2_irq_msk), /* register: zqsfp28_irq_msk_8_1_status */ + NULL +}; + + +static struct attribute *port3_attributes[] = { + SYSFS_ATTR_PTR(port3_present), /* register: zqsfp28_present_8_1_status */ + SYSFS_ATTR_PTR(port3_rst), /* register: zqsfp28_rst_8_1 */ + SYSFS_ATTR_PTR(port3_modsel), /* register: zqsfp28_modsel_8_1 */ + SYSFS_ATTR_PTR(port3_lpmode), /* register: zqsfp28_lpmode_8_1 */ + SYSFS_ATTR_PTR(port3_irq_status), /* register: zqsfp28_irq_8_1_status */ + SYSFS_ATTR_PTR(port3_irq_msk), /* register: zqsfp28_irq_msk_8_1_status */ + NULL +}; + +static struct attribute *port4_attributes[] = { + SYSFS_ATTR_PTR(port4_present), /* register: zqsfp28_present_8_1_status */ + SYSFS_ATTR_PTR(port4_rst), /* register: zqsfp28_rst_8_1 */ + SYSFS_ATTR_PTR(port4_modsel), /* register: zqsfp28_modsel_8_1 */ + SYSFS_ATTR_PTR(port4_lpmode), /* register: zqsfp28_lpmode_8_1 */ + SYSFS_ATTR_PTR(port4_irq_status), /* register: zqsfp28_irq_8_1_status */ + SYSFS_ATTR_PTR(port4_irq_msk), /* register: zqsfp28_irq_msk_8_1_status */ + NULL +}; + +static struct attribute *port5_attributes[] = { + SYSFS_ATTR_PTR(port5_present), /* register: zqsfp28_present_8_1_status */ + SYSFS_ATTR_PTR(port5_rst), /* register: zqsfp28_rst_8_1 */ + SYSFS_ATTR_PTR(port5_modsel), /* register: zqsfp28_modsel_8_1 */ + SYSFS_ATTR_PTR(port5_lpmode), /* register: zqsfp28_lpmode_8_1 */ + SYSFS_ATTR_PTR(port5_irq_status), /* register: zqsfp28_irq_8_1_status */ + SYSFS_ATTR_PTR(port5_irq_msk), /* register: zqsfp28_irq_msk_8_1_status */ + NULL +}; + +static struct attribute *port6_attributes[] = { + SYSFS_ATTR_PTR(port6_present), /* register: zqsfp28_present_8_1_status */ + SYSFS_ATTR_PTR(port6_rst), /* register: zqsfp28_rst_8_1 */ + SYSFS_ATTR_PTR(port6_modsel), /* register: zqsfp28_modsel_8_1 */ + SYSFS_ATTR_PTR(port6_lpmode), /* register: zqsfp28_lpmode_8_1 */ + SYSFS_ATTR_PTR(port6_irq_status), /* register: zqsfp28_irq_8_1_status */ + SYSFS_ATTR_PTR(port6_irq_msk), /* register: zqsfp28_irq_msk_8_1_status */ + NULL +}; + +static struct attribute *port7_attributes[] = { + SYSFS_ATTR_PTR(port7_present), /* register: zqsfp28_present_8_1_status */ + SYSFS_ATTR_PTR(port7_rst), /* register: zqsfp28_rst_8_1 */ + SYSFS_ATTR_PTR(port7_modsel), /* register: zqsfp28_modsel_8_1 */ + SYSFS_ATTR_PTR(port7_lpmode), /* register: zqsfp28_lpmode_8_1 */ + SYSFS_ATTR_PTR(port7_irq_status), /* register: zqsfp28_irq_8_1_status */ + SYSFS_ATTR_PTR(port7_irq_msk), /* register: zqsfp28_irq_msk_8_1_status */ + NULL +}; + +static struct attribute *port8_attributes[] = { + SYSFS_ATTR_PTR(port8_present), /* register: zqsfp28_present_8_1_status */ + SYSFS_ATTR_PTR(port8_rst), /* register: zqsfp28_rst_8_1 */ + SYSFS_ATTR_PTR(port8_modsel), /* register: zqsfp28_modsel_8_1 */ + SYSFS_ATTR_PTR(port8_lpmode), /* register: zqsfp28_lpmode_8_1 */ + SYSFS_ATTR_PTR(port8_irq_status), /* register: zqsfp28_irq_8_1_status */ + SYSFS_ATTR_PTR(port8_irq_msk), /* register: zqsfp28_irq_msk_8_1_status */ + NULL +}; + +static struct attribute *port9_attributes[] = { + SYSFS_ATTR_PTR(port9_present), /* register: zqsfp28_present_16_9_status */ + SYSFS_ATTR_PTR(port9_rst), /* register: zqsfp28_rst_16_9 */ + SYSFS_ATTR_PTR(port9_modsel), /* register: zqsfp28_modsel_16_9 */ + SYSFS_ATTR_PTR(port9_lpmode), /* register: zqsfp28_lpmode_16_9 */ + SYSFS_ATTR_PTR(port9_irq_status), /* register: zqsfp28_irq_16_9_status */ + SYSFS_ATTR_PTR(port9_irq_msk), /* register: zqsfp28_irq_msk_16_9_status */ + NULL +}; + +static struct attribute *port10_attributes[] = { + SYSFS_ATTR_PTR(port10_present), /* register: zqsfp28_present_16_9_status */ + SYSFS_ATTR_PTR(port10_rst), /* register: zqsfp28_rst_16_9 */ + SYSFS_ATTR_PTR(port10_modsel), /* register: zqsfp28_modsel_16_9 */ + SYSFS_ATTR_PTR(port10_lpmode), /* register: zqsfp28_lpmode_16_9 */ + SYSFS_ATTR_PTR(port10_irq_status), /* register: zqsfp28_irq_16_9_status */ + SYSFS_ATTR_PTR(port10_irq_msk), /* register: zqsfp28_irq_msk_16_9_status */ + NULL +}; + +static struct attribute *port11_attributes[] = { + SYSFS_ATTR_PTR(port11_present), /* register: zqsfp28_present_16_9_status */ + SYSFS_ATTR_PTR(port11_rst), /* register: zqsfp28_rst_16_9 */ + SYSFS_ATTR_PTR(port11_modsel), /* register: zqsfp28_modsel_16_9 */ + SYSFS_ATTR_PTR(port11_lpmode), /* register: zqsfp28_lpmode_16_9 */ + SYSFS_ATTR_PTR(port11_irq_status), /* register: zqsfp28_irq_16_9_status */ + SYSFS_ATTR_PTR(port11_irq_msk), /* register: zqsfp28_irq_msk_16_9_status */ + NULL +}; + +static struct attribute *port12_attributes[] = { + SYSFS_ATTR_PTR(port12_present), /* register: zqsfp28_present_16_9_status */ + SYSFS_ATTR_PTR(port12_rst), /* register: zqsfp28_rst_16_9 */ + SYSFS_ATTR_PTR(port12_modsel), /* register: zqsfp28_modsel_16_9 */ + SYSFS_ATTR_PTR(port12_lpmode), /* register: zqsfp28_lpmode_16_9 */ + SYSFS_ATTR_PTR(port12_irq_status), /* register: zqsfp28_irq_16_9_status */ + SYSFS_ATTR_PTR(port12_irq_msk), /* register: zqsfp28_irq_msk_16_9_status */ + NULL +}; + +static struct attribute *port13_attributes[] = { + SYSFS_ATTR_PTR(port13_present), /* register: zqsfp28_present_16_9_status */ + SYSFS_ATTR_PTR(port13_rst), /* register: zqsfp28_rst_16_9 */ + SYSFS_ATTR_PTR(port13_modsel), /* register: zqsfp28_modsel_16_9 */ + SYSFS_ATTR_PTR(port13_lpmode), /* register: zqsfp28_lpmode_16_9 */ + SYSFS_ATTR_PTR(port13_irq_status), /* register: zqsfp28_irq_16_9_status */ + SYSFS_ATTR_PTR(port13_irq_msk), /* register: zqsfp28_irq_msk_16_9_status */ + NULL +}; + +static struct attribute *port14_attributes[] = { + SYSFS_ATTR_PTR(port14_present), /* register: zqsfp28_present_16_9_status */ + SYSFS_ATTR_PTR(port14_rst), /* register: zqsfp28_rst_16_9 */ + SYSFS_ATTR_PTR(port14_modsel), /* register: zqsfp28_modsel_16_9 */ + SYSFS_ATTR_PTR(port14_lpmode), /* register: zqsfp28_lpmode_16_9 */ + SYSFS_ATTR_PTR(port14_irq_status), /* register: zqsfp28_irq_16_9_status */ + SYSFS_ATTR_PTR(port14_irq_msk), /* register: zqsfp28_irq_msk_16_9_status */ + NULL +}; + +static struct attribute *port15_attributes[] = { + SYSFS_ATTR_PTR(port15_present), /* register: zqsfp28_present_16_9_status */ + SYSFS_ATTR_PTR(port15_rst), /* register: zqsfp28_rst_16_9 */ + SYSFS_ATTR_PTR(port15_modsel), /* register: zqsfp28_modsel_16_9 */ + SYSFS_ATTR_PTR(port15_lpmode), /* register: zqsfp28_lpmode_16_9 */ + SYSFS_ATTR_PTR(port15_irq_status), /* register: zqsfp28_irq_16_9_status */ + SYSFS_ATTR_PTR(port15_irq_msk), /* register: zqsfp28_irq_msk_16_9_status */ + NULL +}; + +static struct attribute *port16_attributes[] = { + SYSFS_ATTR_PTR(port16_present), /* register: zqsfp28_present_16_9_status */ + SYSFS_ATTR_PTR(port16_rst), /* register: zqsfp28_rst_16_9 */ + SYSFS_ATTR_PTR(port16_modsel), /* register: zqsfp28_modsel_16_9 */ + SYSFS_ATTR_PTR(port16_lpmode), /* register: zqsfp28_lpmode_16_9 */ + SYSFS_ATTR_PTR(port16_irq_status), /* register: zqsfp28_irq_16_9_status */ + SYSFS_ATTR_PTR(port16_irq_msk), /* register: zqsfp28_irq_msk_16_9_status */ + NULL +}; + + +static const struct attribute_group master_cpld_port_group[] = { + {.attrs = port1_attributes, + .name = "port1",}, + {.attrs = port2_attributes, + .name = "port2",}, + {.attrs = port3_attributes, + .name = "port3",}, + {.attrs = port4_attributes, + .name = "port4",}, + {.attrs = port5_attributes, + .name = "port5",}, + {.attrs = port6_attributes, + .name = "port6",}, + {.attrs = port7_attributes, + .name = "port7",}, + {.attrs = port8_attributes, + .name = "port8",}, + {.attrs = port9_attributes, + .name = "port9",}, + {.attrs = port10_attributes, + .name = "port10",}, + {.attrs = port11_attributes, + .name = "port11",}, + {.attrs = port12_attributes, + .name = "port12",}, + {.attrs = port13_attributes, + .name = "port13",}, + {.attrs = port14_attributes, + .name = "port14",}, + {.attrs = port15_attributes, + .name = "port15",}, + {.attrs = port16_attributes, + .name = "port16",} +}; + +/* ----------------define misc group---------------------------- */ +static struct attribute *misc_attributes[] = { + SYSFS_ATTR_PTR(mjr_rev), /* register: mstr_cpld_rev */ + SYSFS_ATTR_PTR(mnr_rev), /* register: mstr_cpld_rev */ + + SYSFS_ATTR_PTR(scrtch_reg), /* register: mstr_cpld_gpr */ + + SYSFS_ATTR_PTR(brd_rev), /* register: mb_brd_rev_type */ + SYSFS_ATTR_PTR(brd_type), /* register: mb_brd_rev_type */ + + SYSFS_ATTR_PTR(mb_rst), /* register: mstr_srr */ + SYSFS_ATTR_PTR(npu_rst), /* register: mstr_srr */ + SYSFS_ATTR_PTR(mgmt_phy_rst), /* register: mstr_srr */ + + SYSFS_ATTR_PTR(mb_eeprom_wp), /* register: eeprom_wp */ + SYSFS_ATTR_PTR(cpld_spi_wp), /* register: eeprom_wp */ + SYSFS_ATTR_PTR(fan_eeprom_wp), /* register: eeprom_wp */ + + SYSFS_ATTR_PTR(ps2_int_msk), /* register: mstr_irq */ + SYSFS_ATTR_PTR(ps1_int_msk), /* register: mstr_irq */ + SYSFS_ATTR_PTR(usb_fault_msk), /* register: mstr_irq */ + SYSFS_ATTR_PTR(pcie_int_msk), /* register: mstr_irq */ + SYSFS_ATTR_PTR(fan_alert_int_msk), /* register: mstr_irq */ + SYSFS_ATTR_PTR(usb_fault), /* register: mstr_irq */ + SYSFS_ATTR_PTR(pcie_int), /* register: mstr_irq */ + SYSFS_ATTR_PTR(fan_alert_int), /* register: mstr_irq */ + SYSFS_ATTR_PTR(system_led_fld), /* register: mstr_irq */ + SYSFS_ATTR_PTR(power_led), /* register: mstr_irq */ + SYSFS_ATTR_PTR(fan_led), /* register: mstr_irq */ + SYSFS_ATTR_PTR(locate_led), /* register: mstr_irq */ + + SYSFS_ATTR_PTR(led_test), /* register: fan_tray_3_1_led */ + SYSFS_ATTR_PTR(fan_tray3_led), /* register: fan_tray_3_1_led */ + SYSFS_ATTR_PTR(fan_tray2_led), /* register: fan_tray_3_1_led */ + SYSFS_ATTR_PTR(fan_tray1_led), /* register: fan_tray_3_1_led */ + SYSFS_ATTR_PTR(fan_tray6_led), /* register: fan_tray_6_4_led */ + SYSFS_ATTR_PTR(fan_tray5_led), /* register: fan_tray_6_4_led */ + SYSFS_ATTR_PTR(fan_tray4_led), /* register: fan_tray_6_4_led */ + + SYSFS_ATTR_PTR(fan_tray6_present), /* register: fan_tray_status */ + SYSFS_ATTR_PTR(fan_tray5_present), /* register: fan_tray_status */ + SYSFS_ATTR_PTR(fan_tray4_present), /* register: fan_tray_status */ + SYSFS_ATTR_PTR(fan_tray3_present), /* register: fan_tray_status */ + SYSFS_ATTR_PTR(fan_tray2_present), /* register: fan_tray_status */ + SYSFS_ATTR_PTR(fan_tray1_present), /* register: fan_tray_status */ + + SYSFS_ATTR_PTR(fan_type6), /* register: fan_type_status */ + SYSFS_ATTR_PTR(fan_type5), /* register: fan_type_status */ + SYSFS_ATTR_PTR(fan_type4), /* register: fan_type_status */ + SYSFS_ATTR_PTR(fan_type3), /* register: fan_type_status */ + SYSFS_ATTR_PTR(fan_type2), /* register: fan_type_status */ + SYSFS_ATTR_PTR(fan_type1), /* register: fan_type_status */ + + SYSFS_ATTR_PTR(ps1_ps), /* register: psu_en_status */ + SYSFS_ATTR_PTR(ps1_pg), /* register: psu_en_status */ + SYSFS_ATTR_PTR(ps1_int), /* register: psu_en_status */ + SYSFS_ATTR_PTR(ps1_on), /* register: psu_en_status */ + SYSFS_ATTR_PTR(ps2_ps), /* register: psu_en_status */ + SYSFS_ATTR_PTR(ps2_pg), /* register: psu_en_status */ + SYSFS_ATTR_PTR(ps2_int), /* register: psu_en_status */ + SYSFS_ATTR_PTR(ps2_on), /* register: psu_en_status */ + + SYSFS_ATTR_PTR(usb1_vbus_en), /* register: mb_pwr_en_status */ + SYSFS_ATTR_PTR(v5p0_en), /* register: mb_pwr_en_status */ + SYSFS_ATTR_PTR(v3p3_en), /* register: mb_pwr_en_status */ + SYSFS_ATTR_PTR(vcc_1v8_en), /* register: mb_pwr_en_status */ + SYSFS_ATTR_PTR(mac_avs1v_en), /* register: mb_pwr_en_status */ + SYSFS_ATTR_PTR(mac1v_en), /* register: mb_pwr_en_status */ + SYSFS_ATTR_PTR(vcc_1v25_en), /* register: mb_pwr_en_status */ + + SYSFS_ATTR_PTR(vcc_3p3_cpld), /* register: mb_pwr_status */ + SYSFS_ATTR_PTR(vcc5v_pg), /* register: mb_pwr_status */ + SYSFS_ATTR_PTR(vcc3v3_pg), /* register: mb_pwr_status */ + SYSFS_ATTR_PTR(vcc_1v8_pg), /* register: mb_pwr_status */ + SYSFS_ATTR_PTR(mac_avs1v_pg), /* register: mb_pwr_status */ + SYSFS_ATTR_PTR(mac1v_pg), /* register: mb_pwr_status */ + SYSFS_ATTR_PTR(vcc_1v25_pg), /* register: mb_pwr_status */ + + SYSFS_ATTR_PTR(port_1_8_present), /* register: zqsfp28_present_8_1_status */ + SYSFS_ATTR_PTR(port_9_16_present), /* register: zqsfp28_present_16_9_status */ + SYSFS_ATTR_PTR(port_1_8_rst), /* register: zqsfp28_rst_8_1 */ + SYSFS_ATTR_PTR(port_9_16_rst), /* register: zqsfp28_rst_16_9 */ + SYSFS_ATTR_PTR(port_1_8_modsel), /* register: zqsfp28_modsel_8_1 */ + SYSFS_ATTR_PTR(port_9_16_modsel), /* register: zqsfp28_modsel_16_9 */ + SYSFS_ATTR_PTR(port_1_8_irq_status), /* register: zqsfp28_irq_8_1_status */ + SYSFS_ATTR_PTR(port_9_16_irq_status),/* register: zqsfp28_irq_16_9_status */ + SYSFS_ATTR_PTR(port_1_8_irq_msk), /* register: zqsfp28_irq_msk_8_1_status */ + SYSFS_ATTR_PTR(port_9_16_irq_msk), /* register: zqsfp28_irq_msk_16_9_status */ + SYSFS_ATTR_PTR(port_1_8_lpmode), /* register: zqsfp28_lpmode_8_1 */ + SYSFS_ATTR_PTR(port_9_16_lpmode), /* register: zqsfp28_lpmode_16_9 */ + + SYSFS_ATTR_PTR(fan_tray1_6_present), /* register: fan_tray_status */ + SYSFS_ATTR_PTR(psu_en_status_fld), /* register: psu_en_status*/ + + SYSFS_ATTR_PTR(debug), /* debug flag for print more messages */ + NULL +}; +static const struct attribute_group master_cpld_group_misc = { + .attrs = misc_attributes, +}; + +static int master_cpld_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct master_cpld_data *master_cpld; + int err, i; + int grp_number = (int)( sizeof(master_cpld_port_group) / sizeof(master_cpld_port_group[0])); + + /* allocate memory to master_cpld */ + master_cpld = devm_kzalloc(&client->dev, sizeof(struct master_cpld_data) , GFP_KERNEL); + + if (!master_cpld) + return -ENOMEM; + + mutex_init(&master_cpld->lock); + + for(i = 0 ; i < grp_number ; i++){ + err = sysfs_create_group(&client->dev.kobj, &master_cpld_port_group[i]); + if (err){ + printk("%s: Error creeat port group %d.\n", __FUNCTION__, i+1); + } + } + err = sysfs_create_group(&client->dev.kobj, &master_cpld_group_misc); + if (err){ + printk("%s: Error creeat misc group.\n", __FUNCTION__); + } + + master_cpld->client = client; + i2c_set_clientdata(client, master_cpld); + + printk(KERN_INFO "%s: Master CPLD LCMXO3LF created.\n", __FUNCTION__); + + return 0; + +} + +static int master_cpld_remove(struct i2c_client *client) +{ + int i; + int grp_number = (int)( sizeof(master_cpld_port_group) / sizeof(master_cpld_port_group[0])); + + for(i = 0 ; i < grp_number ; i++){ + sysfs_remove_group(&client->dev.kobj, &master_cpld_port_group[i]); + } + sysfs_remove_group(&client->dev.kobj, &master_cpld_group_misc); + + printk(KERN_INFO "%s: Master CPLD removed.\n", __FUNCTION__); + return 0; +} + +static struct i2c_driver master_cpld_driver = { + .driver = { + .name = "master_cpld", + .owner = THIS_MODULE, + }, + .probe = master_cpld_probe, + .remove = master_cpld_remove, + .id_table = master_cpld_ids, +}; + +static int __init master_cpld_init(void) +{ + printk(KERN_INFO "%s: init.\n", __FUNCTION__); + return i2c_add_driver(&master_cpld_driver); +} +module_init(master_cpld_init); + +static void __exit master_cpld_exit(void) +{ + printk(KERN_INFO "%s: exit.\n", __FUNCTION__); + i2c_del_driver(&master_cpld_driver); +} +module_exit(master_cpld_exit); + +MODULE_DESCRIPTION("mitac_ly1200_32x_master_cpld driver"); +MODULE_AUTHOR("Eddy Weng "); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_pb_i2c.c b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_pb_i2c.c new file mode 100644 index 000000000000..bad9260ab4ca --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_pb_i2c.c @@ -0,0 +1,137 @@ +#include +#include +#include "bms_i2c.h" + +#define BMS_PB_I2C_CLIENT_NUM 6 + +static struct i2c_client *bms_pb_clients[BMS_PB_I2C_CLIENT_NUM] = {NULL}; +static int bms_pb_client_index = 0; + +static int __init __find_i2c_adap(struct device *dev, void *data) +{ + const char *name = data; + static const char *prefix = "i2c-"; + struct i2c_adapter *adapter; + + if (strncmp(dev_name(dev), prefix, strlen(prefix)) != 0) + { + return 0; + } + adapter = to_i2c_adapter(dev); + + return (strncmp(adapter->name, name, strlen(name)) == 0); +} + +static int __init find_i2c_adapter_num(enum i2c_adapter_type type) +{ + struct device *dev = NULL; + struct i2c_adapter *adapter; + const char *name = bms_i2c_adapter_names[type]; + + /* find the adapter by name */ + dev = bus_find_device(&i2c_bus_type, NULL, (void *)name, + __find_i2c_adap); + if (!dev) { + pr_err("%s: i2c adapter %s not found on system.\n", + __func__, name); + return -ENODEV; + } + adapter = to_i2c_adapter(dev); + + return adapter->nr; +} + + +static int __init find_i2c_mux_adapter_num(int parent_num, int num) +{ + struct device *dev = NULL; + struct i2c_adapter *adapter; + char name[48]; + + snprintf(name, sizeof(name), "i2c-%d-mux (chan_id %d)", + parent_num, num); + /* find the adapter by name */ + dev = bus_find_device(&i2c_bus_type, NULL, (void *)name, + __find_i2c_adap); + if (!dev) { + pr_err("%s: i2c adapter %s not found on system.\n", + __func__, name); + return -ENODEV; + } + adapter = to_i2c_adapter(dev); + + return adapter->nr; +} + +static __init struct i2c_client *bms_pb_setup_eeprom_24c01( + struct i2c_adapter *adap, int addr) +{ + struct i2c_board_info info_spd = { + I2C_BOARD_INFO("24c01", addr), + }; + + return i2c_new_device(adap, &info_spd); +} + + +static int __init bms_pb_setup_devices(void) +{ + struct i2c_adapter *adap; + int adap_num; + int parent_num; + + parent_num = find_i2c_adapter_num(I2C_ADAPTER_ISMT); + if (parent_num < 0) + return parent_num; + + adap_num = find_i2c_mux_adapter_num(parent_num, I2C_STAGE1_MUX_CHAN3); + if (adap_num < 0) + return adap_num; + + adap = i2c_get_adapter(adap_num); + if (!adap) { + pr_err("%s failed to get i2c adap %d.\n", __func__, adap_num); + goto exit; + } + + bms_pb_clients[bms_pb_client_index++] = bms_pb_setup_eeprom_24c01(adap, 0x50); + bms_pb_clients[bms_pb_client_index++] = bms_pb_setup_eeprom_24c01(adap, 0x51); + +exit: + return 0; +} + +static int __init bms_pb_i2c_init(void) +{ + /* Initial bms_sb_slients array. */ + memset(bms_pb_clients, 0x0, BMS_PB_I2C_CLIENT_NUM); + + bms_pb_setup_devices(); + return 0; +} + + +static void __exit bms_pb_i2c_exit(void){ + int i; + + for (i=(bms_pb_client_index-1); i>=0; i--) { + if (bms_pb_clients[i]) { + i2c_unregister_device(bms_pb_clients[i]); + bms_pb_clients[i] = NULL; + } + } + + bms_pb_client_index = 0; + + +} + + +module_init(bms_pb_i2c_init); +module_exit(bms_pb_i2c_exit); + + +MODULE_DESCRIPTION("mitac_ly1200_32x_pb_i2c driver"); +MODULE_AUTHOR("Eddy Weng "); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_sb_i2c.c b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_sb_i2c.c new file mode 100644 index 000000000000..e2a9718863ff --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_sb_i2c.c @@ -0,0 +1,514 @@ +#include +#include +#include +#include +#include +#include +#include "bms_i2c.h" + +/* Don't include MAC_AVS_1V */ +#define BMS_SB_I2C_CLIENT_NUM 35 +#define BMS_SB_ADAPTER_BASE 2 +#define BMS_SB_STAGE2_MUX_BUS_BASE 6 + + +static struct i2c_client *bms_sb_clients[BMS_SB_I2C_CLIENT_NUM] = {NULL}; +static int bms_sb_client_index = 0; + +enum bms_sb_switch_stage2_mux0_bus { + I2C_STAGE2_MUX0_CHAN0 = 0, + I2C_STAGE2_MUX0_CHAN1, + I2C_STAGE2_MUX0_CHAN2, + I2C_STAGE2_MUX0_CHAN3, + I2C_STAGE2_MUX0_CHAN4, + I2C_STAGE2_MUX0_CHAN5, + I2C_STAGE2_MUX0_CHAN6, + I2C_STAGE2_MUX0_CHAN7, +}; + +enum bms_sb_switch_stage2_mux1_bus { + I2C_STAGE2_MUX1_CHAN8 = 0, + I2C_STAGE2_MUX1_CHAN9, + I2C_STAGE2_MUX1_CHAN10, + I2C_STAGE2_MUX1_CHAN11, + I2C_STAGE2_MUX1_CHAN12, + I2C_STAGE2_MUX1_CHAN13, + I2C_STAGE2_MUX1_CHAN14, + I2C_STAGE2_MUX1_CHAN15, +}; + +enum bms_sb_switch_stage2_mux2_bus { + I2C_STAGE2_MUX2_CHAN16 = 0, + I2C_STAGE2_MUX2_CHAN17, + I2C_STAGE2_MUX2_CHAN18, + I2C_STAGE2_MUX2_CHAN19, + I2C_STAGE2_MUX2_CHAN20, + I2C_STAGE2_MUX2_CHAN21, + I2C_STAGE2_MUX2_CHAN22, + I2C_STAGE2_MUX2_CHAN23, +}; + +enum bms_sb_switch_stage2_mux3_bus { + I2C_STAGE2_MUX3_CHAN24 = 0, + I2C_STAGE2_MUX3_CHAN25, + I2C_STAGE2_MUX3_CHAN26, + I2C_STAGE2_MUX3_CHAN27, + I2C_STAGE2_MUX3_CHAN28, + I2C_STAGE2_MUX3_CHAN29, + I2C_STAGE2_MUX3_CHAN30, + I2C_STAGE2_MUX3_CHAN31, +}; + +static struct pca954x_platform_mode pmode_pca9548_mux[] = { + { .adap_id = BMS_SB_ADAPTER_BASE + 0, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 1, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 2, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 3, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 4, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 5, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 6, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 7, }, +}; + +static struct pca954x_platform_data platdata_pca9548_mux = { + .modes = pmode_pca9548_mux, + .num_modes = ARRAY_SIZE(pmode_pca9548_mux), +}; + +static struct pca954x_platform_mode pmode_stage1_pca9548_mux0[] = { + { .adap_id = BMS_SB_ADAPTER_BASE + 8, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 9, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 10, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 11, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 12, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 13, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 14, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 15, }, +}; + +static struct pca954x_platform_data platdata_stage1_pca9548_mux0 = { + .modes = pmode_stage1_pca9548_mux0, + .num_modes = ARRAY_SIZE(pmode_stage1_pca9548_mux0), +}; + +static struct pca954x_platform_mode pmode_stage1_pca9548_mux1[] = { + { .adap_id = BMS_SB_ADAPTER_BASE + 16, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 17, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 18, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 19, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 20, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 21, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 22, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 23, }, +}; + +static struct pca954x_platform_data platdata_stage1_pca9548_mux1 = { + .modes = pmode_stage1_pca9548_mux1, + .num_modes = ARRAY_SIZE(pmode_stage1_pca9548_mux1), +}; + +static struct pca954x_platform_mode pmode_stage1_pca9548_mux2[] = { + { .adap_id = BMS_SB_ADAPTER_BASE + 24, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 25, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 26, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 27, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 28, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 29, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 30, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 31, }, +}; + +static struct pca954x_platform_data platdata_stage1_pca9548_mux2 = { + .modes = pmode_stage1_pca9548_mux2, + .num_modes = ARRAY_SIZE(pmode_stage1_pca9548_mux2), +}; + +static struct pca954x_platform_mode pmode_stage1_pca9548_mux3[] = { + { .adap_id = BMS_SB_ADAPTER_BASE + 32, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 33, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 34, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 35, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 36, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 37, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 38, }, + { .adap_id = BMS_SB_ADAPTER_BASE + 39, }, +}; + +static struct pca954x_platform_data platdata_stage1_pca9548_mux3 = { + .modes = pmode_stage1_pca9548_mux3, + .num_modes = ARRAY_SIZE(pmode_stage1_pca9548_mux3), +}; + +static int __init __find_i2c_adap(struct device *dev, void *data) +{ + const char *name = data; + static const char *prefix = "i2c-"; + struct i2c_adapter *adapter; + + if (strncmp(dev_name(dev), prefix, strlen(prefix)) != 0) + { + return 0; + } + adapter = to_i2c_adapter(dev); + + return (strncmp(adapter->name, name, strlen(name)) == 0); +} + +static int __init find_i2c_adapter_num(enum i2c_adapter_type type) +{ + struct device *dev = NULL; + struct i2c_adapter *adapter; + const char *name = bms_i2c_adapter_names[type]; + + /* find the adapter by name */ + dev = bus_find_device(&i2c_bus_type, NULL, (void *)name, + __find_i2c_adap); + if (!dev) { + pr_err("%s: i2c adapter %s not found on system.\n", + __func__, name); + return -ENODEV; + } + adapter = to_i2c_adapter(dev); + + return adapter->nr; +} + +static int __init find_i2c_mux_adapter_num(int parent_num, int num) +{ + struct device *dev = NULL; + struct i2c_adapter *adapter; + char name[48]; + + snprintf(name, sizeof(name), "i2c-%d-mux (chan_id %d)", + parent_num, num); + /* find the adapter by name */ + dev = bus_find_device(&i2c_bus_type, NULL, (void *)name, + __find_i2c_adap); + if (!dev) { + pr_err("%s: i2c adapter %s not found on system.\n", + __func__, name); + return -ENODEV; + } + adapter = to_i2c_adapter(dev); + + return adapter->nr; +} + +static __init struct i2c_client *bms_sb_setup_eeprom_24c04( + struct i2c_adapter *adap) +{ + struct i2c_board_info info_spd = { + I2C_BOARD_INFO("24c04", 0x50), + }; + + return i2c_new_device(adap, &info_spd); +} + +static __init struct i2c_client *bms_sb_setup_tmp75( + struct i2c_adapter *adap, int addr) +{ + struct i2c_board_info info_spd = { + I2C_BOARD_INFO("tmp75", addr), + }; + + return i2c_new_device(adap, &info_spd); +} + +static __init struct i2c_client *bms_sb_setup_switch(struct i2c_adapter *adap) +{ + struct i2c_board_info info = { + I2C_BOARD_INFO("pca9548", 0x70), + .platform_data = &platdata_pca9548_mux, + }; + + return i2c_new_device(adap, &info); +} + +static __init struct i2c_client *bms_sb_setup_stage1_mux0(struct i2c_adapter *adap) +{ + struct i2c_board_info info = { + I2C_BOARD_INFO("pca9548", 0x71), + .platform_data = &platdata_stage1_pca9548_mux0, + }; + + return i2c_new_device(adap, &info); +} + +static __init struct i2c_client *bms_sb_setup_stage1_mux1(struct i2c_adapter *adap) +{ + struct i2c_board_info info = { + I2C_BOARD_INFO("pca9548", 0x72), + .platform_data = &platdata_stage1_pca9548_mux1, + }; + + return i2c_new_device(adap, &info); +} + +static __init struct i2c_client *bms_sb_setup_stage1_mux2(struct i2c_adapter *adap) +{ + struct i2c_board_info info = { + I2C_BOARD_INFO("pca9548", 0x73), + .platform_data = &platdata_stage1_pca9548_mux2, + }; + + return i2c_new_device(adap, &info); +} + +static __init struct i2c_client *bms_sb_setup_stage1_mux3(struct i2c_adapter *adap) +{ + struct i2c_board_info info = { + I2C_BOARD_INFO("pca9548", 0x74), + .platform_data = &platdata_stage1_pca9548_mux3, + }; + + return i2c_new_device(adap, &info); +} + +static __init struct i2c_client *bms_sb_setup_slave_cpld(struct i2c_adapter *adap) +{ + struct i2c_board_info info = { + I2C_BOARD_INFO("slave_cpld", 0x33), + }; + + return i2c_new_device(adap, &info); +} + +static __init struct i2c_client *bms_sb_setup_master_cpld(struct i2c_adapter *adap) +{ + struct i2c_board_info info = { + I2C_BOARD_INFO("master_cpld", 0x32), + }; + + return i2c_new_device(adap, &info); +} + +static __init struct i2c_client *bms_sb_setup_sff8436(struct i2c_adapter *adap) +{ + struct i2c_board_info info = { + I2C_BOARD_INFO("sff8436", 0x50), + }; + + return i2c_new_device(adap, &info); +} + +static int __init bms_sb_setup_devices_ismt(void) +{ + struct i2c_adapter *adap; + int adap_num = find_i2c_adapter_num(I2C_ADAPTER_ISMT); + + if (adap_num < 0) + return adap_num; + + adap = i2c_get_adapter(adap_num); + if (!adap) { + pr_err("%s failed to get i2c adap %d.\n", __func__, adap_num); + return 0; + } + + bms_sb_clients[bms_sb_client_index++] = bms_sb_setup_switch(adap); + bms_sb_clients[bms_sb_client_index++] = bms_sb_setup_master_cpld(adap); + bms_sb_clients[bms_sb_client_index++] = bms_sb_setup_slave_cpld(adap); + + return 0; +} + +static int __init bms_sb_setup_devices_stage1(void) +{ + struct i2c_adapter *adap; + int adap_num; + int parent_num; + + parent_num = find_i2c_adapter_num(I2C_ADAPTER_ISMT); + if (parent_num < 0) + return parent_num; + + /* Mux chan0 steup */ + adap_num = find_i2c_mux_adapter_num(parent_num, I2C_STAGE1_MUX_CHAN0); + if (adap_num >= 0){ + adap = i2c_get_adapter(adap_num); + if(adap) { + bms_sb_clients[bms_sb_client_index++] = bms_sb_setup_eeprom_24c04(adap); + }else{ + pr_err("%s failed to get i2c adap %d.\n", __func__, adap_num); + } + }else{ + pr_err("%s failed to find i2c mux adap number %d.\n", __func__, I2C_STAGE1_MUX_CHAN0); + } + + /* Mux chan1 connect to fan board */ + + /* Mux chan2 steup */ + adap_num = find_i2c_mux_adapter_num(parent_num, I2C_STAGE1_MUX_CHAN2); + if (adap_num >= 0){ + adap = i2c_get_adapter(adap_num); + if(adap) { + bms_sb_clients[bms_sb_client_index++] = bms_sb_setup_tmp75(adap, 0x4a); + bms_sb_clients[bms_sb_client_index++] = bms_sb_setup_tmp75(adap, 0x4b); + bms_sb_clients[bms_sb_client_index++] = bms_sb_setup_tmp75(adap, 0x4c); + }else{ + pr_err("%s failed to get i2c adap %d.\n", __func__, adap_num); + } + }else{ + pr_err("%s failed to find i2c mux adap number %d.\n", __func__, I2C_STAGE1_MUX_CHAN2); + } + + /* Mux chan3 connect to power board */ + + /* Mux chan4 setup for i2c mux0 */ + adap_num = find_i2c_mux_adapter_num(parent_num, I2C_STAGE1_MUX_CHAN4); + if (adap_num >= 0){ + adap = i2c_get_adapter(adap_num); + if(adap) { + bms_sb_clients[bms_sb_client_index++] = bms_sb_setup_stage1_mux0(adap); + }else{ + pr_err("%s failed to get i2c adap %d.\n", __func__, adap_num); + } + }else{ + pr_err("%s failed to find i2c mux adap number %d.\n", __func__, I2C_STAGE1_MUX_CHAN4); + } + + /* Mux chan5 setup for i2c mux1 */ + adap_num = find_i2c_mux_adapter_num(parent_num, I2C_STAGE1_MUX_CHAN5); + if (adap_num >= 0){ + adap = i2c_get_adapter(adap_num); + if(adap) { + bms_sb_clients[bms_sb_client_index++] = bms_sb_setup_stage1_mux1(adap); + }else{ + pr_err("%s failed to get i2c adap %d.\n", __func__, adap_num); + } + }else{ + pr_err("%s failed to find i2c mux adap number %d.\n", __func__, I2C_STAGE1_MUX_CHAN5); + } + + /* Mux chan6 setup for i2c mux2 */ + adap_num = find_i2c_mux_adapter_num(parent_num, I2C_STAGE1_MUX_CHAN6); + if (adap_num >= 0){ + adap = i2c_get_adapter(adap_num); + if(adap) { + bms_sb_clients[bms_sb_client_index++] = bms_sb_setup_stage1_mux2(adap); + }else{ + pr_err("%s failed to get i2c adap %d.\n", __func__, adap_num); + } + }else{ + pr_err("%s failed to find i2c mux adap number %d.\n", __func__, I2C_STAGE1_MUX_CHAN6); + } + + /* Mux chan7 setup for i2c mux3 */ + adap_num = find_i2c_mux_adapter_num(parent_num, I2C_STAGE1_MUX_CHAN7); + if (adap_num >= 0){ + adap = i2c_get_adapter(adap_num); + if(adap) { + bms_sb_clients[bms_sb_client_index++] = bms_sb_setup_stage1_mux3(adap); + }else{ + pr_err("%s failed to get i2c adap %d.\n", __func__, adap_num); + } + }else{ + pr_err("%s failed to find i2c mux adap number %d.\n", __func__, I2C_STAGE1_MUX_CHAN7); + } + + return 0; +} + +static int __init bms_sb_setup_devices_stage2(void) +{ + struct i2c_adapter *adap; + int adap_num; + int i2c_base = sizeof(bms_i2c_adapter_names) / sizeof(bms_i2c_adapter_names[0]); + int i; + + /* stage2 mux0 chan0~7 install sff8436 */ + for(i = I2C_STAGE2_MUX0_CHAN0; i <= I2C_STAGE2_MUX0_CHAN7; i++){ + adap_num = find_i2c_mux_adapter_num(I2C_STAGE1_MUX_CHAN4 + i2c_base, I2C_STAGE2_MUX0_CHAN0 + i); + if (adap_num >= 0){ + adap = i2c_get_adapter(adap_num); + if(adap) { + bms_sb_clients[bms_sb_client_index++] = bms_sb_setup_sff8436(adap); + }else{ + pr_err("%s failed to get i2c adap %d.\n", __func__, adap_num); + } + }else{ + pr_err("%s failed to find i2c mux adap number %d.\n", __func__, I2C_STAGE1_MUX_CHAN4 + i2c_base); + } + } + + /* stage2 mux1 chan0~7 install sff8436 */ + for(i = I2C_STAGE2_MUX1_CHAN8; i <= I2C_STAGE2_MUX1_CHAN15; i++){ + adap_num = find_i2c_mux_adapter_num(I2C_STAGE1_MUX_CHAN5 + i2c_base, I2C_STAGE2_MUX1_CHAN8 + i); + if (adap_num >= 0){ + adap = i2c_get_adapter(adap_num); + if(adap) { + bms_sb_clients[bms_sb_client_index++] = bms_sb_setup_sff8436(adap); + }else{ + pr_err("%s failed to get i2c adap %d.\n", __func__, adap_num); + } + }else{ + pr_err("%s failed to find i2c mux adap number %d.\n", __func__, I2C_STAGE1_MUX_CHAN5 + i2c_base); + } + } + + /* stage2 mux2 chan0~7 install sff8436 */ + for(i = I2C_STAGE2_MUX2_CHAN16; i <= I2C_STAGE2_MUX2_CHAN23; i++){ + adap_num = find_i2c_mux_adapter_num(I2C_STAGE1_MUX_CHAN6 + i2c_base, I2C_STAGE2_MUX2_CHAN16 + i); + if (adap_num >= 0){ + adap = i2c_get_adapter(adap_num); + if(adap) { + bms_sb_clients[bms_sb_client_index++] = bms_sb_setup_sff8436(adap); + }else{ + pr_err("%s failed to get i2c adap %d.\n", __func__, adap_num); + } + }else{ + pr_err("%s failed to find i2c mux adap number %d.\n", __func__, I2C_STAGE1_MUX_CHAN6 + i2c_base); + } + } + + /* stage2 mux3 chan0~7 install sff8436 */ + for(i = I2C_STAGE2_MUX3_CHAN24; i <= I2C_STAGE2_MUX3_CHAN31; i++){ + adap_num = find_i2c_mux_adapter_num(I2C_STAGE1_MUX_CHAN7 + i2c_base, I2C_STAGE2_MUX3_CHAN24 + i); + if (adap_num >= 0){ + adap = i2c_get_adapter(adap_num); + if(adap) { + bms_sb_clients[bms_sb_client_index++] = bms_sb_setup_sff8436(adap); + }else{ + pr_err("%s failed to get i2c adap %d.\n", __func__, adap_num); + } + }else{ + pr_err("%s failed to find i2c mux adap number %d.\n", __func__, I2C_STAGE1_MUX_CHAN7 + i2c_base); + } + } +} + +static int __init bms_sb_i2c_init(void) +{ + /* Initial bms_sb_slients array. */ + memset(bms_sb_clients, 0x0, BMS_SB_I2C_CLIENT_NUM); + + bms_sb_setup_devices_ismt(); + mdelay(200); + bms_sb_setup_devices_stage1(); + mdelay(200); + bms_sb_setup_devices_stage2(); + + return 0; +} + +static void __exit bms_sb_i2c_exit(void){ + int i; + + for (i=(bms_sb_client_index-1); i>=0; i--) { + if (bms_sb_clients[i]) { + i2c_unregister_device(bms_sb_clients[i]); + bms_sb_clients[i] = NULL; + } + } + + bms_sb_client_index = 0; + +} + +module_init(bms_sb_i2c_init); +module_exit(bms_sb_i2c_exit); + +MODULE_DESCRIPTION("mitac_ly1200_32x_sb_i2c driver"); +MODULE_AUTHOR("Eddy Weng "); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_slave_cpld.c b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_slave_cpld.c new file mode 100644 index 000000000000..8809573fa4ad --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_slave_cpld.c @@ -0,0 +1,427 @@ +#include +#include + +#include "slave_cpld_reg.h" +#include "slave_cpld_sysfs.h" + +static int debug_flag = 0; + +struct slave_cpld_data { + struct mutex lock; + + struct i2c_client *client; + struct device_attribute bin; +}; + + +static const struct i2c_device_id slave_cpld_ids[] = { + { "slave_cpld", 0 }, + { /* END OF LIST */ } +}; +MODULE_DEVICE_TABLE(i2c, slave_cpld_ids); + +static int slave_cpld_raw_read(struct device *dev, struct device_attribute *attr, char *buf, + int reg_offset, int reg_width, int fld_shift, int fld_width, int fld_mask, char* reg_name){ + unsigned int reg_val = 0, fld_val; + static int debug_flag; + struct slave_cpld_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + int err; + + if (reg_width != 8){ + printk("%s: Register table width setting failed.\n", reg_name); + return -EINVAL; + } + mutex_lock(&data->lock); + if ((err = i2c_smbus_read_byte_data(client, (u8)reg_offset)) < 0) { + /* CPLD read error condition */; + mutex_unlock(&data->lock); + printk("%s: i2c read failed, error code = %d.\n", reg_name, err); + return err; + } + reg_val = err; + if (debug_flag) { + printk("%s: reg_offset = %d, width = %d, cur value = 0x%x.\n", reg_name, reg_offset, reg_width, reg_val); + } + mutex_unlock(&data->lock); + if (fld_width == reg_width) {fld_val = reg_val & fld_mask;} + else {fld_val = (reg_val >> fld_shift) & fld_mask;} + return sprintf(buf, "0x%x\n", fld_val); +} + +static int slave_cpld_raw_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count, + int reg_offset, int reg_width, int fld_shift, int fld_width, int fld_mask, char* reg_name){ + int ret_code; + unsigned int reg_val, fld_val; + unsigned long val; + static int debug_flag; + struct slave_cpld_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + if (reg_width != 8){ + printk("%s: Register table width setting failed.\n", reg_name); + return -EINVAL; + } + /* Parse buf and store to fld_val */ + if ((ret_code = kstrtoul(buf, 16, &val))){ + printk("%s: Conversion value = %s failed, errno = %d.\n", reg_name, buf, ret_code); + return ret_code; + } + fld_val = (unsigned int)val; + mutex_lock(&data->lock); + if ((ret_code = i2c_smbus_read_byte_data(client, (u8)reg_offset)) < 0) { + /* Handle CPLD read error condition */; + mutex_unlock(&data->lock); + printk("%s: i2c read failed, error code = %d.\n", reg_name, ret_code); + return ret_code; + } + reg_val = ret_code; + if (debug_flag) { + printk("%s: offset = %d, width = %d, cur value = 0x%x.\n", reg_name, reg_offset, reg_width, reg_val); + } + if (fld_width == reg_width) {reg_val = fld_val & fld_mask;} + else {reg_val = (reg_val & ~(fld_mask << fld_shift)) | + ((fld_val & (fld_mask)) << fld_shift);} + if ((ret_code = i2c_smbus_write_byte_data(client, (u8)reg_offset, (u8)reg_val)) != 0) { + /* Handle CPLD write error condition */; + mutex_unlock(&data->lock); + printk("%s: i2c write failed, error code = %d.\n", reg_name, ret_code); + return ret_code; + } + else if (debug_flag) { + printk("%s: offset = %d, width = %d, new value = 0x%x.\n", reg_name, reg_offset, reg_width, reg_val); + } + mutex_unlock(&data->lock); + return count; +} + +/*--------------------special file for debug---------------------- */ +static ssize_t slave_cpld_debug_read(struct device *dev, struct device_attribute *attr, + char *buf){ + + return sprintf(buf, "%d\n", debug_flag); +} + + +static ssize_t slave_cpld_debug_write(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + int temp; + int error; + + error = kstrtoint(buf, 10, &temp); + if (error){ + printk(KERN_INFO "%s: Conversion value = %s failed.\n", __FUNCTION__, buf); + return count; + } + debug_flag = temp; + + if(debug_flag) + printk("%s, debug_flag = %d\n", __FUNCTION__, debug_flag); + + return count; +} +SYSFS_MISC_RW_ATTR_DEF(debug, slave_cpld_debug_read, slave_cpld_debug_write) + + + + +/* ----------------define port group---------------------------- */ +static struct attribute *port17_attributes[] = { + SYSFS_ATTR_PTR(port17_present), /* register: zqsfp28_present_24_17_status */ + SYSFS_ATTR_PTR(port17_rst), /* register: zqsfp28_rst_24_17 */ + SYSFS_ATTR_PTR(port17_modsel), /* register: zqsfp28_modsel_24_17 */ + SYSFS_ATTR_PTR(port17_lpmode), /* register: zqsfp28_lpmode_24_17 */ + SYSFS_ATTR_PTR(port17_irq_status), /* register: zqsfp28_irq_24_17_status */ + SYSFS_ATTR_PTR(port17_irq_msk), /* register: zqsfp28_irq_msk_24_17_status */ + NULL +}; + +static struct attribute *port18_attributes[] = { + SYSFS_ATTR_PTR(port18_present), /* register: zqsfp28_present_24_17_status */ + SYSFS_ATTR_PTR(port18_rst), /* register: zqsfp28_rst_24_17 */ + SYSFS_ATTR_PTR(port18_modsel), /* register: zqsfp28_modsel_24_17 */ + SYSFS_ATTR_PTR(port18_lpmode), /* register: zqsfp28_lpmode_24_17 */ + SYSFS_ATTR_PTR(port18_irq_status), /* register: zqsfp28_irq_24_17_status */ + SYSFS_ATTR_PTR(port18_irq_msk), /* register: zqsfp28_irq_msk_24_17_status */ + NULL +}; + +static struct attribute *port19_attributes[] = { + SYSFS_ATTR_PTR(port19_present), /* register: zqsfp28_present_24_17_status */ + SYSFS_ATTR_PTR(port19_rst), /* register: zqsfp28_rst_24_17 */ + SYSFS_ATTR_PTR(port19_modsel), /* register: zqsfp28_modsel_24_17 */ + SYSFS_ATTR_PTR(port19_lpmode), /* register: zqsfp28_lpmode_24_17 */ + SYSFS_ATTR_PTR(port19_irq_status), /* register: zqsfp28_irq_24_17_status */ + SYSFS_ATTR_PTR(port19_irq_msk), /* register: zqsfp28_irq_msk_24_17_status */ + NULL +}; + +static struct attribute *port20_attributes[] = { + SYSFS_ATTR_PTR(port20_present), /* register: zqsfp28_present_24_17_status */ + SYSFS_ATTR_PTR(port20_rst), /* register: zqsfp28_rst_24_17 */ + SYSFS_ATTR_PTR(port20_modsel), /* register: zqsfp28_modsel_24_17 */ + SYSFS_ATTR_PTR(port20_lpmode), /* register: zqsfp28_lpmode_24_17 */ + SYSFS_ATTR_PTR(port20_irq_status), /* register: zqsfp28_irq_24_17_status */ + SYSFS_ATTR_PTR(port20_irq_msk), /* register: zqsfp28_irq_msk_24_17_status */ + NULL +}; + +static struct attribute *port21_attributes[] = { + SYSFS_ATTR_PTR(port21_present), /* register: zqsfp28_present_24_17_status */ + SYSFS_ATTR_PTR(port21_rst), /* register: zqsfp28_rst_24_17 */ + SYSFS_ATTR_PTR(port21_modsel), /* register: zqsfp28_modsel_24_17 */ + SYSFS_ATTR_PTR(port21_lpmode), /* register: zqsfp28_lpmode_24_17 */ + SYSFS_ATTR_PTR(port21_irq_status), /* register: zqsfp28_irq_24_17_status */ + SYSFS_ATTR_PTR(port21_irq_msk), /* register: zqsfp28_irq_msk_24_17_status */ + NULL +}; + +static struct attribute *port22_attributes[] = { + SYSFS_ATTR_PTR(port22_present), /* register: zqsfp28_present_24_17_status */ + SYSFS_ATTR_PTR(port22_rst), /* register: zqsfp28_rst_24_17 */ + SYSFS_ATTR_PTR(port22_modsel), /* register: zqsfp28_modsel_24_17 */ + SYSFS_ATTR_PTR(port22_lpmode), /* register: zqsfp28_lpmode_24_17 */ + SYSFS_ATTR_PTR(port22_irq_status), /* register: zqsfp28_irq_24_17_status */ + SYSFS_ATTR_PTR(port22_irq_msk), /* register: zqsfp28_irq_msk_24_17_status */ + NULL +}; + +static struct attribute *port23_attributes[] = { + SYSFS_ATTR_PTR(port23_present), /* register: zqsfp28_present_24_17_status */ + SYSFS_ATTR_PTR(port23_rst), /* register: zqsfp28_rst_24_17 */ + SYSFS_ATTR_PTR(port23_modsel), /* register: zqsfp28_modsel_24_17 */ + SYSFS_ATTR_PTR(port23_lpmode), /* register: zqsfp28_lpmode_24_17 */ + SYSFS_ATTR_PTR(port23_irq_status), /* register: zqsfp28_irq_24_17_status */ + SYSFS_ATTR_PTR(port23_irq_msk), /* register: zqsfp28_irq_msk_24_17_status */ + NULL +}; + +static struct attribute *port24_attributes[] = { + SYSFS_ATTR_PTR(port24_present), /* register: zqsfp28_present_24_17_status */ + SYSFS_ATTR_PTR(port24_rst), /* register: zqsfp28_rst_24_17 */ + SYSFS_ATTR_PTR(port24_modsel), /* register: zqsfp28_modsel_24_17 */ + SYSFS_ATTR_PTR(port24_lpmode), /* register: zqsfp28_lpmode_24_17 */ + SYSFS_ATTR_PTR(port24_irq_status), /* register: zqsfp28_irq_24_17_status */ + SYSFS_ATTR_PTR(port24_irq_msk), /* register: zqsfp28_irq_msk_24_17_status */ + NULL +}; + +static struct attribute *port25_attributes[] = { + SYSFS_ATTR_PTR(port25_present), /* register: zqsfp28_present_32_25_status */ + SYSFS_ATTR_PTR(port25_rst), /* register: zqsfp28_rst_32_25 */ + SYSFS_ATTR_PTR(port25_modsel), /* register: zqsfp28_modsel_32_25 */ + SYSFS_ATTR_PTR(port25_lpmode), /* register: zqsfp28_lpmode_32_25 */ + SYSFS_ATTR_PTR(port25_irq_status), /* register: zqsfp28_irq_32_25_status */ + SYSFS_ATTR_PTR(port25_irq_msk), /* register: zqsfp28_irq_msk_32_25_status */ + NULL +}; + +static struct attribute *port26_attributes[] = { + SYSFS_ATTR_PTR(port26_present), /* register: zqsfp28_present_32_25_status */ + SYSFS_ATTR_PTR(port26_rst), /* register: zqsfp28_rst_32_25 */ + SYSFS_ATTR_PTR(port26_modsel), /* register: zqsfp28_modsel_32_25 */ + SYSFS_ATTR_PTR(port26_lpmode), /* register: zqsfp28_lpmode_32_25 */ + SYSFS_ATTR_PTR(port26_irq_status), /* register: zqsfp28_irq_32_25_status */ + SYSFS_ATTR_PTR(port26_irq_msk), /* register: zqsfp28_irq_msk_32_25_status */ + NULL +}; + +static struct attribute *port27_attributes[] = { + SYSFS_ATTR_PTR(port27_present), /* register: zqsfp28_present_32_25_status */ + SYSFS_ATTR_PTR(port27_rst), /* register: zqsfp28_rst_32_25 */ + SYSFS_ATTR_PTR(port27_modsel), /* register: zqsfp28_modsel_32_25 */ + SYSFS_ATTR_PTR(port27_lpmode), /* register: zqsfp28_lpmode_32_25 */ + SYSFS_ATTR_PTR(port27_irq_status), /* register: zqsfp28_irq_32_25_status */ + SYSFS_ATTR_PTR(port27_irq_msk), /* register: zqsfp28_irq_msk_32_25_status */ + NULL +}; + +static struct attribute *port28_attributes[] = { + SYSFS_ATTR_PTR(port28_present), /* register: zqsfp28_present_32_25_status */ + SYSFS_ATTR_PTR(port28_rst), /* register: zqsfp28_rst_32_25 */ + SYSFS_ATTR_PTR(port28_modsel), /* register: zqsfp28_modsel_32_25 */ + SYSFS_ATTR_PTR(port28_lpmode), /* register: zqsfp28_lpmode_32_25 */ + SYSFS_ATTR_PTR(port28_irq_status), /* register: zqsfp28_irq_32_25_status */ + SYSFS_ATTR_PTR(port28_irq_msk), /* register: zqsfp28_irq_msk_32_25_status */ + NULL +}; + +static struct attribute *port29_attributes[] = { + SYSFS_ATTR_PTR(port29_present), /* register: zqsfp28_present_32_25_status */ + SYSFS_ATTR_PTR(port29_rst), /* register: zqsfp28_rst_32_25 */ + SYSFS_ATTR_PTR(port29_modsel), /* register: zqsfp28_modsel_32_25 */ + SYSFS_ATTR_PTR(port29_lpmode), /* register: zqsfp28_lpmode_32_25 */ + SYSFS_ATTR_PTR(port29_irq_status), /* register: zqsfp28_irq_32_25_status */ + SYSFS_ATTR_PTR(port29_irq_msk), /* register: zqsfp28_irq_msk_32_25_status */ + NULL +}; + +static struct attribute *port30_attributes[] = { + SYSFS_ATTR_PTR(port30_present), /* register: zqsfp28_present_32_25_status */ + SYSFS_ATTR_PTR(port30_rst), /* register: zqsfp28_rst_32_25 */ + SYSFS_ATTR_PTR(port30_modsel), /* register: zqsfp28_modsel_32_25 */ + SYSFS_ATTR_PTR(port30_lpmode), /* register: zqsfp28_lpmode_32_25 */ + SYSFS_ATTR_PTR(port30_irq_status), /* register: zqsfp28_irq_32_25_status */ + SYSFS_ATTR_PTR(port30_irq_msk), /* register: zqsfp28_irq_msk_32_25_status */ + NULL +}; + +static struct attribute *port31_attributes[] = { + SYSFS_ATTR_PTR(port31_present), /* register: zqsfp28_present_32_25_status */ + SYSFS_ATTR_PTR(port31_rst), /* register: zqsfp28_rst_32_25 */ + SYSFS_ATTR_PTR(port31_modsel), /* register: zqsfp28_modsel_32_25 */ + SYSFS_ATTR_PTR(port31_lpmode), /* register: zqsfp28_lpmode_32_25 */ + SYSFS_ATTR_PTR(port31_irq_status), /* register: zqsfp28_irq_32_25_status */ + SYSFS_ATTR_PTR(port31_irq_msk), /* register: zqsfp28_irq_msk_32_25_status */ + NULL +}; + +static struct attribute *port32_attributes[] = { + SYSFS_ATTR_PTR(port32_present), /* register: zqsfp28_present_32_25_status */ + SYSFS_ATTR_PTR(port32_rst), /* register: zqsfp28_rst_32_25 */ + SYSFS_ATTR_PTR(port32_modsel), /* register: zqsfp28_modsel_32_25 */ + SYSFS_ATTR_PTR(port32_lpmode), /* register: zqsfp28_lpmode_32_25 */ + SYSFS_ATTR_PTR(port32_irq_status), /* register: zqsfp28_irq_32_25_status */ + SYSFS_ATTR_PTR(port32_irq_msk), /* register: zqsfp28_irq_msk_32_25_status */ + NULL +}; + +static const struct attribute_group slave_cpld_port_group[] = { + {.attrs = port17_attributes, + .name = "port17",}, + {.attrs = port18_attributes, + .name = "port18",}, + {.attrs = port19_attributes, + .name = "port19",}, + {.attrs = port20_attributes, + .name = "port20",}, + {.attrs = port21_attributes, + .name = "port21",}, + {.attrs = port22_attributes, + .name = "port22",}, + {.attrs = port23_attributes, + .name = "port23",}, + {.attrs = port24_attributes, + .name = "port24",}, + {.attrs = port25_attributes, + .name = "port25",}, + {.attrs = port26_attributes, + .name = "port26",}, + {.attrs = port27_attributes, + .name = "port27",}, + {.attrs = port28_attributes, + .name = "port28",}, + {.attrs = port29_attributes, + .name = "port29",}, + {.attrs = port30_attributes, + .name = "port30",}, + {.attrs = port31_attributes, + .name = "port31",}, + {.attrs = port32_attributes, + .name = "port32",} +}; + +/* ----------------define misc group---------------------------- */ +static struct attribute *misc_attributes[] = { + SYSFS_ATTR_PTR(mjr_rev), /* register: slv_cpld_rev */ + SYSFS_ATTR_PTR(mnr_rev), /* register: slv_cpld_rev */ + SYSFS_ATTR_PTR(scrtch_reg), /* register: slv_cpld_gpr */ + SYSFS_ATTR_PTR(brd_rev), /* register: mb_brd_rev_type */ + SYSFS_ATTR_PTR(brd_type), /* register: mb_brd_rev_type */ + + SYSFS_ATTR_PTR(port_17_24_present), /* register: zqsfp28_present_24_17_status */ + SYSFS_ATTR_PTR(port_25_32_present), /* register: zqsfp28_present_32_25_status */ + SYSFS_ATTR_PTR(port_17_24_rst), /* register: zqsfp28_rst_24_17 */ + SYSFS_ATTR_PTR(port_25_32_rst), /* register: zqsfp28_rst_32_25 */ + SYSFS_ATTR_PTR(port_17_24_modsel), /* register: zqsfp28_modsel_24_17 */ + SYSFS_ATTR_PTR(port_25_32_modsel), /* register: zqsfp28_modsel_32_25 */ + SYSFS_ATTR_PTR(port_17_24_irq_status),/* register: zqsfp28_irq_24_17_status */ + SYSFS_ATTR_PTR(port_25_32_irq_status),/* register: zqsfp28_irq_32_25_status */ + SYSFS_ATTR_PTR(port_17_24_irq_msk), /* register: zqsfp28_irq_msk_24_17_status */ + SYSFS_ATTR_PTR(port_25_32_irq_msk), /* register: zqsfp28_irq_msk_32_25_status */ + SYSFS_ATTR_PTR(port_17_24_lpmode), /* register: zqsfp28_lpmode_24_17 */ + SYSFS_ATTR_PTR(port_25_32_lpmode), /* register: zqsfp28_lpmode_32_25 */ + + SYSFS_ATTR_PTR(debug), /* debug flag for print more messages */ + NULL +}; +static const struct attribute_group slave_cpld_group_misc = { + .attrs = misc_attributes, +}; + +static int slave_cpld_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct slave_cpld_data *slave_cpld; + int err, i; + int grp_number = (int)( sizeof(slave_cpld_port_group) / sizeof(slave_cpld_port_group[0])); + + /* allocate memory to slave_cpld */ + slave_cpld = devm_kzalloc(&client->dev, sizeof(struct slave_cpld_data) , GFP_KERNEL); + + if (!slave_cpld) + return -ENOMEM; + + mutex_init(&slave_cpld->lock); + + for(i = 0 ; i < grp_number ; i++){ + err = sysfs_create_group(&client->dev.kobj, &slave_cpld_port_group[i]); + if (err){ + printk("%s: Error creeat port group %d.\n", __FUNCTION__, i+1); + } + } + err = sysfs_create_group(&client->dev.kobj, &slave_cpld_group_misc); + if (err){ + printk("%s: Error creeat misc group.\n", __FUNCTION__); + } + + slave_cpld->client = client; + i2c_set_clientdata(client, slave_cpld); + + printk(KERN_INFO "%s: Slave CPLD LCMXO3LF created.\n", __FUNCTION__); + + return 0; + +} + +static int slave_cpld_remove(struct i2c_client *client) +{ + int i; + int grp_number = (int)( sizeof(slave_cpld_port_group) / sizeof(slave_cpld_port_group[0])); + + for(i = 0 ; i < grp_number ; i++){ + sysfs_remove_group(&client->dev.kobj, &slave_cpld_port_group[i]); + } + sysfs_remove_group(&client->dev.kobj, &slave_cpld_group_misc); + + printk(KERN_INFO "%s: Slave CPLD removed.\n", __FUNCTION__); + return 0; +} + +static struct i2c_driver slave_cpld_driver = { + .driver = { + .name = "slave_cpld", + .owner = THIS_MODULE, + }, + .probe = slave_cpld_probe, + .remove = slave_cpld_remove, + .id_table = slave_cpld_ids, +}; + +static int __init slave_cpld_init(void) +{ + printk(KERN_INFO "%s: init.\n", __FUNCTION__); + return i2c_add_driver(&slave_cpld_driver); +} +module_init(slave_cpld_init); + +static void __exit slave_cpld_exit(void) +{ + printk(KERN_INFO "%s: exit.\n", __FUNCTION__); + i2c_del_driver(&slave_cpld_driver); +} +module_exit(slave_cpld_exit); + +MODULE_DESCRIPTION("mitac_ly1200_32x_slave_cpld driver"); +MODULE_AUTHOR("Eddy Weng "); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_system_cpld.c b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_system_cpld.c new file mode 100644 index 000000000000..e5af8b70bf9a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/mitac_ly1200_32x_system_cpld.c @@ -0,0 +1,541 @@ +#define CONFIG_DRV_SYSCPLD_WDT 1 + +#include +#include + +#include "system_cpld_reg.h" +#include "system_cpld_sysfs.h" +#ifdef CONFIG_DRV_SYSCPLD_WDT +#include +#include +#include +#include +#include +#include +#endif + +static int debug_flag = 0; + +struct system_cpld_data { + struct mutex lock; + + struct i2c_client *client; + struct device_attribute bin; +}; +struct system_cpld_data *system_cpld; + +static const struct i2c_device_id system_cpld_ids[] = { + { "system_cpld", 0 }, + { /* END OF LIST */ } +}; +MODULE_DEVICE_TABLE(i2c, system_cpld_ids); + +static int system_cpld_raw_read(struct device *dev, struct device_attribute *attr, char *buf, + int reg_offset, int reg_width, int fld_shift, int fld_width, int fld_mask, char* reg_name){ + unsigned int reg_val = 0, fld_val; + static int debug_flag; + struct system_cpld_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + int err; + + if (reg_width != 8){ + printk("%s: Register table width setting failed.\n", reg_name); + return -EINVAL; + } + mutex_lock(&data->lock); + if ((err = i2c_smbus_read_byte_data(client, (u8)reg_offset)) < 0) { + /* CPLD read error condition */; + mutex_unlock(&data->lock); + printk("%s: i2c read failed, error code = %d.\n", reg_name, err); + return err; + } + reg_val = err; + if (debug_flag) { + printk("%s: reg_offset = %d, width = %d, cur value = 0x%x.\n", reg_name, reg_offset, reg_width, reg_val); + } + mutex_unlock(&data->lock); + if (fld_width == reg_width) {fld_val = reg_val & fld_mask;} + else {fld_val = (reg_val >> fld_shift) & fld_mask;} + return sprintf(buf, "0x%x\n", fld_val); +} + +static int system_cpld_raw_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count, + int reg_offset, int reg_width, int fld_shift, int fld_width, int fld_mask, char* reg_name){ + int ret_code; + unsigned int reg_val, fld_val; + unsigned long val; + static int debug_flag; + struct system_cpld_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + if (reg_width != 8){ + printk("%s: Register table width setting failed.\n", reg_name); + return -EINVAL; + } + /* Parse buf and store to fld_val */ + if ((ret_code = kstrtoul(buf, 16, &val))){ + printk("%s: Conversion value = %s failed, errno = %d.\n", reg_name, buf, ret_code); + return ret_code; + } + fld_val = (unsigned int)val; + mutex_lock(&data->lock); + if ((ret_code = i2c_smbus_read_byte_data(client, (u8)reg_offset)) < 0) { + /* Handle CPLD read error condition */; + mutex_unlock(&data->lock); + printk("%s: i2c read failed, error code = %d.\n", reg_name, ret_code); + return ret_code; + } + reg_val = ret_code; + if (debug_flag) { + printk("%s: offset = %d, width = %d, cur value = 0x%x.\n", reg_name, reg_offset, reg_width, reg_val); + } + if (fld_width == reg_width) {reg_val = fld_val & fld_mask;} + else {reg_val = (reg_val & ~(fld_mask << fld_shift)) | + ((fld_val & (fld_mask)) << fld_shift);} + if ((ret_code = i2c_smbus_write_byte_data(client, (u8)reg_offset, (u8)reg_val)) != 0) { + /* Handle CPLD write error condition */; + mutex_unlock(&data->lock); + printk("%s: i2c write failed, error code = %d.\n", reg_name, ret_code); + return ret_code; + } + else if (debug_flag) { + printk("%s: offset = %d, width = %d, new value = 0x%x.\n", reg_name, reg_offset, reg_width, reg_val); + } + mutex_unlock(&data->lock); + return count; +} + +/*--------------------special file for debug---------------------- */ +static ssize_t system_cpld_debug_read(struct device *dev, struct device_attribute *attr, + char *buf){ + + return sprintf(buf, "%d\n", debug_flag); +} + + +static ssize_t system_cpld_debug_write(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + int temp; + int error; + + error = kstrtoint(buf, 10, &temp); + if (error){ + printk(KERN_INFO "%s: Conversion value = %s failed.\n", __FUNCTION__, buf); + return count; + } + debug_flag = temp; + + if(debug_flag) + printk("%s, debug_flag = %d\n", __FUNCTION__, debug_flag); + + return count; +} +SYSFS_MISC_RW_ATTR_DEF(debug, system_cpld_debug_read, system_cpld_debug_write) + + +/* ----------------define misc group---------------------------- */ +static struct attribute *misc_attributes[] = { + SYSFS_ATTR_PTR(mjr_rev), /* register: sys_cpld_rev */ + SYSFS_ATTR_PTR(mnr_rev), /* register: sys_cpld_rev */ + + SYSFS_ATTR_PTR(scrtch_reg), /* register: sys_cpld_gpr */ + + SYSFS_ATTR_PTR(brd_rev), /* register: cpu_brd_rev_type */ + SYSFS_ATTR_PTR(brd_type), /* register: cpu_brd_rev_type */ + + SYSFS_ATTR_PTR(ssd_present), /* register: sys_srr */ + SYSFS_ATTR_PTR(spi_cs_sel), /* register: sys_srr */ + SYSFS_ATTR_PTR(rst_bios_switch), /* register: sys_srr */ + SYSFS_ATTR_PTR(cpld_upgrade_rst), /* register: sys_srr */ + + SYSFS_ATTR_PTR(cpld_spi_wp), /* register: sys_eeprom_wp */ + SYSFS_ATTR_PTR(system_id_eeprom_wp), /* register: sys_eeprom_wp */ + SYSFS_ATTR_PTR(spi_me_wp), /* register: sys_eeprom_wp */ + SYSFS_ATTR_PTR(spi_bios_wp), /* register: sys_eeprom_wp */ + SYSFS_ATTR_PTR(spi_bak_bios_wp), /* register: sys_eeprom_wp */ + + SYSFS_ATTR_PTR(vrhot_irq_en), /* register: sys_irq */ + SYSFS_ATTR_PTR(cpu_thermtrip_irq_en), /* register: sys_irq */ + SYSFS_ATTR_PTR(temp_alert_irq_en), /* register: sys_irq */ + SYSFS_ATTR_PTR(vrhot_irq), /* register: sys_irq */ + SYSFS_ATTR_PTR(cpu_thermtrip_irq), /* register: sys_irq */ + SYSFS_ATTR_PTR(temp_alert_irq), /* register: sys_irq */ + + SYSFS_ATTR_PTR(wd_timer), /* register: sys_wd */ + SYSFS_ATTR_PTR(wd_en), /* register: sys_wd */ + SYSFS_ATTR_PTR(wd_punch), /* register: sys_wd */ + + SYSFS_ATTR_PTR(mb_rst_en), /* register: sys_mb_rst_en */ + + SYSFS_ATTR_PTR(pwr_v3p3_en), /* register: cpu_pwr_en_status */ + SYSFS_ATTR_PTR(pwr_vcc_vnn_en), /* register: cpu_pwr_en_status */ + SYSFS_ATTR_PTR(pwr_vccsram_en), /* register: cpu_pwr_en_status */ + SYSFS_ATTR_PTR(pwr_vddq_en), /* register: cpu_pwr_en_status */ + SYSFS_ATTR_PTR(pwr_vcc_ref_en), /* register: cpu_pwr_en_status */ + SYSFS_ATTR_PTR(pwr_v1p05_en), /* register: cpu_pwr_en_status */ + SYSFS_ATTR_PTR(pwr_v1p8_en), /* register: cpu_pwr_en_status */ + SYSFS_ATTR_PTR(pwr_v2p5_en), /* register: cpu_pwr_en_status */ + + SYSFS_ATTR_PTR(pg_v3p3), /* register: cpu_pwr_status */ + SYSFS_ATTR_PTR(pg_vcc_vnn), /* register: cpu_pwr_status */ + SYSFS_ATTR_PTR(pg_vccsram), /* register: cpu_pwr_status */ + SYSFS_ATTR_PTR(pg_vddq), /* register: cpu_pwr_status */ + SYSFS_ATTR_PTR(pg_vcc_ref), /* register: cpu_pwr_status */ + SYSFS_ATTR_PTR(pg_v1p05), /* register: cpu_pwr_status */ + SYSFS_ATTR_PTR(pg_v1p8), /* register: cpu_pwr_status */ + SYSFS_ATTR_PTR(pg_v2p5), /* register: cpu_pwr_status */ + + SYSFS_ATTR_PTR(debug), /* debug flag for print more messages */ + NULL +}; +static const struct attribute_group system_cpld_group_misc = { + .attrs = misc_attributes, +}; + +#ifdef CONFIG_DRV_SYSCPLD_WDT +/* + ***************************************************************************** + * + * Watchdog Driver + * + ***************************************************************************** + */ +/* wdt_timeout[] are defined by CPLD spec , -1 means researved + 300 sec is not supported */ +int wdt_timeout[]={15,30,60,90,120,180,240,300,-1,-1,-1,-1,-1,-1,-1,-1}; +#define WD_TIMO_MAX_NUM 16 +/* Default margin */ +#define WD_TIMO 30 + +static int wdt_margin = WD_TIMO; +module_param(wdt_margin, int, 0); +MODULE_PARM_DESC(wdt_margin, "Watchdog timeout in seconds (default " + __MODULE_STRING(WD_TIMO) "s)"); + +static unsigned long wdt_is_open; +static int boot_flag; + +/** + * wdt_ping: + * + * Reload counter one with the watchdog timeout. We don't bother reloading + * the cascade counter. + */ +static void wdt_ping(void) +{ + struct device *dev = &system_cpld->client->dev; + struct device_attribute *fake_attr=NULL; + char *buf="0";/* 0: punch is defined by CPLD spec */ + int err; + err = system_cpld_wd_punch_raw_write(dev, fake_attr, buf, (size_t)0); + if(err < 0){ + system_cpld_wd_punch_raw_write(dev, fake_attr, buf, (size_t)0); + } +} + +/** + * wdt_disable: + * + * disables watchdog. + */ +static void wdt_disable(void) +{ + struct device *dev = &system_cpld->client->dev; + struct device_attribute *fake_attr=NULL; + char *buf="0";/* 0: disable is defined by CPLD spec */ + int err; + err = system_cpld_wd_en_raw_write(dev, fake_attr, buf, (size_t)0); + if(err < 0){ + system_cpld_wd_en_raw_write(dev, fake_attr, buf, (size_t)0); + } +} + +/** + * wdt_enable: + * + * enables watchdog. + */ +static void wdt_enable(void) +{ + struct device *dev = &system_cpld->client->dev; + struct device_attribute *fake_attr=NULL; + char *buf="1";/* 1: enable is defined by CPLD spec */ + int err; + err = system_cpld_wd_en_raw_write(dev, fake_attr, buf, (size_t)0); + if(err < 0){ + system_cpld_wd_en_raw_write(dev, fake_attr, buf, (size_t)0); + } +} + +/** + * wdt_set_timeout: + * + * set watchdog timeout. + */ +static void wdt_set_timeout(int index) +{ + struct device *dev = &system_cpld->client->dev; + struct device_attribute *fake_attr=NULL; + char buf[1]; + if ( WD_TIMO_MAX_NUM == 16 ) { + sprintf(buf,"%x",index); + system_cpld_wd_timer_raw_write(dev, fake_attr, buf, (size_t)0); + } + else + printk(KERN_INFO "%s: It is out of spec.\n", __FUNCTION__); +} + +/** + * wdt_write: + * @file: file handle to the watchdog + * @buf: buffer to write (unused as data does not matter here + * @count: count of bytes + * @ppos: pointer to the position to write. No seeks allowed + * + * A write to a watchdog device is defined as a keepalive signal. Any + * write of data will do, as we we don't define content meaning. + */ +static ssize_t wdt_write(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + if (count) { + wdt_ping(); + return 1; + } + return 0; +} + +/** + * wdt_ioctl: + * @inode: inode of the device + * @file: file handle to the device + * @cmd: watchdog command + * @arg: argument pointer + * + * The watchdog API defines a common set of functions for all watchdogs + * according to their available features. We only actually usefully support + * querying capabilities and current status. + */ +static int wdt_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + int new_margin, rv, i; + static struct watchdog_info ident = { + .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT, + .firmware_version = 1, + .identity = "SYS_CPLD WTD" + }; + + switch (cmd) { + case WDIOC_GETSUPPORT: + return copy_to_user((struct watchdog_info __user *)arg, &ident, + sizeof(ident)) ? -EFAULT : 0; + + case WDIOC_GETSTATUS: + case WDIOC_GETBOOTSTATUS: + return put_user(boot_flag, (int __user *)arg); + case WDIOC_KEEPALIVE: + wdt_ping(); + return 0; + case WDIOC_SETTIMEOUT: + if (get_user(new_margin, (int __user *)arg)) + return -EFAULT; + /* Arbitrary, can't find the card's limits */ + if (new_margin <= 1) + return -EINVAL; + for( i=0; i= WD_TIMO_MAX_NUM || i < 0 ) + return -EINVAL; + wdt_set_timeout(i); + case WDIOC_GETTIMEOUT: + return put_user(wdt_margin, (int __user *)arg); + + case WDIOC_SETOPTIONS: + if (copy_from_user(&rv, (int __user *)arg, sizeof(int))) + return -EFAULT; + + if (rv & WDIOS_DISABLECARD) { + pr_info("System CPLD: disable watchdog\n"); + wdt_disable(); + } + + if (rv & WDIOS_ENABLECARD) { + pr_info("System CPLD: enable watchdog\n"); + wdt_enable(); + } + return -EINVAL; + } + return -ENOTTY; +} + +static long wdt_unlocked_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + int ret; + + ret = wdt_ioctl(file, cmd, arg); + + return ret; +} + +/** + * wdt_open: + * @inode: inode of device + * @file: file handle to device + * + */ +static int wdt_open(struct inode *inode, struct file *file) +{ + if (MINOR(inode->i_rdev) == WATCHDOG_MINOR) { + if (test_and_set_bit(0, &wdt_is_open)) { + return -EBUSY; + } + /* + * Activate + */ + + wdt_enable(); + return nonseekable_open(inode, file); + } + return -ENODEV; +} + +/** + * wdt_close: + * @inode: inode to board + * @file: file handle to board + * + */ +static int wdt_release(struct inode *inode, struct file *file) +{ + if (MINOR(inode->i_rdev) == WATCHDOG_MINOR) + clear_bit(0, &wdt_is_open); + return 0; +} + +/** + * notify_sys: + * @this: our notifier block + * @code: the event being reported + * @unused: unused + * + * Our notifier is called on system shutdowns. We want to turn the card + * off at reboot otherwise the machine will reboot again during memory + * test or worse yet during the following fsck. This would suck, in fact + * trust me - if it happens it does suck. + */ +static int wdt_notify_sys(struct notifier_block *this, unsigned long code, + void *unused) +{ + if (code == SYS_DOWN || code == SYS_HALT) + /* Disable Watchdog */ + wdt_disable(); + return NOTIFY_DONE; +} + +static const struct file_operations wdt_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .write = wdt_write, + .unlocked_ioctl = wdt_unlocked_ioctl, + .open = wdt_open, + .release = wdt_release, +}; + +static struct miscdevice wdt_dev = { + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &wdt_fops, +}; + +/* + * The WDT card needs to learn about soft shutdowns in order to + * turn the timebomb registers off. + */ +static struct notifier_block wdt_notifier = { + .notifier_call = wdt_notify_sys, +}; +#endif /* CONFIG_DRV_SYSCPLD_WDT */ + +static int system_cpld_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + int err; + + /* allocate memory to system_cpld */ + system_cpld = devm_kzalloc(&client->dev, sizeof(struct system_cpld_data) , GFP_KERNEL); + + if (!system_cpld) + return -ENOMEM; + + mutex_init(&system_cpld->lock); + + err = sysfs_create_group(&client->dev.kobj, &system_cpld_group_misc); + if (err){ + printk("%s: Error creeat misc group.\n", __FUNCTION__); + } + + system_cpld->client = client; + i2c_set_clientdata(client, system_cpld); + + printk(KERN_INFO "%s: System CPLD LCMXO3LF created.\n", __FUNCTION__); + +#ifdef CONFIG_DRV_SYSCPLD_WDT + err = misc_register(&wdt_dev); + if (err) + return err; + err = register_reboot_notifier(&wdt_notifier); + if (err) { + misc_deregister(&wdt_dev); + return err; + } + printk(KERN_INFO "%s: System CPLD watchdog created.\n", __FUNCTION__); +#endif + + return 0; + +} + +static int system_cpld_remove(struct i2c_client *client) +{ +#ifdef CONFIG_DRV_SYSCPLD_WDT + misc_deregister(&wdt_dev); + unregister_reboot_notifier(&wdt_notifier); +#endif + sysfs_remove_group(&client->dev.kobj, &system_cpld_group_misc); + + printk(KERN_INFO "%s: System CPLD removed.\n", __FUNCTION__); + return 0; +} + +static struct i2c_driver system_cpld_driver = { + .driver = { + .name = "system_cpld", + .owner = THIS_MODULE, + }, + .probe = system_cpld_probe, + .remove = system_cpld_remove, + .id_table = system_cpld_ids, +}; + +static int __init system_cpld_init(void) +{ + printk(KERN_INFO "%s: init.\n", __FUNCTION__); + return i2c_add_driver(&system_cpld_driver); +} +module_init(system_cpld_init); + +static void __exit system_cpld_exit(void) +{ + printk(KERN_INFO "%s: exit.\n", __FUNCTION__); + i2c_del_driver(&system_cpld_driver); +} +module_exit(system_cpld_exit); + +MODULE_DESCRIPTION("mitac_ly1200_32x_system_cpld driver"); +MODULE_AUTHOR("Eddy Weng "); +MODULE_LICENSE("GPL"); + diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/pmbus.h b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/pmbus.h new file mode 100644 index 000000000000..55cb8663e6e9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/pmbus.h @@ -0,0 +1,366 @@ +#ifndef PMBUS_H +#define PMBUS_H + +/* + * Registers + */ +#define PMBUS_PAGE 0x00 +#define PMBUS_OPERATION 0x01 +#define PMBUS_ON_OFF_CONFIG 0x02 +#define PMBUS_CLEAR_FAULTS 0x03 +#define PMBUS_PHASE 0x04 + +#define PMBUS_CAPABILITY 0x19 +#define PMBUS_QUERY 0x1A + +#define PMBUS_VOUT_MODE 0x20 +#define PMBUS_VOUT_COMMAND 0x21 +#define PMBUS_VOUT_TRIM 0x22 +#define PMBUS_VOUT_CAL_OFFSET 0x23 +#define PMBUS_VOUT_MAX 0x24 +#define PMBUS_VOUT_MARGIN_HIGH 0x25 +#define PMBUS_VOUT_MARGIN_LOW 0x26 +#define PMBUS_VOUT_TRANSITION_RATE 0x27 +#define PMBUS_VOUT_DROOP 0x28 +#define PMBUS_VOUT_SCALE_LOOP 0x29 +#define PMBUS_VOUT_SCALE_MONITOR 0x2A + +#define PMBUS_COEFFICIENTS 0x30 +#define PMBUS_POUT_MAX 0x31 + +#define PMBUS_FAN_CONFIG_12 0x3A +#define PMBUS_FAN_COMMAND_1 0x3B +#define PMBUS_FAN_COMMAND_2 0x3C +#define PMBUS_FAN_CONFIG_34 0x3D +#define PMBUS_FAN_COMMAND_3 0x3E +#define PMBUS_FAN_COMMAND_4 0x3F + +#define PMBUS_VOUT_OV_FAULT_LIMIT 0x40 +#define PMBUS_VOUT_OV_FAULT_RESPONSE 0x41 +#define PMBUS_VOUT_OV_WARN_LIMIT 0x42 +#define PMBUS_VOUT_UV_WARN_LIMIT 0x43 +#define PMBUS_VOUT_UV_FAULT_LIMIT 0x44 +#define PMBUS_VOUT_UV_FAULT_RESPONSE 0x45 +#define PMBUS_IOUT_OC_FAULT_LIMIT 0x46 +#define PMBUS_IOUT_OC_FAULT_RESPONSE 0x47 +#define PMBUS_IOUT_OC_LV_FAULT_LIMIT 0x48 +#define PMBUS_IOUT_OC_LV_FAULT_RESPONSE 0x49 +#define PMBUS_IOUT_OC_WARN_LIMIT 0x4A +#define PMBUS_IOUT_UC_FAULT_LIMIT 0x4B +#define PMBUS_IOUT_UC_FAULT_RESPONSE 0x4C + +#define PMBUS_OT_FAULT_LIMIT 0x4F +#define PMBUS_OT_FAULT_RESPONSE 0x50 +#define PMBUS_OT_WARN_LIMIT 0x51 +#define PMBUS_UT_WARN_LIMIT 0x52 +#define PMBUS_UT_FAULT_LIMIT 0x53 +#define PMBUS_UT_FAULT_RESPONSE 0x54 +#define PMBUS_VIN_OV_FAULT_LIMIT 0x55 +#define PMBUS_VIN_OV_FAULT_RESPONSE 0x56 +#define PMBUS_VIN_OV_WARN_LIMIT 0x57 +#define PMBUS_VIN_UV_WARN_LIMIT 0x58 +#define PMBUS_VIN_UV_FAULT_LIMIT 0x59 + +#define PMBUS_IIN_OC_FAULT_LIMIT 0x5B +#define PMBUS_IIN_OC_WARN_LIMIT 0x5D + +#define PMBUS_POUT_OP_FAULT_LIMIT 0x68 +#define PMBUS_POUT_OP_WARN_LIMIT 0x6A +#define PMBUS_PIN_OP_WARN_LIMIT 0x6B + +#define PMBUS_STATUS_BYTE 0x78 +#define PMBUS_STATUS_WORD 0x79 +#define PMBUS_STATUS_VOUT 0x7A +#define PMBUS_STATUS_IOUT 0x7B +#define PMBUS_STATUS_INPUT 0x7C +#define PMBUS_STATUS_TEMPERATURE 0x7D +#define PMBUS_STATUS_CML 0x7E +#define PMBUS_STATUS_OTHER 0x7F +#define PMBUS_STATUS_MFR_SPECIFIC 0x80 +#define PMBUS_STATUS_FAN_12 0x81 +#define PMBUS_STATUS_FAN_34 0x82 + +#define PMBUS_READ_VIN 0x88 +#define PMBUS_READ_IIN 0x89 +#define PMBUS_READ_VCAP 0x8A +#define PMBUS_READ_VOUT 0x8B +#define PMBUS_READ_IOUT 0x8C +#define PMBUS_READ_TEMPERATURE_1 0x8D +#define PMBUS_READ_TEMPERATURE_2 0x8E +#define PMBUS_READ_TEMPERATURE_3 0x8F +#define PMBUS_READ_FAN_SPEED_1 0x90 +#define PMBUS_READ_FAN_SPEED_2 0x91 +#define PMBUS_READ_FAN_SPEED_3 0x92 +#define PMBUS_READ_FAN_SPEED_4 0x93 +#define PMBUS_READ_DUTY_CYCLE 0x94 +#define PMBUS_READ_FREQUENCY 0x95 +#define PMBUS_READ_POUT 0x96 +#define PMBUS_READ_PIN 0x97 + +#define PMBUS_REVISION 0x98 +#define PMBUS_MFR_ID 0x99 +#define PMBUS_MFR_MODEL 0x9A +#define PMBUS_MFR_REVISION 0x9B +#define PMBUS_MFR_LOCATION 0x9C +#define PMBUS_MFR_DATE 0x9D +#define PMBUS_MFR_SERIAL 0x9E + +/* + * Virtual registers. + * Useful to support attributes which are not supported by standard PMBus + * registers but exist as manufacturer specific registers on individual chips. + * Must be mapped to real registers in device specific code. + * + * Semantics: + * Virtual registers are all word size. + * READ registers are read-only; writes are either ignored or return an error. + * RESET registers are read/write. Reading reset registers returns zero + * (used for detection), writing any value causes the associated history to be + * reset. + * Virtual registers have to be handled in device specific driver code. Chip + * driver code returns non-negative register values if a virtual register is + * supported, or a negative error code if not. The chip driver may return + * -ENODATA or any other error code in this case, though an error code other + * than -ENODATA is handled more efficiently and thus preferred. Either case, + * the calling PMBus core code will abort if the chip driver returns an error + * code when reading or writing virtual registers. + */ +#define PMBUS_VIRT_BASE 0x100 +#define PMBUS_VIRT_READ_TEMP_AVG (PMBUS_VIRT_BASE + 0) +#define PMBUS_VIRT_READ_TEMP_MIN (PMBUS_VIRT_BASE + 1) +#define PMBUS_VIRT_READ_TEMP_MAX (PMBUS_VIRT_BASE + 2) +#define PMBUS_VIRT_RESET_TEMP_HISTORY (PMBUS_VIRT_BASE + 3) +#define PMBUS_VIRT_READ_VIN_AVG (PMBUS_VIRT_BASE + 4) +#define PMBUS_VIRT_READ_VIN_MIN (PMBUS_VIRT_BASE + 5) +#define PMBUS_VIRT_READ_VIN_MAX (PMBUS_VIRT_BASE + 6) +#define PMBUS_VIRT_RESET_VIN_HISTORY (PMBUS_VIRT_BASE + 7) +#define PMBUS_VIRT_READ_IIN_AVG (PMBUS_VIRT_BASE + 8) +#define PMBUS_VIRT_READ_IIN_MIN (PMBUS_VIRT_BASE + 9) +#define PMBUS_VIRT_READ_IIN_MAX (PMBUS_VIRT_BASE + 10) +#define PMBUS_VIRT_RESET_IIN_HISTORY (PMBUS_VIRT_BASE + 11) +#define PMBUS_VIRT_READ_PIN_AVG (PMBUS_VIRT_BASE + 12) +#define PMBUS_VIRT_READ_PIN_MAX (PMBUS_VIRT_BASE + 13) +#define PMBUS_VIRT_RESET_PIN_HISTORY (PMBUS_VIRT_BASE + 14) +#define PMBUS_VIRT_READ_POUT_AVG (PMBUS_VIRT_BASE + 15) +#define PMBUS_VIRT_READ_POUT_MAX (PMBUS_VIRT_BASE + 16) +#define PMBUS_VIRT_RESET_POUT_HISTORY (PMBUS_VIRT_BASE + 17) +#define PMBUS_VIRT_READ_VOUT_AVG (PMBUS_VIRT_BASE + 18) +#define PMBUS_VIRT_READ_VOUT_MIN (PMBUS_VIRT_BASE + 19) +#define PMBUS_VIRT_READ_VOUT_MAX (PMBUS_VIRT_BASE + 20) +#define PMBUS_VIRT_RESET_VOUT_HISTORY (PMBUS_VIRT_BASE + 21) +#define PMBUS_VIRT_READ_IOUT_AVG (PMBUS_VIRT_BASE + 22) +#define PMBUS_VIRT_READ_IOUT_MIN (PMBUS_VIRT_BASE + 23) +#define PMBUS_VIRT_READ_IOUT_MAX (PMBUS_VIRT_BASE + 24) +#define PMBUS_VIRT_RESET_IOUT_HISTORY (PMBUS_VIRT_BASE + 25) +#define PMBUS_VIRT_READ_TEMP2_AVG (PMBUS_VIRT_BASE + 26) +#define PMBUS_VIRT_READ_TEMP2_MIN (PMBUS_VIRT_BASE + 27) +#define PMBUS_VIRT_READ_TEMP2_MAX (PMBUS_VIRT_BASE + 28) +#define PMBUS_VIRT_RESET_TEMP2_HISTORY (PMBUS_VIRT_BASE + 29) + +#define PMBUS_VIRT_READ_VMON (PMBUS_VIRT_BASE + 30) +#define PMBUS_VIRT_VMON_UV_WARN_LIMIT (PMBUS_VIRT_BASE + 31) +#define PMBUS_VIRT_VMON_OV_WARN_LIMIT (PMBUS_VIRT_BASE + 32) +#define PMBUS_VIRT_VMON_UV_FAULT_LIMIT (PMBUS_VIRT_BASE + 33) +#define PMBUS_VIRT_VMON_OV_FAULT_LIMIT (PMBUS_VIRT_BASE + 34) +#define PMBUS_VIRT_STATUS_VMON (PMBUS_VIRT_BASE + 35) + +/* + * CAPABILITY + */ +#define PB_CAPABILITY_SMBALERT (1<<4) +#define PB_CAPABILITY_ERROR_CHECK (1<<7) + +/* + * VOUT_MODE + */ +#define PB_VOUT_MODE_MODE_MASK 0xe0 +#define PB_VOUT_MODE_PARAM_MASK 0x1f + +#define PB_VOUT_MODE_LINEAR 0x00 +#define PB_VOUT_MODE_VID 0x20 +#define PB_VOUT_MODE_DIRECT 0x40 + +/* + * Fan configuration + */ +#define PB_FAN_2_PULSE_MASK ((1 << 0) | (1 << 1)) +#define PB_FAN_2_RPM (1 << 2) +#define PB_FAN_2_INSTALLED (1 << 3) +#define PB_FAN_1_PULSE_MASK ((1 << 4) | (1 << 5)) +#define PB_FAN_1_RPM (1 << 6) +#define PB_FAN_1_INSTALLED (1 << 7) + +/* + * STATUS_BYTE, STATUS_WORD (lower) + */ +#define PB_STATUS_NONE_ABOVE (1<<0) +#define PB_STATUS_CML (1<<1) +#define PB_STATUS_TEMPERATURE (1<<2) +#define PB_STATUS_VIN_UV (1<<3) +#define PB_STATUS_IOUT_OC (1<<4) +#define PB_STATUS_VOUT_OV (1<<5) +#define PB_STATUS_OFF (1<<6) +#define PB_STATUS_BUSY (1<<7) + +/* + * STATUS_WORD (upper) + */ +#define PB_STATUS_UNKNOWN (1<<8) +#define PB_STATUS_OTHER (1<<9) +#define PB_STATUS_FANS (1<<10) +#define PB_STATUS_POWER_GOOD_N (1<<11) +#define PB_STATUS_WORD_MFR (1<<12) +#define PB_STATUS_INPUT (1<<13) +#define PB_STATUS_IOUT_POUT (1<<14) +#define PB_STATUS_VOUT (1<<15) + +/* + * STATUS_IOUT + */ +#define PB_POUT_OP_WARNING (1<<0) +#define PB_POUT_OP_FAULT (1<<1) +#define PB_POWER_LIMITING (1<<2) +#define PB_CURRENT_SHARE_FAULT (1<<3) +#define PB_IOUT_UC_FAULT (1<<4) +#define PB_IOUT_OC_WARNING (1<<5) +#define PB_IOUT_OC_LV_FAULT (1<<6) +#define PB_IOUT_OC_FAULT (1<<7) + +/* + * STATUS_VOUT, STATUS_INPUT + */ +#define PB_VOLTAGE_UV_FAULT (1<<4) +#define PB_VOLTAGE_UV_WARNING (1<<5) +#define PB_VOLTAGE_OV_WARNING (1<<6) +#define PB_VOLTAGE_OV_FAULT (1<<7) + +/* + * STATUS_INPUT + */ +#define PB_PIN_OP_WARNING (1<<0) +#define PB_IIN_OC_WARNING (1<<1) +#define PB_IIN_OC_FAULT (1<<2) + +/* + * STATUS_TEMPERATURE + */ +#define PB_TEMP_UT_FAULT (1<<4) +#define PB_TEMP_UT_WARNING (1<<5) +#define PB_TEMP_OT_WARNING (1<<6) +#define PB_TEMP_OT_FAULT (1<<7) + +/* + * STATUS_FAN + */ +#define PB_FAN_AIRFLOW_WARNING (1<<0) +#define PB_FAN_AIRFLOW_FAULT (1<<1) +#define PB_FAN_FAN2_SPEED_OVERRIDE (1<<2) +#define PB_FAN_FAN1_SPEED_OVERRIDE (1<<3) +#define PB_FAN_FAN2_WARNING (1<<4) +#define PB_FAN_FAN1_WARNING (1<<5) +#define PB_FAN_FAN2_FAULT (1<<6) +#define PB_FAN_FAN1_FAULT (1<<7) + +/* + * CML_FAULT_STATUS + */ +#define PB_CML_FAULT_OTHER_MEM_LOGIC (1<<0) +#define PB_CML_FAULT_OTHER_COMM (1<<1) +#define PB_CML_FAULT_PROCESSOR (1<<3) +#define PB_CML_FAULT_MEMORY (1<<4) +#define PB_CML_FAULT_PACKET_ERROR (1<<5) +#define PB_CML_FAULT_INVALID_DATA (1<<6) +#define PB_CML_FAULT_INVALID_COMMAND (1<<7) + +enum pmbus_sensor_classes { + PSC_VOLTAGE_IN = 0, + PSC_VOLTAGE_OUT, + PSC_CURRENT_IN, + PSC_CURRENT_OUT, + PSC_POWER, + PSC_TEMPERATURE, + PSC_FAN, + PSC_NUM_CLASSES /* Number of power sensor classes */ +}; + +#define PMBUS_PAGES 32 /* Per PMBus specification */ + +/* Functionality bit mask */ +#define PMBUS_HAVE_VIN (1 << 0) +#define PMBUS_HAVE_VCAP (1 << 1) +#define PMBUS_HAVE_VOUT (1 << 2) +#define PMBUS_HAVE_IIN (1 << 3) +#define PMBUS_HAVE_IOUT (1 << 4) +#define PMBUS_HAVE_PIN (1 << 5) +#define PMBUS_HAVE_POUT (1 << 6) +#define PMBUS_HAVE_FAN12 (1 << 7) +#define PMBUS_HAVE_FAN34 (1 << 8) +#define PMBUS_HAVE_TEMP (1 << 9) +#define PMBUS_HAVE_TEMP2 (1 << 10) +#define PMBUS_HAVE_TEMP3 (1 << 11) +#define PMBUS_HAVE_STATUS_VOUT (1 << 12) +#define PMBUS_HAVE_STATUS_IOUT (1 << 13) +#define PMBUS_HAVE_STATUS_INPUT (1 << 14) +#define PMBUS_HAVE_STATUS_TEMP (1 << 15) +#define PMBUS_HAVE_STATUS_FAN12 (1 << 16) +#define PMBUS_HAVE_STATUS_FAN34 (1 << 17) +#define PMBUS_HAVE_VMON (1 << 18) +#define PMBUS_HAVE_STATUS_VMON (1 << 19) + +enum pmbus_data_format { linear = 0, direct, vid }; + +struct pmbus_driver_info { + int pages; /* Total number of pages */ + enum pmbus_data_format format[PSC_NUM_CLASSES]; + /* + * Support one set of coefficients for each sensor type + * Used for chips providing data in direct mode. + */ + int m[PSC_NUM_CLASSES]; /* mantissa for direct data format */ + int b[PSC_NUM_CLASSES]; /* offset */ + int R[PSC_NUM_CLASSES]; /* exponent */ + + u32 func[PMBUS_PAGES]; /* Functionality, per page */ + /* + * The following functions map manufacturing specific register values + * to PMBus standard register values. Specify only if mapping is + * necessary. + * Functions return the register value (read) or zero (write) if + * successful. A return value of -ENODATA indicates that there is no + * manufacturer specific register, but that a standard PMBus register + * may exist. Any other negative return value indicates that the + * register does not exist, and that no attempt should be made to read + * the standard register. + */ + int (*read_byte_data)(struct i2c_client *client, int page, int reg); + int (*read_word_data)(struct i2c_client *client, int page, int reg); + int (*write_word_data)(struct i2c_client *client, int page, int reg, + u16 word); + int (*write_byte)(struct i2c_client *client, int page, u8 value); + /* + * The identify function determines supported PMBus functionality. + * This function is only necessary if a chip driver supports multiple + * chips, and the chip functionality is not pre-determined. + */ + int (*identify)(struct i2c_client *client, + struct pmbus_driver_info *info); +}; + +/* Function declarations */ + +void pmbus_clear_cache(struct i2c_client *client); +int pmbus_set_page(struct i2c_client *client, u8 page); +int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg); +int pmbus_write_word_data(struct i2c_client *client, u8 page, u8 reg, u16 word); +int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg); +int pmbus_write_byte(struct i2c_client *client, int page, u8 value); +void pmbus_clear_faults(struct i2c_client *client); +bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg); +bool pmbus_check_word_register(struct i2c_client *client, int page, int reg); +int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, + struct pmbus_driver_info *info); +int pmbus_do_remove(struct i2c_client *client); +const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client + *client); + +#endif /* PMBUS_H */ diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/slave_cpld_reg.h b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/slave_cpld_reg.h new file mode 100644 index 000000000000..a8169bdb88ee --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/slave_cpld_reg.h @@ -0,0 +1,192 @@ +#ifndef __SLAVE_CPLD_REG +#define __SLAVE_CPLD_REG + +static int slave_cpld_raw_read(struct device *dev, struct device_attribute *attr, char *buf, + int reg_offset, int reg_width, int fld_shift, int fld_width, int fld_mask, char* reg_name); +static int slave_cpld_raw_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count, + int reg_offset, int reg_width, int fld_shift, int fld_width, int fld_mask, char* reg_name); + +/* generic CPLD read function */ +#define FLD_RAW_RD_FUNC(_reg, _fld, _wdh) static ssize_t \ +slave_cpld_##_fld##_raw_read(struct device *dev, struct device_attribute *attr, char *buf) { \ + return slave_cpld_raw_read(dev, attr, buf, _reg##_offset, _reg##_width, _fld##_shift, _fld##_width, _fld##_mask, #_reg); \ +} + +/* generic CPLD write function */ +#define FLD_RAW_WR_FUNC(_reg, _fld, _wdh) static ssize_t \ +slave_cpld_##_fld##_raw_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { \ + return slave_cpld_raw_write(dev, attr, buf, count, _reg##_offset, _reg##_width, _fld##_shift, _fld##_width, _fld##_mask, #_reg); \ +} + +/* CPLD register definition macros */ +#define REG_DEF(_reg, _off, _wdh) \ +static unsigned int _reg##_offset = (unsigned int)(_off); \ +static unsigned int _reg##_width = (unsigned int)(_wdh); + +/* CPLD register field definition macros, with generic read/write function */ +#define FLD_RAW_RO_DEF(_reg, _fld, _sft, _wdh) \ +static unsigned int _fld##_shift = (unsigned int)(_sft); \ +static unsigned int _fld##_width = (unsigned int)(_wdh); \ +static unsigned int _fld##_mask = ((((unsigned int)1) << (_wdh)) - 1); \ +FLD_RAW_RD_FUNC(_reg, _fld, _wdh) + +#define FLD_RAW_RW_DEF(_reg, _fld, _sft, _wdh) \ +static unsigned int _fld##_shift = (unsigned int)(_sft); \ +static unsigned int _fld##_width = (unsigned int)(_wdh); \ +static unsigned int _fld##_mask = ((((unsigned int)1) << (_wdh)) - 1); \ +FLD_RAW_RD_FUNC(_reg, _fld, _wdh) FLD_RAW_WR_FUNC(_reg, _fld, _wdh) + +/* declare slave CPLD registers */ +/* register name offset width */ +/* --------------------------------------- ------- ----- */ +REG_DEF( slv_cpld_rev, 0x00, 8) +REG_DEF( slv_cpld_gpr, 0x01, 8) +REG_DEF( mb_brd_rev_type, 0x02, 8) + +REG_DEF( zqsfp28_present_24_17_status, 0x10, 8) +REG_DEF( zqsfp28_present_32_25_status, 0x11, 8) +REG_DEF( zqsfp28_rst_24_17, 0x12, 8) +REG_DEF( zqsfp28_rst_32_25, 0x13, 8) +REG_DEF( zqsfp28_modsel_24_17, 0x14, 8) +REG_DEF( zqsfp28_modsel_32_25, 0x15, 8) +REG_DEF( zqsfp28_lpmode_24_17, 0x16, 8) +REG_DEF( zqsfp28_lpmode_32_25, 0x17, 8) +REG_DEF( zqsfp28_irq_24_17_status, 0x18, 8) +REG_DEF( zqsfp28_irq_32_25_status, 0x19, 8) +REG_DEF( zqsfp28_irq_msk_24_17_status, 0x1A, 8) +REG_DEF( zqsfp28_irq_msk_32_25_status, 0x1B, 8) + + +/* declare slave CPLD register's fields */ +/* register name field name shift width */ +/* ---------------------- ---------------- ------ ----- */ +FLD_RAW_RO_DEF( slv_cpld_rev, mjr_rev, 4, 4) +FLD_RAW_RO_DEF( slv_cpld_rev, mnr_rev, 0, 4) + +FLD_RAW_RW_DEF( slv_cpld_gpr, scrtch_reg, 0, 8) + +FLD_RAW_RO_DEF( mb_brd_rev_type, brd_rev, 4, 4) +FLD_RAW_RO_DEF( mb_brd_rev_type, brd_type, 0, 4) + +FLD_RAW_RO_DEF( zqsfp28_present_24_17_status, port24_present, 7, 1) +FLD_RAW_RO_DEF( zqsfp28_present_24_17_status, port23_present, 6, 1) +FLD_RAW_RO_DEF( zqsfp28_present_24_17_status, port22_present, 5, 1) +FLD_RAW_RO_DEF( zqsfp28_present_24_17_status, port21_present, 4, 1) +FLD_RAW_RO_DEF( zqsfp28_present_24_17_status, port20_present, 3, 1) +FLD_RAW_RO_DEF( zqsfp28_present_24_17_status, port19_present, 2, 1) +FLD_RAW_RO_DEF( zqsfp28_present_24_17_status, port18_present, 1, 1) +FLD_RAW_RO_DEF( zqsfp28_present_24_17_status, port17_present, 0, 1) + +FLD_RAW_RO_DEF( zqsfp28_present_32_25_status, port32_present, 7, 1) +FLD_RAW_RO_DEF( zqsfp28_present_32_25_status, port31_present, 6, 1) +FLD_RAW_RO_DEF( zqsfp28_present_32_25_status, port30_present, 5, 1) +FLD_RAW_RO_DEF( zqsfp28_present_32_25_status, port29_present, 4, 1) +FLD_RAW_RO_DEF( zqsfp28_present_32_25_status, port28_present, 3, 1) +FLD_RAW_RO_DEF( zqsfp28_present_32_25_status, port27_present, 2, 1) +FLD_RAW_RO_DEF( zqsfp28_present_32_25_status, port26_present, 1, 1) +FLD_RAW_RO_DEF( zqsfp28_present_32_25_status, port25_present, 0, 1) + +FLD_RAW_RW_DEF( zqsfp28_rst_24_17, port24_rst, 7, 1) +FLD_RAW_RW_DEF( zqsfp28_rst_24_17, port23_rst, 6, 1) +FLD_RAW_RW_DEF( zqsfp28_rst_24_17, port22_rst, 5, 1) +FLD_RAW_RW_DEF( zqsfp28_rst_24_17, port21_rst, 4, 1) +FLD_RAW_RW_DEF( zqsfp28_rst_24_17, port20_rst, 3, 1) +FLD_RAW_RW_DEF( zqsfp28_rst_24_17, port19_rst, 2, 1) +FLD_RAW_RW_DEF( zqsfp28_rst_24_17, port18_rst, 1, 1) +FLD_RAW_RW_DEF( zqsfp28_rst_24_17, port17_rst, 0, 1) + +FLD_RAW_RW_DEF( zqsfp28_rst_32_25, port32_rst, 7, 1) +FLD_RAW_RW_DEF( zqsfp28_rst_32_25, port31_rst, 6, 1) +FLD_RAW_RW_DEF( zqsfp28_rst_32_25, port30_rst, 5, 1) +FLD_RAW_RW_DEF( zqsfp28_rst_32_25, port29_rst, 4, 1) +FLD_RAW_RW_DEF( zqsfp28_rst_32_25, port28_rst, 3, 1) +FLD_RAW_RW_DEF( zqsfp28_rst_32_25, port27_rst, 2, 1) +FLD_RAW_RW_DEF( zqsfp28_rst_32_25, port26_rst, 1, 1) +FLD_RAW_RW_DEF( zqsfp28_rst_32_25, port25_rst, 0, 1) + +FLD_RAW_RW_DEF( zqsfp28_modsel_24_17, port24_modsel, 7, 1) +FLD_RAW_RW_DEF( zqsfp28_modsel_24_17, port23_modsel, 6, 1) +FLD_RAW_RW_DEF( zqsfp28_modsel_24_17, port22_modsel, 5, 1) +FLD_RAW_RW_DEF( zqsfp28_modsel_24_17, port21_modsel, 4, 1) +FLD_RAW_RW_DEF( zqsfp28_modsel_24_17, port20_modsel, 3, 1) +FLD_RAW_RW_DEF( zqsfp28_modsel_24_17, port19_modsel, 2, 1) +FLD_RAW_RW_DEF( zqsfp28_modsel_24_17, port18_modsel, 1, 1) +FLD_RAW_RW_DEF( zqsfp28_modsel_24_17, port17_modsel, 0, 1) + +FLD_RAW_RW_DEF( zqsfp28_modsel_32_25, port32_modsel, 7, 1) +FLD_RAW_RW_DEF( zqsfp28_modsel_32_25, port31_modsel, 6, 1) +FLD_RAW_RW_DEF( zqsfp28_modsel_32_25, port30_modsel, 5, 1) +FLD_RAW_RW_DEF( zqsfp28_modsel_32_25, port29_modsel, 4, 1) +FLD_RAW_RW_DEF( zqsfp28_modsel_32_25, port28_modsel, 3, 1) +FLD_RAW_RW_DEF( zqsfp28_modsel_32_25, port27_modsel, 2, 1) +FLD_RAW_RW_DEF( zqsfp28_modsel_32_25, port26_modsel, 1, 1) +FLD_RAW_RW_DEF( zqsfp28_modsel_32_25, port25_modsel, 0, 1) + +FLD_RAW_RW_DEF( zqsfp28_lpmode_24_17, port24_lpmode, 7, 1) +FLD_RAW_RW_DEF( zqsfp28_lpmode_24_17, port23_lpmode, 6, 1) +FLD_RAW_RW_DEF( zqsfp28_lpmode_24_17, port22_lpmode, 5, 1) +FLD_RAW_RW_DEF( zqsfp28_lpmode_24_17, port21_lpmode, 4, 1) +FLD_RAW_RW_DEF( zqsfp28_lpmode_24_17, port20_lpmode, 3, 1) +FLD_RAW_RW_DEF( zqsfp28_lpmode_24_17, port19_lpmode, 2, 1) +FLD_RAW_RW_DEF( zqsfp28_lpmode_24_17, port18_lpmode, 1, 1) +FLD_RAW_RW_DEF( zqsfp28_lpmode_24_17, port17_lpmode, 0, 1) + +FLD_RAW_RW_DEF( zqsfp28_lpmode_32_25, port32_lpmode, 7, 1) +FLD_RAW_RW_DEF( zqsfp28_lpmode_32_25, port31_lpmode, 6, 1) +FLD_RAW_RW_DEF( zqsfp28_lpmode_32_25, port30_lpmode, 5, 1) +FLD_RAW_RW_DEF( zqsfp28_lpmode_32_25, port29_lpmode, 4, 1) +FLD_RAW_RW_DEF( zqsfp28_lpmode_32_25, port28_lpmode, 3, 1) +FLD_RAW_RW_DEF( zqsfp28_lpmode_32_25, port27_lpmode, 2, 1) +FLD_RAW_RW_DEF( zqsfp28_lpmode_32_25, port26_lpmode, 1, 1) +FLD_RAW_RW_DEF( zqsfp28_lpmode_32_25, port25_lpmode, 0, 1) + +FLD_RAW_RO_DEF( zqsfp28_irq_24_17_status, port24_irq_status, 7, 1) +FLD_RAW_RO_DEF( zqsfp28_irq_24_17_status, port23_irq_status, 6, 1) +FLD_RAW_RO_DEF( zqsfp28_irq_24_17_status, port22_irq_status, 5, 1) +FLD_RAW_RO_DEF( zqsfp28_irq_24_17_status, port21_irq_status, 4, 1) +FLD_RAW_RO_DEF( zqsfp28_irq_24_17_status, port20_irq_status, 3, 1) +FLD_RAW_RO_DEF( zqsfp28_irq_24_17_status, port19_irq_status, 2, 1) +FLD_RAW_RO_DEF( zqsfp28_irq_24_17_status, port18_irq_status, 1, 1) +FLD_RAW_RO_DEF( zqsfp28_irq_24_17_status, port17_irq_status, 0, 1) + +FLD_RAW_RO_DEF( zqsfp28_irq_32_25_status, port32_irq_status, 7, 1) +FLD_RAW_RO_DEF( zqsfp28_irq_32_25_status, port31_irq_status, 6, 1) +FLD_RAW_RO_DEF( zqsfp28_irq_32_25_status, port30_irq_status, 5, 1) +FLD_RAW_RO_DEF( zqsfp28_irq_32_25_status, port29_irq_status, 4, 1) +FLD_RAW_RO_DEF( zqsfp28_irq_32_25_status, port28_irq_status, 3, 1) +FLD_RAW_RO_DEF( zqsfp28_irq_32_25_status, port27_irq_status, 2, 1) +FLD_RAW_RO_DEF( zqsfp28_irq_32_25_status, port26_irq_status, 1, 1) +FLD_RAW_RO_DEF( zqsfp28_irq_32_25_status, port25_irq_status, 0, 1) + +FLD_RAW_RW_DEF( zqsfp28_irq_msk_24_17_status, port24_irq_msk, 7, 1) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_24_17_status, port23_irq_msk, 6, 1) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_24_17_status, port22_irq_msk, 5, 1) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_24_17_status, port21_irq_msk, 4, 1) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_24_17_status, port20_irq_msk, 3, 1) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_24_17_status, port19_irq_msk, 2, 1) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_24_17_status, port18_irq_msk, 1, 1) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_24_17_status, port17_irq_msk, 0, 1) + +FLD_RAW_RW_DEF( zqsfp28_irq_msk_32_25_status, port32_irq_msk, 7, 1) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_32_25_status, port31_irq_msk, 6, 1) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_32_25_status, port30_irq_msk, 5, 1) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_32_25_status, port29_irq_msk, 4, 1) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_32_25_status, port28_irq_msk, 3, 1) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_32_25_status, port27_irq_msk, 2, 1) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_32_25_status, port26_irq_msk, 1, 1) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_32_25_status, port25_irq_msk, 0, 1) + +FLD_RAW_RO_DEF( zqsfp28_present_24_17_status, port_17_24_present, 0, 8) +FLD_RAW_RO_DEF( zqsfp28_present_32_25_status, port_25_32_present, 0, 8) +FLD_RAW_RW_DEF( zqsfp28_rst_24_17, port_17_24_rst, 0, 8) +FLD_RAW_RW_DEF( zqsfp28_rst_32_25, port_25_32_rst, 0, 8) +FLD_RAW_RW_DEF( zqsfp28_modsel_24_17, port_17_24_modsel, 0, 8) +FLD_RAW_RW_DEF( zqsfp28_modsel_32_25, port_25_32_modsel, 0, 8) +FLD_RAW_RO_DEF( zqsfp28_irq_24_17_status, port_17_24_irq_status,0, 8) +FLD_RAW_RO_DEF( zqsfp28_irq_32_25_status, port_25_32_irq_status,0, 8) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_24_17_status, port_17_24_irq_msk, 0, 8) +FLD_RAW_RW_DEF( zqsfp28_irq_msk_32_25_status, port_25_32_irq_msk, 0, 8) +FLD_RAW_RW_DEF( zqsfp28_lpmode_24_17, port_17_24_lpmode, 0, 8) +FLD_RAW_RW_DEF( zqsfp28_lpmode_32_25, port_25_32_lpmode, 0, 8) + +#endif /* __SLAVE_CPLD_REG */ diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/slave_cpld_sysfs.h b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/slave_cpld_sysfs.h new file mode 100644 index 000000000000..92d00d29d493 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/slave_cpld_sysfs.h @@ -0,0 +1,155 @@ +#ifndef __SLAVE_CPLD_SYSFS +#define __SLAVE_CPLD_SYSFS + +/* generic CPLD sysfs file definition macros */ +#define SYSFS_RAW_RO_ATTR_DEF(field) \ +struct device_attribute field \ + = __ATTR(field, S_IRUGO, slave_cpld_##field##_raw_read, NULL); + +#define SYSFS_RAW_RW_ATTR_DEF(field) \ +struct device_attribute field \ + = __ATTR(field, S_IRUGO | S_IWUGO, slave_cpld_##field##_raw_read, slave_cpld_##field##_raw_write); + +#define SYSFS_MISC_RO_ATTR_DEF(field, _read) \ +struct device_attribute field \ + = __ATTR(field, S_IRUGO, _read, NULL); + +#define SYSFS_MISC_RW_ATTR_DEF(field, _read, _write) \ +struct device_attribute field \ + = __ATTR(field, S_IRUGO | S_IWUGO, _read, _write); + +#define SYSFS_ATTR_PTR(field) \ +&field.attr + + +/* declare slave CPLD file system */ +SYSFS_RAW_RO_ATTR_DEF(mjr_rev) +SYSFS_RAW_RO_ATTR_DEF(mnr_rev) + +SYSFS_RAW_RW_ATTR_DEF(scrtch_reg) + +SYSFS_RAW_RO_ATTR_DEF(brd_rev) +SYSFS_RAW_RO_ATTR_DEF(brd_type) + +SYSFS_RAW_RO_ATTR_DEF(port24_present) +SYSFS_RAW_RO_ATTR_DEF(port23_present) +SYSFS_RAW_RO_ATTR_DEF(port22_present) +SYSFS_RAW_RO_ATTR_DEF(port21_present) +SYSFS_RAW_RO_ATTR_DEF(port20_present) +SYSFS_RAW_RO_ATTR_DEF(port19_present) +SYSFS_RAW_RO_ATTR_DEF(port18_present) +SYSFS_RAW_RO_ATTR_DEF(port17_present) + +SYSFS_RAW_RO_ATTR_DEF(port32_present) +SYSFS_RAW_RO_ATTR_DEF(port31_present) +SYSFS_RAW_RO_ATTR_DEF(port30_present) +SYSFS_RAW_RO_ATTR_DEF(port29_present) +SYSFS_RAW_RO_ATTR_DEF(port28_present) +SYSFS_RAW_RO_ATTR_DEF(port27_present) +SYSFS_RAW_RO_ATTR_DEF(port26_present) +SYSFS_RAW_RO_ATTR_DEF(port25_present) + +SYSFS_RAW_RW_ATTR_DEF(port24_rst) +SYSFS_RAW_RW_ATTR_DEF(port23_rst) +SYSFS_RAW_RW_ATTR_DEF(port22_rst) +SYSFS_RAW_RW_ATTR_DEF(port21_rst) +SYSFS_RAW_RW_ATTR_DEF(port20_rst) +SYSFS_RAW_RW_ATTR_DEF(port19_rst) +SYSFS_RAW_RW_ATTR_DEF(port18_rst) +SYSFS_RAW_RW_ATTR_DEF(port17_rst) + +SYSFS_RAW_RW_ATTR_DEF(port32_rst) +SYSFS_RAW_RW_ATTR_DEF(port31_rst) +SYSFS_RAW_RW_ATTR_DEF(port30_rst) +SYSFS_RAW_RW_ATTR_DEF(port29_rst) +SYSFS_RAW_RW_ATTR_DEF(port28_rst) +SYSFS_RAW_RW_ATTR_DEF(port27_rst) +SYSFS_RAW_RW_ATTR_DEF(port26_rst) +SYSFS_RAW_RW_ATTR_DEF(port25_rst) + +SYSFS_RAW_RW_ATTR_DEF(port24_modsel) +SYSFS_RAW_RW_ATTR_DEF(port23_modsel) +SYSFS_RAW_RW_ATTR_DEF(port22_modsel) +SYSFS_RAW_RW_ATTR_DEF(port21_modsel) +SYSFS_RAW_RW_ATTR_DEF(port20_modsel) +SYSFS_RAW_RW_ATTR_DEF(port19_modsel) +SYSFS_RAW_RW_ATTR_DEF(port18_modsel) +SYSFS_RAW_RW_ATTR_DEF(port17_modsel) + +SYSFS_RAW_RW_ATTR_DEF(port32_modsel) +SYSFS_RAW_RW_ATTR_DEF(port31_modsel) +SYSFS_RAW_RW_ATTR_DEF(port30_modsel) +SYSFS_RAW_RW_ATTR_DEF(port29_modsel) +SYSFS_RAW_RW_ATTR_DEF(port28_modsel) +SYSFS_RAW_RW_ATTR_DEF(port27_modsel) +SYSFS_RAW_RW_ATTR_DEF(port26_modsel) +SYSFS_RAW_RW_ATTR_DEF(port25_modsel) + +SYSFS_RAW_RW_ATTR_DEF(port24_lpmode) +SYSFS_RAW_RW_ATTR_DEF(port23_lpmode) +SYSFS_RAW_RW_ATTR_DEF(port22_lpmode) +SYSFS_RAW_RW_ATTR_DEF(port21_lpmode) +SYSFS_RAW_RW_ATTR_DEF(port20_lpmode) +SYSFS_RAW_RW_ATTR_DEF(port19_lpmode) +SYSFS_RAW_RW_ATTR_DEF(port18_lpmode) +SYSFS_RAW_RW_ATTR_DEF(port17_lpmode) + +SYSFS_RAW_RW_ATTR_DEF(port32_lpmode) +SYSFS_RAW_RW_ATTR_DEF(port31_lpmode) +SYSFS_RAW_RW_ATTR_DEF(port30_lpmode) +SYSFS_RAW_RW_ATTR_DEF(port29_lpmode) +SYSFS_RAW_RW_ATTR_DEF(port28_lpmode) +SYSFS_RAW_RW_ATTR_DEF(port27_lpmode) +SYSFS_RAW_RW_ATTR_DEF(port26_lpmode) +SYSFS_RAW_RW_ATTR_DEF(port25_lpmode) + +SYSFS_RAW_RO_ATTR_DEF(port24_irq_status) +SYSFS_RAW_RO_ATTR_DEF(port23_irq_status) +SYSFS_RAW_RO_ATTR_DEF(port22_irq_status) +SYSFS_RAW_RO_ATTR_DEF(port21_irq_status) +SYSFS_RAW_RO_ATTR_DEF(port20_irq_status) +SYSFS_RAW_RO_ATTR_DEF(port19_irq_status) +SYSFS_RAW_RO_ATTR_DEF(port18_irq_status) +SYSFS_RAW_RO_ATTR_DEF(port17_irq_status) + +SYSFS_RAW_RO_ATTR_DEF(port32_irq_status) +SYSFS_RAW_RO_ATTR_DEF(port31_irq_status) +SYSFS_RAW_RO_ATTR_DEF(port30_irq_status) +SYSFS_RAW_RO_ATTR_DEF(port29_irq_status) +SYSFS_RAW_RO_ATTR_DEF(port28_irq_status) +SYSFS_RAW_RO_ATTR_DEF(port27_irq_status) +SYSFS_RAW_RO_ATTR_DEF(port26_irq_status) +SYSFS_RAW_RO_ATTR_DEF(port25_irq_status) + +SYSFS_RAW_RW_ATTR_DEF(port24_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port23_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port22_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port21_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port20_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port19_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port18_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port17_irq_msk) + +SYSFS_RAW_RW_ATTR_DEF(port32_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port31_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port30_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port29_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port28_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port27_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port26_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port25_irq_msk) + +SYSFS_RAW_RO_ATTR_DEF(port_17_24_present) +SYSFS_RAW_RO_ATTR_DEF(port_25_32_present) +SYSFS_RAW_RW_ATTR_DEF(port_17_24_rst) +SYSFS_RAW_RW_ATTR_DEF(port_25_32_rst) +SYSFS_RAW_RW_ATTR_DEF(port_17_24_modsel) +SYSFS_RAW_RW_ATTR_DEF(port_25_32_modsel) +SYSFS_RAW_RO_ATTR_DEF(port_17_24_irq_status) +SYSFS_RAW_RO_ATTR_DEF(port_25_32_irq_status) +SYSFS_RAW_RW_ATTR_DEF(port_17_24_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port_25_32_irq_msk) +SYSFS_RAW_RW_ATTR_DEF(port_17_24_lpmode) +SYSFS_RAW_RW_ATTR_DEF(port_25_32_lpmode) + +#endif /* __SLAVE_CPLD_SYSFS */ diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/system_cpld_reg.h b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/system_cpld_reg.h new file mode 100644 index 000000000000..ba66519efe8a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/system_cpld_reg.h @@ -0,0 +1,107 @@ +#ifndef __SYSTEM_CPLD_REG +#define __SYSTEM_CPLD_REG + +static int system_cpld_raw_read(struct device *dev, struct device_attribute *attr, char *buf, + int reg_offset, int reg_width, int fld_shift, int fld_width, int fld_mask, char* reg_name); +static int system_cpld_raw_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count, + int reg_offset, int reg_width, int fld_shift, int fld_width, int fld_mask, char* reg_name); + +/* generic CPLD read function */ +#define FLD_RAW_RD_FUNC(_reg, _fld, _wdh) static ssize_t \ +system_cpld_##_fld##_raw_read(struct device *dev, struct device_attribute *attr, char *buf) { \ + return system_cpld_raw_read(dev, attr, buf, _reg##_offset, _reg##_width, _fld##_shift, _fld##_width, _fld##_mask, #_reg); \ +} + +/* generic CPLD write function */ +#define FLD_RAW_WR_FUNC(_reg, _fld, _wdh) static ssize_t \ +system_cpld_##_fld##_raw_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { \ + return system_cpld_raw_write(dev, attr, buf, count, _reg##_offset, _reg##_width, _fld##_shift, _fld##_width, _fld##_mask, #_reg); \ +} + +/* CPLD register definition macros */ +#define REG_DEF(_reg, _off, _wdh) \ +static unsigned int _reg##_offset = (unsigned int)(_off); \ +static unsigned int _reg##_width = (unsigned int)(_wdh); + +/* CPLD register field definition macros, with generic read/write function */ +#define FLD_RAW_RO_DEF(_reg, _fld, _sft, _wdh) \ +static unsigned int _fld##_shift = (unsigned int)(_sft); \ +static unsigned int _fld##_width = (unsigned int)(_wdh); \ +static unsigned int _fld##_mask = ((((unsigned int)1) << (_wdh)) - 1); \ +FLD_RAW_RD_FUNC(_reg, _fld, _wdh) + +#define FLD_RAW_RW_DEF(_reg, _fld, _sft, _wdh) \ +static unsigned int _fld##_shift = (unsigned int)(_sft); \ +static unsigned int _fld##_width = (unsigned int)(_wdh); \ +static unsigned int _fld##_mask = ((((unsigned int)1) << (_wdh)) - 1); \ +FLD_RAW_RD_FUNC(_reg, _fld, _wdh) FLD_RAW_WR_FUNC(_reg, _fld, _wdh) + +/* declare system CPLD registers */ +/* register name offset width */ +/* --------------------------------------- ------- ----- */ +REG_DEF( sys_cpld_rev, 0x00, 8) +REG_DEF( sys_cpld_gpr, 0x01, 8) +REG_DEF( cpu_brd_rev_type, 0x02, 8) +REG_DEF( sys_srr, 0x03, 8) +REG_DEF( sys_eeprom_wp, 0x04, 8) +REG_DEF( sys_irq, 0x05, 8) +REG_DEF( sys_wd, 0x06, 8) +REG_DEF( sys_mb_rst_en, 0x07, 8) +REG_DEF( cpu_pwr_en_status, 0x08, 8) +REG_DEF( cpu_pwr_status, 0x09, 8) + + +/* declare system CPLD register's fields */ +/* register name field name shift width */ +/* ---------------------- ---------------- ------ ----- */ +FLD_RAW_RO_DEF( sys_cpld_rev, mjr_rev, 4, 4) +FLD_RAW_RO_DEF( sys_cpld_rev, mnr_rev, 0, 4) + +FLD_RAW_RW_DEF( sys_cpld_gpr, scrtch_reg, 0, 8) + +FLD_RAW_RO_DEF( cpu_brd_rev_type, brd_rev, 4, 4) +FLD_RAW_RO_DEF( cpu_brd_rev_type, brd_type, 0, 4) + +FLD_RAW_RO_DEF( sys_srr, ssd_present, 3, 1) +FLD_RAW_RW_DEF( sys_srr, spi_cs_sel, 2, 1) +FLD_RAW_RW_DEF( sys_srr, rst_bios_switch, 1, 1) +FLD_RAW_RW_DEF( sys_srr, cpld_upgrade_rst, 0, 1) + +FLD_RAW_RW_DEF( sys_eeprom_wp, cpld_spi_wp, 4, 1) +FLD_RAW_RW_DEF( sys_eeprom_wp, system_id_eeprom_wp, 3, 1) +FLD_RAW_RW_DEF( sys_eeprom_wp, spi_me_wp, 2, 1) +FLD_RAW_RW_DEF( sys_eeprom_wp, spi_bios_wp, 1, 1) +FLD_RAW_RW_DEF( sys_eeprom_wp, spi_bak_bios_wp, 0, 1) + +FLD_RAW_RW_DEF( sys_irq, vrhot_irq_en, 6, 1) +FLD_RAW_RW_DEF( sys_irq, cpu_thermtrip_irq_en,5, 1) +FLD_RAW_RW_DEF( sys_irq, temp_alert_irq_en, 4, 1) +FLD_RAW_RO_DEF( sys_irq, vrhot_irq, 2, 1) +FLD_RAW_RO_DEF( sys_irq, cpu_thermtrip_irq, 1, 1) +FLD_RAW_RO_DEF( sys_irq, temp_alert_irq, 0, 1) + +FLD_RAW_RW_DEF( sys_wd, wd_timer, 4, 4) +FLD_RAW_RW_DEF( sys_wd, wd_en, 1, 1) +FLD_RAW_RW_DEF( sys_wd, wd_punch, 0, 1) + +FLD_RAW_RW_DEF( sys_mb_rst_en, mb_rst_en, 0, 1) + +FLD_RAW_RO_DEF( cpu_pwr_en_status, pwr_v3p3_en, 7, 1) +FLD_RAW_RO_DEF( cpu_pwr_en_status, pwr_vcc_vnn_en, 6, 1) +FLD_RAW_RO_DEF( cpu_pwr_en_status, pwr_vccsram_en, 5, 1) +FLD_RAW_RO_DEF( cpu_pwr_en_status, pwr_vddq_en, 4, 1) +FLD_RAW_RO_DEF( cpu_pwr_en_status, pwr_vcc_ref_en, 3, 1) +FLD_RAW_RO_DEF( cpu_pwr_en_status, pwr_v1p05_en, 2, 1) +FLD_RAW_RO_DEF( cpu_pwr_en_status, pwr_v1p8_en, 1, 1) +FLD_RAW_RO_DEF( cpu_pwr_en_status, pwr_v2p5_en, 0, 1) + +FLD_RAW_RO_DEF( cpu_pwr_status, pg_v3p3, 7, 1) +FLD_RAW_RO_DEF( cpu_pwr_status, pg_vcc_vnn, 6, 1) +FLD_RAW_RO_DEF( cpu_pwr_status, pg_vccsram, 5, 1) +FLD_RAW_RO_DEF( cpu_pwr_status, pg_vddq, 4, 1) +FLD_RAW_RO_DEF( cpu_pwr_status, pg_vcc_ref, 3, 1) +FLD_RAW_RO_DEF( cpu_pwr_status, pg_v1p05, 2, 1) +FLD_RAW_RO_DEF( cpu_pwr_status, pg_v1p8, 1, 1) +FLD_RAW_RO_DEF( cpu_pwr_status, pg_v2p5, 0, 1) + +#endif /* __SYSTEM_CPLD_REG */ diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/system_cpld_sysfs.h b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/system_cpld_sysfs.h new file mode 100644 index 000000000000..e6b03bd1bd0d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/modules/system_cpld_sysfs.h @@ -0,0 +1,76 @@ +#ifndef __SYSTEM_CPLD_SYSFS +#define __SYSTEM_CPLD_SYSFS + +/* generic CPLD sysfs file definition macros */ +#define SYSFS_RAW_RO_ATTR_DEF(field) \ +struct device_attribute field \ + = __ATTR(field, S_IRUGO, system_cpld_##field##_raw_read, NULL); + +#define SYSFS_RAW_RW_ATTR_DEF(field) \ +struct device_attribute field \ + = __ATTR(field, S_IRUGO | S_IWUGO, system_cpld_##field##_raw_read, system_cpld_##field##_raw_write); + +#define SYSFS_MISC_RO_ATTR_DEF(field, _read) \ +struct device_attribute field \ + = __ATTR(field, S_IRUGO, _read, NULL); + +#define SYSFS_MISC_RW_ATTR_DEF(field, _read, _write) \ +struct device_attribute field \ + = __ATTR(field, S_IRUGO | S_IWUGO, _read, _write); + +#define SYSFS_ATTR_PTR(field) \ +&field.attr + + +/* declare system CPLD file system */ +SYSFS_RAW_RO_ATTR_DEF(mjr_rev) +SYSFS_RAW_RO_ATTR_DEF(mnr_rev) + +SYSFS_RAW_RW_ATTR_DEF(scrtch_reg) + +SYSFS_RAW_RO_ATTR_DEF(brd_rev) +SYSFS_RAW_RO_ATTR_DEF(brd_type) + +SYSFS_RAW_RO_ATTR_DEF(ssd_present) +SYSFS_RAW_RW_ATTR_DEF(spi_cs_sel) +SYSFS_RAW_RW_ATTR_DEF(rst_bios_switch) +SYSFS_RAW_RW_ATTR_DEF(cpld_upgrade_rst) + +SYSFS_RAW_RW_ATTR_DEF(cpld_spi_wp) +SYSFS_RAW_RW_ATTR_DEF(system_id_eeprom_wp) +SYSFS_RAW_RW_ATTR_DEF(spi_me_wp) +SYSFS_RAW_RW_ATTR_DEF(spi_bios_wp) +SYSFS_RAW_RW_ATTR_DEF(spi_bak_bios_wp) + +SYSFS_RAW_RW_ATTR_DEF(vrhot_irq_en) +SYSFS_RAW_RW_ATTR_DEF(cpu_thermtrip_irq_en) +SYSFS_RAW_RW_ATTR_DEF(temp_alert_irq_en) +SYSFS_RAW_RO_ATTR_DEF(vrhot_irq) +SYSFS_RAW_RO_ATTR_DEF(cpu_thermtrip_irq) +SYSFS_RAW_RO_ATTR_DEF(temp_alert_irq) + +SYSFS_RAW_RW_ATTR_DEF(wd_timer) +SYSFS_RAW_RW_ATTR_DEF(wd_en) +SYSFS_RAW_RW_ATTR_DEF(wd_punch) + +SYSFS_RAW_RW_ATTR_DEF(mb_rst_en) + +SYSFS_RAW_RO_ATTR_DEF(pwr_v3p3_en) +SYSFS_RAW_RO_ATTR_DEF(pwr_vcc_vnn_en) +SYSFS_RAW_RO_ATTR_DEF(pwr_vccsram_en) +SYSFS_RAW_RO_ATTR_DEF(pwr_vddq_en) +SYSFS_RAW_RO_ATTR_DEF(pwr_vcc_ref_en) +SYSFS_RAW_RO_ATTR_DEF(pwr_v1p05_en) +SYSFS_RAW_RO_ATTR_DEF(pwr_v1p8_en) +SYSFS_RAW_RO_ATTR_DEF(pwr_v2p5_en) + +SYSFS_RAW_RO_ATTR_DEF(pg_v3p3) +SYSFS_RAW_RO_ATTR_DEF(pg_vcc_vnn) +SYSFS_RAW_RO_ATTR_DEF(pg_vccsram) +SYSFS_RAW_RO_ATTR_DEF(pg_vddq) +SYSFS_RAW_RO_ATTR_DEF(pg_vcc_ref) +SYSFS_RAW_RO_ATTR_DEF(pg_v1p05) +SYSFS_RAW_RO_ATTR_DEF(pg_v1p8) +SYSFS_RAW_RO_ATTR_DEF(pg_v2p5) + +#endif /* __SYSTEM_CPLD_SYSFS */ diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/fan-ctrl/fan-ctrl b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/fan-ctrl/fan-ctrl new file mode 100755 index 000000000000..73ff759b6f45 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/fan-ctrl/fan-ctrl @@ -0,0 +1,679 @@ +#!/bin/bash +#/* +#********************************************************************** +#* +#* @filename fan-ctrl +#* +#* @purpose system daemon for controlling system fan pwm +#* +#* @create 2017/06/21 +#* +#* @author nixon.chu +#* +#* @history 2017/06/21: init version +#* +#********************************************************************** +#*/ + +DIR=$(dirname $0) + +# include files +source ${DIR}/funcs.sh + +#/* +#********************************************************************** +#* +#* CONSTANT VARIABLES +#* +#********************************************************************** +#*/ + +# process name/id +DAEMON_NAME=`basename $0` +DAEMON_PID="$$" + +# define symbol for fan/temperature type sensor +SYMBOL_TEMP="TEMP_" +SYMBOL_FAN="FAN_" + +# describe the structure of temperature sensor by id +STRUCT_TEMP_NAME=0 +STRUCT_TEMP_CMD=1 +STRUCT_TEMP_MAX=2 +STRUCT_TEMP_SIZE=$(( ${STRUCT_TEMP_MAX} + 1 )) + +# describe the structure of fan sensor by id +STRUCT_FAN_CMD=0 +STRUCT_FAN_SIZE=$(( ${STRUCT_FAN_CMD} + 1 )) + +# default fan zone configuration file +DEF_ZONE_CONF="${DIR}/fan-zone.conf" + +# default fan zone thermal configuration file +DEF_TEMP_CONF="${DIR}/fan-zone-thermal.conf" + +# default interval (sec) +DEF_INTERVAL=10 + +# default hysteresis (deg C) +DEF_HYSIS=3 + +# default debug mode (0: OFF, 1: ON) +DEF_DEBUG_MODE=0 + +# default log file +DEF_LOG_FILE="/var/log/syslog" + +# default fan level +DEF_FAN_LEVEL=0 + +# default minimum pwm (38.25=255x15%) +DEF_MIN_PWM=39 + +# default zone id +DEF_ZONE_ID=0 + +# error codes +E_STATUS_GOOD=0 +E_STATUS_FAULT=1 +E_INVALID_ARGS=11 +E_INVALID_CONF=12 + +# message levels +MSG_EMERG=0 +MSG_ALERT=1 +MSG_CRIT=2 +MSG_ERR=3 +MSG_WARNING=4 +MSG_NOTICE=5 +MSG_INFO=6 +MSG_DEBUG=7 + +# default message level +DEF_MSG_LEVEL=$MSG_WARNING + +#/* +#********************************************************************** +#* +#* GLOBAL VARIABLES +#* +#********************************************************************** +#*/ + +# temperature sensor group +GBL_TEMP_GRP=() +GBL_TEMP_NUM=${#GBL_TEMP_GRP[@]} + +# fan sensor group +GBL_FAN_GRP=() +GBL_FAN_NUM=${#GBL_FAN_GRP[@]} + +# fan level table +GBL_FAN_LEVEL=() +GBL_LEVEL_NUM=${#GBL_FAN_LEVEL[@]} + +# load defaults +GBL_ZONE_CONF=$DEF_ZONE_CONF +GBL_TEMP_CONF=$DEF_TEMP_CONF +GBL_INTERVAL=$DEF_INTERVAL +GBL_HYSIS=$DEF_HYSIS +GBL_DEBUG_MODE=$DEF_DEBUG_MODE +GBL_LOG_FILE=$DEF_LOG_FILE +GBL_CUR_LEVEL=$DEF_FAN_LEVEL +GBL_MIN_PWM=$DEF_MIN_PWM +GBL_ZONE_ID=$DEF_ZONE_ID +GBL_MSG_LEVEL=$DEF_MSG_LEVEL + +# temperature sensors' readings/statuses/properties (properties list have to be converted with fan level table) +GBL_TEMP_READINGS=() +GBL_TEMP_STATUSES=() +GBL_TEMP_PROPERTY=() + +#/* +#********************************************************************** +#* +#* FUNCTIONS +#* +#********************************************************************** +#*/ + +#/* +#* FEATURE: +#* usage +#* PURPOSE: +#* show the usage of this daemon +#* PARAMETERS: +#* +#* RETURNS: +#* success, this function returns @E_INVALID_ARGS. +#*/ +function usage() { + local dbg_mode + + [ $GBL_DEBUG_MODE -eq 0 ] && dbg_mode="off" || dbg_mode="on" + + echo -e "Usage: $0 [-z zone_file] [-t thermal_file] [-o log_file] [-d]" >&2 + echo -e "" >&2 + echo -e "Arguments:" >&2 + echo -e " -z, --zone-config Fan zone configuration file (default: $DEF_ZONE_CONF)" >&2 + echo -e " -t, --temp-config Fan zone thermal configuration file (default: $DEF_TEMP_CONF)" >&2 + echo -e " -o, --log-file Log file (default: $DEF_LOG_FILE)" >&2 + echo -e " -d, --debug Debug mode (default: $dbg_mode)" >&2 + exit ${E_INVALID_ARGS} +} + +#/* +#* FEATURE: +#* print_msg +#* PURPOSE: +#* print message by message level +#* PARAMETERS: +#* msg_lvl (IN) message level +#* msg (IN) message +#* RETURNS: +#* +#*/ +function print_msg() { + local msg_lvl=$1 + local msg=$2 + + [ $msg_lvl -le $GBL_MSG_LEVEL ] && echo "${msg}" >&2 +} + +#/* +#* FEATURE: +#* err_msg +#* PURPOSE: +#* log error message +#* PARAMETERS: +#* msg (IN) message +#* err_no (IN) error code +#* RETURNS: +#* success, this function returns non-zero error code. +#*/ +function err_msg() { + local msg=$1 + local err_no=$2 + + log_msg $MSG_ERROR "${msg}" + exit ${err_no} +} + +#/* +#* FEATURE: +#* log_msg +#* PURPOSE: +#* log message +#* PARAMETERS: +#* msg_lvl (IN) message level +#* msg (IN) message +#* RETURNS: +#* +#*/ +function log_msg() { + local msg_lvl=$1 + local msg=$2 + + if [ $GBL_LOG_FILE == $DEF_LOG_FILE ]; then + `logger -t $DAEMON_NAME -p $msg_lvl $msg` + else + echo -e "`date +"%b %_d %T"` `hostname` $DAEMON_NAME[$DAEMON_PID]: ${msg}" >> ${GBL_LOG_FILE} + fi + + print_msg $msg_lvl "${msg}" +} + +#/* +#* FEATURE: +#* debug_temp_grp +#* PURPOSE: +#* debug function for showing the temperature sensor group configs +#* @GBL_TEMP_GRP[]: store sensor group configs (sensor name, command, and max_temp) +#* PARAMETERS: +#* +#* RETURNS: +#* +#*/ +function debug_temp_grp() { + if [ $GBL_DEBUG_MODE -ne 0 ]; then + echo "********* Sensor Group *********" + for ((i=0; i<$GBL_TEMP_NUM; i++)) + do + echo -en "`fetch_temp_struct $i $STRUCT_TEMP_NAME`\t" + echo -en "`fetch_temp_struct $i $STRUCT_TEMP_CMD`\t" + echo "`fetch_temp_struct $i $STRUCT_TEMP_MAX`" + done + fi +} + +#/* +#* FEATURE: +#* debug_temp_readings +#* PURPOSE: +#* debug function for showing the temperature sensors' readings +#* @GBL_TEMP_READINGS[]: store current reading for temperature sensors +#* PARAMETERS: +#* +#* RETURNS: +#* +#*/ +function debug_temp_readings() { + if [ $GBL_DEBUG_MODE -ne 0 ]; then + echo "********* Sensor Reading *********" + for ((i=0; i<$GBL_TEMP_NUM; i++)) + do + echo -e "`fetch_temp_struct $i $STRUCT_TEMP_NAME`\t${GBL_TEMP_READINGS[$i]}" + done + fi +} + +#/* +#* FEATURE: +#* debug_temp_property +#* PURPOSE: +#* debug function for showing the temperature sensors' properties +#* @GBL_TEMP_PROPERTY[]: store temperature sensors' properties (asserted temperature for each fan levels) +#* PARAMETERS: +#* +#* RETURNS: +#* +#*/ +function debug_temp_property() { + local size base start_idx level + if [ $GBL_DEBUG_MODE -ne 0 ]; then + echo "********* Sensor Table *********" + for ((i=0; i<${GBL_TEMP_NUM}; i++)) + do + # show array @GBL_TEMP_PROPERTY[]: format name(1) + fan levels(2-?) + size=$(( ${GBL_LEVEL_NUM}+1 )) + base=$i*${size} + start_idx=$(( $base+1 )) + level=${GBL_LEVEL_NUM} + echo -e "${GBL_TEMP_PROPERTY[$base]}\t\t${GBL_TEMP_PROPERTY[@]:$start_idx:$level}" + done + fi +} + +#/* +#* FEATURE: +#* fetch_temp_struct +#* PURPOSE: +#* fetch the member value of specific temperature sensor +#* PARAMETERS: +#* id (IN) sensor id +#* member_id (IN) member id +#* RETURNS: +#* success, returns member value +#*/ +function fetch_temp_struct() { + local id member_id index_base data + + id=$1 + member_id=$2 + + index_base=$(( $id * $STRUCT_TEMP_SIZE )) + data=${GBL_TEMP_GRP[$(($index_base+$member_id))]} + # remove unuseful characters, such as double quotes('"') and the start/end space(' ') of a string. + data=`echo $data | sed 's/^ *\| *$//g' | sed 's/^"\|\"$//g'` + echo $data +} + +#/* +#* FEATURE: +#* fetch_temp_property +#* PURPOSE: +#* fetch the properties of specific temperature sensor +#* PARAMETERS: +#* name (IN) sensor name +#* RETURNS: +#* success, returns an asserted temperature list +#*/ +function fetch_temp_property() { + local name size base start_idx length + + name=$1 + + size=$(( $GBL_LEVEL_NUM+1 )) + for ((i=0; i<${GBL_TEMP_NUM}; i++)) + do + base=$i*${size} + # find sensor by name + if [ ${GBL_TEMP_PROPERTY[${base}]} == "${name}" ]; then + start_idx=$(( $base+1 )) + length=$GBL_LEVEL_NUM + echo ${GBL_TEMP_PROPERTY[@]:$start_idx:$length} + break + fi + done +} + +#/* +#* FEATURE: +#* debug_fan_speed +#* PURPOSE: +#* debug function for showing system current fan level and PWM +#* @GBL_CUR_LEVEL: system current/output fan level +#* PARAMETERS: +#* +#* RETURNS: +#* +#*/ +function debug_fan_speed() { + if [ $GBL_DEBUG_MODE -ne 0 ]; then + # For human readable, the representation of fan level will start from 1. + echo "Current Level: $(( $GBL_CUR_LEVEL+1 )), PWM: ${GBL_FAN_LEVEL[$GBL_CUR_LEVEL]}" + fi +} + +#/* +#* FEATURE: +#* arg_parse +#* PURPOSE: +#* parser for input arguments +#* PARAMETERS: +#* arg_lists[] (IN) argument list +#* RETURNS: +#* +#*/ +function arg_parse() { + while [[ $# -ge 1 ]] + do + key="$1" + case $key in + -z|--zone-config) + [ $# -lt 2 ] && usage + GBL_ZONE_CONF=$2 + [ ! -e $GBL_ZONE_CONF ] && usage + shift # past argument + ;; + -t|--temp-config) + [ $# -lt 2 ] && usage + GBL_TEMP_CONF=$2 + [ ! -e $GBL_TEMP_CONF ] && usage + shift # past argument + ;; + -o|--log-file) + [ $# -lt 2 ] && usage + GBL_LOG_FILE=$2 + shift # past argument + ;; + -d|--debug) + GBL_DEBUG_MODE=1 + ;; + *) + usage # unknown option + ;; + esac + shift # past argument or value + done +} + +#/* +#* FEATURE: +#* valid_conf +#* PURPOSE: +#* check if configuration files are valid +#* PARAMETERS: +#* +#* RETURNS: +#* success, this function returns nothing +#* fail, returns @E_INVALID_CONF +#*/ +function valid_conf() { + local list_1 list_2 match_num + + list_1=("${!1}") + list_2=("${!2}") + + # validate zone config + [ ${GBL_TEMP_NUM} -eq 0 ] && err_msg "config: status=invalid. reason=no TEMPERATURE SENSORS defined." "${E_INVALID_CONF}" + [ ${GBL_FAN_NUM} -eq 0 ] && err_msg "config: status=invalid. reason=no FAN defined." "${E_INVALID_CONF}" + + # validate thermal config + [ ${GBL_LEVEL_NUM} -eq 0 ] && err_msg "config: status=invalid. reason=no FAN LEVELS defined." "${E_INVALID_CONF}" + [ ${#list_2[@]} -ne ${GBL_TEMP_NUM} ] && err_msg "config: status=invalid. reason=the number of temperature sensors is inconsistent." "${E_INVALID_CONF}" + + # compare temperature sensor name between configuration files + match_num=0 + for i in ${!list_1[@]} + do + for j in ${!list_2[@]} + do + [ "${list_1[$i]}" == "${list_2[$j]}" ] && match_num=$(( $match_num+1 )) + done + done + [ $match_num -ne ${GBL_TEMP_NUM} ] && err_msg "config: status=invalid. reason=the name of temperature sensors is inconsistent." "${E_INVALID_CONF}" + + # validate pwm values + for pwm in ${GBL_FAN_LEVEL[@]} + do + expr $pwm + $GBL_MIN_PWM >/dev/null 2>&1 + [ $? -ne 0 ] && err_msg "config: status=invalid. reason=the value of pwm is not integer." "$E_INVALID_CONF" + [ $pwm -lt $GBL_MIN_PWM ] && err_msg "config: status=invalid. reason=the value of fan level is less than MIN_PWM($GBL_MIN_PWM)." "$E_INVALID_CONF" + done +} + +#/* +#* FEATURE: +#* initialize +#* PURPOSE: +#* load zone config and thermal config +#* PARAMETERS: +#* +#* RETURNS: +#* +#*/ +function initialize() { + local data conf_interval conf_hysis conf_min_pwm conf_zone_id conf_msg_level temp_list_1 temp_list_2 + + log_msg $MSG_INFO "Initializing fan control service..." + + # fetch temperature sensor name from configuration files + temp_list_1=(`cat ${GBL_ZONE_CONF} | grep "^${SYMBOL_TEMP}" | awk -F "," {'print $1'}`) + temp_list_2=(`cat ${GBL_TEMP_CONF} | grep "^${SYMBOL_TEMP}" | awk {'print $1'}`) + + # calculate the number of temperature/fan sensors + GBL_TEMP_NUM=${#temp_list_1[@]} + GBL_FAN_NUM=(`cat ${GBL_ZONE_CONF} | grep "^${SYMBOL_FAN}" | awk {'print $2'} | wc -l`) + + # calculate the number of fan levels + GBL_FAN_LEVEL=(`cat ${GBL_TEMP_CONF} | grep "^PWM" | awk -F "PWM" {'print $2'}`) + GBL_LEVEL_NUM=${#GBL_FAN_LEVEL[@]} + + # check if the interval/hyteresis should be updated. + conf_interval=`cat ${GBL_ZONE_CONF} | grep "^INTERVAL=" | awk -F "=" {'print $2'} | tail` + [ ! -z ${conf_interval} ] && GBL_INTERVAL=${conf_interval} + conf_hysis=`cat ${GBL_ZONE_CONF} | grep "^HYTERESIS=" | awk -F "=" {'print $2'} | tail` + [ ! -z ${conf_hysis} ] && GBL_HYSIS=${conf_hysis} + conf_min_pwm=`cat ${GBL_ZONE_CONF} | grep "^MIN_PWM=" | awk -F "=" {'print $2'} | tail` + [ ! -z ${conf_min_pwm} ] && GBL_MIN_PWM=${conf_min_pwm} + conf_zone_id=`cat ${GBL_ZONE_CONF} | grep "^ZONE_ID=" | awk -F "=" {'print $2'} | tail` + [ ! -z ${conf_zone_id} ] && GBL_ZONE_ID=${conf_zone_id} + conf_msg_level=`cat ${GBL_ZONE_CONF} | grep "^MSG_LEVEL=" | awk -F "=" {'print $2'} | tail` + [ ! -z ${conf_msg_level} ] && GBL_MSG_LEVEL=${conf_msg_level} + + # load zone config + for ((i=1; i<=${GBL_TEMP_NUM}; i++)) + do + GBL_TEMP_STATUSES+=($E_STATUS_GOOD) + data=`cat ${GBL_ZONE_CONF} | grep "^${SYMBOL_TEMP}" | awk NR==$i` + # FIXME + GBL_TEMP_GRP+=("`echo $data | awk -F ", " {'print $1'}`") + GBL_TEMP_GRP+=("`echo $data | awk -F ", " {'print $2'}`") + GBL_TEMP_GRP+=("`echo $data | awk -F ", " {'print $3'}`") + done + debug_temp_grp + + for ((i=1; i<=${GBL_FAN_NUM}; i++)) + do + data=`cat ${GBL_ZONE_CONF} | grep "^${SYMBOL_FAN}" | awk NR==$i{'print $2'}` + GBL_FAN_GRP+=("`echo $data`") + done + + # load thermal config + for ((i=0; i<${GBL_TEMP_NUM}; i++)) + do + index=$(( $i * ${STRUCT_TEMP_SIZE} + ${STRUCT_TEMP_NAME} )) + sensor_name=${GBL_TEMP_GRP[$index]} + GBL_TEMP_PROPERTY+=(`cat ${GBL_TEMP_CONF} | grep "^${sensor_name}" | tail`) + done + debug_temp_property + + # check if the config files is valid + valid_conf temp_list_1[@] temp_list_2[@] +} + +#/* +#* FEATURE: +#* temperature_collection +#* PURPOSE: +#* collect all temperature sensor readlings +#* PARAMETERS: +#* +#* RETURNS: +#* success, returns a series of reading @GBL_TEMP_READINGS[] +#*/ +function temperature_collection() { + local name cmd max_temp reading status pre_status + + GBL_TEMP_READINGS=() + for ((i=0; i<${GBL_TEMP_NUM}; i++)) + do + # read temperature sensor value & record sensor status + name=`fetch_temp_struct $i ${STRUCT_TEMP_NAME}` + cmd=`fetch_temp_struct $i ${STRUCT_TEMP_CMD}` + max_temp=`fetch_temp_struct $i ${STRUCT_TEMP_MAX}` + reading=`eval ${cmd} 2>/dev/null` + if [ $? -eq 0 ]; then + GBL_TEMP_READINGS+=($reading) + status=$E_STATUS_GOOD + else + GBL_TEMP_READINGS+=($max_temp) + status=$E_STATUS_FAULT + fi + + # Compare previous status of temperature sensor, then update it. + pre_status=${GBL_TEMP_STATUSES[$i]} + if [ $pre_status -eq $E_STATUS_GOOD ] && [ $status -eq $E_STATUS_FAULT ]; then + # Good -> Fault + log_msg $MSG_WARN "[ZONE_${GBL_ZONE_ID}] Sensor $name: status=ERROR. reason=read sensor failed." + elif [ $pre_status -eq $E_STATUS_FAULT ] && [ $status -eq $E_STATUS_GOOD ]; then + # Fault -> Good + log_msg $MSG_WARN "[ZONE_${GBL_ZONE_ID}] Sensor $name: status=RECOVER. reason=reading is $reading deg C" + fi + GBL_TEMP_STATUSES[$i]=$status + done + debug_temp_readings +} + +#/* +#* FEATURE: +#* fan_level_selection +#* PURPOSE: +#* select proper fan level by temperature sensor reading +#* PARAMETERS: +#* reading_list (IN) sensor reading list +#* RETURNS: +#* success, returns a fan level value +#*/ +function fan_level_selection() { + local reading_list name reading temp_list highest_level pre_level next_level hysis_temp res res1 + + reading_list=("${!1}") + highest_level=0 + pre_level=${GBL_CUR_LEVEL} + next_level=0 + + # search fan table by each temperature sensor reading + for ((i=0; i<${GBL_TEMP_NUM}; i++)) + do + name=`fetch_temp_struct $i $STRUCT_TEMP_NAME` + reading=${reading_list[$i]} + temp_list=(`fetch_temp_property ${name}`) + for j in ${!temp_list[@]} + do + res=`echo $reading \<= ${temp_list[$j]} | bc -l` + if [ $res -eq 1 ] || [ $j -eq $((${#temp_list[@]}-1)) ]; then + if [ $j -gt $highest_level ]; then + highest_level=$j + fi + break + fi + done + done + + if [ $highest_level -lt $pre_level ]; then + # Determine if require decreasing current fan level @assert_level + local pass_num + pass_num=0 + for ((i=0; i<${GBL_TEMP_NUM}; i++)) + do + name=`fetch_temp_struct $i $STRUCT_TEMP_NAME` + reading=${reading_list[$i]} + temp_list=(`fetch_temp_property ${name}`) + assert_level=$(( $pre_level-1 )) + hysis_temp=`echo ${temp_list[$assert_level]} - $GBL_HYSIS | bc` + res=`echo $reading \<= $hysis_temp | bc -l` + if [ $res -eq 1 ]; then + pass_num=$(( $pass_num+1 )) + else + break + fi + done + if [ $pass_num -eq ${GBL_TEMP_NUM} ]; then + # Decrease fan pwm: All sensor reading should less than its own hysteresis temperature + next_level=${highest_level} + else + # Keep current fan pwm + next_level=${pre_level} + fi + else + # Increase fan pwm + next_level=${highest_level} + fi + GBL_CUR_LEVEL=${next_level} +} + +#/* +#* FEATURE: +#* apply_fan_level +#* PURPOSE: +#* convert given fan level to PWM, then output to fans +#* PARAMETERS: +#* fan_list (IN) fan devices list +#* fan_level (IN) fan level +#* RETURNS: +#* success, returns a pwm value +#*/ +function apply_fan_level() { + local fan_level fan_list + + fan_list=("${!1}") + fan_level=$2 + + for fan in ${fan_list[@]} + do + echo ${GBL_FAN_LEVEL[$fan_level]} > $fan + done + debug_fan_speed +} + +#/* +#********************************************************************** +#* +#* MAIN +#* +#********************************************************************** +#*/ +Platform_init +arg_parse $@ +initialize +log_msg $MSG_INFO "Starting fan control service..." +while [ true ]; do + temperature_collection + fan_level_selection GBL_TEMP_READINGS[@] + apply_fan_level GBL_FAN_GRP[@] ${GBL_CUR_LEVEL} + sleep $GBL_INTERVAL +done + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/fan-ctrl/fan-zone-thermal_B2F.conf b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/fan-ctrl/fan-zone-thermal_B2F.conf new file mode 100644 index 000000000000..fc37dda47f47 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/fan-ctrl/fan-zone-thermal_B2F.conf @@ -0,0 +1,13 @@ +##### Temperature vs Fan table ##### +## FORMAT: "PWM" fan speed(range from 0 to 255) +# Duty Cycle 30% 32.5% 35% 37.5% 40% 45% 50% 55% 60% 65% 70% 75% 80% 90% 100% +PWM 77 83 89 95 102 114 128 141 153 166 179 192 204 230 255 +## FORMAT: sensor name(TEMP_XXX) with asserted temperature by each levels +TEMP_CPU 46 48 50 52 54 57 60 63 66 69 72 75 78 81 84 +TEMP_SWITCH 72 74 76 78 80 83 86 89 92 95 98 101 104 107 110 +#TEMP_HDD 25 +#TEMP_TMP75_CPU 25 +#TEMP_TMP75_CENTER 25 +#TEMP_TMP75_RIGHT 33 37 45 53 61 69 77 85 93 +TEMP_TMP75_FAN 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 +TEMP_XCVR 36 38 40 42 44 46 48 50 52 54 56 58 60 63 66 diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/fan-ctrl/fan-zone-thermal_F2B.conf b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/fan-ctrl/fan-zone-thermal_F2B.conf new file mode 100644 index 000000000000..ee316c66bd06 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/fan-ctrl/fan-zone-thermal_F2B.conf @@ -0,0 +1,12 @@ +##### Temperature vs Fan table ##### +## FORMAT: "PWM" fan speed(range from 0 to 255) +# Duty Cycle 29% 31% 33% 35% 37.5% 40% 45% 50% 55% 60% 65% 70% 75% 80% 90% 100% +PWM 74 79 84 89 96 102 115 128 140 153 166 179 191 204 230 255 +## FORMAT: sensor name(TEMP_XXX) with asserted temperature by each levels +TEMP_CPU 51 53 55 57 59 61 63 65 67 69 71 73 75 77 79 81 +TEMP_SWITCH 69 71 73 75 77 79 81 83 85 87 89 91 93 95 97 99 +#TEMP_HDD 25 +#TEMP_TMP75_CPU 25 +#TEMP_TMP75_CENTER 25 +TEMP_TMP75_RIGHT 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 +#TEMP_TMP75_FAN 25 diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/fan-ctrl/fan-zone_B2F.conf b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/fan-ctrl/fan-zone_B2F.conf new file mode 100644 index 000000000000..b51f3b7aa67d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/fan-ctrl/fan-zone_B2F.conf @@ -0,0 +1,38 @@ +##### ZONE ID ##### +ZONE_ID=0 + +##### SENSOR GROUP START ##### +## FORMAT: name(TEMP_XXX), command, max_temp(deg C) +TEMP_CPU, "data=`sensors | grep coretemp -A2`; [ $? -ne 0 ] && exit 1; echo "$data" | tail -n1 | awk {'print $4'} | sed 's/^+\|°C//g'", 110 +TEMP_SWITCH, "[ `file /var/run/docker-syncd/sswsyncd.socket | grep -c " socket"` -ne 1 ] && exit 1; [ `ss -a | grep "/var/run/sswsyncd/sswsyncd.socket" |grep -c "LISTEN"` -ne 1 ] && exit 1; data=`bcmcmd -c "show temp" | grep "temperature monitor"`; [ $? -ne 0 ] && exit 1; switch_temps=(`echo "$data" | awk {'print $5'} | sed 's/,//g'`); high_temp=0; for reading in ${switch_temps[@]}; do res=`echo "$reading > $high_temp" | bc -l`; [ $res -eq 1 ] && high_temp=$reading; done; echo $high_temp", 120 +#TEMP_HDD, "data=`hddtemp /dev/sdb | grep -v "not available"`; [ $? -ne 0 ] && exit 1; echo "$data" | awk -F ": " {'print $3'} | sed 's/°C//g'", 85 +#TEMP_TMP75_CPU, "data=`sensors | grep tmp75-i2c-0-4e -A2`; [ $? -ne 0 ] && exit 1; echo "$data" | tail -n1 | awk {'print $2'} | sed 's/^+\|°C//g'", 125 +#TEMP_TMP75_CENTER, "data=`sensors | grep tmp75-i2c-4-4a -A2`; [ $? -ne 0 ] && exit 1; echo "$data" | tail -n1 | awk {'print $2'} | sed 's/^+\|°C//g'", 125 +#TEMP_TMP75_RIGHT, "data=`sensors | grep tmp75-i2c-4-4c -A2`; [ $? -ne 0 ] && exit 1; echo "$data" | tail -n1 | awk {'print $2'} | sed 's/^+\|°C//g'", 125 +TEMP_TMP75_FAN, "data=`sensors | grep tmp75-i2c-4-4d -A2`; [ $? -ne 0 ] && exit 1; echo "$data" | tail -n1 | awk {'print $2'} | sed 's/^+\|°C//g'", 125 +##### SENSOR GROUP END ##### + +##### FAN GROUP START ##### +## FORMAT: name(FAN_YYY) input_files +FAN_1 /sys/bus/i2c/devices/3-0020/hwmon/hwmon*/pwm1 +FAN_2 /sys/bus/i2c/devices/3-0020/hwmon/hwmon*/pwm2 +FAN_3 /sys/bus/i2c/devices/3-0020/hwmon/hwmon*/pwm3 +FAN_4 /sys/bus/i2c/devices/3-0020/hwmon/hwmon*/pwm4 +FAN_5 /sys/bus/i2c/devices/3-0020/hwmon/hwmon*/pwm5 +FAN_6 /sys/bus/i2c/devices/3-0020/hwmon/hwmon*/pwm6 +FAN_7 /sys/bus/i2c/devices/3-0023/hwmon/hwmon*/pwm1 +FAN_8 /sys/bus/i2c/devices/3-0023/hwmon/hwmon*/pwm2 +FAN_9 /sys/bus/i2c/devices/3-0023/hwmon/hwmon*/pwm3 +FAN_10 /sys/bus/i2c/devices/3-0023/hwmon/hwmon*/pwm4 +FAN_11 /sys/bus/i2c/devices/3-0023/hwmon/hwmon*/pwm5 +FAN_12 /sys/bus/i2c/devices/3-0023/hwmon/hwmon*/pwm6 +##### FAN GROUP END ##### + +##### INTERVAL (sec) ##### +INTERVAL=10 + +##### HYTERESIS (deg C) ##### +HYTERESIS=2 + +##### MINIMUM PWM (38.25=255x15%) ##### +MIN_PWM=39 diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/fan-ctrl/fan-zone_F2B.conf b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/fan-ctrl/fan-zone_F2B.conf new file mode 100644 index 000000000000..2d5987c5c66b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/fan-ctrl/fan-zone_F2B.conf @@ -0,0 +1,38 @@ +##### ZONE ID ##### +ZONE_ID=0 + +##### SENSOR GROUP START ##### +## FORMAT: name(TEMP_XXX), command, max_temp(deg C) +TEMP_CPU, "data=`sensors | grep coretemp -A2`; [ $? -ne 0 ] && exit 1; echo "$data" | tail -n1 | awk {'print $4'} | sed 's/^+\|°C//g'", 110 +TEMP_SWITCH, "[ `file /var/run/docker-syncd/sswsyncd.socket | grep -c " socket"` -ne 1 ] && exit 1; [ `ss -a | grep "/var/run/sswsyncd/sswsyncd.socket" |grep -c "LISTEN"` -ne 1 ] && exit 1; data=`bcmcmd -c "show temp" | grep "temperature monitor"`; [ $? -ne 0 ] && exit 1; switch_temps=(`echo "$data" | awk {'print $5'} | sed 's/,//g'`); high_temp=0; for reading in ${switch_temps[@]}; do res=`echo "$reading > $high_temp" | bc -l`; [ $res -eq 1 ] && high_temp=$reading; done; echo $high_temp", 120 +#TEMP_HDD, "data=`hddtemp /dev/sdb | grep -v "not available"`; [ $? -ne 0 ] && exit 1; echo "$data" | awk -F ": " {'print $3'} | sed 's/°C//g'", 85 +#TEMP_TMP75_CPU, "data=`sensors | grep tmp75-i2c-0-4e -A2`; [ $? -ne 0 ] && exit 1; echo "$data" | tail -n1 | awk {'print $2'} | sed 's/^+\|°C//g'", 125 +#TEMP_TMP75_CENTER, "data=`sensors | grep tmp75-i2c-4-4a -A2`; [ $? -ne 0 ] && exit 1; echo "$data" | tail -n1 | awk {'print $2'} | sed 's/^+\|°C//g'", 125 +TEMP_TMP75_RIGHT, "data=`sensors | grep tmp75-i2c-4-4c -A2`; [ $? -ne 0 ] && exit 1; echo "$data" | tail -n1 | awk {'print $2'} | sed 's/^+\|°C//g'", 125 +#TEMP_TMP75_FAN, "data=`sensors | grep tmp75-i2c-4-4d -A2`; [ $? -ne 0 ] && exit 1; echo "$data" | tail -n1 | awk {'print $2'} | sed 's/^+\|°C//g'", 125 +##### SENSOR GROUP END ##### + +##### FAN GROUP START ##### +## FORMAT: name(FAN_YYY) input_files +FAN_1 /sys/bus/i2c/devices/3-0020/hwmon/hwmon*/pwm1 +FAN_2 /sys/bus/i2c/devices/3-0020/hwmon/hwmon*/pwm2 +FAN_3 /sys/bus/i2c/devices/3-0020/hwmon/hwmon*/pwm3 +FAN_4 /sys/bus/i2c/devices/3-0020/hwmon/hwmon*/pwm4 +FAN_5 /sys/bus/i2c/devices/3-0020/hwmon/hwmon*/pwm5 +FAN_6 /sys/bus/i2c/devices/3-0020/hwmon/hwmon*/pwm6 +FAN_7 /sys/bus/i2c/devices/3-0023/hwmon/hwmon*/pwm1 +FAN_8 /sys/bus/i2c/devices/3-0023/hwmon/hwmon*/pwm2 +FAN_9 /sys/bus/i2c/devices/3-0023/hwmon/hwmon*/pwm3 +FAN_10 /sys/bus/i2c/devices/3-0023/hwmon/hwmon*/pwm4 +FAN_11 /sys/bus/i2c/devices/3-0023/hwmon/hwmon*/pwm5 +FAN_12 /sys/bus/i2c/devices/3-0023/hwmon/hwmon*/pwm6 +##### FAN GROUP END ##### + +##### INTERVAL (sec) ##### +INTERVAL=10 + +##### HYTERESIS (deg C) ##### +HYTERESIS=2 + +##### MINIMUM PWM (38.25=255x15%) ##### +MIN_PWM=39 diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/fan-ctrl/funcs.sh b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/fan-ctrl/funcs.sh new file mode 100755 index 000000000000..3e417f699543 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/fan-ctrl/funcs.sh @@ -0,0 +1,22 @@ +#!/bin/bash +#/* +#********************************************************************** +#* +#* @filename funcs.sh +#* +#* @purpose api functions script for fan-ctrl +#* +#* @create 2017/08/09 +#* +#* @author nixon.chu +#* +#* @history 2017/08/09: init version +#* +#********************************************************************** +#*/ + +DIR=$(dirname $0) + +function Platform_init() { + ${DIR}/init.sh +} diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/fan-ctrl/init.sh b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/fan-ctrl/init.sh new file mode 100755 index 000000000000..06df071fa147 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/fan-ctrl/init.sh @@ -0,0 +1,26 @@ +#!/bin/bash +DIR=$(dirname $0) + +# board type +BOARD_TYPE=`cat /sys/bus/i2c/devices/1-0032/brd_type` + +# fan tables +FORWARD_SENSOR_CONF=${DIR}/fan-zone_F2B.conf +FORWARD_PWM_CONF=${DIR}/fan-zone-thermal_F2B.conf +REVERSE_SENSOR_CONF=${DIR}/fan-zone_B2F.conf +REVERSE_PWM_CONF=${DIR}/fan-zone-thermal_B2F.conf + +# Nixon: Please refer to "BMS CPLD Design Spec." +# board type : BRD_TYPE[3:0] +# 0x0 (0000b): BMS_AC_PSU_NORMAL_FAN, 0x2 (0010b): BMS_DC_PSU_NORMAL_FAN +# 0x1 (0001b): BMS_AC_PSU_REVERSE_FAN, 0x3 (0011b): BMS_DC_PSU_REVERSE_FAN +case $BOARD_TYPE in + 0x0|0x2) + ln -sf $FORWARD_SENSOR_CONF ${DIR}/fan-zone.conf + ln -sf $FORWARD_PWM_CONF ${DIR}/fan-zone-thermal.conf + ;; + 0x1|0x3) + ln -sf $REVERSE_SENSOR_CONF ${DIR}/fan-zone.conf + ln -sf $REVERSE_PWM_CONF ${DIR}/fan-zone-thermal.conf + ;; +esac diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/script/funcs.sh b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/script/funcs.sh new file mode 100755 index 000000000000..4b0c4c35471f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/script/funcs.sh @@ -0,0 +1,23 @@ +#/bin/bash + +# process name/id +DAEMON_NAME=`basename $0` +DAEMON_PID="$$" + +DEF_SEVERITY="INFO" + +#/* +#* FEATURE: +#* log_msg +#* PURPOSE: +#* log message +#* PARAMETERS: +#* msg (IN) message +#* RETURNS: +#* +#*/ +function log_msg() { + local msg=$1 + + `logger -t $DAEMON_NAME -p $DEF_SEVERITY $msg` +} diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/script/start_service.sh b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/script/start_service.sh new file mode 100755 index 000000000000..5049c0637be4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/script/start_service.sh @@ -0,0 +1,162 @@ +#/bin/bash + +DIR=$(dirname $0) + +# include files +source ${DIR}/funcs.sh + +ACPI_INSTALL_PRINT=0 +ACPID_INSTALL_PRINT=0 +ACPI_SUPPORT_BASE_INSTALL_PRINT=0 +BC_INSTALL_PRINT=0 +ACPID_SOCKET_PRINT=0 +ACPI_GPE01_PRINT=0 +ACPI_GPE02_PRINT=0 +ACPI_GPE47_PRINT=0 +ACPI_STATUS=0 + +while [ 1 ] +do + if [ `dpkg -l |grep -c "acpi "` -eq "0" ]; then + dpkg -i /opt/debs/acpi_1.7-1_amd64.deb + if [ "$?" -ne "0" ]; then + if [ $ACPI_INSTALL_PRINT -eq 0 ]; then + ACPI_INSTALL_PRINT=1 + log_msg "Wait for acpi package install." + fi + sleep 1 + continue + else + log_msg "Install acpi package success." + fi + fi + break +done + +while [ 1 ] +do + if [ `dpkg -l |grep -c "acpid "` -eq "0" ]; then + dpkg -i /opt/debs/acpid_2.0.23-2_amd64.deb + if [ "$?" -ne "0" ]; then + if [ $ACPID_INSTALL_PRINT -eq 0 ]; then + ACPID_INSTALL_PRINT=1 + log_msg "Wait for acpid package install." + fi + sleep 1 + continue + else + log_msg "Install acpid package success." + fi + fi + break +done + +while [ 1 ] +do + if [ `dpkg -l |grep -c "acpi-support-base"` -eq "0" ]; then + dpkg -i /opt/debs/acpi-support-base_0.142-6_all.deb + if [ "$?" -ne "0" ]; then + if [ $ACPI_SUPPORT_BASE_INSTALL_PRINT -eq 0 ]; then + ACPI_SUPPORT_BASE_INSTALL_PRINT=1 + log_msg "Wait for acpi-support-base package install." + fi + sleep 1 + continue + else + log_msg "Install acpi-support-base package success." + fi + fi + break +done + +while [ 1 ] +do + if [ `dpkg -l |grep -c " bc "` -eq "0" ]; then + dpkg -i /opt/debs/bc_1.06.95-9_amd64.deb + if [ "$?" -ne "0" ]; then + if [ $BC_INSTALL_PRINT -eq 0 ]; then + BC_INSTALL_PRINT=1 + log_msg "Wait for bc package install." + fi + sleep 1 + continue + else + log_msg "Install bc package success." + fi + fi + break +done + +while [ 1 ] +do + if [ ! -e "/sys/firmware/acpi/interrupts/gpe01" ]; then + if [ $ACPI_GPE01_PRINT -eq 0 ]; then + ACPI_GPE01_PRINT=1 + log_msg "Wait for acpi gpe01 ready." + fi + sleep 1 + continue + fi + log_msg "The acpi gpe01 ready." + break +done + +while [ 1 ] +do + if [ ! -e "/sys/firmware/acpi/interrupts/gpe02" ]; then + if [ $ACPI_GPE02_PRINT -eq 0 ]; then + ACPI_GPE02_PRINT=1 + log_msg "Wait for acpi gpe02 ready." + fi + sleep 1 + continue + fi + log_msg "The acpi gpe02 ready." + break +done + +while [ 1 ] +do + if [ ! -e "/sys/firmware/acpi/interrupts/gpe47" ]; then + if [ $ACPI_GPE47_PRINT -eq 0 ]; then + ACPI_GPE47_PRINT=1 + log_msg "Wait for acpi gpe47 ready." + fi + sleep 1 + continue + fi + log_msg "The acpi gpe47 ready." + break +done + +while [ 1 ] +do + if [ ! -e "/var/run/acpid.socket" ]; then + if [ $ACPID_SOCKET_PRINT -eq 0 ]; then + ACPID_SOCKET_PRINT=1 + log_msg "Wait for acipd daemon start." + fi + sleep 1 + continue + fi + log_msg "The acpid daemon start." + break +done + +while [ 1 ] +do + if [ `/etc/init.d/acpid status | grep -c "active (running)"` -eq "0" ]; then + if [ $ACPI_STATUS -eq 0 ]; then + ACPI_STATUS=1 + log_msg "Wait for acpid running." + fi + sleep 1 + continue + fi + log_msg "The acpid running now." + break +done + +/etc/init.d/xcvr_servd start +/etc/init.d/sys_servd start +exit 0; diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/script/start_watchdog.sh b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/script/start_watchdog.sh new file mode 100755 index 000000000000..2268e5e0d16e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/script/start_watchdog.sh @@ -0,0 +1,32 @@ +#/bin/bash + +DIR=$(dirname $0) + +# include files +source ${DIR}/funcs.sh + +WATCHDOG_PRINT=0 + +while [ 1 ] +do + if [ `dpkg -l |grep -c "watchdog "` -eq "0" ]; then + dpkg -i /opt/debs/watchdog_5.14-3_amd64.deb + if [ "$?" -ne "0" ]; then + if [ $WATCHDOG_PRINT -eq 0 ]; then + WATCHDOG_PRINT=1 + log_msg "Wait for watchdog package install." + fi + sleep 1 + continue + else + log_msg "Install watchdog package success." + fi + fi + break +done + +ln -sf /opt/watchdog/watchdog.conf /etc/watchdog.conf + +/usr/sbin/watchdog -c /etc/watchdog.conf + +exit 0; diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/sys-serv/sys-servd b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/sys-serv/sys-servd new file mode 100755 index 0000000000000000000000000000000000000000..a1b4f177897c42c8a94085c9ff05092e187a83d5 GIT binary patch literal 56280 zcmeHw3t&{$(f>_CG@_6QSnQ2L`h}JMq_;LWd(S5ccvc2j?;F&6AX{a?MNaZ<~S8f&Dy;3DLv@8!JC?Dy% zN9cQ2mM~t!d1rIdn&weZ=OgtfUx(!DkbE{2#X1D)`cd8J-5W#Dhm!2etZ{LeDr0~zGskpZ8V z!EP6W--Cb2*N6<|K9m9fHUy-z&qW#duK~X&xlp9PltItz4ESxxldjy(4EQw}^yw6Q zG~bJy#)UW-3{l)0YWXM4oZ>GJ1Osy`>qCLy%qiolYHI>BOXpMtEWdwlb#0BmK2#bE z`Tdsv>IMGk!Z)s}w7x!2ud=7jTz$L0K2TF`0fuW3Z|BopZC#*-U@%Y?s9X@Rph#V4 zUNBHvPTCY%3xk!RfF&q@bvP7Q1m)^O!P*9kxUBjHXjz@aQCU+NvQdFWNI?Dqs2>Oh zYij*fwPmHD%Gw&6MaczvzKtq_bfe_bP$=kUv1PS2HGwimJX7ieq586Uf%3Z2V5y^w zn^ap>S=L~cRn^ufR|w{yqEYuUs`V(V9?3w+s;>)H)`Ti7RJW$Ay3VSvoLf^`WtEo( z&^C%IX>{)(KWu%7v=}L93>+EC76IO?hR|Dy^!US6W{i zL{U|NK%G@uRu-tQCs|xvCusviLvCqH)`U zf1%SVPoUDS5(c7w19(jjpHB1~>l&M$ZQX-DqUQ(qf9pX^D{`&tK_{Hz&$jv7R+j*) z=16_{PX2tegl~?=Ux>4>JOi(FCSrksmnjbC>1*KiT!#oA18>d;2N`%OTVF*6-kE_| z)@TC{L)e$sz<0N?mgO_>CmQ%^2L2=ie}jSVVc<&)d`|;E&%oy!_&Nix+lI)C4E)Ik z|55{Q#?2K5p5|ZrT4UgQYb4-W15a~3eKi~SQ#2BAy@CIdf!|=@Pc`tH47}+-Q3HRP z!N0@6pKjn=4g47fevg6IYY8H^8Thjd{+NN6B>_`A417O>ztg~b47|0bgj3{$=NR}r z1Anf8FEH@u8Th^iet?1Z82Et(evpAb-@q3cc$zEeYqWvCP$L1o2L8(i-e=%1GVs$3 z{9prrgMlwJ@V>_VdA_FHTbFt)-|}cEH+CPQgs*XX-U|j3ZWAM~21{bVWc3iAOm-jM5ZR;u|=9A*Csl#G5&NE~P1i#Mf~8bV}1w zD!!D{y(mr17_Z}WcS=(TiI;FXo6;0I;?p?&*L0AO`HDG=+e88>hEXn!0|xmD8IkOl+*W8n!0Sfj?>?uGQeCyoW79K{VCnd>2oPfT`RtZ)2CCKx>S5A zr+ZPFx>CH3)7>deT_|3{>1;}0K?jNDuw%q{yzX_#*H5 z8uxZgn>nc^+Fb6nd@Wmx7_`j4)N92iqT&ZC^81aqtW6UiFR^C%273W~jh#Jxk@pvz zu?f<++njvs^F&Crfq5Arty^EHpsP@)w-9}n@9qy-z}C-mAix*t@NJD<<;!}}x9juJ zDYmo|wY2hLg*h*6DDl44ZejoDL z!akx5iPl@=cOVblqsM!Ek;O4zB;3|g+)2u|6dxqeG^^9sR2+-E?u)c={@8+pi9}=@ zkZq9y`rBkRb|%6jV}-ysS&`y{O~nTzEipgrP0!$3@3xL(}EahTQn0q*QT-Z&kSU8B%bw2Y*mrKZrxL zYPdM|qkk$z4m1@X0O55aup*GfigdUY832a%8TlKFTk|(Y8#}YYXQA9Zq;cN>G^XyY zG(LzLwhs_SA6X`{3tXd#%c?vfVpb)a9w)?ES@6#ep`TKt(TNBm7K z#RsUk_KA?Pst=s^KvpXncUAF9U*yHe8?j}hlX8C*xtoetk}Kv@$!lB2FQ+xL)!w}k znHv`$$XfEGtwpo0$2{h38o#`?u`?%hhLOq&^{`XRqv6Yt*i7;wTVH)I0$tFb&S?eV zTwl|2GGkK#IJOAKzDUOj=0}bW=mTv5z-Yq z&5)h#Dk&>mq-kr&h9sWcA+2~K7~&su9IJ7EL1Zxnvn>fSRZHxvBQ490Rdt9}YvH16 z5vw{{iuZ#B4)vS@94=alpQ03a;3J4>t7f4C(LIIISPp_tq_eC`BT|2JXA6qS@_VZ7N>h7|n_luWy>Q9vL~$_mHRkT%vSlFFZXR$715R z>c!${Ipsm;o4>j*c>`G_ zG)b!7eknvI)q4}wJ9L&R5oHIGWIkrdToPr|hRU_PS*h}#VtJ#L?qaT5?EOi_v)i4b zvXY9r$}H+f%0qg7nn=X|3^z(MxS*+YqoxkvPalAjphqVU;MKqz1NbAKBo8h-++qB$ ze}2}NV5nJ83!ZJbjo8joDjQ;m1@u3M9UL<)>Db1)rhQhJFdbtJJ`f>NaF8E zKzj2X$~-?L^=$Jz{Wq6+_JQbDA;~-=RaHLSlgT_Yp;@wdXwhVw=RPp72ifMyQk8Mc z<6)(e&2x2%Zb|0(Hp?ON{G0?Foq3j#dbW8U{K#dV77)8M&zDqHU>Lk$1t1DJW7HZe-o57I7-vbelZZCfP2-Qj|)v%iXrbhm=HP+FXQQwTr0-M-U2c4xHcLm-EW}xakzJe5hL_s~ts~L8 z*R|QbZVJ%0-NG|~4K8h)NsCNf&b7)jGr***b4g$Z48_%6F=e zGYtY!`3}^&Bf*vLpeXW>57Sltyp-aSDj($HI#JgZq$qV0syrbUDui8mFDkzSm5(|# z$Dr5}dj%!?R!z%-mQgfftGMnC(sNaqmR>uap$9RWQ6FmBSWi&&B=_=|mld}SbUPGM z20~eEpiAA&6}9!e17mRZU4x)BgkGZZZMnhCeJ{8-Va!XkPlh5LjnxOUnr0nT6Z9Nk z7EEjTR{46w`xrkyK$-^Ui4vAa6BymC5Yw0ui3Gr4co7T^?aCqcKdboLF9rVEz}SV z;Kr|-qMP;m`)OGh&Tc=6We%?gG+o9k-4)|PL~b&XU#(ZZWPpf)&(Y!4Ij zSZLSRwjowA&#y<`*e95gIAlzoBjL`-tOL(`o+zmE^EoVo2LQG&G~%vag;X|HFl(^ znLHG2B}HF=YdJKPiIv=mqQ%EU$D=58t8*2(gzE5kD%n_xVh<&<7*loGH`yO)-P)F& z)tVJWScyN$P2Rcrw=ci^@~2pIZH?tbqD|eFFNLl=C134kczx@KIaq=+e`Lp}?`{1c z$Ch`&*2vCCt8Z)DacFVu7l|98TQo*Xe7VYzd~lki;xwbfg>IxqtXJ6E)CyZF9;T&U zQ}KSp2)kr>P5#$M^6YuPC{HUatZer?!nHHIkXkP)k^9cAsU^B>SrS?N1Z?SrS!AWz zRQv>d-tIG|#Fp53Sox4D^OCpDSzHazJDAqEe+Ks$8My}9`{a79VRla+yi3|fNN{4ANJOC z&tkDXT5_A0VXKl&XXt~TiYVIQi_D6ta4-Qeh@ymw8i+$36o)8HAp_}Hq(E_Agx0ew z#^LFC?zY_^0eqb*L{M~~CVeM{9Xh5Tz@3xNiCau;fl&B@-32JdcG3n8%{96`K+=?y zpP5pONT8@oAx2Ex-oI&<5gaIHLtYfVM8fEjsCL4V*Hz{jF449VaiHPtt2TRdlL*`oF72Mv5{v2oOa^)CEJ610ni4JTeSXD#_74clQE9=$s2 zMJ{e^Gf>`{%iEfAzuxGvF4>0hlv=nw-cO%%RubCaPW;aFtWUJ)5Pg&nZ7Y1ZDR zDKW$lR{T-)zt}(7r)gUkaVX4Qywr@}Uiyrn|;mByv_G^vErlM_A9@QLEJ`T%hgH~Twl>TmQ%kkw} z50Rh3>3DH4a32rFtp1f`mZscSF|D|y_~4z7rV2)`ZCgC^Tq=ejfk)bjZuV4(H5&36_XxJ?$RlCp{cd2=pD(y=juZiEyZGknF5L``Nx=( z>GouExk|2!EPfazuR$ztb_Rdy*)#W|zXMD6A7Yr%&RWtREvsB!q}H zEjVrgckLtYdcuO26&A=8pGDlJAp!>7uX@)dC=0s-S>ZciV{|1rMJGB@_#AN1rq{MD zQ>h{IA&Y03vB#lkya?XOjM)a`JU8Rli1B!46iI8`E>TJh`yiNhC&G88$lK(WH;mYS z33g`8G75gz&3FPa%G3l^$zS$0&Xit>xBiUDVmUO(37>6O`BS%|n~28?o@|4sN2SXw z_Y=>VwuGdrE&$bbeA=SLEEB7?6Y{@)jj|+7i>>*19Nh-5Q+6++0-Q%Q!yzJm1#=5S ziJPGpF`Q{KtZ_4Z^d1=g$+i#)o7@bo#PFuc5OXv9oEYfQi>+ke+gwVnCWf^pgU`)S z4Tg5OnkcZyO`S^ATWso&+|;2&rB#Ho&$Di7Z=!lY#oP}b64|jnL+1xP};9jZjeK(&0j4a5aM0&2R!S zxEf)Rn<3WbYJ?4L>Q16MjSzEFpCGE!2n8^gVV~7Rbv43hH$ycTq!DO&lY7dY9_zB= zgL;h4d-YzM{$Jmo_l)86YA-3y}a<}JY#aXrG|dfvZSHES>KJ0wJJ z#C|6~md!%k#LhcbHK>NrKaMb!a=7-LdOyXgIO!mu!`!QSXB2_R0JR2v5TXsXAbMwlE}&Ell0CFXh)12S zpfm%y5tD9+-SG!8FBUf^^0|*F&9_^FuEM*KidgVd3#`DssyH}R#of$rkfB^HKoiwS zcrEt-no%Fx2V5_3gFvG?m3hMc;ZXRt5ou{;N!PIkYFDdn5ZE zD4;hEuZpeR<8q*vKqU2%OVqy-Vhuz0)#}H;jPBdGc&!ya4`YVfGiiNhHn=zY@yAx; zmnfip0T{DfjB`>LR}vTtx{abe%i1C^wg&fzaUGx%uIa4%I%x2`l+YgjhXBl?Gr zBm*A6%OHL~Y=S+=(k{#LsFfj~_6m(UEY&V6r%yOnOH#>b`|B6U;vfQVLo zB??h!U{;9!s#9y1#}>JZ_zAlY@#!Kqxr^w8p4`3LJ&I}DmNw#W0@~}E!}bVs?_eG> zAI|cd2Y4E(PsIxC@bbV3z~8c4ZSgeaF7~Tkg;ksX0S&k0g(B_k+%>Qt ziu_Iq?J?PI(}snMBkvrMN5@~5Y*Fpf7yb}?#>MtoF10OhE5=9hl(!3CEmHO5LxB{0 zVx$L;D=o2Mud+|rBU9}Azb6ECc9?bm z->T)Um}6rSQv!o-8AzU@Cov1Dfa3l7kll_?5{b>ATPl`Nn2F6qp?Gx8PtHfjUVO!+ z(WhiU+KtC198JzwxSPyJnw<;HDq5Bop$})lNBIWN%CddW3|UYb91;xI_#$~ol$O<1 z;>|u^#Fy9NEugpDDq6gKLddd;@?zP$xrTM8wPOt=)5+)Iu@P>K0!bQea%;2^6_x-> z^`;s^TI=7<{(3t)AM~_P=w`B(-K`r?lyBA3M1VGGQcDbwu=;l(Esx$cA+`>8G`@Ai z^WJA-4|2+O?G_Yo+AHSPt}n>4gk42#rnMNL>P?|)76f9tfYWOGSudb^8QOP`KZ!cU zuYig=mV|)l!lRwNUpgbH_I@A3gv*Ivr7R$Z=${)uuWMn(tjICj@3CBQr1kDvg5Ciq zKkplM4Vs^kExU?E9^Lm3(KUsyX>^y;?2g`L2iE#VK11sycFDs<)e{@8m!7y7ZAr)J zLVdOrQJtKiHV}1+&qqg9(}Z$&jq|w16ccN3ccjbOt6zrQ(=2PVfj5@5!yy{h_R$%0 zHL+Xd*70ka{6;Av%i70Kj#5M~Yn$DQ`~x}DFKc(W?bb?+smt1! zTij#dGMBY?Af3j>UA`-@Z)bWNKLWgA<5wWsZDY>@mmi!B26&@kV^7kv;iPB1Gtk2^ zH^-bJ-Kl&JIvGyo=Ya{Q@+n~9RDLH#l*p2s0&MaX-gdi5h@VkV2?u z0xkJkVmEQuR$Ami|9C#eXT5^@Aw?}Z%%60+zb*ag{zaG#(aOd?Wgt)5PfGWsop-{p z@C18g=JIH|d}*K1yYp?(kLB}MlRc%nRIw3IM%ROP&u|)KE?ytPX^;=LewH2Cv9+_` z1>3MNq$js+2#tg2yhvsadYqff&vL}rhEZ0HC`gw%^2P-%>F`vnoNb}AD8907au~%| z)}l8NU8hkRqr5ihgK59^7;dXFjB{du-ubIfhXHhr@8uW`+fwDQ8Vp~;21Y81vFChW z6AzAQkMxtTMGE4RAt64|Eha0B1L#U9i5a028<4mKGRa%h$|M40cEX=@o+v#uBt^)n z(`F(9GQEIIaT+OgPHHUs)d*BBCtR;dEVTcjg|=U1=YZvcc(U?p`KciKy~ zVFD7&XXAqp9Ipx(j$yAHTSk^7hlEEj;ZliIx5u8EM~@HwImAKi%mLn}2x`fnMHqn2+o_#^QXAjAd)x z88#w=8E5a_Pj%9vQu!b~X*r6QO2&Ui{mcDQ$@!$8yj1c>Dmr&?X_qgRqzS}1u!ck? zcZB|6I}v_G5gK!3YCPJ4$CfKzOeubDQUs%DORW7Lj#hYJz&#Q#rF8l31;29=I_t&a z=uX%QZ+t*5PFdUUb6kY>mS^-?`rV7J-sMp5UXZ*UY303z`Hv~@Fy9SoNyr4IjkoqlMb(-w)6$vbT|b$ zw$OSvMyKIGFm35TA*FHwB-u95IdJ|2<3F6iec;Gk0@+4<1uI9F0P@=xpI_5}U7#nE zX>0*oYG`S9S?Z%9P79K->66&K`%z=~Umyv?O`aAdXYdjcQ?9<#Ar{Tdc10!uBBlUHWliUL5UF>I|0}z{1z3ap! zZ<*dz;1(cfY!DrA46xv*C2%LTWTte-6OzvT{Vg22Pi)HFfjgQO_2Q5Mre-i9v|8=s znsOg!Vpa%z&3v2V<^!A6e#Vx!Q7vO3cve)Od^=fs1YVV!$0MlIE41G2Sh>pNq9wMI zcTd$EJR8RwK}nzp#Qupc3VNEnI!lKho%T>0l2Ozk=7SP4Mbsy-U8la#E8+BVK9q9| zL=H&9c~G(&d5k_EN+v;?&WAGRNza>3Ac7R>U67OzGPV+;C~s^@%7o)aitQRHI~~hr?P%R$ zbb4heRX#$=QOe(pewrlz(q#F$&1h&HVzEte#FdzpTF7e<$!@KUl-qWUg>)cz=$hbo zJ1o_XDYwxKu3&XE)mWWcg6>5p=C3{hApynO9`8w7Sw9~m-@p5xw(mFOLA^LV&x`#g z8G8?5AI4a!mr{H-vOZR7FfytnX~F&~rg5%3SH%XRf2KK{Jup_9o`6%^L2M~epn-yR zeM(TD_2`z(7>|i&d;I|1 z(H}np9vtGt_~Y=*bIW;!cu+r)u);0jKS8y<$DV2NlPB?=_6zist}_dx1!it|DQYL4 z4!Atneyd^0F4G?|O0lf=D}c@PxK;0)Zuup2qgGqFi8r>n?+m6P5YPX{s>g4eHWSm9 zsJj;J$lyMRtqYFT!#`Y_4umEML1;I<GOSq znsQ%YJdg96_%?@GEX|U11W@ekoV7=HLYFd5FhA7EaSCPSFDC<1r)Y`YhPq&vp$133 zx`hYPwm-IQXmlTfBUrkU=mQ7ieLx_167B2IIbh}{zXEqwGWR|;n8e=!q!YpU%byj@ z%L?PpzxCs!(ta%5k0|bLVb+1Zl%b?mGkq_LUXS>T8enE(KX9pcq~%A(iKLkVY3~Rv zMO$XQ0nrEX=>#OR@|XVrl_Bxruh54ET4Ga_Xs#%7QAPVYqE#IK7w}}3zcaMW*YUTc z3cV(LzXe1YZewpt=6+PTzo)o!RQ11wRQm$fwi`EDc6g-H^oJNSUxW=0P^*xsKN<;2UXt-#netKj7K&Rv=HwDmSWm7tf(+ z{+9GsAWh-av}!73*%8Al{abf)`h-g~`5hQ+@}loM0}SSk^xW=AJgd_4TN+?gpy-Rb zsLe*0NZxX}#%6m@vkkV{s6Y16sVL-*$G`zRa^eN!*M-sJG_Y^Q}dVb zrrZZtdT10pNFU|v9-8|6?DrSQ}s@BSC4vA?3#~~ z6b(VWYYg?yOi^!uq253K)80~UPiqfZr+n|fl8Vs-OYRcd;L+9NH#}XhE4g1&x{o*D zj7K70iCxVTwWQaXK7_Bt=#yhOsD~J9zs@v-UuWtaYc*zf2FVtR)*Wh@@=* zh&-5VIP5ETT+xQM3nz&@)e))6qCv#8Z3#~z`Q#NGmv*$sfz=k!cDM$#%#9D{5e8d< zN$1QxXlQz*cWLa$KZi$R>sHR0zd?iu&E)hWy+QC8W7#_p4Dq+1u$=R4>?{vWYU~W; zFS{5>j``})H8$F)v9{1e5T5@ihHoS>UBb~O!O^$I_&EI6kv0A`{NXdt$hMo_{g)5+ zAeRb7gFYe=IQpFxLMWj#fR?(LY#V-{lpVW5%N-4?`DI5Dl5wURt%5mGc z#I48<k(t{)RgjF~+t^2wN4lOnH;nK^mY zfHi|W_{8L@!31YazTo|#fAnqrR}OvQHFnBlRH?s)&eq?foE-UJa^#cokdf%~map-J zEZ-&V;ScD;uQ%U1=9V$Hj`_+MKR#h;f4}nM7ceQHZ^fp58kRZ|b_pn`Sk{En%Bn!Q zCsga9@2PvL@e%LRxdG4Z;XpXx8Bp&TG@$+hI_vK6$@kW6){0FR6kp3)jmxMqG$?Lw!_0p%W%1!kwbuJoFctZrq!ry^Wc)!oQX zUyiqxMLms5L7&4bCyC1z;o#|u@{Z^M<%VGX5WPcl^2oQ;9g<6*ic08RQCo!%>U-ub z#An;3Ee6yN;s42+nXhRxhB9#oKJq?fPPl$Z<*>3L<$(qGhI{>xp@WNxh7TK3S0DBV z_?!HpaJ|2xsvJ4e@{a`n$k9Vs3n?-!AIca!a!5^JAwINEC0P~qfuf=!Yub!qTGO=o zSpFpcqQ&>4o%@kR&i#l>)cwr^>TmVntMuoGJZ!R1LtVgAUK%Pr zWc}v^%l*VnjA`}KcB)+%2>Ri~78)K+%Oy^#S%9un?xDZvK$SJn0pIc0em>4oh`I!R zXaFqbfknhPr@G#cX2I9>gA4qmX?JVpynqMI;TaJ2EJUZNsrA%Rp@qqWx?lkQ9JR-?Miw`Jvi#H>8TnOBD{GQ0 zp0C$JfK{0jv4G_1I-cGC~%#?UkltP@c2T-KS1C( zfu#ZsrPBC>2R;CGh|-|SH~7=}L`nvO-{lkHie1Tf^Xn!}%8@MJXz8>?bj6>c2)4J8 zFHM^xcqoTX($3Yc>GCN@GIDvuA&l}WFlMLlrSTi$I~+YS_?Nq(UljlNi@>}g%8xD( zc(uU!0#^!rOyCZI`ve;G;empp?ZRMf&0L98&giVw(^De%JZHMhV>qssdnR2wbGmKeHXB#R?8$(k~U{T0}pTNOzs{^B!bEx?cjTscsdCVZq{d4hSEtxMDKaWg) z4&gM6`NMS>b$Hk_rYT*`v&?x?*LI=7?u(fJ&7SU?Iuq5)JT4C%vLHCGHsr4i-hQ}z znC-AYzsgyCyESgwEdR{nDburjQ56ue%t3$!cy2B_hh2Ji>vOef{Q=!9*8)qmT zs5QH)FU1spDSnDaSNe$fZ6ypbC|xFsnaibl;!ym6k@B{~;PY44&sSz9hvg!Mbx|*p zKkP8&Gat*JHDfH9t4q1z`Z<0MScl8!Xl`d^{l`rz=E4pkr>?9rpexd)orKRRj&s6N z6UJOC1$C7l0am+#v`W`@aPd2ZI%t%fc_pP3a^hmw>nYZ|qB2;G5g@=X?F_NwLH&@q zb%6ne!){29I`(?1yt1BtEv!2x+E$=OZo61ZnQ=*e+e-)E)Fmue#Hok+nXXLiCs zQmEZ63akh@G=VQKEVE`JEL7GYnqn14G5t{OMym+AQuL4?D$@&YDu!Np@=UvSTG6NX#egh0^$Dn88v|{Gh%XoudevQo2brwgyj{9Bn zyW)RoFj%>uw2BOqW}LJALM{7YP(&sfJuvI-Ze16y3}GclKUpT$HSP9))_BE@YW#8R z*0r9zmYgL!Av{jY1c8=l!NWwWnXp5?Yf`p`9WQ6RTWn2A^a|#zq+;@KlDaF z)`kg+)FrJy566DMu%bin2gv%F0!=7b+Ax&Y&`NMxxh6lRIJARtNIsT3$}eWJh6F-o zh&Yv@!tx;~cW@bg+%Dt3hFKou3_C*oXj9{G^c#MJa))P<%XS}r#C9KXgyoOORDP1Z zMjoNuk%uXF)Dg-Zbr^DW-0iBp?EN6Mc~e=AO@qpc2G5+@QrRies~yXd{heAYrm!fg zF($qBwc%h{z+68OUG*(zf5+G%p(RNw3r}3sVm+1U?5?EQ_W`@J@8imgZBaeJIKurY ztC)Vy5w)c4i1Nyc3jE4v4L00p@0X(%EQ8R`Kkun-YU|J{X1vzpNBZ?tsu9vI&(e(} zTHsOaA0NJcu5s3zg}5qxy?{UYP9jkP_-nwWfY<*A@&mpJ7zI4-d&mzsx*7R% zk?;G+4|w|zkRPz-hsY1uxDNRNp9E|Md;>5F*zzOf2iylpKQcb}$H)&@59kH_CSVER zn}ACJ2d+ncz|R1qfUACj{D5cSA&Yf9UOxx)06qff1>6f*0(cdkCoKi+fd@IwfKLNP z0cYUBQXAlJ0qJMCC*p~h2XHH(7jW_h%664e)M2>m{|)Kj0OBQNViu+W?;hw0c<9en1ak z4nFYW1$-5-1hC-`$Pak(o5&AX1{ei=3$P7vAinox^#mWF2k_wA$PYN~9pnf69B?V% z+kZlSz~|bKA8;n#-fRQxi|=|^`S6#$$Pd`-edGuH7_bCz!9L^%Ecpxa1GWOj0O{(Z zfR%N}bSrC7LDm^39iO)*>-Yk~pNW6dzLiK^C_Dtx^IKMb(3pR9BGF2Zz3$7Le;w#y&>sYJ_*nt%AIm`h6X^X+`b|#$ zb)dfk`b3kSJ=V^@9rRqp>rcwbP~pvpWS5B*MWWt#-2$o`gohZ z9rPnXLRD^x2?ivQM{emUSoSH=FshXWR1ogZ@j5s5-bMeR zO)m%iub@BTqJP__F9Ur(#>_ih^sr4|2l}tOpl=7gAI8*7`S*g}0D6Bff42eFDb#cTGCo$n}a@GF> zr~aT{|DTCOFZ3fje@+iOevSuy(vykAW2St%$3^9rgZ?V$=VLsu^Aiyl(U*b#=ChgW zw+{3xFxSXbzwMxZ4tgg0>;=6PbCgWuLpRKsmVo{M{KVETXH7RU5b4(+^pCe@9)HGz zUb!ui_}H`$^3lch2mSJ2ClVRkAN1LvS5gMMeah|jSqJ*}x}a|dJq9`-X3+Vo9sk=4 z`e&ezG3DRs(7T~s&cK|FbhXPj$3M_d1)bK(HoeZtKOXdpK+jaaa?mGqk$)NJH-mnq zDZjyyzYg>U(EFQoV|>{T`eM*CjURhKzZ3L~^~ap`KS1Xrd)j{4PqG5s{-BS<+;yf| ze)d$GJ|6T+&@VFSa~=K5K@WpI$)smH@p~EQkAR-ZzUx4L5_CQ}qxGwDfA%HJ<6Pzc#@4?Z=G^mlCKB{+gx$V5-*@^y=pW%t*0rwu_u2W!gI$pkD`iqpSW)oce?Q z)GL|i58be4_#^1gy5w)P<@X1D0oEjca?#(k>El5kiM2>3dO7F^K+j~qWuRAKjk4V( z|9M;fI?xMVO(YhY^&?(fLc$N74WZajWUPj6Mv(PMfRjp;dP zY){YFo_)bTwr3u%Lsmjg8{|+mlP_;CFQYsHHJx0Ru4MQPg|_kc2m^}XYf(=xLoC<$ zT37C6c$!LDdsde4-5HWb2;u8=fo($Pma+9FA98J;68z$2s|#|%UQo9 zaG=0Z0w)NZEwDo10)h7kd{E$z1#T4hqQKV$?i2Wlz~c&}e1QW6juJRQ;B0{v0v8Cp zN8p13e=KmLz!wF+E^wc~PXr!!vXn1ypukZACkUJ^utFdk?Z5F)bA{52`U&~!4N}&6 z!B3L9~O7KSt_K2JXINay2U0^?lKT2%Hh9%>UBu)8`(cW}O7RNM> zq|{Viz3$W$*lYMP+FSA;oxL}RAG8V7dcj`9_5IO6%72XZ9{xqxTecPKD!|?&j?vzd z|LE*(E0S~rdyPm!9Z{0KN@U`H#-tT90H1d(m;iqrNErG1`077h!L`|5zga1bZL* zI{X;sCo4pcO{xCJC_Wt+$ zB*`Y?hhND2Wa7ASmwE<`56r2=%Ml|AFDV>0cxcfD>ds0cjxHQAcqq|uV_Aju4b`F2 zIe?*{g7fqpzfo3a71q>-0)=D7P8y8wNl0pLO}KDQ7$58yTv=`vQVNIo=UIj24K`D||*e71FFT6~Umd0Koo`#HNQEC)~BSES`X&VCN>=0Dy__xw5sPxbY4Z#Vx5 zmVSQj#&@^$b9OiWL`$DHaN|$1n&o-48{fmKJK1ZZ_&&$#Y3XwcCNam#x1w@>!HqAl zTJbHYG)5xypN~DpKfO7d)g1}W_`qa{w9&)Y8FmQB7F8FWJ*RRvp6g}AM1{646a2pfKSA&_ z1n)o3%b05fKVR@W2Pph~f~Pa`B>&cd3cp714+=hikizpBWzgu?w}}63!LJv7`ff1k z-z@s~7kr2CFTX&^;j_x1(V170^Q|u{Jf9&3{sO@dl;?EP2El(<@Sg~NhTu18IX5VNJ}U^?8-joNCWY62`;p*#->mS@f|ssSupvtI z`kmnU%pdSx!T?=MySjU)`$3mN!#3;zpqyx?;B zJKQ;~{C(ihLi}%C=_PjiI>7kUct{NC^i&7idZmmDCu0LMD^2`Aoi{d9iBpI z%jsc#(%;MMyCu^?!JjH|><+;{Ao#xyRQ!_!|AgQlJxAd?1iwx2p0gF6-#G&9HNorW z>faas_XV$?SHCOxPQm}VkCLP9*&Q2%>Fje3<9k>$u2uYJiX3kS{#n9*-i3-^*S8LM z@*nz0I9+}DFV2r=kh2E(0&peIHy#rCJ9~Rsg7%-E3Vzi23O`!pzr^^|`P(au7bXMz zIRpMv;K{G(*I(%JVk$@133=)5b`j%yShZp|y(pfLf&UiZ*>BgBuw3$Ex@t1;KP2+U zo#$mf-7ddiIj33Cq<;GA407Jjfd5AZe9sfo*Y_O8_psJUef9Wzx!@lYJ^5WOXnd34 zpOW^vnQLKLiv+Kq&-1%~pxq<*htBmfXFvXHSwCRBWkvH9UeMMvz>~i%eY}KGs19Gh z6@E$D;7=LwpJ%|Ig$*!@lQp9M1d(*P;D0#N%NRb}kGmUzXa9Mqgz-@ctn+~iv<5D@FyGVGOhnc<`*Ud{7&RNalMzZR}1Y!!B3Gm`JmwG%s$ntQOfNv_;Uq+ zrN_${ey0<6R|)<w6O4`%^Sc8-dFPUBpbHIMlvVSsOloT73iCm^)%WZ-`)1O7#k z({QSiqvOUt!Rzx_?~43SfG0im@0#hj-K~eRLs;gYxH{he@6g@C7J$&`(PQqdI z*9s|D$FZ5h?>R;B^E=j%zW{i$n^*h_D89ZX{PQpMa+==>#NF2g-+QXU^SfZcuLGXS z)xU42+xH{9_{XyNpjQ;02bC`RBJw zn5gCdf$^tVYo1Ve-H!DA0E#E)pYCOTJ)ikp_zQ$z%PA;O{Q5i_zng@dXEUBfxc&^! zfG^H~ze(gjCi?KZ^N?5vJjMBBzq%86kE=wLcu?eACw|pmc%Bq|RL+6&yRV?N3SOUk z)dul7x$q(jyT^4^_}W)_;iyrg zhC*^0CO_?Ct6gcFWC#TtEVYka92!7d z?SA?a8YA#93tuCxs?rSh$FOO0yS7HM>Cc@Km)}2O*0tkiPMUhH-(NUlXwfj1qdD-o zBYb*Wf7Vog+KfMyswlim@4{Dyv1iZfyCs$5i*+zklhsv>D&FCg zFRvz5=aP%vx#&CQ&ey@A3_cw0=HTyo`>Sf_y3x*;s{GW_ZX$m*R%hX_kka==&4#j( zuGTWXc1U%j#^O(inmKKxD<`#&Zf94OhmRaKf|VmrFy-hpAL?;h!A2)Fr;W#B_B7l{ zjcjwT=Io9clHOWXTQ(oDEfDZ}Cr+L;cAS4$;jqGy z2&QEV+!&pcKbB~FxO}k_FP8=I{m(9P*zRV>D?F$S`cV#l(A?FHo%fIYetgfrrWVw) z(hwd;x(mP~&ziF8IycfkY33As%u$a9GpCHB;bA5p-lj*0^l8UnQiPI#S63CDTdAV6 zttH*4BVY8n=(41Y%2QGzp8aiVGMXLO`8P1wDJ7ct@hN0Z+mVC4#P(Y@H5;z_c7M30 zsN^)+=t zBq~z*Z8NwEDGfn)n4=!UX*udxS=P`+R%ci9Bv}S5Yoo&;o z&r$mI$1LqW=Xe+|n+&6zD)CSAC^x4$i#w|w4z%AmUT=Gv3NHw>7!w`cIr2HfD92;% zn=n9I@wa~Muwj&%h^uAZGsM#aT*4d*9KoSJIS zx7UMiag8n%(j17+}*Qe_o;{X%VvDdW`({L^Kz zJg%y=z8))O%1j0!SH|MECTXTjI__?W zsK_o~=U)vR`5);=mp+fV2>btZovwiWSH#)r2=2`M`rIaczn3olMy|T$zt}Ez!TXUi z^Xun8b=YU6YuF40^1_i@D#ODf;1(DvU1?uezx#;6;e|B@uU7N;R~GhMdH+92iUX+|L?CAn /sys/bus/i2c/devices/1-0032/system_led_fld + CURRENTR_LED=1 + fi + else + if [ $SYSTEM_READY -eq 0 ]; then + # set SYSTEM LED to Amber + if [ "$CURRENTR_LED" -ne "2" ]; then + echo 0x02 > /sys/bus/i2c/devices/1-0032/system_led_fld + CURRENTR_LED=2 + fi + else + # set SYS LED to Green + if [ "$CURRENTR_LED" -ne "1" ]; then + echo 0x01 > /sys/bus/i2c/devices/1-0032/system_led_fld + CURRENTR_LED=1 + fi + fi + fi + sleep 10 +done + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/watchdog/watchdog.conf b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/watchdog/watchdog.conf new file mode 100644 index 000000000000..81f0b7b819bf --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/watchdog/watchdog.conf @@ -0,0 +1,45 @@ +#ping = 172.31.14.1 +#ping = 172.26.1.255 +#interface = eth0 +#file = /var/log/messages +#change = 1407 + +# Uncomment to enable test. Setting one of these values to '0' disables it. +# These values will hopefully never reboot your machine during normal use +# (if your machine is really hung, the loadavg will go much higher than 25) +#max-load-1 = 24 +#max-load-5 = 18 +#max-load-15 = 12 + +# Note that this is the number of pages! +# To get the real size, check how large the pagesize is on your machine. +#min-memory = 1 +#allocatable-memory = 1 + +#repair-binary = /usr/sbin/repair +#repair-timeout = +#test-binary = +#test-timeout = + +watchdog-device = /dev/watchdog + +# Defaults compiled into the binary +#temperature-device = +#max-temperature = 120 + +# Defaults compiled into the binary +#admin = root +#interval = 1 +#logtick = 1 +#log-dir = /var/log/watchdog + +# This greatly decreases the chance that watchdog won't be scheduled before +# your machine is really loaded +realtime = yes +priority = 99 + +# Check if rsyslogd is still running by enabling the following line +#pidfile = /var/run/rsyslogd.pid + +# timeout : 15 , 30 , 60 , 90 , 120 , 180 , 240 sec +watchdog-timeout = 120 diff --git a/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/xcvr-serv/xcvr-servd b/platform/broadcom/sonic-platform-modules-mitac/ly1200-32x/opt/xcvr-serv/xcvr-servd new file mode 100755 index 0000000000000000000000000000000000000000..c882ff8e335af0e1f1722c990166b8711f407307 GIT binary patch literal 31456 zcmchA3w%`7wfD{o0!R`R6cBY(f}j$T@GvOq1Q?ts(MXA{aQrscOfVx*iwy^+O*P|*65uvsSS#nTI$^YT6^y^=S*fu zVt@TkemU#x_1?IPRH6c>1k;~AL-&2L8+cxJEP=Th$=rP6|O{N3%j^nTq-62 zlZAgfQwYi{4ZDey zISx4%z*W2v@UX06$Xsn_P7S9kdm3uFyCFw@j`dL46^rU>H!WMTsLr#nuC^h#W8sdH zWeb-rDeyNI6tn-tM<#E(vyxToc-W94+tcw+Wl8jPm+WcuPW{&Zy!W?BZ4bYC#kAY+ zDW6ZW`X85LK3)Z(BK zcc$?3xfJ;SmjeH43j7~Z;5{ku2U7U|mlXULrNDQlz|V(%8~ziIe^0@`6O75?_FxMB z7gF%Ql7jyyDezCGzaUXN zc`F6}zaW#0|4a&eG=-i}3cNr+&smpug|-=)*tZt)|aoUYi#hYcWwuiHc36pHP>+JILml&d}%@a}+f{(!HsSrAtOskWguV4%D^kbvTC z@Z0P2H8i^F8mrxb+QtThMJfb(tAVP9T9Zk4AmDSc+UmxJ25)s-JyZPNfWLZ+*VE+o zx$6xbR#IbKZFRG#u50us<^*vd)5vr+Wp|nIBk2tYf0M7aAy6Zb&xY#yCgHE$+~BSg z9=8|aCv2dxPWYSsb&Z=vy|*4t2=)R2mhJ@Wygt!TTkRFKjnx70k|K9N1pRehFZ2a` z2uPz3fg#(fKDE^Q8W0T z#wJZC8eNk#UDK6>GL0mTH2xEU#yuPU1G8!;(MUI)*l`ejC+e`K2WJyKL)c98FMv;v zuacf_(D&X^MQV6XF@vw<>7c?-L=x(aqsxR>CYW}@gr_*@qsN5Ta|5FFn(*d%LZ1mw zw)GJ);j=XoaL9y5#*Jgxgr96+aj~|FQ>1$eU&&Lp2~T6OKJrZXsTv75(}d44;cX^- zt_eTigx6(3YzTJe^b8I5-G2t&W@$WU^FE`;kO?aCLzt4of(uCh{ z!e3>=A2i{wHsQNW_-gzquouQB0!P5AjHe4h!wz=V&O@YkB~&bGm9XEF9n=7gL&=a_1u zGNq~MMk_d-PHAegQ9GwUycua~s?kDDze8ziqEQ>C-=Z`%&1fE{|43i4 z(nB8sk^f6dQxlB#ar$SJrluF|;q(gmN>h`G+By9YrKzbz3pwqh z^c+gtIQ<}{scA&>IK7F|)Fh&U)Av&P3Q7ar$;jQ1!!XO(D96(^pZNnn1J_>7qZCgPz>JqT@Fy{BzF zLWEc!n0FCUY<#YUjsl%NO!P|U=iX)oM?cDd0%vH*c{FmXGwrzZrH=wL3~f`iw%jX7 z58H3OdHL-&A%fE?AsA^uz&0Mwng>+cyU$VkInr51j@>GPSp)wEa)z=qBoOP_7<~vb zbd8o-oZ ze9${!llq@MTtXbw{-mWTn&bKBRFrI?mO*r358Y%#5FEpY!77eWhZ8x0W^)+fj2)r= zDe?>@nM&PLd}=ynW|N)$Iae8_{7 zbXbrth44jHf#~N!LZHHxgQ24@zZL3f>q|rTy|t}nSOl&Ip`#+r+2I%py>zIFoX-S1 zGA2WK@I%rw43rqS+QRD}!TTt9Nzoyx;rJ2u&=r7l1wxUW~u%=2DJ;dBboYO*`($*^!6r!9wep3T=*s>s5?YOeRu~| z`*2NHjYCdq0d0;v`I1QdqM-cgjLFHQU2aK*tdvjLw2>Lx! zqd#ULe%By!2l1qZxZ5Cdhwudpk)|9nz{|-Q@?E-`1~yZ#@(zZ6llj+;BpW%Gp);+*5f?dmo7nuv#qPpnPo4pLfGxu zG>5A>FSFg*(N5gwWio4&&E!F3Iv(TuFdtLxf2C^w_aY#=bGn!s$@x64uy~xi>kr5x zDnTnX)~DX*3en27fe^D8QQ0LKULn*Pgy%d4#*jn9gC^9+^Tf8o*>RAA%ig_%jwdqd zJswL7BYC)>!3|x;Fq}F=exeq4T3gJ$Ku51d`O1KOvs4A_RdhT$&j+B1u8lnBGs2SR zbutXcq|8f)G7IczV#kl{qfRz>R{8WvS4t zVD}c_jQ-n!_U!D~y+Pr)Q4|3uCH_p7Ss=8VCi`J#yxMU((?Qc6^NnToi!JUU%fXv)J?81G|Z^t1EYR1N2jmyW<+jE=ej& z-6zVrM#?htY%ot`<{mN>dIj{)&NiZw+fD|-^ZG5xoS{w*0y8Ymp!0{nG#7TVx+<(j z*p?685_&~ia1K=NVU=;Sbu-!Qz#W<`bNiKGt7Wzmp~X6>0@KLCBU@zOJF(b6rL1gI96cefbu2Pui0rY7 z1WDwo1hu_Zp1Z*#`+#rUtonf0crtqy?)@2!1FbD9O8aP<3wA_2?!jJ)YJn-VuiW_evGV8G}D7ecgF*^<5Q|yp(J^t8N4&>I5EjFh+x0E zBAE_Vv8F=atT7iMB;_x!rsQYksoHPsi{FluK{>hVcp_rt-E<7`{YSDl#LbeNs6Q;EN{S;DJ<7f7_nCAj(nQ!(pq?`L{v$H zQQS6c4@9s%&`0Y<4BM(aG5L3f9gz^tlw?7D1Fpa(Mr>Z4_sP}y(#T!xqTySi@(seO z$b{YE+n2OQaTjRq4G%(<5oP_jV@f^d8V*A%(o3S}%!@=&pyq5mGHnO1l=0Wt|sd#RL- zMawCfqMiiEehG#o;C>e+nikA6n#um*}=Ys1{8 z@-zlLnzP;p^W0+{KrexHyR&0AZ7`y}Z9zT`&x5p4U>8$#9D|3c0z>pN>@aXIC|5|x zm597dW$K`U9_0dIeqo$juNNF?&qq!0m z6Y0)p7HxC;7Wsk=&QLZI?&_vm+&XlIoY~#>Ji41!(`}y~fJg_=$*?!jz`oNc`#Wf+ zou87(yHSfrRNiKfx~v{8C6E3Y5u{vG{-Em`-Z=wD>vqAgb|Wi#6H=Hse}Fj_b!2i*ItdGN$5}MmzMC9pbH7vvFKL#PyX!T0 zCx@an9AgI-plXckK;@C7J1CZzBsorn%ZJf(pE3>CZ=xDXt}Lpbm9TkAYbeHwDDK#I zIS>Z%hlcvW2&t##)vusT4)3;7^h)vR+FyvJ@?46=v0X>do*hP83@=@GjZMJS(2KF2 zfdy!u;ZYv@Ulx^0-f=( z_mMXd0_sg=SGgHP*;T?8FVPNKy*v)zxT}nQ2ilFnt&8dx4{ljtFb224LX>OQA?oI| z6Okog2vKLeKa@u`sXOv4`QSJ=uuczvXWk&E5(mJavu2XizV%pryOw<;jZIRc(V@2u z79xDTq2MW_D;~~}(do6$OfDwxjG4(6cEpHInc)E%NwVnd({`gz=;#cEE3ux$`1#VI z2;4O~>UvU5lNOpA^cmq>2DA~rpfM$Qtv^{ro`E@8TH2ohYeZ(UKNOJ%*qmufP%aU2 z#0#~c5d<+LoSU%SjiPXdGk==B68G%-!ZYR<*{Bu`VHf)D@Qlmjsa4?_*B2YKrQsP@ z#Z%XWXUvSJW`$?u#8Xp9TQ}l^d#rK~8|Fhn?D4_+UCO#$T1WfMda}?a21=+YXLZu$ zLcaVDI6~_tV4tGPOZf78ba??^ev2;Clm*-pq0RnKFk)1Iv*dv8PJhPT8<$41oig(- zS?;dKBy+ejB6ra9d9bBQGdLmlpSCg;_Z2dKx&wwupuR=vX((hP zm0(+!P4`Z;sVrruDcLi~*w|#LXH&wbFjFAIKORlk7+6fg-;lxs51rSnAsKi10VP;^ zUcthVdCgaX*(lHNVBFb5cL|!)2QF&Ej5eIrSU?NH;oL{Bp{bkco`I?bq00W`72(bE z$K5C}Ob&8)(W7#hHZ68UXvQ=wYXergL>qG@*+2eDGGE>p`B;@?kY^X?q93c0{74CZ ztV-gO!sD+b%a!1`D~V8oDJseB*Q-i0C83h=SgYy>4L3AE4jYqx?l=Zo&QoK}wIon6 zCdQ7+9yRZ}09%b{h+LnuqCcc6M$;dvUDyVkgl>jwc*k|h`2cFaoGSgc55qx+qo3wl zXvHFOCGrmh))DHqRGvhfGImj8*qjH)NkZ_R!rMSdZ9jO8S`PL}F*srCv6n0QS-Eh) z6pwFbInI87jmaUpJ?0p?n(mWDc=yH8cL-joeUI6%Ls5Bz20_ydFO#uY%Q$*X*th?v zd3#M7dI{@@e9%M9?Btc0GMlI7ZQ$fd9iuWMM(w{xv{>~m@Fe;hIn%>%dj*nCO!TI#!bC5E7H*n# zwviB*&!=#urgylPIf$uYdEZ)u+TI?Fv^)B-PYFP~w*BpnGvpp7S;!9N2beEc4$+#y zhWjacv3~FGOglREP|L~CP`d-Wos}o#_QOfcQJ=wTMCf%=Ym62j0d;3@A`D@A-(@V( zS;d)9PkZ@^cE>SLkF^uSNOhDMWV#6I4B^7iFs2ke?GAm57J_tlwePSEF)^k=$Kf+$ z$u9%D2iOqJ^m=&Pp(iY`{wm>D>1F5jqG{ITf9~N3!FuMBB()!Czwj07Y@SHX^}-H zPht7t+^4BH(Tp+LLfeLqNE_ePY`#5`Zej-U_0ya!5<#|*s~*bL25YWv0TXHKj_e|7 z&fiSxB`9jW?Rk>6MbeByv4u{=GhB&U)o0{+mGB zV}FYftrB6%C#o&ww7r}fQaqEiL*0sP0o3_4T&g7o3jclBen0mBd1{$+;ihR;)xA|B z_i1~2?$fCK!3YHjHvd&d$2z(A5KXRfu$^{_^eT)@)^t1Gp9me}G_hu+iNeqj<}SMC z#tor&PT{ve?mkRSwx@$WoRWUPp4smB;5_84cFL6FebcR~wn$pLoV~5}X{h!EvI%{|?w*D>Aybm=)x3BbpRk=@B4(nK>^P+mb+S0S*b`B{+fjB}BHN6LSNE@toS{r(Q zHFU(LpLVuAm*!kP5PXXsV7+f+>HVb}OCKn8;SoRM`M!6b!vICkysAfB)A+f0Ar|4; z|3#aE{zbLL)r&mdZFtb%zo=+oVd3K9MNN%(H>1c^;%f4F@xDa>kr*3)tq(6~1l)n3 zf9(AA{;gxyU*G8Qd+UgOZ2EnE_I=F!bxp9~6^nLMZ^IiKexIxU(`;-k_LjSfmYD)J zYJ8dB6fk9I>~b=2W8;qpZfyMVz>SSx1@63YTCD2T4X)xP@j#{4Z{Z&isBy?~pvK5= z1Zs@@Mxe&XZv<*o{^F&s#l_=@ljI+NoZ@n0i<9IZdz>Wy*yAMmjX14w*VcJGwm_pz zy|ZPj_xk#MJAzzbclHCg0)#P#?W>wWG9KfiG1v(@@-)KLbmw^7eYE)}HqN4>a{zaRcy!i#i8$`TR>FvdMDR^rA z^p+&5nO}Gt)TPJ7&Mz~@`GtwZno=~5^29cSDq9n*L#f3*p*Jgy%7NNxZCTVT=+3CE z;?9b~RfR=278cqH`JfD`%fdpFKK7?{RYjRizLLl>yRE{({6?FN+gC3~+RiT$=hyZ5 z{QPA)_(t1w`+T+A+;x80M%T%=Ms2}{tqqOa8*D~l*|>c)p;_d6YztW$7lz+lALMJM zl9MV$u%VjX4Ykcr5JUH5bSs!vp!-OSlM!rl{@k8;A>{8ciHxWPLR`GS4y{7WRj^n= zyMhlYc&CE*EBI9fzpda?3jRdFR}}10@aGDC>RM^r3O=mi^^*Ry zg6}F=xKQFBRPeNd-&64X@#Yc02r+ew6k|GQZcB6Ah512F-|r_@68i_^2O5A0l69wiWKk-yqo%`DDo?V`S^XR1b=)<*Unzkc>`N ztz@gbe6?AmU7B$dJ^FDac-KB3i`|dwlRuBet_OVfBp!|gjQk=Ndjin^LM(O+@JE3C zfS-9W7R$sg){}s90XM%Ci>(HH2YVA9z(1UZJfH{rQBMG-{~q#yU&ZETKj6#Q5Y5C* z$+NiCHy6;48+5Aye+B3Pd=)nzcL56A5PyQ`xT}2(@EBk};6yy-l9`F$(Eywa*blfG z@Hcoi#{+m2PfhItEWvYMPXK-s@EG7rco?l8F!No=V=emwz`1~P@VHtX;B*zYw1?J- zv>kbAmtHV2dr#WLJi^bx|K6X)V%I7j0?GN&oFA#6bS72L3LzgM16!X3#yrugAS@znM<9aFF~i;Ge{! z40jX4@NcbQ{|V50L0@I2%kZ-NG0^`C`pstg4i;y6Kj<^@_)4dlp8ickejr%_==5OIb_?BS&^@3(3VOAL{(wQ>1^SDiFSC?ikx_n6fc^&h zjl~vvfk8h8`Y`&B$1M84%KBFW*AIFt`V}wHSLWn>DczAX^NSgd99u`GBWM1jS4|)*J5l3g9opG%SY6fzd zjzstci8k;%6~hGzUpUpySM8VBA^5<9(|oi~vNP29CY9EHYkSm1(V^4WbLRZyDSq7e;I#Gw!v?2+oNZ^h|6eEl zJ5!1FYNkp*wki0Cf?rqg`wAXV@VJ7nDEOv=?<+VVN9wy+!FdWUQ*e!f_b6DS;5G#x zQSj>ueqX@@3LaPR6$Rf^@O=d*7KN5L8ew<-9Df?rqg`wAXV@VJ7B zar}GJx;>VtcC|&py$YUCa9F|l%Vj>-D~NhV&(YwGaEYgDIwo9YCt$Q2UH=*RF;1!M zXjQsB>iVwna`alcTij{_f)%8_iCxQmp&6f0Ug( zrC9fu|0p}tlw#cvZ&B@GuYx@aiW}|BS*T!@g4(aq;&!28)Z>qq8!sHq&P7V0Zb#$Q zulYx_qsKknjT&CX?tQMV&4H(ofJoy(O%-HyhqU-OS<=L*HB+mV(VFC5K| zO)1pvXuSG0|7douRE)YE9aQZiqM&VsojEELY*lc-f@8IFm15NGNXv~Ej+URRl|tQ) z#;afRk7j4CV$|(O%Z(R~W+z`M)a_`z`ZfP(cIGL@%eBDAgrnKHM(Ne<=wq6p_ocXZG9}|vdXMxEM@zO!4iV^m(a={{LCvP2KmW=Dq@%2Xj;b5Ad-?nPijkfu# zy_;&?4Ynl(%L|GZ78Nd#SBb=uf+Y)!h=vOx3jEFW0rw_A{2(R6E&7UY#59Ql?9zJ+ zN>`RG47fL|)aHg@!KPp>e)G82BMK;m`*vGIfv33v`XmhaBxRe|=ck|RWHyy>f#&np zxk*4>HPr<~0sls40e&A8*EL9h*66`~Pf_6A;;O-~b9!A{Jdo8XDdEBmC3mxw(AN)E zgALl<^|jS7-3Wy^6|fblag*OK3aT6H>(%o$Bf@S%WKhu4?Iw)8q~E}tlN6sJRwTt| z8v8wFWf}NI?$)II6NKImvhq(9$@Wn)u)C!9U#$F-gx<%o;wKBe-($s35qjUtioZZq zsQnHreyZ_%=T>}9Ctoe4T+`)YbcMW@3i8$k=zY z;-?GxIkdzhL(IVMlPAMpEcUAXGqX&FxJ2lEH7g#YZh102vqaau$?zjbHPkfxTIw0@ z3(UG{y^@CA&qV)e{7n~FWhCr(7AU+u0bi={tqJ%~vi`WAl#CUOP6BT0u|4^4(# zGX6_}Cw_X=o({dPS&)LC-ee_zwiinNyIBhN`xO3!!mm0 zD*Ts$Cx7T!bUH5Nvk>1_{1L^^_Xa@w55-SUdDEf!k0}1%6-#`CsY3ix@zW#Hbm(;g z&`IOd$NbYodzqcsjpJ>`kF1BpkSxw0k^y+9_rWPe2mOwFT9S4re>qy5dZvnBUt?!ZzITSJGr&(1vjqL}2OWA|l9@sHnS!1!r$f)XE&)E7p9LxKt5V?a zQTpvlzusrutnkhR{O5tsgFm|zo}I!e#QI0}|6gMKRPmbyc4p;!dANE~>0h0o|2gJo zR?F$l6!>#WKmA%29el43a0)V#EIvz8;Mb?X(=W+V{96Fp9N-b|rqI0gO^Oc;~-vkZ8uZ(CG-gE$|bVE(CM#S%NG zt0h{{J$@?p#PP0~^~@9%Dn8u&A@fg4KmB?b9oc*q;>$|^ua?>w!}k_(^#tP;lL^qT zn^1hVtNOD^(M|$yGx6!mS5xTuGw{>WXNv5E@%o(7|813Dz84B*lQH$4hW=U4TXcM8 zF@Bb)ONiSIz>}YPABgX%Lyv>;+PgU1sPr@?=-H8i|8b?CewLOFFQ0{YDh2;67<+OzHQw9B~CmmrvT4EqP3#HQ*Ed7Nl;Y1_SXhmR^YmlY210&7 zgV){$jvw1KJ?n;NCONuw-fRk~ozg_p^|f6fKUE-PL%t#Sc230(AN7@y-h# zWF?ddK@ZxwHZ=#lE?%9-Ir#}Y6UFe5Sm@zF%C~fCaq$f|#H|vYAKx?4OG>PC`S_lR zVR;GEtyx!E?r=HoTuq-x;S$!@6eA<39^qR3sXI%{%T|HQMBy*12-j_E?^;>9)^*pK zHJ@;-cdaj7xz<7I_*)&-{vem7pbWU`{hvlXsorL{o4?Va9y52zr|7M;#BZTksr;dk z`X(##e4m7&kjw9f#KY56+u)MnF(S@v{IQb+6h1N&{~}D>EPZuEeICY&WW8||eUXG7 z;igw7*hWLJKJJKo(ZN;i#wS`_o9f+7!sX>UA|q(HLJku-(QEZMzFC0|t>sfRR)6#- zRIJ#zF@C^R>q+vd7^~dK54%|D^7}7VoMB6b9Wi!MT=-isR!%N&cfg9|Pt{maR*l>? z3{<^)hpVY^yVr+~3vU6SKDs?t=@Flqv63yZpw?g|8-}o}h_|}@Tg~NR5b>Ia#S8R; zNvfvXgFQg*b6f%JKN`|fwcEc{$ZzeW@PJk7mT&nM67768)>*~ig1^xvUrC6Yk{wIg zU1&8P_#E_mEq1LcN?Y< ziJc`6`>AW)$aXD1tEJ-;{}k6qoBT=_9`NT^x$xO4`57xKpL|cnic{0Hj}7R49!<@$ zog$BPyMhwTk-#{sX}poX8dsQ#8}f6~?MUHyVWrT2@ZqQ1Wv* z6+b1)uLcP})!V53uS&NAL(h#e;OC0z3d>eLFkQABcOo?f|60B^-Hw#N{RRdiTN%W% zj^m`|XG*fT2M}8-hP=KX(M|$5^z*1PC3Wa)f)C&yx3&!b^?i#UD?_B84(-48Q^T#G z(X*vGt?zH-VSY|W6`$qzz{pSSze0*r}n{sR0b%6}0!s#7Xl#(Jett^X450I1@Cggin3W_f-8r9#Q;a@72J>O#Y>Cdljc zc8}WdUN>J$N~q;D_VEOH{rvOX63L;$pxHUrMgkX|_&2vdy?;`u=~eB2y#Ny&zEjwYX?Yx{pG2Ps{83T>5*w^rP@}==!Ps*X8gg zXlDERe%RhSSj?#JG8Ok<>lsLp*Z0jjm3)P=pGy90g1oWcSS}@Ysdk{{?fOE&4*|&+ zoqv5FZr8n%VMy_5VAmH4(v3KBu`mIz<(DVmb#^qI2D-LwX8mtvKU*^@VnWhV_s#Mr n?vttcR5@{6hJU)pq~ospFKVC3><`s~fJ66#G9~k>uL=GyV(dpR literal 0 HcmV?d00001 diff --git a/platform/broadcom/sonic-platform-modules-quanta b/platform/broadcom/sonic-platform-modules-quanta deleted file mode 160000 index 2a300312a084..000000000000 --- a/platform/broadcom/sonic-platform-modules-quanta +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2a300312a084cd96cdd3657020b5e207adc04559 diff --git a/platform/broadcom/sonic-platform-modules-quanta/.gitignore b/platform/broadcom/sonic-platform-modules-quanta/.gitignore new file mode 100755 index 000000000000..2615f7f89bbb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/.gitignore @@ -0,0 +1,37 @@ +# Object files +*.o +*.ko +*.cmd +*.mod.c +*.symvers +*.order +*.obj +*.elf + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su diff --git a/platform/broadcom/sonic-platform-modules-quanta/LICENSE b/platform/broadcom/sonic-platform-modules-quanta/LICENSE new file mode 100755 index 000000000000..609b3082d11c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/LICENSE @@ -0,0 +1,16 @@ +Copyright (C) 2016 Microsoft, Inc +Copyright (C) 2018 Quanta Computer 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/broadcom/sonic-platform-modules-quanta/README.md b/platform/broadcom/sonic-platform-modules-quanta/README.md new file mode 100644 index 000000000000..bcc06271904a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/README.md @@ -0,0 +1,2 @@ +# sonic-platform-modules-quanta +SONiC platform folder which contain drivers for Quanta Switch diff --git a/platform/broadcom/sonic-platform-modules-quanta/debian/changelog b/platform/broadcom/sonic-platform-modules-quanta/debian/changelog new file mode 100755 index 000000000000..77d3407ec943 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/debian/changelog @@ -0,0 +1,6 @@ +sonic-quanta-platform-modules (1.0) unstable; urgency=low + + * Add support for Quanta IX1B-32X + * Initial release + + -- Chih-Pei Chang Jonathan Tsai Wed, 20 Dec 2017 09:26:01 +0800 diff --git a/platform/broadcom/sonic-platform-modules-quanta/debian/compat b/platform/broadcom/sonic-platform-modules-quanta/debian/compat new file mode 100755 index 000000000000..ec635144f600 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/debian/compat @@ -0,0 +1 @@ +9 diff --git a/platform/broadcom/sonic-platform-modules-quanta/debian/control b/platform/broadcom/sonic-platform-modules-quanta/debian/control new file mode 100755 index 000000000000..af058ee98f2d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/debian/control @@ -0,0 +1,12 @@ +Source: sonic-quanta-platform-modules +Section: main +Priority: extra +Maintainer: Chih-Pei Chang , Jonathan Tsai +Build-Depends: debhelper (>= 8.0.0), bzip2 +Standards-Version: 3.9.3 + +Package: sonic-platform-quanta-ix1b-32x +Architecture: amd64 +Depends: linux-image-3.16.0-5-amd64 +Description: kernel modules for platform devices such as psu, led, sfp + diff --git a/platform/broadcom/sonic-platform-modules-quanta/debian/rules b/platform/broadcom/sonic-platform-modules-quanta/debian/rules new file mode 100755 index 000000000000..45bb29742a1c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/debian/rules @@ -0,0 +1,86 @@ +#!/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 + +PYTHON ?= python2 + +PACKAGE_PRE_NAME := sonic-platform-quanta +KVERSION ?= $(shell uname -r) +KERNEL_SRC := /lib/modules/$(KVERSION) +MOD_SRC_DIR:= $(shell pwd) +MODULE_DIRS:= ix1b-32x +MODULE_DIR := modules +UTILS_DIR := utils +SERVICE_DIR := service +CLASSES_DIR := classes +CONF_DIR := conf + +%: + dh $@ --with systemd,python2,python3 --buildsystem=pybuild + +clean: + dh_testdir + dh_testroot + dh_clean + +build: + #make modules -C $(KERNEL_SRC)/build M=$(MODULE_SRC) + (for mod in $(MODULE_DIRS); do \ + make modules -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ + $(PYTHON) $${mod}/setup.py build; \ + 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}/usr/local/bin; \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system; \ + cp $(MOD_SRC_DIR)/$${mod}/$(MODULE_DIR)/*.ko debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin/; \ + cp $(MOD_SRC_DIR)/$${mod}/$(SERVICE_DIR)/*.service debian/$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system/; \ + $(PYTHON) $${mod}/setup.py install --root=$(MOD_SRC_DIR)/debian/$(PACKAGE_PRE_NAME)-$${mod} --install-layout=deb; \ + done) + # 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 diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/classes/__init__.py b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/classes/__init__.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/Makefile b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/Makefile new file mode 100755 index 000000000000..fd73f274ef53 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/Makefile @@ -0,0 +1,3 @@ +obj-m:=qci_pmbus.o qci_cpld_qsfp28.o qci_platform_ix1b.o + + diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/pmbus.h b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/pmbus.h new file mode 100755 index 000000000000..fa9beb3eb60c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/pmbus.h @@ -0,0 +1,387 @@ +/* + * pmbus.h - Common defines and structures for PMBus devices + * + * Copyright (c) 2010, 2011 Ericsson AB. + * Copyright (c) 2012 Guenter Roeck + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef PMBUS_H +#define PMBUS_H + +/* + * Registers + */ +#define PMBUS_PAGE 0x00 +#define PMBUS_OPERATION 0x01 +#define PMBUS_ON_OFF_CONFIG 0x02 +#define PMBUS_CLEAR_FAULTS 0x03 +#define PMBUS_PHASE 0x04 + +#define PMBUS_CAPABILITY 0x19 +#define PMBUS_QUERY 0x1A + +#define PMBUS_VOUT_MODE 0x20 +#define PMBUS_VOUT_COMMAND 0x21 +#define PMBUS_VOUT_TRIM 0x22 +#define PMBUS_VOUT_CAL_OFFSET 0x23 +#define PMBUS_VOUT_MAX 0x24 +#define PMBUS_VOUT_MARGIN_HIGH 0x25 +#define PMBUS_VOUT_MARGIN_LOW 0x26 +#define PMBUS_VOUT_TRANSITION_RATE 0x27 +#define PMBUS_VOUT_DROOP 0x28 +#define PMBUS_VOUT_SCALE_LOOP 0x29 +#define PMBUS_VOUT_SCALE_MONITOR 0x2A + +#define PMBUS_COEFFICIENTS 0x30 +#define PMBUS_POUT_MAX 0x31 + +#define PMBUS_FAN_CONFIG_12 0x3A +#define PMBUS_FAN_COMMAND_1 0x3B +#define PMBUS_FAN_COMMAND_2 0x3C +#define PMBUS_FAN_CONFIG_34 0x3D +#define PMBUS_FAN_COMMAND_3 0x3E +#define PMBUS_FAN_COMMAND_4 0x3F + +#define PMBUS_VOUT_OV_FAULT_LIMIT 0x40 +#define PMBUS_VOUT_OV_FAULT_RESPONSE 0x41 +#define PMBUS_VOUT_OV_WARN_LIMIT 0x42 +#define PMBUS_VOUT_UV_WARN_LIMIT 0x43 +#define PMBUS_VOUT_UV_FAULT_LIMIT 0x44 +#define PMBUS_VOUT_UV_FAULT_RESPONSE 0x45 +#define PMBUS_IOUT_OC_FAULT_LIMIT 0x46 +#define PMBUS_IOUT_OC_FAULT_RESPONSE 0x47 +#define PMBUS_IOUT_OC_LV_FAULT_LIMIT 0x48 +#define PMBUS_IOUT_OC_LV_FAULT_RESPONSE 0x49 +#define PMBUS_IOUT_OC_WARN_LIMIT 0x4A +#define PMBUS_IOUT_UC_FAULT_LIMIT 0x4B +#define PMBUS_IOUT_UC_FAULT_RESPONSE 0x4C + +#define PMBUS_OT_FAULT_LIMIT 0x4F +#define PMBUS_OT_FAULT_RESPONSE 0x50 +#define PMBUS_OT_WARN_LIMIT 0x51 +#define PMBUS_UT_WARN_LIMIT 0x52 +#define PMBUS_UT_FAULT_LIMIT 0x53 +#define PMBUS_UT_FAULT_RESPONSE 0x54 +#define PMBUS_VIN_OV_FAULT_LIMIT 0x55 +#define PMBUS_VIN_OV_FAULT_RESPONSE 0x56 +#define PMBUS_VIN_OV_WARN_LIMIT 0x57 +#define PMBUS_VIN_UV_WARN_LIMIT 0x58 +#define PMBUS_VIN_UV_FAULT_LIMIT 0x59 + +#define PMBUS_IIN_OC_FAULT_LIMIT 0x5B +#define PMBUS_IIN_OC_WARN_LIMIT 0x5D + +#define PMBUS_POUT_OP_FAULT_LIMIT 0x68 +#define PMBUS_POUT_OP_WARN_LIMIT 0x6A +#define PMBUS_PIN_OP_WARN_LIMIT 0x6B + +#define PMBUS_STATUS_BYTE 0x78 +#define PMBUS_STATUS_WORD 0x79 +#define PMBUS_STATUS_VOUT 0x7A +#define PMBUS_STATUS_IOUT 0x7B +#define PMBUS_STATUS_INPUT 0x7C +#define PMBUS_STATUS_TEMPERATURE 0x7D +#define PMBUS_STATUS_CML 0x7E +#define PMBUS_STATUS_OTHER 0x7F +#define PMBUS_STATUS_MFR_SPECIFIC 0x80 +#define PMBUS_STATUS_FAN_12 0x81 +#define PMBUS_STATUS_FAN_34 0x82 + +#define PMBUS_READ_VIN 0x88 +#define PMBUS_READ_IIN 0x89 +#define PMBUS_READ_VCAP 0x8A +#define PMBUS_READ_VOUT 0x8B +#define PMBUS_READ_IOUT 0x8C +#define PMBUS_READ_TEMPERATURE_1 0x8D +#define PMBUS_READ_TEMPERATURE_2 0x8E +#define PMBUS_READ_TEMPERATURE_3 0x8F +#define PMBUS_READ_FAN_SPEED_1 0x90 +#define PMBUS_READ_FAN_SPEED_2 0x91 +#define PMBUS_READ_FAN_SPEED_3 0x92 +#define PMBUS_READ_FAN_SPEED_4 0x93 +#define PMBUS_READ_DUTY_CYCLE 0x94 +#define PMBUS_READ_FREQUENCY 0x95 +#define PMBUS_READ_POUT 0x96 +#define PMBUS_READ_PIN 0x97 + +#define PMBUS_REVISION 0x98 +#define PMBUS_MFR_ID 0x99 +#define PMBUS_MFR_MODEL 0x9A +#define PMBUS_MFR_REVISION 0x9B +#define PMBUS_MFR_LOCATION 0x9C +#define PMBUS_MFR_DATE 0x9D +#define PMBUS_MFR_SERIAL 0x9E + +/* + * Virtual registers. + * Useful to support attributes which are not supported by standard PMBus + * registers but exist as manufacturer specific registers on individual chips. + * Must be mapped to real registers in device specific code. + * + * Semantics: + * Virtual registers are all word size. + * READ registers are read-only; writes are either ignored or return an error. + * RESET registers are read/write. Reading reset registers returns zero + * (used for detection), writing any value causes the associated history to be + * reset. + * Virtual registers have to be handled in device specific driver code. Chip + * driver code returns non-negative register values if a virtual register is + * supported, or a negative error code if not. The chip driver may return + * -ENODATA or any other error code in this case, though an error code other + * than -ENODATA is handled more efficiently and thus preferred. Either case, + * the calling PMBus core code will abort if the chip driver returns an error + * code when reading or writing virtual registers. + */ +#define PMBUS_VIRT_BASE 0x100 +#define PMBUS_VIRT_READ_TEMP_AVG (PMBUS_VIRT_BASE + 0) +#define PMBUS_VIRT_READ_TEMP_MIN (PMBUS_VIRT_BASE + 1) +#define PMBUS_VIRT_READ_TEMP_MAX (PMBUS_VIRT_BASE + 2) +#define PMBUS_VIRT_RESET_TEMP_HISTORY (PMBUS_VIRT_BASE + 3) +#define PMBUS_VIRT_READ_VIN_AVG (PMBUS_VIRT_BASE + 4) +#define PMBUS_VIRT_READ_VIN_MIN (PMBUS_VIRT_BASE + 5) +#define PMBUS_VIRT_READ_VIN_MAX (PMBUS_VIRT_BASE + 6) +#define PMBUS_VIRT_RESET_VIN_HISTORY (PMBUS_VIRT_BASE + 7) +#define PMBUS_VIRT_READ_IIN_AVG (PMBUS_VIRT_BASE + 8) +#define PMBUS_VIRT_READ_IIN_MIN (PMBUS_VIRT_BASE + 9) +#define PMBUS_VIRT_READ_IIN_MAX (PMBUS_VIRT_BASE + 10) +#define PMBUS_VIRT_RESET_IIN_HISTORY (PMBUS_VIRT_BASE + 11) +#define PMBUS_VIRT_READ_PIN_AVG (PMBUS_VIRT_BASE + 12) +#define PMBUS_VIRT_READ_PIN_MAX (PMBUS_VIRT_BASE + 13) +#define PMBUS_VIRT_RESET_PIN_HISTORY (PMBUS_VIRT_BASE + 14) +#define PMBUS_VIRT_READ_POUT_AVG (PMBUS_VIRT_BASE + 15) +#define PMBUS_VIRT_READ_POUT_MAX (PMBUS_VIRT_BASE + 16) +#define PMBUS_VIRT_RESET_POUT_HISTORY (PMBUS_VIRT_BASE + 17) +#define PMBUS_VIRT_READ_VOUT_AVG (PMBUS_VIRT_BASE + 18) +#define PMBUS_VIRT_READ_VOUT_MIN (PMBUS_VIRT_BASE + 19) +#define PMBUS_VIRT_READ_VOUT_MAX (PMBUS_VIRT_BASE + 20) +#define PMBUS_VIRT_RESET_VOUT_HISTORY (PMBUS_VIRT_BASE + 21) +#define PMBUS_VIRT_READ_IOUT_AVG (PMBUS_VIRT_BASE + 22) +#define PMBUS_VIRT_READ_IOUT_MIN (PMBUS_VIRT_BASE + 23) +#define PMBUS_VIRT_READ_IOUT_MAX (PMBUS_VIRT_BASE + 24) +#define PMBUS_VIRT_RESET_IOUT_HISTORY (PMBUS_VIRT_BASE + 25) +#define PMBUS_VIRT_READ_TEMP2_AVG (PMBUS_VIRT_BASE + 26) +#define PMBUS_VIRT_READ_TEMP2_MIN (PMBUS_VIRT_BASE + 27) +#define PMBUS_VIRT_READ_TEMP2_MAX (PMBUS_VIRT_BASE + 28) +#define PMBUS_VIRT_RESET_TEMP2_HISTORY (PMBUS_VIRT_BASE + 29) + +#define PMBUS_VIRT_READ_VMON (PMBUS_VIRT_BASE + 30) +#define PMBUS_VIRT_VMON_UV_WARN_LIMIT (PMBUS_VIRT_BASE + 31) +#define PMBUS_VIRT_VMON_OV_WARN_LIMIT (PMBUS_VIRT_BASE + 32) +#define PMBUS_VIRT_VMON_UV_FAULT_LIMIT (PMBUS_VIRT_BASE + 33) +#define PMBUS_VIRT_VMON_OV_FAULT_LIMIT (PMBUS_VIRT_BASE + 34) +#define PMBUS_VIRT_STATUS_VMON (PMBUS_VIRT_BASE + 35) + +/* + * CAPABILITY + */ +#define PB_CAPABILITY_SMBALERT (1<<4) +#define PB_CAPABILITY_ERROR_CHECK (1<<7) + +/* + * VOUT_MODE + */ +#define PB_VOUT_MODE_MODE_MASK 0xe0 +#define PB_VOUT_MODE_PARAM_MASK 0x1f + +#define PB_VOUT_MODE_LINEAR 0x00 +#define PB_VOUT_MODE_VID 0x20 +#define PB_VOUT_MODE_DIRECT 0x40 + +/* + * Fan configuration + */ +#define PB_FAN_2_PULSE_MASK ((1 << 0) | (1 << 1)) +#define PB_FAN_2_RPM (1 << 2) +#define PB_FAN_2_INSTALLED (1 << 3) +#define PB_FAN_1_PULSE_MASK ((1 << 4) | (1 << 5)) +#define PB_FAN_1_RPM (1 << 6) +#define PB_FAN_1_INSTALLED (1 << 7) + +/* + * STATUS_BYTE, STATUS_WORD (lower) + */ +#define PB_STATUS_NONE_ABOVE (1<<0) +#define PB_STATUS_CML (1<<1) +#define PB_STATUS_TEMPERATURE (1<<2) +#define PB_STATUS_VIN_UV (1<<3) +#define PB_STATUS_IOUT_OC (1<<4) +#define PB_STATUS_VOUT_OV (1<<5) +#define PB_STATUS_OFF (1<<6) +#define PB_STATUS_BUSY (1<<7) + +/* + * STATUS_WORD (upper) + */ +#define PB_STATUS_UNKNOWN (1<<8) +#define PB_STATUS_OTHER (1<<9) +#define PB_STATUS_FANS (1<<10) +#define PB_STATUS_POWER_GOOD_N (1<<11) +#define PB_STATUS_WORD_MFR (1<<12) +#define PB_STATUS_INPUT (1<<13) +#define PB_STATUS_IOUT_POUT (1<<14) +#define PB_STATUS_VOUT (1<<15) + +/* + * STATUS_IOUT + */ +#define PB_POUT_OP_WARNING (1<<0) +#define PB_POUT_OP_FAULT (1<<1) +#define PB_POWER_LIMITING (1<<2) +#define PB_CURRENT_SHARE_FAULT (1<<3) +#define PB_IOUT_UC_FAULT (1<<4) +#define PB_IOUT_OC_WARNING (1<<5) +#define PB_IOUT_OC_LV_FAULT (1<<6) +#define PB_IOUT_OC_FAULT (1<<7) + +/* + * STATUS_VOUT, STATUS_INPUT + */ +#define PB_VOLTAGE_UV_FAULT (1<<4) +#define PB_VOLTAGE_UV_WARNING (1<<5) +#define PB_VOLTAGE_OV_WARNING (1<<6) +#define PB_VOLTAGE_OV_FAULT (1<<7) + +/* + * STATUS_INPUT + */ +#define PB_PIN_OP_WARNING (1<<0) +#define PB_IIN_OC_WARNING (1<<1) +#define PB_IIN_OC_FAULT (1<<2) + +/* + * STATUS_TEMPERATURE + */ +#define PB_TEMP_UT_FAULT (1<<4) +#define PB_TEMP_UT_WARNING (1<<5) +#define PB_TEMP_OT_WARNING (1<<6) +#define PB_TEMP_OT_FAULT (1<<7) + +/* + * STATUS_FAN + */ +#define PB_FAN_AIRFLOW_WARNING (1<<0) +#define PB_FAN_AIRFLOW_FAULT (1<<1) +#define PB_FAN_FAN2_SPEED_OVERRIDE (1<<2) +#define PB_FAN_FAN1_SPEED_OVERRIDE (1<<3) +#define PB_FAN_FAN2_WARNING (1<<4) +#define PB_FAN_FAN1_WARNING (1<<5) +#define PB_FAN_FAN2_FAULT (1<<6) +#define PB_FAN_FAN1_FAULT (1<<7) + +/* + * CML_FAULT_STATUS + */ +#define PB_CML_FAULT_OTHER_MEM_LOGIC (1<<0) +#define PB_CML_FAULT_OTHER_COMM (1<<1) +#define PB_CML_FAULT_PROCESSOR (1<<3) +#define PB_CML_FAULT_MEMORY (1<<4) +#define PB_CML_FAULT_PACKET_ERROR (1<<5) +#define PB_CML_FAULT_INVALID_DATA (1<<6) +#define PB_CML_FAULT_INVALID_COMMAND (1<<7) + +enum pmbus_sensor_classes { + PSC_VOLTAGE_IN = 0, + PSC_VOLTAGE_OUT, + PSC_CURRENT_IN, + PSC_CURRENT_OUT, + PSC_POWER, + PSC_TEMPERATURE, + PSC_FAN, + PSC_NUM_CLASSES /* Number of power sensor classes */ +}; + +#define PMBUS_PAGES 32 /* Per PMBus specification */ + +/* Functionality bit mask */ +#define PMBUS_HAVE_VIN (1 << 0) +#define PMBUS_HAVE_VCAP (1 << 1) +#define PMBUS_HAVE_VOUT (1 << 2) +#define PMBUS_HAVE_IIN (1 << 3) +#define PMBUS_HAVE_IOUT (1 << 4) +#define PMBUS_HAVE_PIN (1 << 5) +#define PMBUS_HAVE_POUT (1 << 6) +#define PMBUS_HAVE_FAN12 (1 << 7) +#define PMBUS_HAVE_FAN34 (1 << 8) +#define PMBUS_HAVE_TEMP (1 << 9) +#define PMBUS_HAVE_TEMP2 (1 << 10) +#define PMBUS_HAVE_TEMP3 (1 << 11) +#define PMBUS_HAVE_STATUS_VOUT (1 << 12) +#define PMBUS_HAVE_STATUS_IOUT (1 << 13) +#define PMBUS_HAVE_STATUS_INPUT (1 << 14) +#define PMBUS_HAVE_STATUS_TEMP (1 << 15) +#define PMBUS_HAVE_STATUS_FAN12 (1 << 16) +#define PMBUS_HAVE_STATUS_FAN34 (1 << 17) +#define PMBUS_HAVE_VMON (1 << 18) +#define PMBUS_HAVE_STATUS_VMON (1 << 19) + +enum pmbus_data_format { linear = 0, direct, vid }; + +struct pmbus_driver_info { + int pages; /* Total number of pages */ + enum pmbus_data_format format[PSC_NUM_CLASSES]; + /* + * Support one set of coefficients for each sensor type + * Used for chips providing data in direct mode. + */ + int m[PSC_NUM_CLASSES]; /* mantissa for direct data format */ + int b[PSC_NUM_CLASSES]; /* offset */ + int R[PSC_NUM_CLASSES]; /* exponent */ + + u32 func[PMBUS_PAGES]; /* Functionality, per page */ + /* + * The following functions map manufacturing specific register values + * to PMBus standard register values. Specify only if mapping is + * necessary. + * Functions return the register value (read) or zero (write) if + * successful. A return value of -ENODATA indicates that there is no + * manufacturer specific register, but that a standard PMBus register + * may exist. Any other negative return value indicates that the + * register does not exist, and that no attempt should be made to read + * the standard register. + */ + int (*read_byte_data)(struct i2c_client *client, int page, int reg); + int (*read_word_data)(struct i2c_client *client, int page, int reg); + int (*write_word_data)(struct i2c_client *client, int page, int reg, + u16 word); + int (*write_byte)(struct i2c_client *client, int page, u8 value); + /* + * The identify function determines supported PMBus functionality. + * This function is only necessary if a chip driver supports multiple + * chips, and the chip functionality is not pre-determined. + */ + int (*identify)(struct i2c_client *client, + struct pmbus_driver_info *info); +}; + +/* Function declarations */ + +void pmbus_clear_cache(struct i2c_client *client); +int pmbus_set_page(struct i2c_client *client, u8 page); +int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg); +int pmbus_write_word_data(struct i2c_client *client, u8 page, u8 reg, u16 word); +int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg); +int pmbus_write_byte(struct i2c_client *client, int page, u8 value); +void pmbus_clear_faults(struct i2c_client *client); +bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg); +bool pmbus_check_word_register(struct i2c_client *client, int page, int reg); +int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, + struct pmbus_driver_info *info); +int pmbus_do_remove(struct i2c_client *client); +const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client + *client); + +#endif /* PMBUS_H */ diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_cpld_qsfp28.c b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_cpld_qsfp28.c new file mode 100755 index 000000000000..15c5369fd219 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_cpld_qsfp28.c @@ -0,0 +1,409 @@ +/* + * A CPLD driver for monitor QSFP28 module I/O + * + * The CPLD is customize by Quanta for controlling QSFP28 module signals, + * they are RESET , INTERREPT , Module_Present, LPMODE + * Each CPLD control 16 modules, each module use 4 bits in register. + * + * Copyright (C) 2015 Quanta Inc. + * + * Author: Luffy Cheng + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static DEFINE_IDA(cpld_ida); + +enum platform_type { + QSFP28 = 0, + NONE +}; + +static struct class *cpld_class = NULL; + +struct sfp_data { + struct i2c_client *cpld_client; + char name[8]; + u8 port_id; + u8 cpld_port; +}; + +struct cpld_data { + struct mutex lock; + struct device *port_dev[16]; + struct sfp_data *port_data[16]; +}; + +static int cpld_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int cpld_remove(struct i2c_client *client); + +static const struct i2c_device_id cpld_id[] = { + { "CPLD-QSFP28", QSFP28 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, cpld_id); + +static struct i2c_driver cpld_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "qci_cpld_qsfp28", + }, + .probe = cpld_probe, + .remove = cpld_remove, + .id_table = cpld_id, +// .address_list = normal_i2c, +}; + +#define CPLD_ID_PREFIX "port-" +#define CPLD_ID_FORMAT CPLD_ID_PREFIX "%d" + +#define RESET_MASK 0x08 +#define INTERRUPT_MASK 0x04 +#define MODULE_PRESENT_MASK 0x02 +#define LPMODE_MASK 0x01 + +static inline u8 get_group_cmd(u8 group) +{ + //FIXME: if group cmd change + return (group + 1); +} + +static inline u8 port_remapping(u8 phy_port) +{ + /* FIXME: implement by hardware design */ + /* The CPLD register port mapping is weird : + * MSB -------- LSB (word data) + * P3 P4 P1 P2 (per port 4 bits) + * For easy coding bit shift, we treat it as hw port swap + */ + return (phy_port % 2) ? (phy_port - 1) : (phy_port + 1); +} + +static ssize_t get_reset(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sfp_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->cpld_client; + u8 group = (u8)(data->cpld_port / 4); + u8 group_port = data->cpld_port % 4; + s32 value; + + dev_dbg(&client->dev, "port_id %d => cpld_port %d, group %d(%d)\n", data->port_id, + data->cpld_port + 1, group + 1, group_port + 1); + + value = i2c_smbus_read_word_data(client, get_group_cmd(group)); + if (value < 0) + return -ENODEV; + + dev_dbg(&client->dev, "read group%d value= %x\n", group + 1, value); + + value >>= (group_port * 4); + value &= RESET_MASK; + + return sprintf(buf, "%d\n", value ? 1 : 0); +} + +static ssize_t get_interrupt(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sfp_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->cpld_client; + u8 group = (u8)(data->cpld_port / 4); + u8 group_port = data->cpld_port % 4; + s32 value; + + dev_dbg(&client->dev, "port_id %d => cpld_port %d, group %d(%d)\n", data->port_id, + data->cpld_port + 1, group + 1, group_port + 1); + + value = i2c_smbus_read_word_data(client, get_group_cmd(group)); + if (value < 0) + return -ENODEV; + + dev_dbg(&client->dev, "read group%d value= %x\n", group + 1, value); + + value >>= (group_port * 4); + value &= INTERRUPT_MASK; + + return sprintf(buf, "%d\n", value ? 1 : 0); +} + +static ssize_t get_module_present(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sfp_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->cpld_client; + u8 group = (u8)(data->cpld_port / 4); + u8 group_port = data->cpld_port % 4; + s32 value; + + dev_dbg(&client->dev, "port_id %d => cpld_port %d, group %d(%d)\n", data->port_id, + data->cpld_port + 1, group + 1, group_port + 1); + + value = i2c_smbus_read_word_data(client, get_group_cmd(group)); + if (value < 0) + return -ENODEV; + + dev_dbg(&client->dev, "read group%d value= %x\n", group + 1, value); + + value >>= (group_port * 4); + value &= MODULE_PRESENT_MASK; + + //FIXME: if present is not low active + return sprintf(buf, "%d\n", value ? 0 : 1); +} + +static ssize_t get_lpmode(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sfp_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->cpld_client; + u8 group = (u8)(data->cpld_port / 4); + u8 group_port = data->cpld_port % 4; + s32 value; + + dev_dbg(&client->dev, "port_id %d => cpld_port %d, group %d(%d)\n", data->port_id, + data->cpld_port + 1, group + 1, group_port + 1); + + value = i2c_smbus_read_word_data(client, get_group_cmd(group)); + if (value < 0) + return -ENODEV; + + dev_dbg(&client->dev, "read group%d value= %x\n", group + 1, value); + + value >>= (group_port * 4); + value &= LPMODE_MASK; + + return sprintf(buf, "%d\n", value ? 1 : 0); +} + +static ssize_t set_reset(struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t count) +{ + struct sfp_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->cpld_client; + u8 group = (u8)(data->cpld_port / 4); + u8 group_port = data->cpld_port % 4; + s32 value; + long disable; + + dev_dbg(&client->dev, "port_id %d => cpld_port %d, group %d(%d)\n", data->port_id, + data->cpld_port + 1, group + 1, group_port + 1); + + if (kstrtol(buf, 0, &disable)) + return -EINVAL; + + if ((disable != 1) && (disable != 0)) + return -EINVAL; + +// mutex_lock(&data->lock); + value = i2c_smbus_read_word_data(client, get_group_cmd(group)); + if (value < 0) + return -ENODEV; + + dev_dbg(&client->dev, "read group%d value= %x\n", group + 1, value); + + value &= ~(RESET_MASK << (group_port * 4)); + if (disable) + value |= (RESET_MASK << (group_port * 4)); + + dev_dbg(&client->dev, "write group%d value= %x\n", group + 1, value); + + i2c_smbus_write_word_data(client, get_group_cmd(group), (u16)value); +// mutex_unlock(&data->lock); + + return count; +} + +static ssize_t set_lpmode(struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t count) +{ + struct sfp_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->cpld_client; + u8 group = (u8)(data->cpld_port / 4); + u8 group_port = data->cpld_port % 4; + s32 value; + long disable; + + dev_dbg(&client->dev, "port_id %d => cpld_port %d, group %d(%d)\n", data->port_id, + data->cpld_port + 1, group + 1, group_port + 1); + + if (kstrtol(buf, 0, &disable)) + return -EINVAL; + + if ((disable != 1) && (disable != 0)) + return -EINVAL; + +// mutex_lock(&data->lock); + value = i2c_smbus_read_word_data(client, get_group_cmd(group)); + if (value < 0) + return -ENODEV; + + dev_dbg(&client->dev, "read group%d value= %x\n", group + 1, value); + + value &= ~(LPMODE_MASK << (group_port * 4)); + if (disable) + value |= (LPMODE_MASK << (group_port * 4)); + + dev_dbg(&client->dev, "write group%d value= %x\n", group + 1, value); + + i2c_smbus_write_word_data(client, get_group_cmd(group), (u16)value); +// mutex_unlock(&data->lock); + + return count; +} + +static DEVICE_ATTR(reset, S_IWUSR | S_IRUGO, get_reset, set_reset); +static DEVICE_ATTR(lpmode, S_IWUSR | S_IRUGO, get_lpmode, set_lpmode); +static DEVICE_ATTR(module_present, S_IRUGO, get_module_present, NULL); +static DEVICE_ATTR(interrupt, S_IRUGO, get_interrupt, NULL); + +static const struct attribute *sfp_attrs[] = { + &dev_attr_reset.attr, + &dev_attr_lpmode.attr, + &dev_attr_module_present.attr, + &dev_attr_interrupt.attr, + NULL, +}; + +static const struct attribute_group sfp_attr_group = { + .attrs = (struct attribute **) sfp_attrs, +}; + +static int cpld_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct cpld_data *data; + struct sfp_data *port_data; + struct device *port_dev; + int port_nr, i, err; + + if (!cpld_class) + { + cpld_class = class_create(THIS_MODULE, "cpld-qsfp28"); + if (IS_ERR(cpld_class)) { + pr_err("couldn't create sysfs class\n"); + return PTR_ERR(cpld_class); + } + } + + data = devm_kzalloc(&client->dev, sizeof(struct cpld_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; + + /* register sfp port data to sysfs */ + for (i = 0; i < 16; i++) + { + port_nr = ida_simple_get(&cpld_ida, 1, 99, GFP_KERNEL); + if (port_nr < 0) + return ERR_PTR(port_nr); + + port_data = kzalloc(sizeof(struct sfp_data), GFP_KERNEL); + + port_dev = device_create(cpld_class, &client->dev, MKDEV(0,0), port_data, CPLD_ID_FORMAT, port_nr); + if (IS_ERR(port_dev)) { + err = PTR_ERR(port_dev); + // printk("err_status\n"); + } + + data->port_dev[i] = port_dev; + data->port_data[i] = port_data; + + dev_info(&client->dev, "Register qsfp28 port-%d\n", port_nr); + + /* FIXME: implement Logical/Physical port remapping */ + //port_data->cpld_port = i; + port_data->cpld_port = port_remapping(i); + sprintf(port_data->name, "port-%d", port_nr); + port_data->port_id = port_nr; + dev_set_drvdata(port_dev, port_data); + port_dev->init_name = port_data->name; + port_data->cpld_client = client; + + err = sysfs_create_group(&port_dev->kobj, &sfp_attr_group); + // if (status) printk("err status\n"); + } + + i2c_set_clientdata(client, data); + mutex_init(&data->lock); + + dev_info(&client->dev, "%s device found\n", client->name); + + + return 0; + +//FIXME: implement error check +exit_remove: +// sysfs_remove_group(&client->dev.kobj, &data->attrs); + return err; +} + +/* FIXME: for older kernel doesn't with idr_is_empty function, implement here */ +static int idr_has_entry(int id, void *p, void *data) +{ + return 1; +} + +static bool cpld_idr_is_empty(struct idr *idp) +{ + return !idr_for_each(idp, idr_has_entry, NULL); +} + +static int cpld_remove(struct i2c_client *client) +{ + struct cpld_data *data = i2c_get_clientdata(client); + int i, id; + + for (i = 15; i >= 0; i--) + { + dev_info(data->port_dev[i], "Remove qsfp28 port-%d\n", data->port_data[i]->port_id); + device_unregister(data->port_dev[i]); + ida_simple_remove(&cpld_ida, data->port_data[i]->port_id); + kfree(data->port_data[i]); + } + + if (cpld_idr_is_empty(&cpld_ida.idr)) + class_destroy(cpld_class); + + return 0; +} + +module_i2c_driver(cpld_driver); + +MODULE_AUTHOR("Luffy Cheng "); +MODULE_DESCRIPTION("Quanta Switch SFP CPLD driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_platform.h b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_platform.h new file mode 100755 index 000000000000..0737c8ce8170 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_platform.h @@ -0,0 +1,64 @@ +/* + * Driver model definations for Quanta Platform drivers + * + * Copyright (C) 2015-2016 Quanta QCT + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#ifndef __QCI_PLATFORM_H_INCLUDED +#define __QCI_PLATFORM_H_INCLUDED + +#define MUX_INFO(bus, deselect) \ + {.adap_id = bus, .deselect_on_exit = deselect} + +#define GPIO_INFO(id, gpio_nr) \ + {.gpio_id = id, .system_gpio_nr = gpio_nr} + +struct platform_gpio { + int gpio_id; + int system_gpio_nr; +}; + +/* FIXME: Please add important GPIO which need to be request */ +enum PLATFORM_GPIO_ID { + GPIO_PSU1_PRSNT, + GPIO_PSU1_PWRGD, + GPIO_PSU2_PRSNT, + GPIO_PSU2_PWRGD, +}; + +#define LED_ON LED_FULL + +#define LED_INFO(id) \ + {.led_id = id, .cdev = NULL} + +struct platform_led { + int led_id; + struct led_classdev *cdev; +}; + +enum PLATFORM_LED_ID { + SYSLED_AMBER, + SYSLED_GREEN, + FRONT_PSU1_GREEN, + FRONT_PSU1_RED, + FRONT_PSU2_GREEN, + FRONT_PSU2_RED, + FRONT_FAN_GREEN, + FRONT_FAN_RED, + REAR_FAN1_RED, + REAR_FAN2_RED, + REAR_FAN3_RED, + REAR_FAN4_RED, + REAR_FAN5_RED, + REAR_FAN6_RED, + TOTAL_LED_NR +}; + +extern int qci_platform_get_gpio(int platform_gpio); +extern int qci_platform_set_led(int led_id, bool led_on); + +#endif /* __QCI_PLATFORM_H_INCLUDED */ diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_platform_ix1b.c b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_platform_ix1b.c new file mode 100755 index 000000000000..f783c88fb9a1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_platform_ix1b.c @@ -0,0 +1,491 @@ +/* + * Quanta IX1B platform driver + * + * + * Copyright (C) 2014 Quanta Computer 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE > KERNEL_VERSION(3,12,0) +#include +#else +#include +#endif +#include "qci_platform.h" + +#define QUANTA_CPU_RGL + +static struct pca954x_platform_mode pca9548sfp1_modes[] = { + MUX_INFO(0x20, 1), + MUX_INFO(0x21, 1), + MUX_INFO(0x22, 1), + MUX_INFO(0x23, 1), + MUX_INFO(0x24, 1), + MUX_INFO(0x25, 1), + MUX_INFO(0x26, 1), + MUX_INFO(0x27, 1), +}; + +static struct pca954x_platform_data pca9548sfp1_data = { + .modes = pca9548sfp1_modes, + .num_modes = 8, +}; + +static struct pca954x_platform_mode pca9548sfp2_modes[] = { + MUX_INFO(0x28, 1), + MUX_INFO(0x29, 1), + MUX_INFO(0x2a, 1), + MUX_INFO(0x2b, 1), + MUX_INFO(0x2c, 1), + MUX_INFO(0x2d, 1), + MUX_INFO(0x2e, 1), + MUX_INFO(0x2f, 1), +}; + +static struct pca954x_platform_data pca9548sfp2_data = { + .modes = pca9548sfp2_modes, + .num_modes = 8, +}; + +static struct pca954x_platform_mode pca9548sfp3_modes[] = { + MUX_INFO(0x30, 1), + MUX_INFO(0x31, 1), + MUX_INFO(0x32, 1), + MUX_INFO(0x33, 1), + MUX_INFO(0x34, 1), + MUX_INFO(0x35, 1), + MUX_INFO(0x36, 1), + MUX_INFO(0x37, 1), +}; + +static struct pca954x_platform_data pca9548sfp3_data = { + .modes = pca9548sfp3_modes, + .num_modes = 8, +}; + +static struct pca954x_platform_mode pca9548sfp4_modes[] = { + MUX_INFO(0x38, 1), + MUX_INFO(0x39, 1), + MUX_INFO(0x3a, 1), + MUX_INFO(0x3b, 1), + MUX_INFO(0x3c, 1), + MUX_INFO(0x3d, 1), + MUX_INFO(0x3e, 1), + MUX_INFO(0x3f, 1), +}; + +static struct pca954x_platform_data pca9548sfp4_data = { + .modes = pca9548sfp4_modes, + .num_modes = 8, +}; + +static struct pca954x_platform_mode pca9546_1_modes[] = { + MUX_INFO(0x10, 1), + MUX_INFO(0x11, 1), + MUX_INFO(0x12, 1), + MUX_INFO(0x13, 1), +}; + +static struct pca954x_platform_data pca9546_1_data = { + .modes = pca9546_1_modes, + .num_modes = 4, +}; + +static struct pca954x_platform_mode pca9546_2_modes[] = { + MUX_INFO(0x14, 1), + MUX_INFO(0x15, 1), + MUX_INFO(0x16, 1), + MUX_INFO(0x17, 1), +}; + +static struct pca954x_platform_data pca9546_2_data = { + .modes = pca9546_2_modes, + .num_modes = 4, +}; + +/* CPU gpio base defined in devicetree + * default is ARCH_NR_GPIOS - 32, (256-32=224) + * It must match devicetree default gpio base + * */ +#define PCA9555_PSU_GPIO_BASE 0x10 +#define PCA9555_FAN_GPIO_BASE 0x20 +#define PCA9555_ID_GPIO_BASE 0x30 + +#if defined(QUANTA_CPU_RGL) +#define PCA9555_CPU_LED_GPIO_BASE 0x80 + +static struct pca954x_platform_mode pca9546_cpu1_modes[] = { + MUX_INFO(0x18, 1), + MUX_INFO(0x19, 1), + MUX_INFO(0x1a, 1), + MUX_INFO(0x1b, 1), +}; + +static struct pca954x_platform_data pca9546_cpu1_data = { + .modes = pca9546_cpu1_modes, + .num_modes = 4, +}; + +static struct pca953x_platform_data pca9555_cpuled_data = { + .gpio_base = PCA9555_CPU_LED_GPIO_BASE, +}; +#endif + +static struct pca953x_platform_data pca9555psu1_data = { + .gpio_base = PCA9555_PSU_GPIO_BASE, +}; + +static struct pca953x_platform_data pca9555fan_data = { + .gpio_base = PCA9555_FAN_GPIO_BASE, +}; + +static struct pca953x_platform_data pca9555ID_data = { + .gpio_base = PCA9555_ID_GPIO_BASE, +}; + +static struct i2c_board_info ix1b_i2c_devices[] = { + { + I2C_BOARD_INFO("pca9546", 0x77), + .platform_data = &pca9546_1_data, + }, + { + I2C_BOARD_INFO("pca9546", 0x72), + .platform_data = &pca9546_2_data, + }, + { + I2C_BOARD_INFO("pca9555", 0x26), + .platform_data = &pca9555psu1_data, + }, + { + I2C_BOARD_INFO("24c02", 0x54), + }, + { + I2C_BOARD_INFO("pca9548", 0x73), + .platform_data = &pca9548sfp1_data, + }, + { + I2C_BOARD_INFO("pca9548", 0x74), + .platform_data = &pca9548sfp2_data, + }, + { + I2C_BOARD_INFO("pca9548", 0x75), + .platform_data = &pca9548sfp3_data, + }, + { + I2C_BOARD_INFO("pca9548", 0x76), + .platform_data = &pca9548sfp4_data, + }, + { + I2C_BOARD_INFO("CPLD-QSFP28", 0x38), + }, + { + I2C_BOARD_INFO("CPLD-QSFP28", 0x39), + }, + { + I2C_BOARD_INFO("pca9555", 0x23), + .platform_data = &pca9555ID_data, + }, + { + I2C_BOARD_INFO("pca9555", 0x25), + .platform_data = &pca9555fan_data, + }, + { + I2C_BOARD_INFO("qci_pmbus_ix1b", 0x5f), + }, + { + I2C_BOARD_INFO("qci_pmbus_ix1b", 0x59), + }, +#if defined(QUANTA_CPU_RGL) + { + I2C_BOARD_INFO("pca9546", 0x71), + .platform_data = &pca9546_cpu1_data, + }, + { + I2C_BOARD_INFO("pca9555", 0x20), + .platform_data = &pca9555_cpuled_data, + }, + { + I2C_BOARD_INFO("24c02", 0x50), + }, +#endif +}; + +static struct platform_driver ix1b_platform_driver = { + .driver = { + .name = "qci-ix1b", + .owner = THIS_MODULE, + }, +}; + +static struct platform_led ix1b_leds[] = { +#if defined(QUANTA_CPU_RGL) + LED_INFO(SYSLED_AMBER), + LED_INFO(SYSLED_GREEN), +#endif + LED_INFO(FRONT_PSU1_GREEN), + LED_INFO(FRONT_PSU1_RED), + LED_INFO(FRONT_PSU2_GREEN), + LED_INFO(FRONT_PSU2_RED), + LED_INFO(FRONT_FAN_GREEN), + LED_INFO(FRONT_FAN_RED), + LED_INFO(REAR_FAN1_RED), + LED_INFO(REAR_FAN2_RED), + LED_INFO(REAR_FAN3_RED), + LED_INFO(REAR_FAN4_RED), +}; + +static struct gpio_led system_led[] = { +#if defined(QUANTA_CPU_RGL) + { + .name = "sysled_amber", + .default_trigger = "timer", + .gpio = (PCA9555_CPU_LED_GPIO_BASE + 10), + .active_low = 0, + }, + { + .name = "sysled_green", + .gpio = (PCA9555_CPU_LED_GPIO_BASE + 11), + .active_low = 0, + }, +#endif + { + .name = "front_led_psu1_green", + .gpio = (PCA9555_PSU_GPIO_BASE + 10), + .active_low = 0, + }, + { + .name = "front_led_psu1_red", + .gpio = (PCA9555_PSU_GPIO_BASE + 11), + .active_low = 0, + }, + { + .name = "front_led_psu2_green", + .gpio = (PCA9555_PSU_GPIO_BASE + 12), + .active_low = 0, + }, + { + .name = "front_led_psu2_red", + .gpio = (PCA9555_PSU_GPIO_BASE + 13), + .active_low = 0, + }, + { + .name = "front_led_fan_green", + .gpio = (PCA9555_PSU_GPIO_BASE + 14), + .active_low = 0, + }, + { + .name = "front_led_fan_red", + .gpio = (PCA9555_PSU_GPIO_BASE + 15), + .active_low = 0, + }, + { + .name = "rear_led_fan1_red", + .gpio = (PCA9555_FAN_GPIO_BASE + 12), + .active_low = 0, + }, + { + .name = "rear_led_fan2_red", + .gpio = (PCA9555_FAN_GPIO_BASE + 13), + .active_low = 0, + }, + { + .name = "rear_led_fan3_red", + .gpio = (PCA9555_FAN_GPIO_BASE + 14), + .active_low = 0, + }, + { + .name = "rear_led_fan4_red", + .gpio = (PCA9555_FAN_GPIO_BASE + 15), + .active_low = 0, + }, +}; + +static struct gpio_led_platform_data system_led_data = { + .num_leds = ARRAY_SIZE(system_led), + .leds = system_led +}; + +static struct platform_device system_led_dev = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &system_led_data, + }, +}; + +static struct platform_device *ix1b_device; + +struct gpio_led_data { + struct led_classdev cdev; + unsigned gpio; + struct work_struct work; + u8 new_level; + u8 can_sleep; + u8 active_low; + u8 blinking; + int (*platform_gpio_blink_set)(unsigned gpio, int state, + unsigned long *delay_on, unsigned long *delay_off); +}; + +struct gpio_leds_priv { + int num_leds; + struct gpio_led_data leds[]; +}; + +static int __init ix1b_platform_init(void) +{ + struct i2c_client *client; + struct i2c_adapter *adapter; + struct gpio_leds_priv *priv; + int i; + int ret; + + ret = platform_driver_register(&ix1b_platform_driver); + if (ret < 0) + return ret; + + /* Register platform stuff */ + ix1b_device = platform_device_alloc("qci-ix1b", -1); + if (!ix1b_device) { + ret = -ENOMEM; + goto fail_platform_driver; + } + + ret = platform_device_add(ix1b_device); + if (ret) + goto fail_platform_device; + + adapter = i2c_get_adapter(0); + client = i2c_new_device(adapter, &ix1b_i2c_devices[0]); // pca9546_1 + printk("[CC] NEW device pca9546_1\n"); + client = i2c_new_device(adapter, &ix1b_i2c_devices[1]); // pca9546_2 + printk("[CC] NEW device pca9546_2\n"); +#if defined(QUANTA_CPU_RGL) + client = i2c_new_device(adapter, &ix1b_i2c_devices[14]); // cpu pca9546_1 + printk("[CC] NEW device cpu pca9546_1\n"); +#endif + i2c_put_adapter(adapter); + + adapter = i2c_get_adapter(0x14); + client = i2c_new_device(adapter, &ix1b_i2c_devices[12]); // pmbus_psu1 + printk("[CC] NEW device pmbus_psu1\n"); + i2c_put_adapter(adapter); + + adapter = i2c_get_adapter(0x15); + client = i2c_new_device(adapter, &ix1b_i2c_devices[13]); // pmbus_psu2 + printk("[CC] NEW device pmbus_psu2\n"); + i2c_put_adapter(adapter); + + adapter = i2c_get_adapter(0x16); + client = i2c_new_device(adapter, &ix1b_i2c_devices[2]); // pca9555-PSU1 + printk("[CC] NEW device pca9555-PSU1\n"); + client = i2c_new_device(adapter, &ix1b_i2c_devices[3]); // MB_BOARDINFO_EEPROM + printk("[CC] NEW device MB_BOARDINFO_EEPROM\n"); + client = i2c_new_device(adapter, &ix1b_i2c_devices[10]); // pca9555-ID + printk("[CC] NEW device pca9555-ID\n"); + i2c_put_adapter(adapter); + + adapter = i2c_get_adapter(0x17); + client = i2c_new_device(adapter, &ix1b_i2c_devices[11]); // pca9555-fan + printk("[CC] NEW device pca9555-fan\n"); + i2c_put_adapter(adapter); + + adapter = i2c_get_adapter(0x10); + client = i2c_new_device(adapter, &ix1b_i2c_devices[4]); // pca9548_2 SFP + printk("[CC] NEW device pca9548_2 SFP\n"); + client = i2c_new_device(adapter, &ix1b_i2c_devices[5]); // pca9548_3 SFP + printk("[CC] NEW device pca9548_3 SFP\n"); + client = i2c_new_device(adapter, &ix1b_i2c_devices[6]); // pca9548_4 SFP + printk("[CC] NEW device pca9548_4 SFP\n"); + client = i2c_new_device(adapter, &ix1b_i2c_devices[8]); // CPLD2 + printk("[CC] NEW device CPLD2\n"); + client = i2c_new_device(adapter, &ix1b_i2c_devices[9]); // CPLD3 + printk("[CC] NEW device CPLD3\n"); + i2c_put_adapter(adapter); + + adapter = i2c_get_adapter(0x11); + client = i2c_new_device(adapter, &ix1b_i2c_devices[7]); // pca9548_5 SFP + printk("[CC] NEW device pca9548_5 SFP\n"); + i2c_put_adapter(adapter); + +#if defined(QUANTA_CPU_RGL) + adapter = i2c_get_adapter(0x18); + client = i2c_new_device(adapter, &ix1b_i2c_devices[15]); // cpu pca9555_1 + printk("[CC] NEW device cpu pca9555_1\n"); + i2c_put_adapter(adapter); + + for(i = 0x20; i < 0x40; i++) + { + adapter = i2c_get_adapter(i); + client = i2c_new_device(adapter, &ix1b_i2c_devices[16]); // eeprom for loopback module + i2c_put_adapter(adapter); + } + printk("[CC] NEW device eeprom\n"); +#endif + + /* Register LED devices */ + platform_device_register(&system_led_dev); + priv = platform_get_drvdata(&system_led_dev); + for (i = 0; i < priv->num_leds; i++) { + printk("leds-gpio gpio-%d: Register led %s\n", priv->leds[i].gpio, priv->leds[i].cdev.name); + ix1b_leds[i].cdev = &(priv->leds[i].cdev); + } + printk("[CC] NEW device led\n"); + + return 0; + +fail_platform_device: + platform_device_put(ix1b_device); + +fail_platform_driver: + platform_driver_unregister(&ix1b_platform_driver); + return ret; +} + +static void __exit ix1b_platform_exit(void) +{ + platform_device_unregister(ix1b_device); + platform_driver_unregister(&ix1b_platform_driver); +} + +module_init(ix1b_platform_init); +module_exit(ix1b_platform_exit); + + +MODULE_AUTHOR("Quanta Computer Inc."); +MODULE_DESCRIPTION("Quanta IX1B Platform Driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_pmbus.c b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_pmbus.c new file mode 100755 index 000000000000..f54a0f204d67 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/modules/qci_pmbus.c @@ -0,0 +1,487 @@ +/* + * QUANTA Generic PMBUS driver + * + * + * Based on generic pmbus driver and ltc2978 driver + * + * Author: Chih-Pei Chang + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +//#include <../drivers/hwmon/pmbus/pmbus.h> +#include "pmbus.h" +#include + +enum projects { ly8, ix1, ix2, ix1b }; + +#define DELAY_TIME 1000 /* uS */ + +/* Needed to access the mutex. Copied from pmbus_core.c */ +#define PB_STATUS_BASE 0 +#define PB_STATUS_VOUT_BASE (PB_STATUS_BASE + PMBUS_PAGES) +#define PB_STATUS_IOUT_BASE (PB_STATUS_VOUT_BASE + PMBUS_PAGES) +#define PB_STATUS_FAN_BASE (PB_STATUS_IOUT_BASE + PMBUS_PAGES) +#define PB_STATUS_FAN34_BASE (PB_STATUS_FAN_BASE + PMBUS_PAGES) +#define PB_STATUS_TEMP_BASE (PB_STATUS_FAN34_BASE + PMBUS_PAGES) +#define PB_STATUS_INPUT_BASE (PB_STATUS_TEMP_BASE + PMBUS_PAGES) +#define PB_STATUS_VMON_BASE (PB_STATUS_INPUT_BASE + 1) +#define PB_NUM_STATUS_REG (PB_STATUS_VMON_BASE + 1) +struct pmbus_data { + struct device *dev; + struct device *hwmon_dev; + + u32 flags; /* from platform data */ + + int exponent[PMBUS_PAGES]; + /* linear mode: exponent for output voltages */ + + const struct pmbus_driver_info *info; + + int max_attributes; + int num_attributes; + struct attribute_group group; + const struct attribute_group *groups[2]; + + struct pmbus_sensor *sensors; + + struct mutex update_lock; + bool valid; + unsigned long last_updated; /* in jiffies */ + + /* + * A single status register covers multiple attributes, + * so we keep them all together. + */ + u8 status[PB_NUM_STATUS_REG]; + u8 status_register; + + u8 currpage; +}; + +static int qci_pmbus_read_block(struct i2c_client *client, u8 command, int data_len, u8 *data) +{ + int result = 0; + int retry_count = 3; + + while (retry_count) { + retry_count--; + + result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + + if (result < 0) { + msleep(10); + continue; + } + + result = 0; + break; + } + + return result; +} + +static ssize_t qci_pmbus_show_mfr_id(struct device *dev, + struct device_attribute *da, char *buf) +{ + int ret, len; + u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1], *str; + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + + ret = qci_pmbus_read_block(client, PMBUS_MFR_ID, I2C_SMBUS_BLOCK_MAX, block_buffer); + if (ret < 0) { + dev_err(&client->dev, "Failed to read Manufacturer ID\n"); + return ret; + } + len = block_buffer[0]; + block_buffer[(len+1)] = '\0'; + str = &(block_buffer[1]); + + return snprintf(buf, PAGE_SIZE, "%s\n", str); +} + +static ssize_t qci_pmbus_show_mfr_model(struct device *dev, + struct device_attribute *da, char *buf) +{ + int ret, len; + u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1], *str; + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + + ret = qci_pmbus_read_block(client, PMBUS_MFR_MODEL, I2C_SMBUS_BLOCK_MAX, block_buffer); + if (ret < 0) { + dev_err(&client->dev, "Failed to read Manufacturer Model\n"); + return ret; + } + len = block_buffer[0]; + block_buffer[(len+1)] = '\0'; + str = &(block_buffer[1]); + + return snprintf(buf, PAGE_SIZE, "%s\n", str); +} + +static ssize_t qci_pmbus_show_mfr_revision(struct device *dev, + struct device_attribute *da, char *buf) +{ + int ret, len; + u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1], *str; + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + + ret = qci_pmbus_read_block(client, PMBUS_MFR_REVISION, I2C_SMBUS_BLOCK_MAX, block_buffer); + if (ret < 0) { + dev_err(&client->dev, "Failed to read Manufacturer Revision\n"); + return ret; + } + len = block_buffer[0]; + block_buffer[(len+1)] = '\0'; + str = &(block_buffer[1]); + + return snprintf(buf, PAGE_SIZE, "%s\n", str); +} + +static ssize_t qci_pmbus_show_mfr_location(struct device *dev, + struct device_attribute *da, char *buf) +{ + int ret, len; + u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1], *str; + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + + ret = qci_pmbus_read_block(client, PMBUS_MFR_LOCATION, I2C_SMBUS_BLOCK_MAX, block_buffer); + if (ret < 0) { + dev_err(&client->dev, "Failed to read Manufacture Location\n"); + return ret; + } + len = block_buffer[0]; + block_buffer[(len+1)] = '\0'; + str = &(block_buffer[1]); + + return snprintf(buf, PAGE_SIZE, "%s\n", str); +} + +static ssize_t qci_pmbus_show_mfr_serial(struct device *dev, + struct device_attribute *da, char *buf) +{ + int ret, len; + u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1], *str; + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + + ret = qci_pmbus_read_block(client, PMBUS_MFR_SERIAL, I2C_SMBUS_BLOCK_MAX, block_buffer); + if (ret < 0) { + dev_err(&client->dev, "Failed to read Manufacturer Serial\n"); + return ret; + } + len = block_buffer[0]; + block_buffer[(len+1)] = '\0'; + str = &(block_buffer[1]); + + return snprintf(buf, PAGE_SIZE, "%s\n", str); +} + + +static DEVICE_ATTR(mfr_id, S_IRUGO, qci_pmbus_show_mfr_id, NULL); +static DEVICE_ATTR(mfr_model, S_IRUGO, qci_pmbus_show_mfr_model, NULL); +static DEVICE_ATTR(mfr_revision, S_IRUGO, qci_pmbus_show_mfr_revision, NULL); +static DEVICE_ATTR(mfr_location, S_IRUGO, qci_pmbus_show_mfr_location, NULL); +static DEVICE_ATTR(mfr_serial, S_IRUGO, qci_pmbus_show_mfr_serial, NULL); + + +static struct attribute *qci_pmbus_inventory_attrs[] = { + &dev_attr_mfr_id.attr, + &dev_attr_mfr_model.attr, + &dev_attr_mfr_revision.attr, + &dev_attr_mfr_location.attr, + &dev_attr_mfr_serial.attr, + NULL +}; + +static struct attribute_group qci_pmbus_inventory_attr_grp = { + .attrs = qci_pmbus_inventory_attrs +}; + +/* FIXME: add project specific id here */ +static const struct i2c_device_id qci_pmbus_id[] = { + {"qci_pmbus_ly8", ly8}, + {"qci_pmbus_ix1", ix1}, + {"qci_pmbus_ix2", ix2}, + {"qci_pmbus_ix1b", ix1b}, + {} +}; +MODULE_DEVICE_TABLE(i2c, qci_pmbus_id); + +/* + * Find sensor groups and status registers on each page. + */ +static void qci_pmbus_find_sensor_groups(struct i2c_client *client, + struct pmbus_driver_info *info) +{ + int page; + + /* Sensors detected on page 0 only */ + if (pmbus_check_word_register(client, 0, PMBUS_READ_VIN)) + info->func[0] |= PMBUS_HAVE_VIN; + if (pmbus_check_word_register(client, 0, PMBUS_READ_VCAP)) + info->func[0] |= PMBUS_HAVE_VCAP; + if (pmbus_check_word_register(client, 0, PMBUS_READ_IIN)) + info->func[0] |= PMBUS_HAVE_IIN; + if (pmbus_check_word_register(client, 0, PMBUS_READ_PIN)) + info->func[0] |= PMBUS_HAVE_PIN; + if (info->func[0] + && pmbus_check_byte_register(client, 0, PMBUS_STATUS_INPUT)) + info->func[0] |= PMBUS_HAVE_STATUS_INPUT; + if (pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_12) && + pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_1)) { + info->func[0] |= PMBUS_HAVE_FAN12; + if (pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_12)) + info->func[0] |= PMBUS_HAVE_STATUS_FAN12; + } + if (pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_34) && + pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_3)) { + info->func[0] |= PMBUS_HAVE_FAN34; + if (pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_34)) + info->func[0] |= PMBUS_HAVE_STATUS_FAN34; + } + if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_1)) + info->func[0] |= PMBUS_HAVE_TEMP; + if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_2)) + info->func[0] |= PMBUS_HAVE_TEMP2; + if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_3)) + info->func[0] |= PMBUS_HAVE_TEMP3; + if (info->func[0] & (PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 + | PMBUS_HAVE_TEMP3) + && pmbus_check_byte_register(client, 0, + PMBUS_STATUS_TEMPERATURE)) + info->func[0] |= PMBUS_HAVE_STATUS_TEMP; + + /* Sensors detected on all pages */ + for (page = 0; page < info->pages; page++) { + if (pmbus_check_word_register(client, page, PMBUS_READ_VOUT)) { + info->func[page] |= PMBUS_HAVE_VOUT; + if (pmbus_check_byte_register(client, page, + PMBUS_STATUS_VOUT)) + info->func[page] |= PMBUS_HAVE_STATUS_VOUT; + } + if (pmbus_check_word_register(client, page, PMBUS_READ_IOUT)) { + info->func[page] |= PMBUS_HAVE_IOUT; + if (pmbus_check_byte_register(client, 0, + PMBUS_STATUS_IOUT)) + info->func[page] |= PMBUS_HAVE_STATUS_IOUT; + } + if (pmbus_check_word_register(client, page, PMBUS_READ_POUT)) + info->func[page] |= PMBUS_HAVE_POUT; + } +} + +/* + * Identify chip parameters. + */ +static int qci_pmbus_identify(struct i2c_client *client, + struct pmbus_driver_info *info) +{ + int ret = 0; + + if (!info->pages) { + /* + * Check if the PAGE command is supported. If it is, + * keep setting the page number until it fails or until the + * maximum number of pages has been reached. Assume that + * this is the number of pages supported by the chip. + */ + if (pmbus_check_byte_register(client, 0, PMBUS_PAGE)) { + int page; + + for (page = 1; page < PMBUS_PAGES; page++) { + if (pmbus_set_page(client, page) < 0) + break; + } + pmbus_set_page(client, 0); + info->pages = page; + } else { + info->pages = 1; + } + } + + if (pmbus_check_byte_register(client, 0, PMBUS_VOUT_MODE)) { + int vout_mode; + + vout_mode = pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE); + if (vout_mode >= 0 && vout_mode != 0xff) { + switch (vout_mode >> 5) { + case 0: + break; + case 1: + info->format[PSC_VOLTAGE_OUT] = vid; + break; + case 2: + info->format[PSC_VOLTAGE_OUT] = direct; + break; + default: + ret = -ENODEV; + goto abort; + } + } + } + + /* + * We should check if the COEFFICIENTS register is supported. + * If it is, and the chip is configured for direct mode, we can read + * the coefficients from the chip, one set per group of sensor + * registers. + * + * To do this, we will need access to a chip which actually supports the + * COEFFICIENTS command, since the command is too complex to implement + * without testing it. Until then, abort if a chip configured for direct + * mode was detected. + */ + if (info->format[PSC_VOLTAGE_OUT] == direct) { + ret = -ENODEV; + goto abort; + } + + /* if no function pre-defined, try to find sensor groups */ + if (info->func[0] == 0) qci_pmbus_find_sensor_groups(client, info); +abort: + return ret; +} + +int qci_pmbus_set_page(struct i2c_client *client, u8 page) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + int rv = 0; + int newpage; + + if (page != data->currpage) { + rv = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page); + udelay(DELAY_TIME); + newpage = i2c_smbus_read_byte_data(client, PMBUS_PAGE); + if (newpage != page) + rv = -EIO; + else + data->currpage = page; + } + return rv; +} + +int qci_write_byte(struct i2c_client *client, int page, u8 value) +{ + int rv; + + if (page >= 0) { + rv = qci_pmbus_set_page(client, page); + if (rv < 0) + return rv; + } + + rv = i2c_smbus_write_byte(client, value); + udelay(DELAY_TIME); + return rv; +} + +int qci_write_word_data(struct i2c_client *client, int page, int reg, u16 word) +{ + int rv; + + rv = qci_pmbus_set_page(client, page); + if (rv < 0) + return rv; + + rv = i2c_smbus_write_word_data(client, reg, word); + udelay(DELAY_TIME); + return rv; +} + +static int qci_pmbus_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct device *dev = &client->dev; + struct pmbus_driver_info *info; + int ret, i; + + dev_info(dev, "qci_pmbus_probe\n"); + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_WORD_DATA)) + return -ENODEV; + + info = devm_kzalloc(&client->dev, sizeof(struct pmbus_driver_info), + GFP_KERNEL); + + if (!info) + return -ENOMEM; + + info->func[0] = 0; + + /* FIXME: add project specific function table here */ + switch (id->driver_data) { + case ly8: + info->pages = 1; + info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT + | PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12 + | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT + | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT + ; + break; + case ix1: + case ix2: + case ix1b: + info->pages = 1; + info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN + | PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT + | PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12 + | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 + | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_TEMP + | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT + | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT + | PMBUS_HAVE_POUT + ; + break; + default: + break; + } + info->write_word_data = qci_write_word_data; + info->write_byte = qci_write_byte; + info->identify = qci_pmbus_identify; /* FIXME: reserve for future use */ + + /* Register sysfs hooks */ + ret = sysfs_create_group(&dev->kobj, &qci_pmbus_inventory_attr_grp); + if (ret) { + dev_err(dev, "Failed to create sysfs entries\n"); + return -1; + } + + return pmbus_do_probe(client, id, info); +} + +/* This is the driver that will be inserted */ +static struct i2c_driver qci_pmbus_driver = { + .driver = { + .name = "qci-pmbus", + }, + .probe = qci_pmbus_probe, + .remove = pmbus_do_remove, + .id_table = qci_pmbus_id, +}; + +module_i2c_driver(qci_pmbus_driver); + + +MODULE_AUTHOR("Quanta Computer Inc."); +MODULE_VERSION("1.0"); +MODULE_DESCRIPTION("QUANTA generic PMBus driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/service/ix1b-platform-init.service b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/service/ix1b-platform-init.service new file mode 100755 index 000000000000..a51c0cca6914 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/service/ix1b-platform-init.service @@ -0,0 +1,13 @@ +[Unit] +Description=Quanta IX1B-32X Platform initialization service +Before=pmon.service +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/quanta_ix1b_util.py install +ExecStop=/usr/local/bin/quanta_ix1b_util.py clean +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/setup.py b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/setup.py new file mode 100755 index 000000000000..e37687db7eca --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/setup.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python + +import os +import sys +from setuptools import setup +os.listdir + +setup( + name='ix1b_32x', + version='1.0', + description='Module to initialize Quanta IX1B-32X platforms', + + packages=['ix1b_32x'], + package_dir={'ix1b_32x': 'ix1b-32x/classes'}, +) + diff --git a/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/utils/quanta_ix1b_util.py b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/utils/quanta_ix1b_util.py new file mode 100755 index 000000000000..f530cf3dbb7b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/utils/quanta_ix1b_util.py @@ -0,0 +1,203 @@ +#!/usr/bin/env python +# +# Copyright (C) 2018 Quanta Computer 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 3 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, see . + +""" +Usage: %(scriptName)s [options] command object + +options: + -h | --help : this help message + -d | --debug : run with debug mode + -f | --force : ignore error during installation or clean +command: + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes +""" + +import os +import commands +import sys, getopt +import logging +import re +import time +from collections import namedtuple + +DEBUG = False +args = [] +FORCE = 0 +i2c_prefix = '/sys/bus/i2c/devices/' + + +if DEBUG == True: + print sys.argv[0] + print 'ARGV :', sys.argv[1:] + + +def main(): + global DEBUG + global args + global FORCE + + if len(sys.argv)<2: + show_help() + + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', + 'debug', + 'force', + ]) + if DEBUG == True: + print options + print args + print len(sys.argv) + + for opt, arg in options: + if opt in ('-h', '--help'): + show_help() + elif opt in ('-d', '--debug'): + DEBUG = True + logging.basicConfig(level=logging.INFO) + elif opt in ('-f', '--force'): + FORCE = 1 + else: + logging.info('no option') + for arg in args: + if arg == 'install': + install() + elif arg == 'clean': + uninstall() + else: + show_help() + + + return 0 + +def show_help(): + print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + sys.exit(0) + +def show_log(txt): + if DEBUG == True: + print "[IX1B-32X]"+txt + return + +def exec_cmd(cmd, show): + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) + show_log (cmd +"with result:" + str(status)) + show_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + +instantiate =[ +#turn on module power +'echo 53 > /sys/class/gpio/export', +'echo out > /sys/class/gpio/gpio53/direction', +'echo 1 >/sys/class/gpio/gpio53/value', +#turn on 100G led by default +'i2cset -y 0x13 0x38 0x00 0xff', +'i2cset -y 0x13 0x38 0x01 0xff', +'i2cset -y 0x13 0x39 0x00 0xff', +'i2cset -y 0x13 0x39 0x01 0xff' +] + +drivers =[ +'lpc_ich', +'i2c-i801', +'i2c-dev', +'i2c-mux-pca954x', +'gpio-pca953x', +'qci_pmbus', +'leds-gpio', +'qci_cpld_qsfp28', +'qci_platform_ix1b' +] + + + +def system_install(): + global FORCE + + #remove default drivers to avoid modprobe order conflicts + status, output = exec_cmd("rmmod i2c_ismt ", 1) + status, output = exec_cmd("rmmod i2c-i801 ", 1) + #setup driver dependency + status, output = exec_cmd("depmod -a ", 1) + #install drivers + for i in range(0,len(drivers)): + status, output = exec_cmd("modprobe "+drivers[i], 1) + if status: + print output + if FORCE == 0: + return status + + #instantiate devices + for i in range(0,len(instantiate)): + time.sleep(1) + status, output = exec_cmd(instantiate[i], 1) + if status: + print output + if FORCE == 0: + return status + + #for i in range(22,30): + # status, output =exec_cmd("echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-0/i2c-4/i2c-"+str(i)+"/new_device", 1) + # if status: + # print output + # if FORCE == 0: + # return status + + return + + +def system_ready(): + if not device_found(): + return False + return True + +def install(): + if not device_found(): + print "No device, installing...." + status = system_install() + if status: + if FORCE == 0: + return status + else: + print " ix1b driver already installed...." + return + +def uninstall(): + global FORCE + #uninstall drivers + for i in range(len(drivers)-1,-1,-1): + status, output = exec_cmd("rmmod "+drivers[i], 1) + if status: + print output + if FORCE == 0: + return status + return + +def device_found(): + ret1, log = exec_cmd("ls "+i2c_prefix+"i2c-0", 0) + return ret1 + +if __name__ == "__main__": + main() + + + diff --git a/platform/broadcom/sonic-platform-modules-s6000 b/platform/broadcom/sonic-platform-modules-s6000 deleted file mode 160000 index ed9ea067b5cb..000000000000 --- a/platform/broadcom/sonic-platform-modules-s6000 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit ed9ea067b5cbfd7d1c835a903729f9dc28d3b035 diff --git a/platform/broadcom/sonic-platform-modules-s6000/LICENSE b/platform/broadcom/sonic-platform-modules-s6000/LICENSE new file mode 100644 index 000000000000..676cdeec726b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-s6000/LICENSE @@ -0,0 +1,15 @@ +Copyright (C) 2016 Microsoft, 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/broadcom/sonic-platform-modules-s6000/MAINTAINERS b/platform/broadcom/sonic-platform-modules-s6000/MAINTAINERS new file mode 100644 index 000000000000..65e3129fcc13 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-s6000/MAINTAINERS @@ -0,0 +1,7 @@ +# This file describes the maintainers for sonic-platform-modules-s6000 +# See the SONiC project governance document for more information + +Name = "Shuotian Cheng" +Email = "shuche@microsoft.com" +Github = stcheng +Mailinglist = sonicproject@googlegroups.com diff --git a/platform/broadcom/sonic-platform-modules-s6000/README.md b/platform/broadcom/sonic-platform-modules-s6000/README.md new file mode 100644 index 000000000000..7913d168a30a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-s6000/README.md @@ -0,0 +1,2 @@ +# sonic-platform-modules-s6000 +Device drivers for support of Dell S6000 for the SONiC project diff --git a/platform/broadcom/sonic-platform-modules-s6000/debian/changelog b/platform/broadcom/sonic-platform-modules-s6000/debian/changelog new file mode 100644 index 000000000000..0a6b7820bdeb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-s6000/debian/changelog @@ -0,0 +1,5 @@ +platform-modules-s6000 (1.0) unstable; urgency=low + + * Initial release + + -- Shuotian Cheng Mon, 11 Nov 2015 11:11:11 -0800 diff --git a/platform/broadcom/sonic-platform-modules-s6000/debian/compat b/platform/broadcom/sonic-platform-modules-s6000/debian/compat new file mode 100644 index 000000000000..45a4fb75db86 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-s6000/debian/compat @@ -0,0 +1 @@ +8 diff --git a/platform/broadcom/sonic-platform-modules-s6000/debian/control b/platform/broadcom/sonic-platform-modules-s6000/debian/control new file mode 100644 index 000000000000..394a1f4aa4af --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-s6000/debian/control @@ -0,0 +1,12 @@ +Source: platform-modules-s6000 +Section: main +Priority: extra +Maintainer: Shuotian Cheng +Build-Depends: debhelper (>= 8.0.0), bzip2 +Standards-Version: 3.9.3 + +Package: platform-modules-s6000 +Architecture: amd64 +Depends: linux-image-3.16.0-5-amd64 +Description: kernel modules for platform devices such as fan, led, sfp + diff --git a/platform/broadcom/sonic-platform-modules-s6000/debian/copyright b/platform/broadcom/sonic-platform-modules-s6000/debian/copyright new file mode 100644 index 000000000000..6fbc5a7f6ca0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-s6000/debian/copyright @@ -0,0 +1,16 @@ +Provides linux sysfs interface to Dell S6000 platform hardware peripherals +Copyright (C) 2016 Microsoft + +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/broadcom/sonic-platform-modules-s6000/debian/platform-modules-s6000.init b/platform/broadcom/sonic-platform-modules-s6000/debian/platform-modules-s6000.init new file mode 100755 index 000000000000..1c7047cc7611 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-s6000/debian/platform-modules-s6000.init @@ -0,0 +1,45 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup S6000 board. +### END INIT INFO + +case "$1" in +start) + echo -n "Setting up board... " + + depmod -a + modprobe i2c_mux_gpio + modprobe dell_s6000_platform + + /usr/local/bin/set-fan-speed 15000 + /usr/local/bin/reset-qsfp + + echo "done." + ;; + +stop) + echo "done." + rmmod dell_s6000_platform + rmmod i2c_mux_gpio + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/platform-modules-s6000.init {start|stop}" + exit 1 + ;; +esac + +exit 0 + diff --git a/platform/broadcom/sonic-platform-modules-s6000/debian/rules b/platform/broadcom/sonic-platform-modules-s6000/debian/rules new file mode 100755 index 000000000000..9912e052b551 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-s6000/debian/rules @@ -0,0 +1,32 @@ +#!/usr/bin/make -f + +export INSTALL_MOD_DIR:=extra + +PACKAGE_NAME := platform-modules-s6000 +KVERSION ?= $(shell uname -r) +KERNEL_SRC := /lib/modules/$(KVERSION) +MODULE_SRC := $(shell pwd)/modules +SCRIPT_SRC := $(shell pwd)/scripts + +%: + dh $@ + +override_dh_auto_build: + make -C $(KERNEL_SRC)/build M=$(MODULE_SRC) + +override_dh_auto_install: + dh_installdirs -p$(PACKAGE_NAME) $(KERNEL_SRC)/$(INSTALL_MOD_DIR) + cp $(MODULE_SRC)/*.ko debian/$(PACKAGE_NAME)/$(KERNEL_SRC)/$(INSTALL_MOD_DIR) + dh_installdirs -p$(PACKAGE_NAME) usr/local/bin + cp -r $(SCRIPT_SRC)/* debian/$(PACKAGE_NAME)/usr/local/bin + +override_dh_usrlocal: + +override_dh_pysupport: + +override_dh_clean: + dh_clean + rm -f $(MODULE_SRC)/*.o $(MODULE_SRC)/*.ko $(MODULE_SRC)/*.mod.c $(MODULE_SRC)/.*.cmd + rm -f $(MODULE_SRC)/Module.markers $(MODULE_SRC)/Module.symvers $(MODULE_SRC)/modules.order + rm -rf $(MODULE_SRC)/.tmp_versions + diff --git a/platform/broadcom/sonic-platform-modules-s6000/modules/Makefile b/platform/broadcom/sonic-platform-modules-s6000/modules/Makefile new file mode 100644 index 000000000000..12e80d01010c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-s6000/modules/Makefile @@ -0,0 +1 @@ +obj-m := dell_s6000_platform.o diff --git a/platform/broadcom/sonic-platform-modules-s6000/modules/dell_s6000_platform.c b/platform/broadcom/sonic-platform-modules-s6000/modules/dell_s6000_platform.c new file mode 100644 index 000000000000..d2a92770cecb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-s6000/modules/dell_s6000_platform.c @@ -0,0 +1,2031 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define S6000_MUX_BASE_NR 10 +#define QSFP_MODULE_BASE_NR 20 + +/* 74CBTLV3253 Dual 1-of-4 multiplexer/demultiplexer */ +#define MUX_CHANNEL_NUM 2 + +#define CPLD_DEVICE_NUM 3 +#define QSFP_MODULE_NUM 16 +#define QSFP_DEVICE_NUM 2 + +#define SFF8436_INFO(data) \ + .type = "sff8436", .addr = 0x50, .platform_data = (data) + +#define SFF_8346_PORT(eedata) \ + .byte_len = 128, .page_size = 1, .flags = SFF_8436_FLAG_READONLY + +static void device_release(struct device *dev) +{ + return; +} + +/* + * S6000 74CBTLV3253 MUX + */ +static const unsigned s6000_mux_gpios[] = { + 1, 2 +}; + +static const unsigned s6000_mux_values[] = { + 0, 1, 2, 3 +}; + +static struct i2c_mux_gpio_platform_data s6000_mux_platform_data = { + .parent = 2, + .base_nr = S6000_MUX_BASE_NR, + .values = s6000_mux_values, + .n_values = ARRAY_SIZE(s6000_mux_values), + .gpios = s6000_mux_gpios, + .n_gpios = ARRAY_SIZE(s6000_mux_gpios), + .idle = 0, +}; + +static struct platform_device s6000_mux = { + .name = "i2c-mux-gpio", + .id = 0, + .dev = { + .platform_data = &s6000_mux_platform_data, + .release = device_release + }, +}; + +/* + * S6000 CPLD + */ + +enum cpld_type { + system_cpld, + master_cpld, + slave_cpld, +}; + +struct cpld_platform_data { + int reg_addr; + struct i2c_client *client; +}; + +static struct cpld_platform_data s6000_cpld_platform_data[] = { + [system_cpld] = { + .reg_addr = 0x31, + }, + + [master_cpld] = { + .reg_addr = 0x32, + }, + + [slave_cpld] = { + .reg_addr = 0x33, + }, +}; + +static struct platform_device s6000_cpld = { + .name = "dell-s6000-cpld", + .id = 0, + .dev = { + .platform_data = s6000_cpld_platform_data, + .release = device_release + }, +}; + +/* + * S6000 QSFP MUX + */ + +struct qsfp_mux_platform_data { + int parent; + int base_nr; + int reg_addr; + struct i2c_client *cpld; +}; + +struct qsfp_mux { + struct i2c_adapter *parent; + struct i2c_adapter **child; + struct qsfp_mux_platform_data data; +}; +static struct qsfp_mux_platform_data s6000_qsfp_mux_platform_data[] = { + { + .parent = S6000_MUX_BASE_NR + 2, + .base_nr = QSFP_MODULE_BASE_NR, + .cpld = NULL, + .reg_addr = 0x0, + }, + { + .parent = S6000_MUX_BASE_NR + 3, + .base_nr = QSFP_MODULE_BASE_NR + QSFP_MODULE_NUM, + .cpld = NULL, + .reg_addr = 0xa, + }, +}; + +static struct platform_device s6000_qsfp_mux[] = { + { + .name = "dell-s6000-qsfp-mux", + .id = 0, + .dev = { + .platform_data = &s6000_qsfp_mux_platform_data[0], + .release = device_release, + }, + }, + { + .name = "dell-s6000-qsfp-mux", + .id = 1, + .dev = { + .platform_data = &s6000_qsfp_mux_platform_data[1], + .release = device_release, + }, + }, +}; + +/* + * S6000 I2C DEVICES + */ + +struct i2c_device_platform_data { + int parent; + struct i2c_board_info info; + struct i2c_client *client; +}; + +static struct sff_8436_platform_data sff_8436_port[] = { + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, +}; + +static struct i2c_device_platform_data s6000_i2c_device_platform_data[] = { + { + /* PSU 1 FRU EEPROM */ + .parent = 1, + .info = { I2C_BOARD_INFO("24c02", 0x50) }, + .client = NULL, + }, + { + /* PSU 2 FRU EEPROM */ + .parent = 1, + .info = { I2C_BOARD_INFO("24c02", 0x51) }, + }, + { + /* PSU 1 PMBUS */ + .parent = 1, + .info = { I2C_BOARD_INFO("dni_dps460", 0x58) }, + }, + { + /* PSU 2 PMBUS */ + .parent = 1, + .info = { I2C_BOARD_INFO("dni_dps460", 0x59) }, + }, + { + /* TEMP Sensor EMC1428-7 */ + .parent = S6000_MUX_BASE_NR, + .info = { I2C_BOARD_INFO("emc1403", 0x4d) }, + }, + { + /* JEDEC JC 42.4 compliant temperature sensors */ + .parent = S6000_MUX_BASE_NR, + .info = { I2C_BOARD_INFO("jc42", 0x18) }, + }, + { + /* DDR3 MODULE SPD */ + .parent = S6000_MUX_BASE_NR, + .info = { I2C_BOARD_INFO("spd", 0x50) } , + }, + { + /* + * ID EEPROM + * AT24C64D-SSHM-T + */ + .parent = S6000_MUX_BASE_NR, + .info = { I2C_BOARD_INFO("24c02", 0x53) } , + }, + { + /* + * FAN Tray Controller 1 + * MAX6620ATI+T + */ + .parent = S6000_MUX_BASE_NR + 1, + .info = { I2C_BOARD_INFO("max6620", 0x29) }, + }, + { + /* + * FAN Tray Controller 2 + * MAX6620ATI+T + */ + .parent = S6000_MUX_BASE_NR + 1, + .info = { I2C_BOARD_INFO("max6620", 0x2a) }, + }, + { + /* + * Hot-Swap PSU 1 + * LTC1451UFD#TRPBF + */ + .parent = S6000_MUX_BASE_NR + 1, + .info = { I2C_BOARD_INFO("ltc4215", 0x40) }, + }, + { + /* + * Hot-Swap PSU 2 + * LTC1451UFD#TRPBF + */ + .parent = S6000_MUX_BASE_NR + 1, + .info = { I2C_BOARD_INFO("ltc4215", 0x42) }, + }, + { + /* + * Temp Sensor MAC + * TMP75AIDR + */ + .parent = S6000_MUX_BASE_NR + 1, + .info = { I2C_BOARD_INFO("tmp75", 0x4c) }, + }, + { + /* + * Temp Sensor NIC + * TMP75AIDR + */ + .parent = S6000_MUX_BASE_NR + 1, + .info = { I2C_BOARD_INFO("tmp75", 0x4d) }, + }, + { + /* + * Temp Sensor AMB + * TMP75AIDR + */ + .parent = S6000_MUX_BASE_NR + 1, + .info = { I2C_BOARD_INFO("tmp75", 0x4e) }, + }, + { + /* + * FAN Tray 1 EEPROM + * M24C02-WMN6TP + */ + .parent = S6000_MUX_BASE_NR + 1, + .info = { I2C_BOARD_INFO("24c02", 0x51) }, + }, + { + /* + * FAN Tray 2 EEPROM + * M24C02-WMN6TP + */ + .parent = S6000_MUX_BASE_NR + 1, + .info = { I2C_BOARD_INFO("24c02", 0x52) }, + }, + { + /* + * FAN Tray 3 EEPROM + * M24C02-WMN6TP + */ + .parent = S6000_MUX_BASE_NR + 1, + .info = { I2C_BOARD_INFO("24c02", 0x53) }, + }, + /* QSFP Modules */ + { + .parent = QSFP_MODULE_BASE_NR, + .info = { SFF8436_INFO(&sff_8436_port[0]) }, + }, + { + .parent = QSFP_MODULE_BASE_NR + 1, + .info = { SFF8436_INFO(&sff_8436_port[1]) }, + }, + { + .parent = QSFP_MODULE_BASE_NR + 2, + .info = { SFF8436_INFO(&sff_8436_port[2]) }, + }, + { + .parent = QSFP_MODULE_BASE_NR + 3, + .info = { SFF8436_INFO(&sff_8436_port[3]) }, + }, + { + .parent = QSFP_MODULE_BASE_NR + 4, + .info = { SFF8436_INFO(&sff_8436_port[4]) }, + }, + { + .parent = QSFP_MODULE_BASE_NR + 5, + .info = { SFF8436_INFO(&sff_8436_port[5]) }, + }, + { + .parent = QSFP_MODULE_BASE_NR + 6, + .info = { SFF8436_INFO(&sff_8436_port[6]) }, + }, + { + .parent = QSFP_MODULE_BASE_NR + 7, + .info = { SFF8436_INFO(&sff_8436_port[7]) }, + }, + { + .parent = QSFP_MODULE_BASE_NR + 8, + .info = { SFF8436_INFO(&sff_8436_port[8]) }, + }, + { + .parent = QSFP_MODULE_BASE_NR + 9, + .info = { SFF8436_INFO(&sff_8436_port[9]) }, + }, + { + .parent = QSFP_MODULE_BASE_NR + 10, + .info = { SFF8436_INFO(&sff_8436_port[10]) }, + }, + { + .parent = QSFP_MODULE_BASE_NR + 11, + .info = { SFF8436_INFO(&sff_8436_port[11]) }, + }, + { + .parent = QSFP_MODULE_BASE_NR + 12, + .info = { SFF8436_INFO(&sff_8436_port[12]) }, + }, + { + .parent = QSFP_MODULE_BASE_NR + 13, + .info = { SFF8436_INFO(&sff_8436_port[13]) }, + }, + { + .parent = QSFP_MODULE_BASE_NR + 14, + .info = { SFF8436_INFO(&sff_8436_port[14]) }, + }, + { + .parent = QSFP_MODULE_BASE_NR + 15, + .info = { SFF8436_INFO(&sff_8436_port[15]) }, + }, + { + .parent = QSFP_MODULE_BASE_NR + 16, + .info = { SFF8436_INFO(&sff_8436_port[16]) }, + }, + { + .parent = QSFP_MODULE_BASE_NR + 17, + .info = { SFF8436_INFO(&sff_8436_port[17]) }, + }, + { + .parent = QSFP_MODULE_BASE_NR + 18, + .info = { SFF8436_INFO(&sff_8436_port[18]) }, + }, + { + .parent = QSFP_MODULE_BASE_NR + 19, + .info = { SFF8436_INFO(&sff_8436_port[19]) }, + }, + { + .parent = QSFP_MODULE_BASE_NR + 20, + .info = { SFF8436_INFO(&sff_8436_port[20]) }, + }, + { + .parent = QSFP_MODULE_BASE_NR + 21, + .info = { SFF8436_INFO(&sff_8436_port[21]) }, + }, + { + .parent = QSFP_MODULE_BASE_NR + 22, + .info = { SFF8436_INFO(&sff_8436_port[22]) }, + }, + { + .parent = QSFP_MODULE_BASE_NR + 23, + .info = { SFF8436_INFO(&sff_8436_port[23]) }, + }, + { + .parent = QSFP_MODULE_BASE_NR + 24, + .info = { SFF8436_INFO(&sff_8436_port[24]) }, + }, + { + .parent = QSFP_MODULE_BASE_NR + 25, + .info = { SFF8436_INFO(&sff_8436_port[25]) }, + }, + { + .parent = QSFP_MODULE_BASE_NR + 26, + .info = { SFF8436_INFO(&sff_8436_port[26]) }, + }, + { + .parent = QSFP_MODULE_BASE_NR + 27, + .info = { SFF8436_INFO(&sff_8436_port[27]) }, + }, + { + .parent = QSFP_MODULE_BASE_NR + 28, + .info = { SFF8436_INFO(&sff_8436_port[28]) }, + }, + { + .parent = QSFP_MODULE_BASE_NR + 29, + .info = { SFF8436_INFO(&sff_8436_port[29]) }, + }, + { + .parent = QSFP_MODULE_BASE_NR + 30, + .info = { SFF8436_INFO(&sff_8436_port[30]) }, + .client = NULL, + }, + { + .parent = QSFP_MODULE_BASE_NR + 31, + .info = { SFF8436_INFO(&sff_8436_port[31]) }, + .client = NULL, + }, +}; + +static struct platform_device s6000_i2c_device[] = { + { + .name = "dell-s6000-i2c-device", + .id = 0, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[0], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 1, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[1], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 2, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[2], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 3, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[3], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 4, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[4], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 5, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[5], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 6, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[6], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 7, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[7], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 8, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[8], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 9, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[9], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 10, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[10], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 11, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[11], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 12, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[12], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 13, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[13], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 14, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[14], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 15, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[15], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 16, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[16], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 17, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[17], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 18, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[18], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 19, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[19], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 20, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[20], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 21, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[21], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 22, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[22], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 23, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[23], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 24, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[24], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 25, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[25], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 26, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[26], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 27, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[27], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 28, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[28], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 29, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[29], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 30, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[30], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 31, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[31], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 32, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[32], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 33, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[33], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 34, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[34], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 35, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[35], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 36, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[36], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 37, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[37], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 38, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[38], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 39, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[39], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 40, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[40], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 41, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[41], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 42, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[42], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 43, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[43], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 44, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[44], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 45, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[45], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 46, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[46], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 47, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[47], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 48, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[48], + .release = device_release, + }, + }, + { + .name = "dell-s6000-i2c-device", + .id = 49, + .dev = { + .platform_data = &s6000_i2c_device_platform_data[49], + .release = device_release, + }, + }, +}; + + + +static int cpld_reg_write_byte(struct i2c_client *client, u8 regaddr, u8 val) +{ + union i2c_smbus_data data; + + data.byte = val; + return client->adapter->algo->smbus_xfer(client->adapter, client->addr, + client->flags, + I2C_SMBUS_WRITE, + regaddr, I2C_SMBUS_BYTE_DATA, &data); +} + +static int qsfp_mux_select(struct i2c_adapter *adap, void *data, u32 chan) +{ + struct qsfp_mux *mux = data; + unsigned short mask = ~(unsigned short)(1 << chan); + + cpld_reg_write_byte(mux->data.cpld, mux->data.reg_addr, (u8)(mask & 0xff)); + return cpld_reg_write_byte(mux->data.cpld, mux->data.reg_addr + 1, (u8)(mask >> 8)); +} + +static int __init qsfp_mux_probe(struct platform_device *pdev) +{ + struct qsfp_mux *mux; + struct qsfp_mux_platform_data *pdata; + struct i2c_adapter *parent; + int i, ret; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + return -ENODEV; + } + + parent = i2c_get_adapter(pdata->parent); + if (!parent) { + dev_err(&pdev->dev, "Parent adapter (%d) not found\n", + pdata->parent); + return -ENODEV; + } + + mux = kzalloc(sizeof(*mux), GFP_KERNEL); + if (!mux) { + ret = -ENOMEM; + goto alloc_failed; + } + + mux->parent = parent; + mux->data = *pdata; + mux->child = kzalloc(sizeof(struct i2c_adapter *) * QSFP_MODULE_NUM, GFP_KERNEL); + if (!mux->child) { + ret = -ENOMEM; + goto alloc_failed2; + } + + for (i = 0; i < QSFP_MODULE_NUM; i++) { + int nr = pdata->base_nr + i; + unsigned int class = 0; + + mux->child[i] = i2c_add_mux_adapter(parent, &pdev->dev, mux, + nr, i, class, + qsfp_mux_select, NULL); + if (!mux->child[i]) { + ret = -ENODEV; + dev_err(&pdev->dev, "Failed to add adapter %d\n", i); + goto add_adapter_failed; + } + } + + dev_info(&pdev->dev, "16 port mux on %s adapter\n", parent->name); + + platform_set_drvdata(pdev, mux); + + return 0; + +add_adapter_failed: + for (; i > 0; i--) + i2c_del_mux_adapter(mux->child[i - 1]); + kfree(mux->child); +alloc_failed2: + kfree(mux); +alloc_failed: + i2c_put_adapter(parent); + + return ret; +} + +static int __exit qsfp_mux_remove(struct platform_device *pdev) +{ + int i; + struct qsfp_mux *mux = platform_get_drvdata(pdev); + + for (i = 0; i < QSFP_MODULE_NUM; i++) + i2c_del_mux_adapter(mux->child[i]); + + platform_set_drvdata(pdev, NULL); + i2c_put_adapter(mux->parent); + kfree(mux->child); + kfree(mux); + + return 0; +} + +static struct platform_driver qsfp_mux_driver = { + .probe = qsfp_mux_probe, + .remove = __exit_p(qsfp_mux_remove), /* TODO */ + .driver = { + .owner = THIS_MODULE, + .name = "dell-s6000-qsfp-mux", + }, +}; + +/* TODO */ +/* module_platform_driver */ + +static ssize_t get_modsel(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + u32 data = 0; + struct cpld_platform_data *pdata = dev->platform_data; + + ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x0); + if (ret < 0) + return sprintf(buf, "na"); + data = (u32)ret & 0xff; + + ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x1); + if (ret < 0) + return sprintf(buf, "na"); + data |= (u32)(ret & 0xff) << 8; + + ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0xa); + if (ret < 0) + return sprintf(buf, "na"); + data |= (u32)(ret & 0xff) << 16; + + ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0xb); + if (ret < 0) + return sprintf(buf, "na"); + data |= (u32)(ret & 0xff) << 24; + + return sprintf(buf, "0x%08x\n", data); +} + +static ssize_t get_lpmode(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + u32 data = 0; + struct cpld_platform_data *pdata = dev->platform_data; + + ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x2); + if (ret < 0) + return sprintf(buf, "na"); + data = (u32)ret & 0xff; + + ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x3); + if (ret < 0) + return sprintf(buf, "na"); + data |= (u32)(ret & 0xff) << 8; + + ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0xc); + if (ret < 0) + return sprintf(buf, "na"); + data |= (u32)(ret & 0xff) << 16; + + ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0xd); + if (ret < 0) + return sprintf(buf, "na"); + data |= (u32)(ret & 0xff) << 24; + + return sprintf(buf, "0x%08x\n", data); +} + +static ssize_t set_lpmode(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + unsigned long data; + int err; + struct cpld_platform_data *pdata = dev->platform_data; + + err = kstrtoul(buf, 16, &data); + if (err) + return err; + + i2c_smbus_write_byte_data(pdata[slave_cpld].client, 0x2, (u8)(data & 0xff)); + i2c_smbus_write_byte_data(pdata[slave_cpld].client, 0x3, (u8)((data >> 8) & 0xff)); + i2c_smbus_write_byte_data(pdata[master_cpld].client, 0xc, (u8)((data >> 16) & 0xff)); + i2c_smbus_write_byte_data(pdata[master_cpld].client, 0xd, (u8)((data >> 24) & 0xff)); + + return count; +} + +static ssize_t get_reset(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + u32 data = 0; + struct cpld_platform_data *pdata = dev->platform_data; + + ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x6); + if (ret < 0) + return sprintf(buf, "na"); + data = (u32)ret & 0xff; + + ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x7); + if (ret < 0) + return sprintf(buf, "na"); + data |= (u32)(ret & 0xff) << 8; + + ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x10); + if (ret < 0) + return sprintf(buf, "na"); + data |= (u32)(ret & 0xff) << 16; + + ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x11); + if (ret < 0) + return sprintf(buf, "na"); + data |= (u32)(ret & 0xff) << 24; + + return sprintf(buf, "0x%08x\n", data); +} + +static ssize_t set_reset(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + unsigned long data; + int err; + struct cpld_platform_data *pdata = dev->platform_data; + + err = kstrtoul(buf, 16, &data); + if (err) + return err; + + i2c_smbus_write_byte_data(pdata[slave_cpld].client, 0x6, (u8)(data & 0xff)); + i2c_smbus_write_byte_data(pdata[slave_cpld].client, 0x7, (u8)((data >> 8)& 0xff)); + i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x10, (u8)((data >> 16) & 0xff)); + i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x11, (u8)((data >> 24) & 0xff)); + + return count; +} + +static ssize_t get_modprs(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + u32 data = 0; + struct cpld_platform_data *pdata = dev->platform_data; + + ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x4); + if (ret < 0) + return sprintf(buf, "read error"); + data = (u32)ret & 0xff; + + ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, 0x5); + if (ret < 0) + return sprintf(buf, "read error"); + data |= (u32)(ret & 0xff) << 8; + + ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0xe); + if (ret < 0) + return sprintf(buf, "na"); + data |= (u32)(ret & 0xff) << 16; + + ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0xf); + if (ret < 0) + return sprintf(buf, "na"); + data |= (u32)(ret & 0xff) << 24; + + return sprintf(buf, "0x%08x\n", data); +} + +static ssize_t set_power_reset(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + unsigned long data; + int err; + struct cpld_platform_data *pdata = dev->platform_data; + + err = kstrtoul(buf, 10, &data); + if (err) + return err; + + if (data) + { + i2c_smbus_write_byte_data(pdata[system_cpld].client, 0x1, (u8)(0xfd)); + } + + return count; +} + +static ssize_t get_power_reset(struct device *dev, struct device_attribute *devattr, char *buf) +{ + return sprintf(buf, "0\n"); +} + +static ssize_t get_fan_prs(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + u32 data = 0; + struct cpld_platform_data *pdata = dev->platform_data; + + ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8); + if (ret < 0) + return sprintf(buf, "read error"); + data = (u32)((ret & 0xc0) >> 6); + + ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x9); + if (ret < 0) + return sprintf(buf, "read error"); + data |= (u32)((ret & 0x01) << 2); + data = ~data & 0x7; + + return sprintf(buf, "0x%x\n", data); +} + +static ssize_t get_psu0_prs(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + u32 data = 0; + struct cpld_platform_data *pdata = dev->platform_data; + + ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x3); + if (ret < 0) + return sprintf(buf, "read error"); + + if (!(ret & 0x80)) + data = 1; + + return sprintf(buf, "%d\n", data); +} + +static ssize_t get_psu1_prs(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + u32 data = 0; + struct cpld_platform_data *pdata = dev->platform_data; + + ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x3); + if (ret < 0) + return sprintf(buf, "read error"); + + if (!(ret & 0x08)) + data = 1; + + return sprintf(buf, "%d\n", data); +} + +static ssize_t get_psu0_status(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + u32 data = 0; + struct cpld_platform_data *pdata = dev->platform_data; + + ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x3); + if (ret < 0) + return sprintf(buf, "read error"); + + if (!(ret & 0x40)) + data = 1; + + return sprintf(buf, "%d\n", data); +} + +static ssize_t get_psu1_status(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + u32 data = 0; + struct cpld_platform_data *pdata = dev->platform_data; + + ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x3); + if (ret < 0) + return sprintf(buf, "read error"); + + if (!(ret & 0x04)) + data = 1; + + return sprintf(buf, "%d\n", data); +} + +static ssize_t get_system_led(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + u32 data = 0; + struct cpld_platform_data *pdata = dev->platform_data; + + ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); + if (ret < 0) + return sprintf(buf, "read error"); + + data = (u32)(ret & 0x60) >> 5; + + switch (data) + { + case 0: + ret = sprintf(buf, "blink_green\n"); + break; + case 1: + ret = sprintf(buf, "green\n"); + break; + case 2: + ret = sprintf(buf, "yellow\n"); + break; + default: + ret = sprintf(buf, "blink_yellow\n"); + } + + return ret; +} + +static ssize_t set_system_led(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + int ret; + u32 data = 0; + struct cpld_platform_data *pdata = dev->platform_data; + + if (!strncmp(buf, "blink_green", 11)) + { + data = 0; + } + else if (!strncmp(buf, "green", 5)) + { + data = 1; + } + else if (!strncmp(buf, "yellow", 6)) + { + data = 2; + } + else if (!strncmp(buf, "blink_yellow", 12)) + { + data = 3; + } + else + { + return -1; + } + + ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); + if (ret < 0) + return ret; + + i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x7, (u8)((ret & 0x9F) | (data << 5))); + + return count; +} + +static ssize_t get_locator_led(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + u32 data = 0; + struct cpld_platform_data *pdata = dev->platform_data; + + ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); + if (ret < 0) + return sprintf(buf, "read error"); + + data = (u32)(ret & 0x18) >> 3; + + switch (data) + { + case 0: + ret = sprintf(buf, "off\n"); + break; + case 1: + ret = sprintf(buf, "blink_blue\n"); + break; + case 2: + ret = sprintf(buf, "blue\n"); + break; + default: + ret = sprintf(buf, "invalid\n"); + } + + return ret; +} + +static ssize_t set_locator_led(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + int ret; + u32 data = 0; + struct cpld_platform_data *pdata = dev->platform_data; + + if (!strncmp(buf, "off", 3)) + { + data = 0; + } + else if (!strncmp(buf, "blink_blue", 10)) + { + data = 1; + } + else if (!strncmp(buf, "blue", 4)) + { + data = 2; + } + else + { + return -1; + } + + ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); + if (ret < 0) + return ret; + + i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x7, (u8)((ret & 0xE7) | (data << 3))); + + return count; +} + +static ssize_t get_power_led(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + u32 data = 0; + struct cpld_platform_data *pdata = dev->platform_data; + + ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); + if (ret < 0) + return sprintf(buf, "read error"); + + data = (u32)(ret & 0x06) >> 1; + + switch (data) + { + case 0: + ret = sprintf(buf, "off\n"); + break; + case 1: + ret = sprintf(buf, "yellow\n"); + break; + case 2: + ret = sprintf(buf, "green\n"); + break; + default: + ret = sprintf(buf, "blink_yellow\n"); + } + + return ret; +} + +static ssize_t set_power_led(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + int ret; + u32 data = 0; + struct cpld_platform_data *pdata = dev->platform_data; + + if (!strncmp(buf, "off", 3)) + { + data = 0; + } + else if (!strncmp(buf, "yellow", 6)) + { + data = 1; + } + else if (!strncmp(buf, "green", 5)) + { + data = 2; + } + else if (!strncmp(buf, "blink_yellow", 12)) + { + data = 3; + } + else + { + return -1; + } + + ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); + if (ret < 0) + return ret; + + i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x7, (u8)((ret & 0xF9) | (data << 1))); + + return count; +} + +static ssize_t get_master_led(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + u32 data = 0; + struct cpld_platform_data *pdata = dev->platform_data; + + ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); + if (ret < 0) + return sprintf(buf, "read error"); + + data = (u32)(ret & 0x1); + + switch (data) + { + case 0: + ret = sprintf(buf, "green\n"); + break; + default: + ret = sprintf(buf, "off\n"); + break; + } + + return ret; +} + +static ssize_t set_master_led(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + int ret; + u32 data = 0; + struct cpld_platform_data *pdata = dev->platform_data; + + if (!strncmp(buf, "green", 5)) + { + data = 0; + } + else if (!strncmp(buf, "off", 3)) + { + data = 1; + } + else + { + return -1; + } + + ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x7); + if (ret < 0) + return ret; + + i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x7, (u8)((ret & 0xFE) | data)); + + return count; +} + +static ssize_t get_fan_led(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + u32 data = 0; + struct cpld_platform_data *pdata = dev->platform_data; + + ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x9); + if (ret < 0) + return sprintf(buf, "read error"); + + data = (u32)(ret & 0x18) >> 3; + + switch (data) + { + case 0: + ret = sprintf(buf, "off\n"); + break; + case 1: + ret = sprintf(buf, "yellow\n"); + break; + case 2: + ret = sprintf(buf, "green\n"); + break; + default: + ret = sprintf(buf, "blink_yellow\n"); + } + + return ret; +} + +static ssize_t set_fan_led(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + int ret; + u32 data = 0; + struct cpld_platform_data *pdata = dev->platform_data; + + if (!strncmp(buf, "off", 3)) + { + data = 0; + } + else if (!strncmp(buf, "yellow", 6)) + { + data = 1; + } + else if (!strncmp(buf, "green", 5)) + { + data = 2; + } + else if (!strncmp(buf, "blink_yellow", 12)) + { + data = 3; + } + else + { + return -1; + } + + ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x9); + if (ret < 0) + return ret; + + i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x9, (u8)((ret & 0xE7) | (data << 3))); + + return count; +} + +static ssize_t get_fan0_led(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + u32 data = 0; + struct cpld_platform_data *pdata = dev->platform_data; + + ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8); + if (ret < 0) + return sprintf(buf, "read error"); + + data = (u32)(ret & 0x3); + + switch (data) + { + case 0: + ret = sprintf(buf, "off\n"); + break; + case 1: + ret = sprintf(buf, "green\n"); + break; + case 2: + ret = sprintf(buf, "yellow\n"); + break; + default: + ret = sprintf(buf, "unknown\n"); + } + + return ret; +} + +static ssize_t set_fan0_led(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + int ret; + u32 data = 0; + struct cpld_platform_data *pdata = dev->platform_data; + + if (!strncmp(buf, "off", 3)) + { + data = 0; + } + else if (!strncmp(buf, "yellow", 6)) + { + data = 2; + } + else if (!strncmp(buf, "green", 5)) + { + data = 1; + } + else + { + return -1; + } + + ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8); + if (ret < 0) + return ret; + + i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x8, (u8)((ret & 0xFC) | data)); + + return count; +} + + +static ssize_t get_fan1_led(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + u32 data = 0; + struct cpld_platform_data *pdata = dev->platform_data; + + ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8); + if (ret < 0) + return sprintf(buf, "read error"); + + data = (u32)(ret & 0xc) >> 2; + + switch (data) + { + case 0: + ret = sprintf(buf, "off\n"); + break; + case 1: + ret = sprintf(buf, "green\n"); + break; + case 2: + ret = sprintf(buf, "yellow\n"); + break; + default: + ret = sprintf(buf, "unknown\n"); + } + + return ret; +} + +static ssize_t set_fan1_led(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + int ret; + u32 data = 0; + struct cpld_platform_data *pdata = dev->platform_data; + + if (!strncmp(buf, "off", 3)) + { + data = 0; + } + else if (!strncmp(buf, "yellow", 6)) + { + data = 2; + } + else if (!strncmp(buf, "green", 5)) + { + data = 1; + } + else + { + return -1; + } + + ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8); + if (ret < 0) + return ret; + + i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x8, (u8)((ret & 0xF3) | (data << 2))); + + return count; +} + +static ssize_t get_fan2_led(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + u32 data = 0; + struct cpld_platform_data *pdata = dev->platform_data; + + ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8); + if (ret < 0) + return sprintf(buf, "read error"); + + data = (u32)(ret & 0x30) >> 4; + + switch (data) + { + case 0: + ret = sprintf(buf, "off\n"); + break; + case 1: + ret = sprintf(buf, "green\n"); + break; + case 2: + ret = sprintf(buf, "yellow\n"); + break; + default: + ret = sprintf(buf, "unknown\n"); + } + + return ret; +} + +static ssize_t set_fan2_led(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + int ret; + u32 data = 0; + struct cpld_platform_data *pdata = dev->platform_data; + + if (!strncmp(buf, "off", 3)) + { + data = 0; + } + else if (!strncmp(buf, "yellow", 6)) + { + data = 2; + } + else if (!strncmp(buf, "green", 5)) + { + data = 1; + } + else + { + return -1; + } + + ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, 0x8); + if (ret < 0) + return ret; + + i2c_smbus_write_byte_data(pdata[master_cpld].client, 0x8, (u8)((ret & 0xCF) | (data << 4))); + + return count; +} + +static DEVICE_ATTR(qsfp_modsel, S_IRUGO, get_modsel, NULL); +static DEVICE_ATTR(qsfp_modprs, S_IRUGO, get_modprs, NULL); +static DEVICE_ATTR(qsfp_lpmode, S_IRUGO | S_IWUSR, get_lpmode, set_lpmode); +static DEVICE_ATTR(qsfp_reset, S_IRUGO | S_IWUSR, get_reset, set_reset); +static DEVICE_ATTR(power_reset, S_IRUGO | S_IWUSR, get_power_reset, set_power_reset); +static DEVICE_ATTR(fan_prs, S_IRUGO, get_fan_prs, NULL); +static DEVICE_ATTR(psu0_prs, S_IRUGO, get_psu0_prs, NULL); +static DEVICE_ATTR(psu1_prs, S_IRUGO, get_psu1_prs, NULL); +static DEVICE_ATTR(psu0_status, S_IRUGO, get_psu0_status, NULL); +static DEVICE_ATTR(psu1_status, S_IRUGO, get_psu1_status, NULL); +static DEVICE_ATTR(system_led, S_IRUGO | S_IWUSR, get_system_led, set_system_led); +static DEVICE_ATTR(locator_led, S_IRUGO | S_IWUSR, get_locator_led, set_locator_led); +static DEVICE_ATTR(power_led, S_IRUGO | S_IWUSR, get_power_led, set_power_led); +static DEVICE_ATTR(master_led, S_IRUGO | S_IWUSR, get_master_led, set_master_led); +static DEVICE_ATTR(fan_led, S_IRUGO | S_IWUSR, get_fan_led, set_fan_led); +static DEVICE_ATTR(fan0_led, S_IRUGO | S_IWUSR, get_fan0_led, set_fan0_led); +static DEVICE_ATTR(fan1_led, S_IRUGO | S_IWUSR, get_fan1_led, set_fan1_led); +static DEVICE_ATTR(fan2_led, S_IRUGO | S_IWUSR, get_fan2_led, set_fan2_led); + +static struct attribute *s6000_cpld_attrs[] = { + &dev_attr_qsfp_modsel.attr, + &dev_attr_qsfp_lpmode.attr, + &dev_attr_qsfp_reset.attr, + &dev_attr_qsfp_modprs.attr, + &dev_attr_power_reset.attr, + &dev_attr_fan_prs.attr, + &dev_attr_psu0_prs.attr, + &dev_attr_psu1_prs.attr, + &dev_attr_psu0_status.attr, + &dev_attr_psu1_status.attr, + &dev_attr_system_led.attr, + &dev_attr_locator_led.attr, + &dev_attr_power_led.attr, + &dev_attr_master_led.attr, + &dev_attr_fan_led.attr, + &dev_attr_fan0_led.attr, + &dev_attr_fan1_led.attr, + &dev_attr_fan2_led.attr, + NULL, +}; + +static struct attribute_group s6000_cpld_attr_grp = { + .attrs = s6000_cpld_attrs, +}; + +static int __init cpld_probe(struct platform_device *pdev) +{ + struct cpld_platform_data *pdata; + struct i2c_adapter *parent; + int i; + int ret; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + return -ENODEV; + } + + parent = i2c_get_adapter(S6000_MUX_BASE_NR); + if (!parent) { + printk(KERN_WARNING "Parent adapter (%d) not found\n", + S6000_MUX_BASE_NR); + return -ENODEV; + } + + for (i = 0; i < CPLD_DEVICE_NUM; i++) { + pdata[i].client = i2c_new_dummy(parent, pdata[i].reg_addr); + if (!pdata[i].client) { + printk(KERN_WARNING "Fail to create dummy i2c client for addr %d\n", pdata[i].reg_addr); + goto error; + } + } + + ret = sysfs_create_group(&pdev->dev.kobj, &s6000_cpld_attr_grp); + if (ret) + goto error; + + return 0; + +error: + i--; + for (; i >= 0; i--) { + if (pdata[i].client) { + i2c_unregister_device(pdata[i].client); + } + } + + i2c_put_adapter(parent); + + return -ENODEV; +} + +static int __exit cpld_remove(struct platform_device *pdev) +{ + int i; + struct i2c_adapter *parent = NULL; + struct cpld_platform_data *pdata = pdev->dev.platform_data; + + sysfs_remove_group(&pdev->dev.kobj, &s6000_cpld_attr_grp); + + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + } else { + for (i = 0; i < CPLD_DEVICE_NUM; i++) { + if (pdata[i].client) { + if (!parent) { + parent = (pdata[i].client)->adapter; + } + i2c_unregister_device(pdata[i].client); + } + } + } + + i2c_put_adapter(parent); + + return 0; +} + +static struct platform_driver cpld_driver = { + .probe = cpld_probe, + .remove = __exit_p(cpld_remove), + .driver = { + .owner = THIS_MODULE, + .name = "dell-s6000-cpld", + }, +}; + +static int __init i2c_device_probe(struct platform_device *pdev) +{ + struct i2c_device_platform_data *pdata; + struct i2c_adapter *parent; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + return -ENODEV; + } + + parent = i2c_get_adapter(pdata->parent); + if (!parent) { + dev_err(&pdev->dev, "Parent adapter (%d) not found\n", + pdata->parent); + return -ENODEV; + } + + pdata->client = i2c_new_device(parent, &pdata->info); + if (!pdata->client) { + dev_err(&pdev->dev, "Failed to create i2c client %s at %d\n", + pdata->info.type, pdata->parent); + return -ENODEV; + } + + return 0; +} + +static int __exit i2c_deivce_remove(struct platform_device *pdev) +{ + struct i2c_adapter *parent; + struct i2c_device_platform_data *pdata; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + return -ENODEV; + } + + if (pdata->client) { + parent = i2c_get_adapter(pdata->parent); + i2c_unregister_device(pdata->client); + i2c_put_adapter(parent); + } + + return 0; +} + + +static struct platform_driver i2c_device_driver = { + .probe = i2c_device_probe, + .remove = __exit_p(i2c_deivce_remove), + .driver = { + .owner = THIS_MODULE, + .name = "dell-s6000-i2c-device", + } +}; + +static int __init dell_s6000_platform_init(void) +{ + int ret = 0; + struct cpld_platform_data *cpld_pdata; + struct qsfp_mux_platform_data *qsfp_pdata; + int i; + + printk("delll_s6000_platform module initialization\n"); + + mdelay(10000); + + ret = platform_driver_register(&cpld_driver); + if (ret) { + printk(KERN_WARNING "Fail to register cpld driver\n"); + goto error_cpld_driver; + } + + ret = platform_driver_register(&qsfp_mux_driver); + if (ret) { + printk(KERN_WARNING "Fail to register qsfp mux driver\n"); + goto error_qsfp_mux_driver; + } + + ret = platform_driver_register(&i2c_device_driver); + if (ret) { + printk(KERN_WARNING "Fail to register i2c device driver\n"); + goto error_i2c_device_driver; + } + + ret = platform_device_register(&s6000_mux); + if (ret) { + printk(KERN_WARNING "Fail to create gpio mux\n"); + goto error_mux; + } + + ret = platform_device_register(&s6000_cpld); + if (ret) { + printk(KERN_WARNING "Fail to create cpld device\n"); + goto error_cpld; + } + + cpld_pdata = s6000_cpld.dev.platform_data; + qsfp_pdata = s6000_qsfp_mux[0].dev.platform_data; + qsfp_pdata->cpld = cpld_pdata[slave_cpld].client; + qsfp_pdata = s6000_qsfp_mux[1].dev.platform_data; + qsfp_pdata->cpld = cpld_pdata[master_cpld].client; + + for (i = 0; i < QSFP_DEVICE_NUM; i++) { + ret = platform_device_register(&s6000_qsfp_mux[i]); + if (ret) { + printk(KERN_WARNING "fail to create qsfp mux %d\n", i); + goto error_qsfp_mux; + } + } + + for (i = 0; i < ARRAY_SIZE(s6000_i2c_device_platform_data); i++) { + ret = platform_device_register(&s6000_i2c_device[i]); + if (ret) { + printk(KERN_WARNING "fail to create qsfp mux %d\n", i); + goto error_i2c_device; + } + } + + if (ret) + goto error_qsfp_mux; + + return 0; + +error_i2c_device: + i--; + for (; i >= 0; i--) { + platform_device_unregister(&s6000_i2c_device[i]); + } + i = QSFP_DEVICE_NUM; +error_qsfp_mux: + i--; + for (; i >= 0; i--) { + platform_device_unregister(&s6000_qsfp_mux[i]); + } + platform_device_unregister(&s6000_cpld); +error_cpld: + platform_device_unregister(&s6000_mux); +error_mux: + platform_driver_unregister(&i2c_device_driver); +error_i2c_device_driver: + platform_driver_unregister(&qsfp_mux_driver); +error_qsfp_mux_driver: + platform_driver_unregister(&cpld_driver); +error_cpld_driver: + return ret; +} + +static void __exit dell_s6000_platform_exit(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(s6000_i2c_device_platform_data); i++) + platform_device_unregister(&s6000_i2c_device[i]); + for (i = 0; i < MUX_CHANNEL_NUM; i++) + platform_device_unregister(&s6000_qsfp_mux[i]); + platform_device_unregister(&s6000_cpld); + platform_device_unregister(&s6000_mux); + + platform_driver_unregister(&i2c_device_driver); + platform_driver_unregister(&cpld_driver); + platform_driver_unregister(&qsfp_mux_driver); +} + +module_init(dell_s6000_platform_init); +module_exit(dell_s6000_platform_exit); + +MODULE_DESCRIPTION("DELL S6000 Platform Support"); +MODULE_AUTHOR("Guohan Lu "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-s6000/scripts/reset-qsfp b/platform/broadcom/sonic-platform-modules-s6000/scripts/reset-qsfp new file mode 100755 index 000000000000..6b017ed37c26 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-s6000/scripts/reset-qsfp @@ -0,0 +1,25 @@ +#!/bin/bash + +# Usage: +# Reset QSFP manually by writing 1/0 to QSFP reset pin + +QSFP_RESET=/sys/bus/platform/devices/dell-s6000-cpld.0/qsfp_reset + +logger -t platform-modules "Reset QSFP modules" + +# Retry three times +for i in `seq 1 3` +do + if [ -w $QSFP_RESET ]; then + echo 0x00000000 > $QSFP_RESET + # Sleep 1 second to reset QSFP + sleep 1 + echo 0xffffffff > $QSFP_RESET + exit 0 + fi + # Sleep for 3 seconds to wait for device tree to be ready + sleep 3 +done + +logger -p user.error -t platform-modules "Failed to reset QSFP modules!" +exit 1 diff --git a/platform/broadcom/sonic-platform-modules-s6000/scripts/set-fan-speed b/platform/broadcom/sonic-platform-modules-s6000/scripts/set-fan-speed new file mode 100755 index 000000000000..00c738f23a8d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-s6000/scripts/set-fan-speed @@ -0,0 +1,58 @@ +#!/bin/bash + +# Usage: +# Set all fans speed to $1 + +usage() { + echo "This script must be run with super-user privilege." + echo "Warning! Wrongly set fan speed may result in physical damage to the device." + echo "" + echo "usage: set-fan-speed speed_in_rpm" + echo "example: set-fan-speed 15000" +} + +if [ $# -ne 1 ]; then + usage + exit 1 +fi + +PSU_FAN1=/sys/class/i2c-adapter/i2c-1/1-0058/fan1_target +PSU_FAN2=/sys/class/i2c-adapter/i2c-1/1-0059/fan1_target + +# Three fan trays with each contains two separate fans +# fan1-fan4 fan2-fan5 fan3-fan6 +FAN1=/sys/class/i2c-adapter/i2c-11/11-0029/fan1_target +FAN2=/sys/class/i2c-adapter/i2c-11/11-0029/fan2_target +FAN3=/sys/class/i2c-adapter/i2c-11/11-0029/fan3_target +FAN4=/sys/class/i2c-adapter/i2c-11/11-0029/fan4_target +FAN5=/sys/class/i2c-adapter/i2c-11/11-002a/fan1_target +FAN6=/sys/class/i2c-adapter/i2c-11/11-002a/fan2_target + +speed=$1 +logger -t platform-modules "Trying to set fan speed to $speed" + +# Retry three times +for i in `seq 1 3` +do + if [ -w $FAN1 -o -w $FAN2 -o -w $FAN3 ]; then + # set default psu fan speed + echo $speed > $PSU_FAN1 + echo $speed > $PSU_FAN2 + # set default fan speed + echo $speed > $FAN1 + echo $speed > $FAN2 + echo $speed > $FAN3 + echo $speed > $FAN4 + echo $speed > $FAN5 + echo $speed > $FAN6 + + logger -t platform-modules "Fan speed is set to $speed" + + exit 0 + fi + # Sleep for 3 seconds to wait for device tree to be ready + sleep 3 +done + +logger -p user.error -t platform-modules "Failed to set fan speed!" +exit 1 diff --git a/platform/nephos/sonic-platform-modules-ingrasys b/platform/nephos/sonic-platform-modules-ingrasys deleted file mode 160000 index 796169e43aee..000000000000 --- a/platform/nephos/sonic-platform-modules-ingrasys +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 796169e43aee944fdf7b549d04cb181117e0fb89 diff --git a/platform/nephos/sonic-platform-modules-ingrasys/.gitignore b/platform/nephos/sonic-platform-modules-ingrasys/.gitignore new file mode 100644 index 000000000000..c6127b38c1aa --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/.gitignore @@ -0,0 +1,52 @@ +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf diff --git a/platform/nephos/sonic-platform-modules-ingrasys/LICENSE b/platform/nephos/sonic-platform-modules-ingrasys/LICENSE new file mode 100644 index 000000000000..9cecc1d4669e --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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 3 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, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/platform/nephos/sonic-platform-modules-ingrasys/debian/changelog b/platform/nephos/sonic-platform-modules-ingrasys/debian/changelog new file mode 100644 index 000000000000..a3e3f92cc731 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/debian/changelog @@ -0,0 +1,11 @@ +platform-driver (1.0.0) unstable; urgency=low + + * Add support for S9130-32X, S9230-64X series + + -- developer Wed, 29 Mar 2017 11:00:00 +0800 + +platform-driver (1.0.0) unstable; urgency=low + + * Initial release (Closes: #nnnn) + + -- developer Wed, 05 Oct 2016 16:30:45 +0800 diff --git a/platform/nephos/sonic-platform-modules-ingrasys/debian/compat b/platform/nephos/sonic-platform-modules-ingrasys/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/debian/compat @@ -0,0 +1 @@ +9 diff --git a/platform/nephos/sonic-platform-modules-ingrasys/debian/control b/platform/nephos/sonic-platform-modules-ingrasys/debian/control new file mode 100644 index 000000000000..3db0b5f3505f --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/debian/control @@ -0,0 +1,15 @@ +Source: platform-driver +Section: unknown +Priority: optional +Maintainer: Wade He +Build-Depends: debhelper (>= 9), dh-systemd +Standards-Version: 1.0.0 + +Package: sonic-platform-ingrasys-s9130-32x +Architecture: amd64 +Description: This package contains S9130-32X platform driver utility for SONiC project. + +Package: sonic-platform-ingrasys-s9230-64x +Architecture: amd64 +Description: This package contains S9230-64X platform driver utility for SONiC project. + diff --git a/platform/nephos/sonic-platform-modules-ingrasys/debian/rules b/platform/nephos/sonic-platform-modules-ingrasys/debian/rules new file mode 100644 index 000000000000..4ca2c6ac9b87 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/debian/rules @@ -0,0 +1,82 @@ +#!/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. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +export INSTALL_MOD_DIR:=extra + +PACKAGE_PRE_NAME := sonic-platform-ingrasys +KVERSION ?= $(shell uname -r) +KERNEL_SRC := /lib/modules/$(KVERSION) +MOD_SRC_DIR:= $(shell pwd) +MODULE_DIRS:= s9130-32x s9230-64x +MODULE_DIR := modules +UTILS_DIR := utils +SERVICE_DIR := service +CONF_DIR := conf + +%: + dh $@ --with systemd + +clean: + dh_testdir + dh_testroot + dh_clean + +build: + #make modules -C $(KERNEL_SRC)/build M=$(MODULE_SRC) + (for mod in $(MODULE_DIRS); do \ + make modules -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ + 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 \ + mkdir debian/tmp/usr/sbin -p; \ + mkdir debian/tmp/lib/systemd/system -p; \ + mkdir debian/tmp/etc -p; \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp $(MOD_SRC_DIR)/$${mod}/$(MODULE_DIR)/*.ko debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/*.sh debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/sbin/; \ + cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/*.ctrl debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/sbin/; \ + cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/fancontrol debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/sbin/; \ + cp $(MOD_SRC_DIR)/$${mod}/$(SERVICE_DIR)/*.service debian/$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system/; \ + done) + # 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 diff --git a/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9130-32x.dirs b/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9130-32x.dirs new file mode 100644 index 000000000000..bec29f195770 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9130-32x.dirs @@ -0,0 +1,3 @@ +usr/sbin +lib/systemd/system +etc/ \ No newline at end of file diff --git a/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9130-32x.install b/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9130-32x.install new file mode 100644 index 000000000000..38efbef5d864 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9130-32x.install @@ -0,0 +1,3 @@ +lib/systemd/ +usr/sbin/ +etc/ \ No newline at end of file diff --git a/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9130-32x.links b/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9130-32x.links new file mode 100644 index 000000000000..4e59c7e191e4 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9130-32x.links @@ -0,0 +1 @@ +/usr/share/sonic/device/x86_64-ingrasys_s9130_32x-r0/fancontrol /etc/fancontrol diff --git a/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9130-32x.postinst b/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9130-32x.postinst new file mode 100644 index 000000000000..504511bd72cc --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9130-32x.postinst @@ -0,0 +1,44 @@ +# Automatically added by dh_systemd_enable +# This will only remove masks created by d-s-h on package removal. +deb-systemd-helper unmask s9130-32x-monitor.service >/dev/null || true +deb-systemd-helper unmask fancontrol.service >/dev/null || true +deb-systemd-helper unmask qsfp-monitor.service >/dev/null || true +# Generate kernel modules.dep and map files for add eeprom_mb. +depmod -a +# was-enabled defaults to true, so new installations run enable. +if deb-systemd-helper --quiet was-enabled s9130-32x-monitor.service; then + # Enables the unit on first installation, creates new + # symlinks on upgrades if the unit file has changed. + deb-systemd-helper enable s9130-32x-monitor.service >/dev/null || true +else + # Update the statefile to add new symlinks (if any), which need to be + # cleaned up on purge. Also remove old symlinks. + deb-systemd-helper update-state s9130-32x-monitor.service >/dev/null || true +fi +if deb-systemd-helper --quiet was-enabled qsfp-monitor.service; then + # Enables the unit on first installation, creates new + # symlinks on upgrades if the unit file has changed. + deb-systemd-helper enable qsfp-monitor.service >/dev/null || true +else + # Update the statefile to add new symlinks (if any), which need to be + # cleaned up on purge. Also remove old symlinks. + deb-systemd-helper update-state qsfp-monitor.service >/dev/null || true +fi +# End automatically added section +# Automatically added by dh_installinit +if [ -x "/etc/init.d/s9130-32x-monitor" ]; then + update-rc.d s9130-32x-monitor defaults >/dev/null + invoke-rc.d s9130-32x-monitor start || exit $? +fi +if [ -x "/etc/init.d/qsfp-monitor" ]; then + update-rc.d qsfp-monitor defaults >/dev/null + invoke-rc.d qsfp-monitor start || exit $? +fi +# End automatically added section +# Automatically added by dh_systemd_start +if [ -d /run/systemd/system ]; then + systemctl --system daemon-reload >/dev/null || true + deb-systemd-invoke start s9130-32x-monitor.service >/dev/null || true + deb-systemd-invoke start qsfp-monitor.service >/dev/null || true +fi +# End automatically added section diff --git a/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9130-32x.postrm b/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9130-32x.postrm new file mode 100644 index 000000000000..bc4de635053e --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9130-32x.postrm @@ -0,0 +1,38 @@ +# Automatically added by dh_systemd_start +if [ -d /run/systemd/system ]; then + systemctl --system daemon-reload >/dev/null || true + fi +# End automatically added section +# Automatically added by dh_installinit +if [ "$1" = "purge" ] ; then + update-rc.d s9130-32x-monitor remove >/dev/null + update-rc.d qsfp-monitor remove >/dev/null +fi + + +# In case this system is running systemd, we make systemd reload the unit files +# to pick up changes. +if [ -d /run/systemd/system ] ; then + systemctl --system daemon-reload >/dev/null || true +fi +# End automatically added section +# Automatically added by dh_systemd_enable +if [ "$1" = "remove" ]; then + if [ -x "/usr/bin/deb-systemd-helper" ]; then + deb-systemd-helper mask s9130-32x-monitor.service >/dev/null + deb-systemd-helper mask qsfp-monitor.service >/dev/null + fi +fi + +if [ "$1" = "purge" ]; then + if [ -x "/usr/bin/deb-systemd-helper" ]; then + deb-systemd-helper purge s9130-32x-monitor.service >/dev/null + deb-systemd-helper unmask s9130-32x-monitor.service >/dev/null + deb-systemd-helper purge qsfp-monitor.service >/dev/null + deb-systemd-helper unmask qsfp-monitor.service >/dev/null + fi +fi +# Generate kernel modules.dep and map files for remove eeprom_mb. +depmod -a || true +# End automatically added section + diff --git a/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9130-32x.prerm b/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9130-32x.prerm new file mode 100644 index 000000000000..a5271f1faf68 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9130-32x.prerm @@ -0,0 +1,17 @@ +# Automatically added by dh_systemd_start +if [ -d /run/systemd/system ]; then + deb-systemd-invoke stop s9130-32x-monitor.service >/dev/null + deb-systemd-invoke stop qsfp-monitor.service >/dev/null +fi +# End automatically added section +# Automatically added by dh_installinit +if [ -x "/etc/init.d/s9130-32x-monitor" ]; then + invoke-rc.d s9130-32x-monitor stop || exit $? +fi +if [ -x "/etc/init.d/qsfp-monitor" ]; then + invoke-rc.d qsfp-monitor stop || exit $? +fi +# Driver deinit +/usr/sbin/i2c_utils.sh i2c_deinit +# End automatically added section + diff --git a/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9130-32x.upstart b/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9130-32x.upstart new file mode 100644 index 000000000000..bda8c7661c34 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9130-32x.upstart @@ -0,0 +1,6 @@ +description "SONiC platform service" + +respawn + +exec /usr/sbin/s9130_32x_monitor.sh +exec /usr/sbin/qsfp_monitor.sh diff --git a/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9230-64x.dirs b/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9230-64x.dirs new file mode 100644 index 000000000000..bec29f195770 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9230-64x.dirs @@ -0,0 +1,3 @@ +usr/sbin +lib/systemd/system +etc/ \ No newline at end of file diff --git a/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9230-64x.install b/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9230-64x.install new file mode 100644 index 000000000000..38efbef5d864 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9230-64x.install @@ -0,0 +1,3 @@ +lib/systemd/ +usr/sbin/ +etc/ \ No newline at end of file diff --git a/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9230-64x.links b/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9230-64x.links new file mode 100644 index 000000000000..e5b8a45693d0 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9230-64x.links @@ -0,0 +1 @@ +/usr/share/sonic/device/x86_64-ingrasys_s9230_64x-r0/fancontrol /etc/fancontrol diff --git a/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9230-64x.postinst b/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9230-64x.postinst new file mode 100644 index 000000000000..ebba922f41de --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9230-64x.postinst @@ -0,0 +1,45 @@ +# Automatically added by dh_systemd_enable +# This will only remove masks created by d-s-h on package removal. +deb-systemd-helper unmask s9230-64x-monitor.service >/dev/null || true +deb-systemd-helper unmask fancontrol.service >/dev/null || true +deb-systemd-helper unmask qsfp-monitor.service >/dev/null || true +# Generate kernel modules.dep and map files for add eeprom_mb +# and ingrasys_s9230_64x_i2c_cpld +depmod -a +# was-enabled defaults to true, so new installations run enable. +if deb-systemd-helper --quiet was-enabled s9230-64x-monitor.service; then + # Enables the unit on first installation, creates new + # symlinks on upgrades if the unit file has changed. + deb-systemd-helper enable s9230-64x-monitor.service >/dev/null || true +else + # Update the statefile to add new symlinks (if any), which need to be + # cleaned up on purge. Also remove old symlinks. + deb-systemd-helper update-state s9230-64x-monitor.service >/dev/null || true +fi +if deb-systemd-helper --quiet was-enabled qsfp-monitor.service; then + # Enables the unit on first installation, creates new + # symlinks on upgrades if the unit file has changed. + deb-systemd-helper enable qsfp-monitor.service >/dev/null || true +else + # Update the statefile to add new symlinks (if any), which need to be + # cleaned up on purge. Also remove old symlinks. + deb-systemd-helper update-state qsfp-monitor.service >/dev/null || true +fi +# End automatically added section +# Automatically added by dh_installinit +if [ -x "/etc/init.d/s9230-64x-monitor" ]; then + update-rc.d s9230-64x-monitor defaults >/dev/null + invoke-rc.d s9230-64x-monitor start || exit $? +fi +if [ -x "/etc/init.d/qsfp-monitor" ]; then + update-rc.d qsfp-monitor defaults >/dev/null + invoke-rc.d qsfp-monitor start || exit $? +fi +# End automatically added section +# Automatically added by dh_systemd_start +if [ -d /run/systemd/system ]; then + systemctl --system daemon-reload >/dev/null || true + deb-systemd-invoke start s9230-64x-monitor.service >/dev/null || true + deb-systemd-invoke start qsfp-monitor.service >/dev/null || true +fi +# End automatically added section diff --git a/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9230-64x.postrm b/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9230-64x.postrm new file mode 100644 index 000000000000..36efe65f6bc1 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9230-64x.postrm @@ -0,0 +1,38 @@ +# Automatically added by dh_systemd_start +if [ -d /run/systemd/system ]; then + systemctl --system daemon-reload >/dev/null || true + fi +# End automatically added section +# Automatically added by dh_installinit +if [ "$1" = "purge" ] ; then + update-rc.d s9230-64x-monitor remove >/dev/null + update-rc.d qsfp-monitor remove >/dev/null +fi + + +# In case this system is running systemd, we make systemd reload the unit files +# to pick up changes. +if [ -d /run/systemd/system ] ; then + systemctl --system daemon-reload >/dev/null || true +fi +# End automatically added section +# Automatically added by dh_systemd_enable +if [ "$1" = "remove" ]; then + if [ -x "/usr/bin/deb-systemd-helper" ]; then + deb-systemd-helper mask s9230-64x-monitor.service >/dev/null + deb-systemd-helper mask qsfp-monitor.service >/dev/null + fi +fi + +if [ "$1" = "purge" ]; then + if [ -x "/usr/bin/deb-systemd-helper" ]; then + deb-systemd-helper purge s9230-64x-monitor.service >/dev/null + deb-systemd-helper unmask s9230-64x-monitor.service >/dev/null + deb-systemd-helper purge qsfp-monitor.service >/dev/null + deb-systemd-helper unmask qsfp-monitor.service >/dev/null + fi +fi +# Generate kernel modules.dep and map files for remove eeprom_mb. +depmod -a || true +# End automatically added section + diff --git a/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9230-64x.prerm b/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9230-64x.prerm new file mode 100644 index 000000000000..1c7ace21990e --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9230-64x.prerm @@ -0,0 +1,17 @@ +# Automatically added by dh_systemd_start +if [ -d /run/systemd/system ]; then + deb-systemd-invoke stop s9230-64x-monitor.service >/dev/null + deb-systemd-invoke stop qsfp-monitor.service >/dev/null +fi +# End automatically added section +# Automatically added by dh_installinit +if [ -x "/etc/init.d/s9230-64x-monitor" ]; then + invoke-rc.d s9230-64x-monitor stop || exit $? +fi +if [ -x "/etc/init.d/qsfp-monitor" ]; then + invoke-rc.d qsfp-monitor stop || exit $? +fi +# Driver deinit +/usr/sbin/i2c_utils.sh i2c_deinit +# End automatically added section + diff --git a/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9230-64x.upstart b/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9230-64x.upstart new file mode 100644 index 000000000000..6cbd9482f2d2 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/debian/sonic-platform-ingrasys-s9230-64x.upstart @@ -0,0 +1,6 @@ +description "SONiC platform service" + +respawn + +exec /usr/sbin/s9230_64x_monitor.sh +exec /usr/sbin/qsfp_monitor.sh diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/README.md b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/README.md new file mode 100644 index 000000000000..1b3b14db343b --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/README.md @@ -0,0 +1,167 @@ +# Ingrasys S9130-32X Platform Driver for SONiC + +Copyright (C) 2016 Ingrasys, 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 3 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, see . + + +## Licensing terms + +The Licensing terms of the files within this project is split 2 parts. +The Linux kernel is released under the GNU General Public License version 2. +All other code is released under the GNU General Public License version 3. +Please see the LICENSE file for copies of both licenses. + +## Contents of this package + + - service/ + > Service config files for platform initialization and monitoring + - utils/ + > Scripts useful during platform bringup and sysfs function + - conf/ + > Platform configure files. + +## Kernel modules and drivers + +The driver for interacting with Ingrasys S9130-32X is contained in the I2C +kernel module and initialization script. The initialization script loads +the modules in the correct order. It has been built and tested against +the Linux 3.16 kernel. + +The initialization script will modprobe the needed modules, navigate to the +module's device directory in sysfs, and write configuration data to +the kernel module. + +### IGB + +This is OOB Ports on front panel for management plane. + +The IGB module must be loaded first on Ingrasys S9130-32X platform. + +### I2C i801 + +The I2C i801 on Ingrasys S9130-32X can be found in +`/sys/bus/i2c/devices/i2c-0/` + +This is I2C bus for power monitor, FAN controller, HWM and thermal sensors. + +### I2C PCA9548 +The PCA9548 module on S9130-32X can be found in +`/sys/bus/i2c/devices/i2c-1/` , `/sys/bus/i2c/devices/i2c-2/`, +`/sys/bus/i2c/devices/i2c-3/`, `/sys/bus/i2c/devices/i2c-4/`, +`/sys/bus/i2c/devices/i2c-5/`, `/sys/bus/i2c/devices/i2c-6/`, +`/sys/bus/i2c/devices/i2c-7/`, `/sys/bus/i2c/devices/i2c-8/` + +The pca9548 module for zQSFP module get/set functions, PSU information, +fan status and EEPROM. + +## Hardware components + +The hardware components are initialized in the init script on S9130-32X. +The following describes manual initialization as well as interaction. +The examples below are just for Ingrasys S9130-32X platform. + +### Hardware initialization + +When the sonic-platform-ingrasys-s9130-32x package is installed on the S9130-32X, +it is automatically initialized. If you want to manual initialization, the +utility command usage as follows: +``` + i2c_utils.sh i2c_init +``` + +### EEPROM + +The EEPROM is including the board SKU, model name, vendor name, serial number, +and other information can be accessed with the specific eeprom kernel module. +After using `modprobe eeprom_mb` to detect the eeprom, it will show up in sysfs. + +The hexdump utility can be used to decode the raw output of the EEPROM. +For example, +``` + bash# echo "mb_eeprom 0x51" > /sys/bus/i2c/devices/i2c-0/new_device + bash# cat /sys/bus/i2c/drivers/mb_eeprom/0-0051/eeprom | hexdump -C +``` + +### Front panel LEDs + +LEDs can be setup on/off by using i2c utility `/usr/sbin/i2c_utils.sh`. +Utility function command usage as follows: + +``` +Status LED: + i2c_utils.sh i2c_sys_led green|amber + +Fan status LED: + i2c_utils.sh i2c_fan_led green|amber on|off + +PSU1 status LED: + i2c_utils.sh i2c_psu1_led green|amber on|off + +PSU2 status LED: + i2c_utils.sh i2c_psu2_led green|amber on|off + +``` +QSFP Module Port LEDs control by ASIC library. + + +### Fan speed + +Fan speed are controlled by the w83795 kernel module. +It can be found in `/sys/class/hwmon/hwmon5/device/`. +If they were compiled as modules, you will need to modprobe w83795 for +their sysfs entries to show up. Each fan has an `fan_input` file +for reading the fan speed. And `pwm1` setting fan1 to fan4, +`pwm2` setting fan5 to fan8. + +There is docker-platform-monitor container installed fancontrol package that can +automatic control platform fan speed. + + +### Temperature sensors + +There is docker-platform-monitor container installed lm-sensors package that can +monitor platform temperature. And `sensors` command can show each +temperature sensors status. + +### Power supplies + +Power supplies status and its EEPROM info can be used i2c utility +`/usr/sbin/i2c_utils.sh` to get. +The usage as follows: +``` +PSU EEPROM: + i2c_utils.sh i2c_psu_eeprom_get + hexdump -C psu0.rom + hexdump -C psu1.rom + +PSU Status: + i2c_utils.sh i2c_psu_status +``` + +### QSFPs +QSFP modules are managed by the pca9548 kernel driver. +The i2c utility `/usr/sbin/i2c_utils.sh` can be used to get status and +module EEPROM informations. +The usage as follows: +``` +QSFP EEPROM: + i2c_utils.sh i2c_qsfp_eeprom_get [1-32] + +QSFP Insert Event: + i2c_utils.sh i2c_qsfp_eeprom_get [1-32] + 0 => not insert + 1 => inserted +``` + diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/modules/Makefile b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/modules/Makefile new file mode 100644 index 000000000000..688bb4666444 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/modules/Makefile @@ -0,0 +1,2 @@ +obj-m := eeprom_mb.o +obj-m += ingrasys_s9130_32x_psu.o diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/modules/eeprom_mb.c b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/modules/eeprom_mb.c new file mode 100644 index 000000000000..528864d93382 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/modules/eeprom_mb.c @@ -0,0 +1,267 @@ +/* + * Copyright (C) 1998, 1999 Frodo Looijaard and + * Philip Edelbrock + * Copyright (C) 2003 Greg Kroah-Hartman + * Copyright (C) 2003 IBM Corp. + * Copyright (C) 2004 Jean Delvare + * + * 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. + */ + +/* enable dev_dbg print out */ +//#define DEBUG + +#include +#include +#include +#include +#include +#include +#include + +/* Addresses to scan */ +static const unsigned short normal_i2c[] = { /*0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57,*/ I2C_CLIENT_END }; + +/* Size of EEPROM in bytes */ +#define EEPROM_SIZE 512 + +#define SLICE_BITS (6) +#define SLICE_SIZE (1 << SLICE_BITS) +#define SLICE_NUM (EEPROM_SIZE/SLICE_SIZE) + +/* Each client has this additional data */ +struct eeprom_data { + struct mutex update_lock; + u8 valid; /* bitfield, bit!=0 if slice is valid */ + unsigned long last_updated[SLICE_NUM]; /* In jiffies, 8 slices */ + u8 data[EEPROM_SIZE]; /* Register values */ +}; + + +static void mb_eeprom_update_client(struct i2c_client *client, u8 slice) +{ + struct eeprom_data *data = i2c_get_clientdata(client); + int i, j; + int ret; + int addr; + + mutex_lock(&data->update_lock); + + if (!(data->valid & (1 << slice)) || + time_after(jiffies, data->last_updated[slice] + 300 * HZ)) { + dev_dbg(&client->dev, "Starting eeprom update, slice %u\n", slice); + + addr = slice << SLICE_BITS; + + ret = i2c_smbus_write_byte_data(client, (u8)((addr >> 8) & 0xFF), (u8)(addr & 0xFF)); + /* select the eeprom address */ + if (ret < 0) { + dev_err(&client->dev, "address set failed\n"); + goto exit; + } + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BYTE)) { + goto exit; + } + + for (i = slice << SLICE_BITS; i < (slice + 1) << SLICE_BITS; i+= SLICE_SIZE) { + for (j = i; j < (i+SLICE_SIZE); j++) { + int res; + + res = i2c_smbus_read_byte(client); + if (res < 0) { + goto exit; + } + + data->data[j] = res & 0xFF; + } + } + + data->last_updated[slice] = jiffies; + data->valid |= (1 << slice); + } +exit: + mutex_unlock(&data->update_lock); +} + +static ssize_t mb_eeprom_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj)); + struct eeprom_data *data = i2c_get_clientdata(client); + u8 slice; + + if (off > EEPROM_SIZE) { + return 0; + } + if (off + count > EEPROM_SIZE) { + count = EEPROM_SIZE - off; + } + if (count == 0) { + return 0; + } + + /* Only refresh slices which contain requested bytes */ + for (slice = off >> SLICE_BITS; slice <= (off + count - 1) >> SLICE_BITS; slice++) { + mb_eeprom_update_client(client, slice); + } + + memcpy(buf, &data->data[off], count); + + return count; +} + +static ssize_t mb_eeprom_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj)); + struct eeprom_data *data = i2c_get_clientdata(client); + int ret; + int i; + u8 cmd; + u16 value16; + + dev_dbg(&client->dev, "mb_eeprom_write off=%d, count=%d\n", (int)off, (int)count); + + if (off > EEPROM_SIZE) { + return 0; + } + if (off + count > EEPROM_SIZE) { + count = EEPROM_SIZE - off; + } + if (count == 0) { + return 0; + } + + mutex_lock(&data->update_lock); + + for(i=0; i < count; i++) { + /* write command */ + cmd = (off >> 8) & 0xff; + value16 = off & 0xff; + value16 |= buf[i] << 8; + ret = i2c_smbus_write_word_data(client, cmd, value16); + + if (ret < 0) { + dev_err(&client->dev, "write address failed at %d \n", (int)off); + goto exit; + } + + off++; + + /* need to wait for write complete */ + udelay(10000); + } +exit: + mutex_unlock(&data->update_lock); + /* force to update client when reading */ + for(i=0; i < SLICE_NUM; i++) { + data->last_updated[i] = 0; + } + + return count; +} + +static struct bin_attribute mb_eeprom_attr = { + .attr = { + .name = "eeprom", + .mode = S_IRUGO | S_IWUSR, + }, + .size = EEPROM_SIZE, + .read = mb_eeprom_read, + .write = mb_eeprom_write, +}; + +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int mb_eeprom_detect(struct i2c_client *client, struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = client->adapter; + + /* EDID EEPROMs are often 24C00 EEPROMs, which answer to all + addresses 0x50-0x57, but we only care about 0x51 and 0x55. So decline + attaching to addresses >= 0x56 on DDC buses */ + if (!(adapter->class & I2C_CLASS_SPD) && client->addr >= 0x56) { + return -ENODEV; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE) + && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { + return -ENODEV; + } + + strlcpy(info->type, "eeprom", I2C_NAME_SIZE); + + return 0; +} + +static int mb_eeprom_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct eeprom_data *data; + int err; + + if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) { + err = -ENOMEM; + goto exit; + } + + memset(data->data, 0xff, EEPROM_SIZE); + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + /* create the sysfs eeprom file */ + err = sysfs_create_bin_file(&client->dev.kobj, &mb_eeprom_attr); + if (err) { + goto exit_kfree; + } + + return 0; + +exit_kfree: + kfree(data); +exit: + return err; +} + +static int mb_eeprom_remove(struct i2c_client *client) +{ + sysfs_remove_bin_file(&client->dev.kobj, &mb_eeprom_attr); + kfree(i2c_get_clientdata(client)); + + return 0; +} + +static const struct i2c_device_id mb_eeprom_id[] = { + { "mb_eeprom", 0 }, + { } +}; + +static struct i2c_driver mb_eeprom_driver = { + .driver = { + .name = "mb_eeprom", + }, + .probe = mb_eeprom_probe, + .remove = mb_eeprom_remove, + .id_table = mb_eeprom_id, + + .class = I2C_CLASS_DDC | I2C_CLASS_SPD, + .detect = mb_eeprom_detect, + .address_list = normal_i2c, +}; + +module_i2c_driver(mb_eeprom_driver); + +MODULE_AUTHOR("Wade "); +MODULE_DESCRIPTION("Ingrasys Mother Borad EEPROM driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/modules/ingrasys_s9130_32x_platform.h b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/modules/ingrasys_s9130_32x_platform.h new file mode 100644 index 000000000000..23dcf17a855b --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/modules/ingrasys_s9130_32x_platform.h @@ -0,0 +1,148 @@ +#ifndef _S9130_32X_PLATFORM_H +#define _S9130_32X_PLATFORM_H + +#include + +// remove debug before release +#define DEBUG + +enum bus_order { + I2C_BUS_MAIN, + MUX_9548_0_CH0, + MUX_9548_0_CH1, + MUX_9548_0_CH2, + MUX_9548_0_CH3, + MUX_9548_0_CH4, + MUX_9548_0_CH5, + MUX_9548_0_CH6, + MUX_9548_0_CH7, + MUX_9548_1_CH0, + MUX_9548_1_CH1, + MUX_9548_1_CH2, + MUX_9548_1_CH3, + MUX_9548_1_CH4, + MUX_9548_1_CH5, + MUX_9548_1_CH6, + MUX_9548_1_CH7, + MUX_9546_0_CH0, + MUX_9546_0_CH1, + MUX_9546_0_CH2, + MUX_9546_0_CH3, + MUX_9546_1_CH0, + MUX_9546_1_CH1, + MUX_9546_1_CH2, + MUX_9546_1_CH3, + MUX_9548_2_CH0, + MUX_9548_2_CH1, + MUX_9548_2_CH2, + MUX_9548_2_CH3, + MUX_9548_2_CH4, + MUX_9548_2_CH5, + MUX_9548_2_CH6, + MUX_9548_2_CH7, + MUX_9548_3_CH0, + MUX_9548_3_CH1, + MUX_9548_3_CH2, + MUX_9548_3_CH3, + MUX_9548_3_CH4, + MUX_9548_3_CH5, + MUX_9548_3_CH6, + MUX_9548_3_CH7, + MUX_9548_4_CH0, + MUX_9548_4_CH1, + MUX_9548_4_CH2, + MUX_9548_4_CH3, + MUX_9548_4_CH4, + MUX_9548_4_CH5, + MUX_9548_4_CH6, + MUX_9548_4_CH7, + MUX_9548_5_CH0, + MUX_9548_5_CH1, + MUX_9548_5_CH2, + MUX_9548_5_CH3, + MUX_9548_5_CH4, + MUX_9548_5_CH5, + MUX_9548_5_CH6, + MUX_9548_5_CH7, + MUX_9548_6_CH0, + MUX_9548_6_CH1, + MUX_9548_6_CH2, + MUX_9548_6_CH3, + MUX_9548_6_CH4, + MUX_9548_6_CH5, + MUX_9548_6_CH6, + MUX_9548_6_CH7, + MUX_9548_7_CH0, + MUX_9548_7_CH1, + MUX_9548_7_CH2, + MUX_9548_7_CH3, + MUX_9548_7_CH4, + MUX_9548_7_CH5, + MUX_9548_7_CH6, + MUX_9548_7_CH7, + MUX_9548_8_CH0, + MUX_9548_8_CH1, + MUX_9548_8_CH2, + MUX_9548_8_CH3, + MUX_9548_8_CH4, + MUX_9548_8_CH5, + MUX_9548_8_CH6, + MUX_9548_8_CH7, + MUX_9548_9_CH0, + MUX_9548_9_CH1, + MUX_9548_9_CH2, + MUX_9548_9_CH3, + MUX_9548_9_CH4, + MUX_9548_9_CH5, + MUX_9548_9_CH6, + MUX_9548_9_CH7, + MUX_9548_10_CH0, + MUX_9548_10_CH1, + MUX_9548_10_CH2, + MUX_9548_10_CH3, + MUX_9548_10_CH4, + MUX_9548_10_CH5, + MUX_9548_10_CH6, + MUX_9548_10_CH7, +}; + +#define I2C_ADDR_MUX_9555_0 (0x20) +#define I2C_ADDR_MUX_9555_1 (0x24) +#define I2C_ADDR_MUX_9555_2 (0x25) +#define I2C_ADDR_MUX_9555_3 (0x26) +#define I2C_ADDR_MUX_9539_0 (0x76) +#define I2C_ADDR_MUX_9539_1 (0x76) +#define I2C_BUS_FAN_STATUS (I2C_BUS_MAIN) +#define I2C_BUS_SYS_LED (MUX_9548_1_CH1) + +#define NUM_OF_I2C_MUX (11) +#define NUM_OF_CPLD (5) +#define NUM_OF_QSFP_PORT (64) +#define NUM_OF_SFP_PORT (2) +#define QSFP_EEPROM_I2C_ADDR (0x50) + +enum gpio_reg { + REG_PORT0_IN, + REG_PORT1_IN, + REG_PORT0_OUT, + REG_PORT1_OUT, + REG_PORT0_POL, + REG_PORT1_POL, + REG_PORT0_DIR, + REG_PORT1_DIR, +}; + +struct ing_i2c_board_info { + int ch; + int size; + struct i2c_board_info *board_info; +}; + +struct i2c_init_data { + __u16 ch; + __u16 addr; + __u8 reg; + __u8 value; +}; + +#endif diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/modules/ingrasys_s9130_32x_psu.c b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/modules/ingrasys_s9130_32x_psu.c new file mode 100644 index 000000000000..d3186a56b95c --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/modules/ingrasys_s9130_32x_psu.c @@ -0,0 +1,407 @@ +/* + * S9130-32x PSU driver + * + * Copyright (C) 2017 Ingrasys, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ingrasys_s9130_32x_platform.h" + +static ssize_t show_psu_eeprom(struct device *dev, + struct device_attribute *da, + char *buf); +static struct s9130_psu_data *s9130_psu_update_status(struct device *dev); +static struct s9130_psu_data *s9130_psu_update_eeprom(struct device *dev); +static int s9130_psu_read_block(struct i2c_client *client, + u8 command, + u8 *data, + int data_len); + + +#define DRIVER_NAME "psu" + +// Addresses scanned +static const unsigned short normal_i2c[] = { 0x50, I2C_CLIENT_END }; + +/* PSU EEPROM SIZE */ +#define EEPROM_SZ 256 +#define READ_EEPROM 1 +#define NREAD_EEPROM 0 + +static struct i2c_client pca9555_client; + +/* pca9555 gpio pin mapping */ +#define PSU2_PWROK 0 +#define PSU2_PRSNT_L 1 +#define PSU2_PWRON_L 2 +#define PSU1_PWROK 3 +#define PSU1_PRSNT_L 4 +#define PSU1_PWRON_L 5 +#define TMP_75_INT_L 6 + +/* Driver Private Data */ +struct s9130_psu_data { + struct device *hwmon_dev; + struct mutex lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 index; /* PSU index */ + s32 status; /* IO expander value */ + char eeprom[EEPROM_SZ]; /* psu eeprom data */ + char psuABS; /* PSU absent */ + char psuPG; /* PSU power good */ +}; + +enum s9130_psu_sysfs_attributes { + PSU_POWER_GOOD, + PSU_ABSENT, + PSU_EEPROM +}; + +enum psu_index +{ + s9130_psu1, + s9130_psu2 +}; + +/* + * display power good attribute + */ +static ssize_t +show_psu_pg(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct s9130_psu_data *data = s9130_psu_update_status(dev); + unsigned int value; + + mutex_lock(&data->lock); + value = data->psuPG; + mutex_unlock(&data->lock); + + return sprintf(buf, "%d\n", value); +} + +/* + * display power absent attribute + */ +static ssize_t +show_psu_abs(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct s9130_psu_data *data = s9130_psu_update_status(dev); + unsigned int value; + + mutex_lock(&data->lock); + value = data->psuABS; + mutex_unlock(&data->lock); + + return sprintf(buf, "%d\n", value); +} + + +/* + * sysfs attributes for psu + */ +static SENSOR_DEVICE_ATTR(psu_pg, S_IRUGO, show_psu_pg, NULL, PSU_POWER_GOOD); +static SENSOR_DEVICE_ATTR(psu_abs, S_IRUGO, show_psu_abs, NULL, PSU_ABSENT); +static SENSOR_DEVICE_ATTR(psu_eeprom, S_IRUGO, show_psu_eeprom, NULL, PSU_EEPROM); + +static struct attribute *s9130_psu_attributes[] = { + &sensor_dev_attr_psu_pg.dev_attr.attr, + &sensor_dev_attr_psu_abs.dev_attr.attr, + &sensor_dev_attr_psu_eeprom.dev_attr.attr, + NULL +}; + +/* + * display psu eeprom content + */ +static ssize_t +show_psu_eeprom(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct s9130_psu_data *data = s9130_psu_update_eeprom(dev); + + memcpy(buf, (char *)data->eeprom, EEPROM_SZ); + return EEPROM_SZ; +} + +static const struct attribute_group s9130_psu_group = { + .attrs = s9130_psu_attributes, +}; + +/* + * check gpio expander is accessible + */ +static int +pca9555_detect(struct i2c_client *client) +{ + if (i2c_smbus_read_byte_data(client, REG_PORT0_DIR) < 0) { + return -ENODEV; + } + + return 0; +} + +/* + * client address init + */ +static void +i2c_devices_client_address_init(struct i2c_client *client) +{ + pca9555_client = *client; + pca9555_client.addr = 0x25; +} + +static int +s9130_psu_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct s9130_psu_data *data; + int status, err; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct s9130_psu_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + memset(data, 0, sizeof(struct s9130_psu_data)); + i2c_set_clientdata(client, data); + data->valid = 0; + data->index = dev_id->driver_data; + mutex_init(&data->lock); + + i2c_devices_client_address_init(client); + + err = pca9555_detect(&pca9555_client); + if (err) { + return err; + } + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &s9130_psu_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &s9130_psu_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int +s9130_psu_remove(struct i2c_client *client) +{ + struct s9130_psu_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &s9130_psu_group); + kfree(data); + + return 0; +} + + +/* + * psu eeprom read utility + */ +static int +s9130_psu_read_block(struct i2c_client *client, + u8 command, + u8 *data, + int data_len) +{ + int i=0, ret=0; + int blk_max = 32; //max block read size + + /* read eeprom, 32 * 8 = 256 bytes */ + for (i=0; i < EEPROM_SZ/blk_max; i++) { + ret = i2c_smbus_read_i2c_block_data(client, (i*blk_max), blk_max, + data + (i*blk_max)); + if (ret < 0) { + return ret; + } + } + return ret; +} + +/* + * update eeprom content + */ +static struct s9130_psu_data +*s9130_psu_update_eeprom(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct s9130_psu_data *data = i2c_get_clientdata(client); + s32 status = 0; + int psu_pwrok = 0; + int psu_prsnt_l = 0; + + mutex_lock(&data->lock); + + if (time_after(jiffies, data->last_updated + 300 * HZ) + || !data->valid) { + + /* Read psu status */ + + status = i2c_smbus_read_word_data(&(pca9555_client), REG_PORT0_IN); + data->status = status; + + /*read psu status from io expander*/ + + if (data->index == s9130_psu1) { + psu_pwrok = PSU1_PWROK; + psu_prsnt_l = PSU1_PRSNT_L; + } else { + psu_pwrok = PSU2_PWROK; + psu_prsnt_l = PSU2_PRSNT_L; + } + data->psuPG = (status >> psu_pwrok) & 0x1; + data->psuABS = (status >> psu_prsnt_l) & 0x1; + + /* Read eeprom */ + if (!data->psuABS) { + //clear local eeprom data + memset(data->eeprom, 0, EEPROM_SZ); + + //read eeprom + status = s9130_psu_read_block(client, 0, data->eeprom, + ARRAY_SIZE(data->eeprom)); + + if (status < 0) { + memset(data->eeprom, 0, EEPROM_SZ); + dev_err(&client->dev, "Read eeprom failed, status=(%d)\n", status); + } else { + data->valid = 1; + } + } else { + memset(data->eeprom, 0, EEPROM_SZ); + } + data->last_updated = jiffies; + } + + mutex_unlock(&data->lock); + + return data; +} + +/* + * update psu status + */ +static struct s9130_psu_data +*s9130_psu_update_status(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct s9130_psu_data *data = i2c_get_clientdata(client); + s32 status = 0; + int psu_pwrok = 0; + int psu_prsnt_l = 0; + + mutex_lock(&data->lock); + + /* Read psu status */ + + status = i2c_smbus_read_word_data(&(pca9555_client), REG_PORT0_IN); + data->status = status; + + /*read psu status from io expander*/ + + if (data->index == s9130_psu1) { + psu_pwrok = PSU1_PWROK; + psu_prsnt_l = PSU1_PRSNT_L; + } else { + psu_pwrok = PSU2_PWROK; + psu_prsnt_l = PSU2_PRSNT_L; + } + data->psuPG = (status >> psu_pwrok) & 0x1; + data->psuABS = (status >> psu_prsnt_l) & 0x1; + + mutex_unlock(&data->lock); + + return data; +} + +static const struct i2c_device_id s9130_psu_id[] = { + { "psu1", s9130_psu1 }, + { "psu2", s9130_psu2 }, + {} +}; + +MODULE_DEVICE_TABLE(i2c, s9130_psu_id); + +static struct i2c_driver s9130_psu_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = DRIVER_NAME, + }, + .probe = s9130_psu_probe, + .remove = s9130_psu_remove, + .id_table = s9130_psu_id, + .address_list = normal_i2c, +}; + +static int __init s9130_psu_init(void) +{ + return i2c_add_driver(&s9130_psu_driver); +} + +static void __exit s9130_psu_exit(void) +{ + i2c_del_driver(&s9130_psu_driver); +} + +module_init(s9130_psu_init); +module_exit(s9130_psu_exit); + +MODULE_AUTHOR("Jason Tsai "); +MODULE_DESCRIPTION("S9130-32X psu driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/service/qsfp-monitor.service b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/service/qsfp-monitor.service new file mode 100644 index 000000000000..10b48f648b98 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/service/qsfp-monitor.service @@ -0,0 +1,15 @@ +[Unit] +Description= This QSFP Monitor service is to setup QSFP SI. +Requires=s9130-32x-monitor.service +After=s9130-32x-monitor.service + +[Service] +ExecStart=/usr/sbin/qsfp_monitor.sh +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/service/s9130-32x-monitor.service b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/service/s9130-32x-monitor.service new file mode 100644 index 000000000000..3163b0af6f12 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/service/s9130-32x-monitor.service @@ -0,0 +1,19 @@ +[Unit] +Description= This Platform Monitor service is to initialize platform and monitor platform. +Before=platform-monitor.service +After=sysinit.target +Wants=fancontrol.service +Wants=qsfp-monitor.service +DefaultDependencies=no + +[Service] +ExecStartPre=/usr/sbin/i2c_utils.sh i2c_init +ExecStart=/usr/sbin/s9130_32x_monitor.sh +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/i2c_utils.sh b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/i2c_utils.sh new file mode 100644 index 000000000000..71da18f6cab0 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/i2c_utils.sh @@ -0,0 +1,1685 @@ +#!/bin/bash + +# Copyright (C) 2016 Ingrasys, 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 3 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, see . + +# trun on for more debug output +#DEBUG="on" + +VERSION="1.0.0" +TRUE=200 +FALSE=404 + +EXEC_FUNC=${1} +COLOR_LED=${2} +QSFP_PORT=${2} +QSFP_ACTION=${2} +MB_EEPROM_ACTION=${2} +ONOFF_LED=${3} +FAN_TRAY=${4} + +############################################################ +# Distributor ID: Debian +# Description: Debian GNU/Linux 8.6 (jessie) +# Release: 8.6 +# Codename: jessie +# Linux debian 3.16.0-4-amd64 #1 +# SMP Debian 3.16.36-1+deb8u1 (2016-09-03) x86_64 GNU/Linux +############################################################ + +# Color Definition +COLOR_TITLE="\e[1;32m" ### Green ### +COLOR_WARNING="\e[1;33m" ### Yellow ### +COLOR_ERROR="\e[1;31m" ### Red ### +COLOR_END="\e[0m" ### END ### + +NUM_I801_DEVICE=0 + +# MAIN MUX PCA9548#0 0x75 +NUM_MUX_9548_0_CH0=$(( ${NUM_I801_DEVICE} + 1 )) # ucd9090 0x34 +NUM_MUX_9548_0_CH1=$(( ${NUM_I801_DEVICE} + 2 )) # PCA9539 0x77 for fp LED & HW ID +NUM_MUX_9548_0_CH7=$(( ${NUM_I801_DEVICE} + 8 )) # W83795 0x2E + +# FRU MUX PCA9545#1 0x72 +NUM_MUX_9545_1_CH0=$(( ${NUM_I801_DEVICE} + 9 )) # PSU1 0x50 +NUM_MUX_9545_1_CH1=$(( ${NUM_I801_DEVICE} + 10 )) # PSU2 0x50 +NUM_MUX_9545_1_CH2=$(( ${NUM_I801_DEVICE} + 11 )) # FAN board IO exander 0x20 +NUM_MUX_9545_1_CH3=$(( ${NUM_I801_DEVICE} + 12 )) # TMP75#0 0x48 TMP75#1 0x49 + +# HOST MUX PCA9548#2 0X70 +NUM_MUX_9548_2_CH0=$(( ${NUM_I801_DEVICE} + 13 )) # PCA9548#3 0x71 +NUM_MUX_9548_2_CH1=$(( ${NUM_I801_DEVICE} + 14 )) # PCA9548#4 0x71 +NUM_MUX_9548_2_CH2=$(( ${NUM_I801_DEVICE} + 15 )) # PCA9548#5 0x71 +NUM_MUX_9548_2_CH3=$(( ${NUM_I801_DEVICE} + 16 )) # PCA9548#6 0x71 +NUM_MUX_9548_2_CH4=$(( ${NUM_I801_DEVICE} + 17 )) # PCA9535#3~6 0x20~0x23 ZQSFP ABS/INT +NUM_MUX_9548_2_CH5=$(( ${NUM_I801_DEVICE} + 18 )) # PCA9535#7~10 0x20~0x23 ZQSFP LPMODE/RST +NUM_MUX_9548_3_CH0=$(( ${NUM_I801_DEVICE} + 21 )) # QSFP 0 EEPROM +NUM_MUX_9548_4_CH0=$(( ${NUM_I801_DEVICE} + 29 )) # QSFP 8 EEPROM +NUM_MUX_9548_5_CH0=$(( ${NUM_I801_DEVICE} + 37 )) # QSFP 16 EEPROM +NUM_MUX_9548_6_CH0=$(( ${NUM_I801_DEVICE} + 45 )) # QSFP 24 EEPROM + +# MUX Alias +I2C_BUS_MAIN=${NUM_I801_DEVICE} +I2C_BUS_HWM=${NUM_MUX_9548_0_CH7} +I2C_BUS_FAN_STATUS=${NUM_MUX_9545_1_CH2} +I2C_BUS_SYS_LED=${NUM_MUX_9548_0_CH1} +I2C_BUS_HW_ID=${NUM_MUX_9548_0_CH1} +I2C_BUS_BMC_HW_ID=${I2C_BUS_MAIN} +I2C_BUS_PSU_STAT=${I2C_BUS_MAIN} +I2C_BUS_FANTRAY_LED=${NUM_MUX_9545_1_CH2} +I2C_BUS_MB_EEPROM=${I2C_BUS_MAIN} +I2C_BUS_CB_EEPROM=${I2C_BUS_MAIN} +I2C_BUS_PSU1_EEPROM=${NUM_MUX_9545_1_CH1} +I2C_BUS_PSU2_EEPROM=${NUM_MUX_9545_1_CH0} + +PATH_SYS_I2C_DEVICES="/sys/bus/i2c/devices" +PATH_HWMON_ROOT_DEVICES="/sys/class/hwmon" +PATH_HWMON_W83795_DEVICE="${PATH_HWMON_ROOT_DEVICES}/hwmon5" +PATH_I801_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_I801_DEVICE}" +PATH_MUX_9548_0_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_0_CH0}" +PATH_MUX_9548_0_CH1="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_0_CH1}" +PATH_MUX_9548_0_CH7="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_0_CH7}" +PATH_MUX_9545_1_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9545_1_CH0}" +PATH_MUX_9545_1_CH1="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9545_1_CH1}" +PATH_MUX_9545_1_CH2="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9545_1_CH2}" +PATH_MUX_9545_1_CH3="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9545_1_CH3}" +PATH_MUX_9548_2_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_2_CH0}" +PATH_MUX_9548_2_CH1="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_2_CH1}" +PATH_MUX_9548_2_CH2="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_2_CH2}" +PATH_MUX_9548_2_CH3="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_2_CH3}" +PATH_MUX_9548_2_CH4="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_2_CH4}" +PATH_MUX_9548_2_CH5="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_2_CH5}" +PATH_MUX_9548_3_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_3_CH0}" +PATH_MUX_9548_4_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_4_CH0}" +PATH_MUX_9548_5_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_5_CH0}" +PATH_MUX_9548_6_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_6_CH0}" + +# I2C Address +### I2C MUX +I2C_ADDR_MUX_9548_0=0x73 # MAIN MUX +I2C_ADDR_MUX_9545_1=0x72 # FRU MUX +I2C_ADDR_MUX_9548_2=0x70 # HOST MUX +I2C_ADDR_MUX_9548_3=0x71 # ZQSFP MUX #1 EEPROM +I2C_ADDR_MUX_9548_4=0x71 # ZQSFP MUX #2 EEPROM +I2C_ADDR_MUX_9548_5=0x71 # ZQSFP MUX #3 EEPROM +I2C_ADDR_MUX_9548_6=0x71 # ZQSFP MUX #4 EEPROM +### GPIO Expander +I2C_ADDR_MUX_9539_0=0x76 # LED & HW ID +I2C_ADDR_MUX_9539_1=0x75 # BMC PRSNT & HWM reset +I2C_ADDR_MUX_9539_2=0x74 # SYS SEL & RST +I2C_ADDR_MUX_9535_3=0x20 # ZQSFP0~15 ABS +I2C_ADDR_MUX_9535_4=0x21 # ZQSFP16~31 ABS +I2C_ADDR_MUX_9535_5=0x22 # ZQSFP0~15 INT +I2C_ADDR_MUX_9535_6=0x23 # ZQSFP16~31 INT +I2C_ADDR_MUX_9535_7=0x20 # ZQSFP0~15 LPMODE +I2C_ADDR_MUX_9535_8=0x21 # ZQSFP16~31 LPMODE +I2C_ADDR_MUX_9535_9=0x22 # ZQSFP0~15 RST +I2C_ADDR_MUX_9535_10=0x23 # ZQSFP16~31 RST +I2C_ADDR_MUX_9535_11=0x20 # on FAN board, fan status and led config +I2C_ADDR_MUX_9555_12=0x24 # on BMC board, INT and HW ID +I2C_ADDR_MUX_9555_13=0x25 # on BMC board, PSU status +I2C_ADDR_MUX_9555_14=0x26 # on BMC board, RST and SEL +I2C_ADDR_MUX_9539_15=0x77 # on CPU board, STATUS and ERR from CPLD +### peripheral +I2C_ADDR_MB_EEPROM=0x55 # on main board +I2C_ADDR_CB_EEPROM=0x51 # on cpu board +I2C_ADDR_UCD9090=0x34 +I2C_ADDR_W83795=0x2F +I2C_ADDR_PSU1_EEPROM=0x50 +I2C_ADDR_PSU2_EEPROM=0x50 +I2C_ADDR_TMP75_REAR=0x4C +I2C_ADDR_TMP75_FRONT=0x49 +I2C_ADDR_TMP75_CB=0x4F # on cpu board +I2C_ADDR_TMP75_BB=0x4A # on bmc board +I2C_ADDR_QSFP_EEPROM=0x50 + +#sysfs +PATH_SYSFS_PSU1="${PATH_SYS_I2C_DEVICES}/${I2C_BUS_PSU1_EEPROM}-$(printf "%04x" $I2C_ADDR_PSU1_EEPROM)" +PATH_SYSFS_PSU2="${PATH_SYS_I2C_DEVICES}/${I2C_BUS_PSU2_EEPROM}-$(printf "%04x" $I2C_ADDR_PSU2_EEPROM)" + +#ACTIVE LOW enable flag +ACTIVE_LOW_EN=1 +ACTIVE_HIGH_EN=0 +#GPIO Direction In/Out +DIR_IN=in +DIR_OUT=out + +#Power Supply Status +PSU_DC_ON=1 +PSU_DC_OFF=0 +PSU_EXIST=1 +PSU_NOT_EXIST=0 + +# IO expander register +# direction +REG_PORT0_DIR=6 +REG_PORT1_DIR=7 +# polarity +REG_PORT0_POL=4 +REG_PORT1_POL=5 +# output +REG_PORT0_OUT=2 +REG_PORT1_OUT=3 +# input +REG_PORT0_IN=0 +REG_PORT1_IN=1 + +#ZQSFP GPIO sysfs index +ZQSFP_PORT0_ABS_GPIO_IDX=240 # 240~255 +ZQSFP_PORT16_ABS_GPIO_IDX=224 # 224~239 + +# switch port number range +MIN_PORT_NUM=1 +MAX_PORT_NUM=32 + +# Help usage function +function _help { + echo "=========================================================" + echo "# Description: Help Function" + echo "=========================================================" + echo "----------------------------------------------------" + echo "EX : ${0} help" + echo " : ${0} i2c_init" + echo " : ${0} i2c_deinit" + echo " : ${0} i2c_fan_speed_init" + echo " : ${0} i2c_io_exp_init" + echo " : ${0} i2c_gpio_init" + echo " : ${0} i2c_gpio_deinit" + echo " : ${0} i2c_led_test" + echo " : ${0} i2c_psu_eeprom_get" + echo " : ${0} i2c_mb_eeprom_get" + echo " : ${0} i2c_cb_eeprom_get" + echo " : ${0} i2c_eeprom_sync" + echo " : ${0} i2c_qsfp_eeprom_get [1-32]" + echo " : ${0} i2c_qsfp_eeprom_init new|delete" + echo " : ${0} i2c_mb_eeprom_init new|delete" + echo " : ${0} i2c_cb_eeprom_init new|delete" + echo " : ${0} i2c_qsfp_status_get [1-32]" + echo " : ${0} i2c_qsfp_type_get [1-32]" + echo " : ${0} i2c_board_type_get" + echo " : ${0} i2c_bmc_board_type_get" + echo " : ${0} i2c_psu_status" + echo " : ${0} i2c_led_psu_status_set" + echo " : ${0} i2c_led_fan_status_set" + echo " : ${0} i2c_led_fan_tray_status_set" + echo " : ${0} i2c_test_all" + echo " : ${0} i2c_sys_led green|amber" + echo " : ${0} i2c_fan_led green|amber on|off" + echo " : ${0} i2c_psu1_led green|amber on|off" + echo " : ${0} i2c_psu2_led green|amber on|off" + echo " : ${0} i2c_fan_tray_led green|amber on|off [1-4]" + echo "----------------------------------------------------" +} + +#Pause function +function _pause { + read -p "$*" +} + +#Retry command function +function _retry { + local i + for i in {1..5}; + do + eval "${*}" && break || echo "retry"; sleep 1; + done +} + +#I2C Init +function _i2c_init { + echo "=========================================================" + echo "# Description: I2C Init" + echo "=========================================================" + + #rmmod i2c_ismt + _util_rmmod i2c_i801 + modprobe i2c_i801 disable_features=0x10 + modprobe i2c_dev + modprobe i2c_mux_pca954x force_deselect_on_exit=1 + + # add MUX PCA9548#0 on I801, assume to be i2c-1~8 + if [ ! -e ${PATH_MUX_9548_0_CH0} ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_0}' > ${PATH_I801_DEVICE}/new_device" + else + echo "pca9548 ${I2C_ADDR_MUX_9548_0} already init." + fi + # add MUX PCA9545#1 on I801, assume to be i2c-9~12 + if [ ! -e ${PATH_MUX_9545_1_CH0} ]; then + _retry "echo 'pca9545 ${I2C_ADDR_MUX_9545_1}' > ${PATH_I801_DEVICE}/new_device" + else + echo "pca9545 ${I2C_ADDR_MUX_9545_1} already init." + fi + # add MUX PCA9548#2 on I801, assume to be i2c-13~20 + if [ ! -e ${PATH_MUX_9548_2_CH0} ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_2}' > ${PATH_I801_DEVICE}/new_device" + else + echo "pca9548 ${I2C_ADDR_MUX_9548_2} already init." + fi + # add MUX PCA9548#3 on PCA9548#2 CH0, assume to be i2c-21~28 + if [ ! -e ${PATH_MUX_9548_3_CH0} ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_3}' > ${PATH_MUX_9548_2_CH0}/new_device" + else + echo "pca9548 ${I2C_ADDR_MUX_9548_3} already init." + fi + # add MUX PCA9548#4 on PCA9548#2 CH1, assume to be i2c-29~36 + if [ ! -e ${PATH_MUX_9548_4_CH0} ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_4}' > ${PATH_MUX_9548_2_CH1}/new_device" + else + echo "pca9548 ${I2C_ADDR_MUX_9548_4} already init." + fi + # add MUX PCA9548#5 on PCA9548#2 CH2, assume to be i2c-37~44 + if [ ! -e ${PATH_MUX_9548_5_CH0} ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_5}' > ${PATH_MUX_9548_2_CH2}/new_device" + else + echo "pca9548 ${I2C_ADDR_MUX_9548_5} already init." + fi + # add MUX PCA9548#6 on PCA9548#2 CH3, assume to be i2c-45~52 + if [ ! -e ${PATH_MUX_9548_6_CH0} ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_6}' > ${PATH_MUX_9548_2_CH3}/new_device" + else + echo "pca9548 ${I2C_ADDR_MUX_9548_6} already init." + fi + + _i2c_hwm_init + _util_rmmod eeprom + modprobe eeprom_mb + modprobe gpio-pca953x + _i2c_io_exp_init + _i2c_gpio_init + _i2c_sensors_init + _i2c_psu_init + + # Init LED_CLR register (pull shift register out of reset), should be after io exp init + _port_led_clr_init + _i2c_qsfp_eeprom_init "new" + _i2c_mb_eeprom_init "new" + _i2c_cb_eeprom_init "new" + _i2c_fan_speed_init + _i2c_led_psu_status_set + _i2c_led_fan_status_set + + # sync eeprom content + _i2c_eeprom_sync + + # trun on sys led + echo "led_sys setup..." + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_sys_led + + _config_rmem +} + +#I2C Deinit +function _i2c_deinit { + echo "i2c deinit..." + _i2c_gpio_deinit + for mod in coretemp jc42 w83795 eeprom eeprom_mb gpio-pca953x i2c_mux_pca954x i2c_i801 ingrasys_s9130_32x_psu; + do + _util_rmmod $mod + done + echo "Done" +} + +function _i2c_sensors_init { + echo "SENSORS init..." + local dev_path + # to make sure hwmon index in sysfs as expected, + # need to remove kernel module and then probe them in expected order + # remove all sensors kernel module + _util_rmmod coretemp + _util_rmmod jc42 + _util_rmmod w83795 + # probe coretemp kernel module + modprobe coretemp + # probe hwmon kernel module + modprobe w83795 + # add tmp75 to sysfs + ####Main board thermal + dev_path="${PATH_SYS_I2C_DEVICES}/${NUM_MUX_9545_1_CH3}-$(printf "%04x" ${I2C_ADDR_TMP75_REAR})" + if ! [ -L ${dev_path} ]; then + echo "tmp75 ${I2C_ADDR_TMP75_REAR}" > ${PATH_MUX_9545_1_CH3}/new_device # hwmon1 + else + echo "${dev_path} already exist" + fi + dev_path="${PATH_SYS_I2C_DEVICES}/${NUM_MUX_9545_1_CH3}-$(printf "%04x" ${I2C_ADDR_TMP75_FRONT})" + if ! [ -L ${dev_path} ]; then + echo "tmp75 ${I2C_ADDR_TMP75_FRONT}" > ${PATH_MUX_9545_1_CH3}/new_device #hwmon2 + else + echo "${dev_path} already exist" + fi + ####BMC board thermal + dev_path="${PATH_SYS_I2C_DEVICES}/${NUM_MUX_9548_0_CH7}-$(printf "%04x" ${I2C_ADDR_TMP75_BB})" + if ! [ -L ${dev_path} ]; then + echo "tmp75 ${I2C_ADDR_TMP75_BB}" > ${PATH_MUX_9548_0_CH7}/new_device #hwmon3 + else + echo "${dev_path} already exist" + fi + ####CPU board thermal + dev_path="${PATH_SYS_I2C_DEVICES}/${I2C_BUS_MAIN}-$(printf "%04x" ${I2C_ADDR_TMP75_CB})" + if ! [ -L ${dev_path} ]; then + echo "tmp75 ${I2C_ADDR_TMP75_CB}" > ${PATH_I801_DEVICE}/new_device #hwmon4 + else + echo "${dev_path} already exist" + fi + # add w83795 to sysfs + dev_path="${PATH_SYS_I2C_DEVICES}/${NUM_MUX_9548_0_CH7}-$(printf "%04x" ${I2C_ADDR_W83795})" + if ! [ -L ${dev_path} ]; then + echo "w83795adg ${I2C_ADDR_W83795}" > ${PATH_MUX_9548_0_CH7}/new_device #hwmon5 + else + echo "${dev_path} already exist" + fi + + # probe jc42 kernel module + modprobe jc42 + + echo "Done" +} + +function _port_led_clr_init { + echo "port led init..." + # gpio pin on GPIO MUX PCA9539#2 I/O 0.2 + # pull high to out of reset + output_reg=${REG_PORT0_OUT} + mask=0x04 + value=0x04 + _util_i2cset -m ${mask} -y ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9539_2} ${output_reg} ${value} + echo "Done" +} + +#FAN Speed Init +function _i2c_fan_speed_init { + echo -n "FAN SPEED INIT..." + if [ -e "${PATH_HWMON_W83795_DEVICE}" ]; then + # init fan speed + echo 120 > ${PATH_HWMON_W83795_DEVICE}/device/pwm1 + echo 120 > ${PATH_HWMON_W83795_DEVICE}/device/pwm2 + echo "SUCCESS" + else + echo "FAIL" + fi +} + +# HWM init +function _i2c_hwm_init { + echo "HWM INIT..." + # select bank0 + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x00 0x80 + # SW reset, Disable monitor + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x01 0x9C + # disable TR5/TR6 DTS + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x04 0x0 + # enable FANIN1~8 + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x06 0xFF + # disable FANIN9~14 + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x07 0x00 + # CLKIN clock frequency set as 48Mhz + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x01 0x1C + # select bank 2 + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x00 0x82 + # set PWM mode in FOMC + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x0F 0x00 + # set 25KHz fan output frequency in F1OPFP&F2OPFP + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x18 0x84 + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x19 0x84 +} + +#Temperature sensor Init +function _i2c_temp_init { + echo "TEMP INIT..." + # enable temp monitor on w83795 + # select bank0 + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x00 0x80 + # enable TR4 temperature monitoring + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x05 0x40 + # disable TR5/TR6 DTS + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x04 0x0 + echo "Done" +} + +#VOLMON Init +function _i2c_volmon_init { + echo "VOLMON INIT..." + # enable voltage monitor on w83795 + # VSEN1 P0V9 + # VSEN2 VDD + # VSEN3 P1V2 + # VSEN4 P1V8 + # select bank0 + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x00 0x80 + # enable vsen1~4, disable vsen5~8 + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x02 0x0F + # enable 3VDD,VBAT + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x03 0x50 + echo "Done" +} + +#FANIN Init +function _i2c_fan_init { + echo "FANIN INIT..." + # enable fan monitor on w83795 + # 4 fantray with 8 FANIN + # select bank0 + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x00 0x80 + # enable FANIN1~8 + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x06 0xFF + # disable FANIN9~14 + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x07 0x00 + + # select bank 2 + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x00 0x82 + # set PWM mode in FOMC + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x0F 0x00 + + echo "Done" +} + +#IO Expander Init +function _i2c_io_exp_init { + echo "=========================================================" + echo "# Description: I2C IO Expender Init" + echo "=========================================================" + + # need to init BMC io expander first due to some io expander are reset default + echo "Init BMC INT & HW ID IO Expander" + # all input + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_12} ${REG_PORT0_DIR} 0xFF + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_12} ${REG_PORT1_DIR} 0xFF + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_12} ${REG_PORT0_POL} 0x00 + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_12} ${REG_PORT1_POL} 0x00 + + echo "Init BMC PSU status IO Expander" + # PWRON default 0 (ACTIVE_LOW) + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_13} ${REG_PORT0_OUT} 0x00 + # default 0 (ACTIVE_LOW) + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_13} ${REG_PORT1_OUT} 0x00 + # I/O 0.2 0.5 output(PWRON), rest input + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_13} ${REG_PORT0_DIR} 0xDB + # I/O 1.0~1.1 input, 1.2~1.4 output (1.5~1.7 not enable) + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_13} ${REG_PORT1_DIR} 0xE3 + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_13} ${REG_PORT0_POL} 0x00 + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_13} ${REG_PORT1_POL} 0x00 + + echo "Init BMC RST and SEL IO Expander" + # RST default is 1 (ACTIVE_LOW) + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_14} ${REG_PORT0_OUT} 0x3F + # SEL default is 0 (HOST), EN default is 1 (ACTIVE_HIGH) + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_14} ${REG_PORT1_OUT} 0x1F + # I/O 0.0~0.5 output, 0.6~0.7 not use + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_14} ${REG_PORT0_DIR} 0xC0 + # all output + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_14} ${REG_PORT1_DIR} 0x00 + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_14} ${REG_PORT0_POL} 0x00 + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_14} ${REG_PORT1_POL} 0x00 + + echo "Init System LED & HW ID IO Expander" + # I/O_0.x for System LED default 0, I/O_1.x for HW ID + _util_i2cset -y -r ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${REG_PORT0_OUT} 0x00 + # System LED => all output + _util_i2cset -y -r ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${REG_PORT0_DIR} 0x00 + # HW ID => all input + _util_i2cset -y -r ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${REG_PORT1_DIR} 0xFF + _util_i2cset -y -r ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${REG_PORT0_POL} 0x00 + _util_i2cset -y -r ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${REG_PORT1_POL} 0x00 + + echo "Init System PRSNT and HWM RST IO Expander" + # HWM_RST_L default 1 (ACTIVE_LOW) + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9539_1} ${REG_PORT0_OUT} 0x04 + # all input expect HWM_RST_L (0.2) + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9539_1} ${REG_PORT0_DIR} 0xFB + # port1 not used + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9539_1} ${REG_PORT1_DIR} 0x00 + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9539_1} ${REG_PORT0_POL} 0x00 + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9539_1} ${REG_PORT1_POL} 0x00 + + echo "Init System SEL and RST IO Expander" + # RST 0.0~0.3 default 1 (ACTIVE low), rest default 0 + # SEL set to value 0 (host) + # LED_CLR also do init in _port_led_clr_init + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9539_2} ${REG_PORT0_OUT} 0x0F + # RST 1.6~1.7 default 1 (ACTIVE low), INT 1.0~1.4 default 1 (ACTIVE low) + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9539_2} ${REG_PORT1_OUT} 0xDF + # all output, but MAC_RST_L 0.0 need to set as input to prevent reboot issue + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9539_2} ${REG_PORT0_DIR} 0x09 + # RST 1.5 !~ 1.7 output, rest are input + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9539_2} ${REG_PORT1_DIR} 0x1F + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9539_2} ${REG_PORT0_POL} 0x00 + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9539_2} ${REG_PORT1_POL} 0x00 + + echo "Init FAN Board Status IO Expander" + # LED_G_L set to 0, LED_Y_L set to 1 (ACTIVE_LOW) + _util_i2cset -y -r ${I2C_BUS_FAN_STATUS} ${I2C_ADDR_MUX_9535_11} ${REG_PORT0_OUT} 0x22 + _util_i2cset -y -r ${I2C_BUS_FAN_STATUS} ${I2C_ADDR_MUX_9535_11} ${REG_PORT1_OUT} 0x22 + # DIR/ABS is input, LED_Y/LED_G is output + _util_i2cset -y -r ${I2C_BUS_FAN_STATUS} ${I2C_ADDR_MUX_9535_11} ${REG_PORT0_DIR} 0xCC + _util_i2cset -y -r ${I2C_BUS_FAN_STATUS} ${I2C_ADDR_MUX_9535_11} ${REG_PORT1_DIR} 0xCC + _util_i2cset -y -r ${I2C_BUS_FAN_STATUS} ${I2C_ADDR_MUX_9535_11} ${REG_PORT0_POL} 0x00 + _util_i2cset -y -r ${I2C_BUS_FAN_STATUS} ${I2C_ADDR_MUX_9535_11} ${REG_PORT1_POL} 0x00 + + echo "Init CPU CPLD IO Expander" + # all input + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9539_15} ${REG_PORT0_DIR} 0xFF + # all input + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9539_15} ${REG_PORT1_DIR} 0xFF + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9539_15} ${REG_PORT0_POL} 0x00 + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9539_15} ${REG_PORT1_POL} 0x00 + + echo "Init ZQSFP IO Expender" + + echo "set ZQSFP ABS" + #zQSFP 0-15 ABS + # all input + _util_i2cset -y -r ${NUM_MUX_9548_2_CH4} ${I2C_ADDR_MUX_9535_3} ${REG_PORT0_DIR} 0xFF + _util_i2cset -y -r ${NUM_MUX_9548_2_CH4} ${I2C_ADDR_MUX_9535_3} ${REG_PORT1_DIR} 0xFF + _util_i2cset -y -r ${NUM_MUX_9548_2_CH4} ${I2C_ADDR_MUX_9535_3} ${REG_PORT0_POL} 0x00 + _util_i2cset -y -r ${NUM_MUX_9548_2_CH4} ${I2C_ADDR_MUX_9535_3} ${REG_PORT1_POL} 0x00 + #zQSFP 16-31 ABS + # all input + _util_i2cset -y -r ${NUM_MUX_9548_2_CH4} ${I2C_ADDR_MUX_9535_4} ${REG_PORT0_DIR} 0xFF + _util_i2cset -y -r ${NUM_MUX_9548_2_CH4} ${I2C_ADDR_MUX_9535_4} ${REG_PORT1_DIR} 0xFF + _util_i2cset -y -r ${NUM_MUX_9548_2_CH4} ${I2C_ADDR_MUX_9535_4} ${REG_PORT0_POL} 0x00 + _util_i2cset -y -r ${NUM_MUX_9548_2_CH4} ${I2C_ADDR_MUX_9535_4} ${REG_PORT1_POL} 0x00 + + echo "set ZQSFP INT" + #zQSFP 0-15 INT + # all input + _util_i2cset -y -r ${NUM_MUX_9548_2_CH4} ${I2C_ADDR_MUX_9535_5} ${REG_PORT0_DIR} 0xFF + _util_i2cset -y -r ${NUM_MUX_9548_2_CH4} ${I2C_ADDR_MUX_9535_5} ${REG_PORT1_DIR} 0xFF + _util_i2cset -y -r ${NUM_MUX_9548_2_CH4} ${I2C_ADDR_MUX_9535_5} ${REG_PORT0_POL} 0x00 + _util_i2cset -y -r ${NUM_MUX_9548_2_CH4} ${I2C_ADDR_MUX_9535_5} ${REG_PORT1_POL} 0x00 + #zQSFP 16-31 INT + # all input + _util_i2cset -y -r ${NUM_MUX_9548_2_CH4} ${I2C_ADDR_MUX_9535_6} ${REG_PORT0_DIR} 0xFF + _util_i2cset -y -r ${NUM_MUX_9548_2_CH4} ${I2C_ADDR_MUX_9535_6} ${REG_PORT1_DIR} 0xFF + _util_i2cset -y -r ${NUM_MUX_9548_2_CH4} ${I2C_ADDR_MUX_9535_6} ${REG_PORT0_POL} 0x00 + _util_i2cset -y -r ${NUM_MUX_9548_2_CH4} ${I2C_ADDR_MUX_9535_6} ${REG_PORT1_POL} 0x00 + + echo "set ZQSFP LP_MODE = 0" + #ZQSFP 0-15 LP_MODE + # default is 0 + _util_i2cset -y -r ${NUM_MUX_9548_2_CH5} ${I2C_ADDR_MUX_9535_7} ${REG_PORT0_OUT} 0x00 + _util_i2cset -y -r ${NUM_MUX_9548_2_CH5} ${I2C_ADDR_MUX_9535_7} ${REG_PORT1_OUT} 0x00 + # all output + _util_i2cset -y -r ${NUM_MUX_9548_2_CH5} ${I2C_ADDR_MUX_9535_7} ${REG_PORT0_DIR} 0x00 + _util_i2cset -y -r ${NUM_MUX_9548_2_CH5} ${I2C_ADDR_MUX_9535_7} ${REG_PORT1_DIR} 0x00 + _util_i2cset -y -r ${NUM_MUX_9548_2_CH5} ${I2C_ADDR_MUX_9535_7} ${REG_PORT0_POL} 0x00 + _util_i2cset -y -r ${NUM_MUX_9548_2_CH5} ${I2C_ADDR_MUX_9535_7} ${REG_PORT1_POL} 0x00 + #ZQSFP 16-31 LP_MODE + # default is 0 + _util_i2cset -y -r ${NUM_MUX_9548_2_CH5} ${I2C_ADDR_MUX_9535_8} ${REG_PORT0_OUT} 0x00 + _util_i2cset -y -r ${NUM_MUX_9548_2_CH5} ${I2C_ADDR_MUX_9535_8} ${REG_PORT1_OUT} 0x00 + # all output + _util_i2cset -y -r ${NUM_MUX_9548_2_CH5} ${I2C_ADDR_MUX_9535_8} ${REG_PORT0_DIR} 0x00 + _util_i2cset -y -r ${NUM_MUX_9548_2_CH5} ${I2C_ADDR_MUX_9535_8} ${REG_PORT1_DIR} 0x00 + _util_i2cset -y -r ${NUM_MUX_9548_2_CH5} ${I2C_ADDR_MUX_9535_8} ${REG_PORT0_POL} 0x00 + _util_i2cset -y -r ${NUM_MUX_9548_2_CH5} ${I2C_ADDR_MUX_9535_8} ${REG_PORT1_POL} 0x00 + + echo "set ZQSFP RST = 1" + #ZQSFP 0-15 RST + # default is 1 (ACTIVE_LOW) + _util_i2cset -y -r ${NUM_MUX_9548_2_CH5} ${I2C_ADDR_MUX_9535_9} ${REG_PORT0_OUT} 0xFF + _util_i2cset -y -r ${NUM_MUX_9548_2_CH5} ${I2C_ADDR_MUX_9535_9} ${REG_PORT1_OUT} 0xFF + # all output + _util_i2cset -y -r ${NUM_MUX_9548_2_CH5} ${I2C_ADDR_MUX_9535_9} ${REG_PORT0_DIR} 0x00 + _util_i2cset -y -r ${NUM_MUX_9548_2_CH5} ${I2C_ADDR_MUX_9535_9} ${REG_PORT1_DIR} 0x00 + _util_i2cset -y -r ${NUM_MUX_9548_2_CH5} ${I2C_ADDR_MUX_9535_9} ${REG_PORT0_POL} 0x00 + _util_i2cset -y -r ${NUM_MUX_9548_2_CH5} ${I2C_ADDR_MUX_9535_9} ${REG_PORT1_POL} 0x00 + #ZQSFP 16-31 RST + # default is 1 (ACTIVE_LOW) + _util_i2cset -y -r ${NUM_MUX_9548_2_CH5} ${I2C_ADDR_MUX_9535_10} ${REG_PORT0_OUT} 0xFF + _util_i2cset -y -r ${NUM_MUX_9548_2_CH5} ${I2C_ADDR_MUX_9535_10} ${REG_PORT1_OUT} 0xFF + # all output + _util_i2cset -y -r ${NUM_MUX_9548_2_CH5} ${I2C_ADDR_MUX_9535_10} ${REG_PORT0_DIR} 0x00 + _util_i2cset -y -r ${NUM_MUX_9548_2_CH5} ${I2C_ADDR_MUX_9535_10} ${REG_PORT1_DIR} 0x00 + _util_i2cset -y -r ${NUM_MUX_9548_2_CH5} ${I2C_ADDR_MUX_9535_10} ${REG_PORT0_POL} 0x00 + _util_i2cset -y -r ${NUM_MUX_9548_2_CH5} ${I2C_ADDR_MUX_9535_10} ${REG_PORT1_POL} 0x00 + +} + +#GPIO Init +function _i2c_gpio_init { + local i=0 + local start=255 + local end=255 + local ch_num=16 + + #ABS Port 0-15 + echo "pca9535 ${I2C_ADDR_MUX_9535_3}" > ${PATH_MUX_9548_2_CH4}/new_device + start=$[ ${end}-${ch_num}+1] + for (( i=$start; i<=$end; i++ )) + do + _util_gpio_export ${i} ${DIR_IN} ${ACTIVE_LOW_EN} + done + + #ABS Port 16-31 + end=$[ ${start}-1] + echo "pca9535 ${I2C_ADDR_MUX_9535_4}" > ${PATH_MUX_9548_2_CH4}/new_device + start=$[ ${end}-${ch_num}+1] + for (( i=$start; i<=$end; i++ )) + do + _util_gpio_export ${i} ${DIR_IN} ${ACTIVE_LOW_EN} + done + + #INT Port 0-15 + end=$[ ${start}-1] + echo "pca9535 ${I2C_ADDR_MUX_9535_5}" > ${PATH_MUX_9548_2_CH4}/new_device + start=$[ ${end}-${ch_num}+1] + for (( i=$start; i<=$end; i++ )) + do + _util_gpio_export ${i} ${DIR_IN} ${ACTIVE_LOW_EN} + done + + #INT Port 16-31 + end=$[ ${start}-1] + echo "pca9535 ${I2C_ADDR_MUX_9535_6}" > ${PATH_MUX_9548_2_CH4}/new_device + start=$[ ${end}-${ch_num}+1] + for (( i=$start; i<=$end; i++ )) + do + _util_gpio_export ${i} ${DIR_IN} ${ACTIVE_LOW_EN} + done + + #LP Mode Port 0-15 + end=$[ ${start}-1] + echo "pca9535 ${I2C_ADDR_MUX_9535_7}" > ${PATH_MUX_9548_2_CH5}/new_device + start=$[ ${end}-${ch_num}+1] + for (( i=$start; i<=$end; i++ )) + do + _util_gpio_export ${i} ${DIR_OUT} ${ACTIVE_HIGH_EN} + done + + #LP Mode Port 16-31 + end=$[ ${start}-1] + echo "pca9535 ${I2C_ADDR_MUX_9535_8}" > ${PATH_MUX_9548_2_CH5}/new_device + start=$[ ${end}-${ch_num}+1] + for (( i=$start; i<=$end; i++ )) + do + _util_gpio_export ${i} ${DIR_OUT} ${ACTIVE_HIGH_EN} + done + + #RESET Port 0-15 + end=$[ ${start}-1] + echo "pca9535 ${I2C_ADDR_MUX_9535_9}" > ${PATH_MUX_9548_2_CH5}/new_device + start=$[ ${end}-${ch_num}+1] + for (( i=$start; i<=$end; i++ )) + do + # need to set value to low (became ACTIVE_HIGH) to take port out of reset + _util_gpio_export ${i} ${DIR_OUT} ${ACTIVE_LOW_EN} 0 + done + + #RESET Port 16-31 + end=$[ ${start}-1] + echo "pca9535 ${I2C_ADDR_MUX_9535_10}" > ${PATH_MUX_9548_2_CH5}/new_device + start=$[ ${end}-${ch_num}+1] + for (( i=$start; i<=$end; i++ )) + do + # need to set value to low (became ACTIVE_HIGH) to take port out of reset + _util_gpio_export ${i} ${DIR_OUT} ${ACTIVE_LOW_EN} 0 + done +} + +#GPIO DeInit +function _i2c_gpio_deinit { + echo ${I2C_ADDR_MUX_9535_3} > /sys/bus/i2c/devices/i2c-${NUM_MUX_9548_2_CH4}/delete_device + echo ${I2C_ADDR_MUX_9535_4} > /sys/bus/i2c/devices/i2c-${NUM_MUX_9548_2_CH4}/delete_device + echo ${I2C_ADDR_MUX_9535_5} > /sys/bus/i2c/devices/i2c-${NUM_MUX_9548_2_CH4}/delete_device + echo ${I2C_ADDR_MUX_9535_6} > /sys/bus/i2c/devices/i2c-${NUM_MUX_9548_2_CH4}/delete_device + echo ${I2C_ADDR_MUX_9535_7} > /sys/bus/i2c/devices/i2c-${NUM_MUX_9548_2_CH5}/delete_device + echo ${I2C_ADDR_MUX_9535_8} > /sys/bus/i2c/devices/i2c-${NUM_MUX_9548_2_CH5}/delete_device + echo ${I2C_ADDR_MUX_9535_9} > /sys/bus/i2c/devices/i2c-${NUM_MUX_9548_2_CH5}/delete_device + echo ${I2C_ADDR_MUX_9535_10} > /sys/bus/i2c/devices/i2c-${NUM_MUX_9548_2_CH5}/delete_device +} + +#Set FAN Tray LED +function _i2c_led_fan_tray_status_set { + echo "FAN Tray Status Setup" + #FAN Status get + FAN1_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan8_alarm` + FAN2_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan7_alarm` + FAN3_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan6_alarm` + FAN4_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan5_alarm` + FAN5_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan4_alarm` + FAN6_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan3_alarm` + FAN7_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan2_alarm` + FAN8_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan1_alarm` + + # check if io expander for fan tray exist + result=`i2cget -y ${I2C_BUS_FANTRAY_LED} ${I2C_ADDR_MUX_9535_11} ${REG_PORT0_IN} 2>/dev/null` + err_code=$? + if [ "$err_code" != "0" ]; then + echo "fan tray not exist!" + return + fi + + if [ "${FAN1_ALARM}" == "0" ] && [ "${FAN2_ALARM}" == "0" ]; then + FAN_TRAY=1 + echo "FAN_TRAY${FAN_TRAY}..." + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + else + FAN_TRAY=1 + echo "FAN_TRAY${FAN_TRAY}..." + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + fi + + if [ "${FAN3_ALARM}" == "0" ] && [ "${FAN4_ALARM}" == "0" ]; then + FAN_TRAY=2 + echo "FAN_TRAY${FAN_TRAY}..." + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + else + FAN_TRAY=2 + echo "FAN_TRAY${FAN_TRAY}..." + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + fi + + if [ "${FAN5_ALARM}" == "0" ] && [ "${FAN6_ALARM}" == "0" ]; then + FAN_TRAY=3 + echo "FAN_TRAY${FAN_TRAY}..." + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + else + FAN_TRAY=3 + echo "FAN_TRAY${FAN_TRAY}..." + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + fi + + if [ "${FAN7_ALARM}" == "0" ] && [ "${FAN8_ALARM}" == "0" ]; then + FAN_TRAY=4 + echo "FAN_TRAY${FAN_TRAY}..." + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + else + FAN_TRAY=4 + echo "FAN_TRAY${FAN_TRAY}..." + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_tray_led + fi +} + +#Set FAN LED +function _i2c_led_fan_status_set { + echo "FAN Status Setup" + #PSU Status set + FAN1_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan1_alarm` + FAN2_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan2_alarm` + FAN3_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan3_alarm` + FAN4_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan4_alarm` + FAN5_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan5_alarm` + FAN6_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan6_alarm` + FAN7_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan7_alarm` + FAN8_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan8_alarm` + + echo "led_fan setup..." + # all fan ok + if [ "${FAN1_ALARM}" == "0" ] && [ "${FAN2_ALARM}" == "0" ] \ + && [ "${FAN3_ALARM}" == "0" ] && [ "${FAN4_ALARM}" == "0" ] \ + && [ "${FAN5_ALARM}" == "0" ] && [ "${FAN6_ALARM}" == "0" ] \ + && [ "${FAN7_ALARM}" == "0" ] && [ "${FAN8_ALARM}" == "0" ]; then + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_led + # all fan fail + elif [ "${FAN1_ALARM}" == "1" ] && [ "${FAN2_ALARM}" == "1" ] \ + && [ "${FAN3_ALARM}" == "1" ] && [ "${FAN4_ALARM}" == "1" ] \ + && [ "${FAN5_ALARM}" == "1" ] && [ "${FAN6_ALARM}" == "1" ] \ + && [ "${FAN7_ALARM}" == "1" ] && [ "${FAN8_ALARM}" == "1" ]; then + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_led + # partial fan fail + else + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_fan_led + fi +} + +#Set Power Supply LED +function _i2c_led_psu_status_set { + echo "PSU LED Status Setup" + + #PSU Status set + _i2c_psu_status + + #PSU1 Status + echo "led_psu1 setup..." + if [ "${psu1Exist}" == ${PSU_EXIST} ]; then + if [ "${psu1PwGood}" == ${PSU_DC_ON} ]; then + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu1_led + else + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu1_led + fi + else + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu1_led + fi + + #PSU2 Status + echo "led_psu2 setup..." + if [ "${psu2Exist}" == ${PSU_EXIST} ]; then + if [ "${psu2PwGood}" == ${PSU_DC_ON} ]; then + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu2_led + else + COLOR_LED="amber" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu2_led + fi + else + COLOR_LED="green" + ONOFF_LED="off" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_psu2_led + fi +} + +#LED Test +function _i2c_led_test { + echo "=========================================================" + echo "# Description: I2C SYSTEM LED TEST..." + echo "=========================================================" + local output_reg=${REG_PORT0_OUT} + local mask=0xFF + local value=0xFF + + #sys led (green) + # set sys_led_g (0.7) = 1 + mask=0x80 + value=0x80 + _util_i2cset -m ${mask} -y ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${output_reg} ${value} + _pause 'Check SYS LED green light and Press [Enter] key to continue...' + #sys led (amber) + # set sys_led_g (0.7) = 0 + mask=0x80 + value=0x00 + _util_i2cset -m ${mask} -y ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${output_reg} ${value} + _pause 'Check SYS LED amber light and Press [Enter] key to continue...' + + #FAN led (green) + # set fan_led_en (0.6) = 1 & fan_led_y (0.5) = 0 + mask=0x60 + value=0x40 + _util_i2cset -m ${mask} -y ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${output_reg} ${value} + _pause 'Check FAN LED green light and Press [Enter] key to continue...' + #FAN led (amber) + # set fan_led_en (0.6) = 1 & fan_led_y (0.5) = 1 + mask=0x60 + value=0x60 + _util_i2cset -m ${mask} -y ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${output_reg} ${value} + _pause 'Check FAN LED amber light and Press [Enter] key to continue...' + + #PSU1 led (green) + # set psu1_pwr_ok_oe (0.4) = 1 & psu1_led_y (0.3) = 0 + mask=0x18 + value=0x10 + _util_i2cset -m ${mask} -y ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${output_reg} ${value} + _pause 'Check PSU1 LED green light and Press [Enter] key to continue...' + #PSU1 led (amber) + # set psu1_pwr_ok_oe (0.4) = 1 & psu1_led_y (0.3) = 1 + mask=0x18 + value=0x18 + _util_i2cset -m ${mask} -y ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${output_reg} ${value} + _pause 'Check PSU1 LED amber light and Press [Enter] key to continue...' + + #PSU2 led (green) + # set psu0_pwr_ok_oe (0.2) = 1 & psu0_led_y (0.1) = 0 + mask=0x06 + value=0x04 + _util_i2cset -m ${mask} -y ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${output_reg} ${value} + _pause 'Check PSU2 LED green light and Press [Enter] key to continue...' + #PSU2 led (amber) + # set psu0_pwr_ok_oe (0.2) = 1 & psu0_led_y (0.1) = 1 + mask=0x06 + value=0x06 + _util_i2cset -m ${mask} -y ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${output_reg} ${value} + _pause 'Check PSU2 LED amber light and Press [Enter] key to continue...' + + #Turn OFF All LED (can't trun off system led) + # set set fan_led_en (0.6), psu1_pwr_ok_oe (0.4), psu0_pwr_ok_oe (0.2) = 0 + mask=0x54 + value=0x00 + _util_i2cset -m ${mask} -y ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${output_reg} ${value} + _pause 'Check turn off all LEDs (exclude SYS LED) and Press [Enter] key to continue...' + + # restore sys led + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_sys_led + + echo "Done" +} + +#Set QSFP Port variable +function _qsfp_port_i2c_var_set { + local port=$1 + case ${port} in + 1|2|3|4|5|6|7|8) + i2cbus=${NUM_MUX_9548_2_CH4} + eeprombusbase=${NUM_MUX_9548_3_CH0} + gpioBase=${ZQSFP_PORT0_ABS_GPIO_IDX} + ;; + 9|10|11|12|13|14|15|16) + i2cbus=${NUM_MUX_9548_2_CH4} + eeprombusbase=${NUM_MUX_9548_4_CH0} + gpioBase=${ZQSFP_PORT0_ABS_GPIO_IDX} + ;; + 17|18|19|20|21|22|23|24) + i2cbus=${NUM_MUX_9548_2_CH4} + eeprombusbase=${NUM_MUX_9548_5_CH0} + gpioBase=${ZQSFP_PORT16_ABS_GPIO_IDX} + ;; + 25|26|27|28|29|30|31|32) + i2cbus=${NUM_MUX_9548_2_CH4} + eeprombusbase=${NUM_MUX_9548_6_CH0} + gpioBase=${ZQSFP_PORT16_ABS_GPIO_IDX} + ;; + *) + echo "Please input 1~32" + ;; + esac +} + +#Set QSFP Port variable +function _qsfp_eeprom_var_set { + local port=$1 + # port 1 => zqsfp0 + # port 2 => zqsfp1 + # ... + eeprombusidx=$(( (${port} - 1) % 8)) + eeprombus=$(( ${eeprombusbase} + ${eeprombusidx} )) + eepromAddr=${I2C_ADDR_QSFP_EEPROM} +} + +#Get QSFP EEPROM Information +function _i2c_qsfp_eeprom_get { + + # input parameter validation + _util_input_check ${QSFP_PORT} ${MIN_PORT_NUM} ${MAX_PORT_NUM} + + _util_get_qsfp_abs + + if [ $status = 0 ]; then + exit + fi + + _qsfp_eeprom_var_set ${QSFP_PORT} + + cat ${PATH_SYS_I2C_DEVICES}/$eeprombus-$(printf "%04x" $eepromAddr)/eeprom | hexdump -C +} + +#Init QSFP EEPROM +function _i2c_qsfp_eeprom_init { + echo "QSFP EEPROM INIT..." + + #Action check + action=$1 + if [ -z "${action}" ]; then + echo "No action, skip" + return + elif [ "${action}" != "new" ] && [ "${action}" != "delete" ]; then + echo "Error action, skip" + return + fi + + #Init 1-32 ports EEPROM + local i + for i in {1..32}; + do + _qsfp_port_i2c_var_set ${i} + + _qsfp_eeprom_var_set ${i} + + if [ "${action}" == "new" ] && \ + ! [ -L ${PATH_SYS_I2C_DEVICES}/$eeprombus-$(printf "%04x" $eepromAddr) ]; then + echo "sff8436 $eepromAddr" > ${PATH_SYS_I2C_DEVICES}/i2c-$eeprombus/new_device + elif [ "${action}" == "delete" ] && \ + [ -L ${PATH_SYS_I2C_DEVICES}/$eeprombus-$(printf "%04x" $eepromAddr) ]; then + echo "$eepromAddr" > ${PATH_SYS_I2C_DEVICES}/i2c-$eeprombus/delete_device + fi + done + echo "Done" +} + +#Init Main Board EEPROM +function _i2c_mb_eeprom_init { + echo -n "Main Board EEPROM INIT..." + + #Action check + action=$1 + if [ -z "${action}" ]; then + echo "No action, skip" + return + elif [ "${action}" != "new" ] && [ "${action}" != "delete" ]; then + echo "Error action, skip" + return + fi + + #Init mb EEPROM + if [ "${action}" == "new" ] && \ + ! [ -L ${PATH_SYS_I2C_DEVICES}/${I2C_BUS_MB_EEPROM}-$(printf "%04x" $I2C_ADDR_MB_EEPROM) ]; then + echo "mb_eeprom ${I2C_ADDR_MB_EEPROM}" > ${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_MB_EEPROM}/new_device + elif [ "${action}" == "delete" ] && \ + [ -L ${PATH_SYS_I2C_DEVICES}/${I2C_BUS_MB_EEPROM}-$(printf "%04x" $I2C_ADDR_MB_EEPROM) ]; then + echo "$I2C_ADDR_MB_EEPROM" > ${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_MB_EEPROM}/delete_device + fi + echo "Done" +} + +#Init CPU Board EEPROM +function _i2c_cb_eeprom_init { + echo -n "CPU Board EEPROM INIT..." + + #Action check + action=$1 + if [ -z "${action}" ]; then + echo "No action, skip" + return + elif [ "${action}" != "new" ] && [ "${action}" != "delete" ]; then + echo "Error action, skip" + return + fi + + #Init cpu EEPROM + if [ "${action}" == "new" ] && \ + ! [ -L ${PATH_SYS_I2C_DEVICES}/${I2C_BUS_CB_EEPROM}-$(printf "%04x" $I2C_ADDR_CB_EEPROM) ]; then + echo "mb_eeprom ${I2C_ADDR_CB_EEPROM}" > ${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_CB_EEPROM}/new_device + elif [ "${action}" == "delete" ] && \ + [ -L ${PATH_SYS_I2C_DEVICES}/${I2C_BUS_CB_EEPROM}-$(printf "%04x" $I2C_ADDR_CB_EEPROM) ]; then + echo "$I2C_ADDR_CB_EEPROM" > ${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_CB_EEPROM}/delete_device + fi + echo "Done" +} + + +#get QSFP Status +function _i2c_qsfp_status_get { + + # input parameter validation + _util_input_check ${QSFP_PORT} ${MIN_PORT_NUM} ${MAX_PORT_NUM} + + local stat + _util_get_qsfp_abs + echo "status=$status" +} + +#get QSFP Type +function _i2c_qsfp_type_get { + + # input parameter validation + _util_input_check ${QSFP_PORT} ${MIN_PORT_NUM} ${MAX_PORT_NUM} + + _qsfp_port_i2c_var_set ${QSFP_PORT} + + _qsfp_eeprom_var_set ${QSFP_PORT} + + #Get QSFP EEPROM info + qsfp_info=$(base64 ${PATH_SYS_I2C_DEVICES}/$eeprombus-$(printf "%04x" $eepromAddr)/eeprom) + + identifier=$(echo $qsfp_info | base64 -d -i | hexdump -s 128 -n 1 -e '"%x"') + connector=$(echo $qsfp_info | base64 -d -i | hexdump -s 130 -n 1 -e '"%x"') + transceiver=$(echo $qsfp_info | base64 -d -i | hexdump -s 131 -n 1 -e '"%x"') + + echo "identifier=$identifier" + echo "connector=$connector" + echo "transceiver=$transceiver" +} + +#Init PSU Kernel Module +function _i2c_psu_init { + echo "=========================================================" + echo "# Description: I2C PSU Init" + echo "=========================================================" + modprobe ingrasys_s9130_32x_psu + + echo "psu1 ${I2C_ADDR_PSU1_EEPROM}" > ${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_PSU1_EEPROM}/new_device + echo "psu2 ${I2C_ADDR_PSU2_EEPROM}" > ${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_PSU2_EEPROM}/new_device +} + +#Get PSU EEPROM Information +function _i2c_psu_eeprom_get { + local eeprom_psu1="" + local eeprom_psu2="" + + echo "=========================================================" + echo "# Description: I2C PSU EEPROM Get..." + echo "=========================================================" + + eeprom_psu1="${PATH_SYSFS_PSU1}/psu_eeprom" + cat ${eeprom_psu1} | hexdump -C + + eeprom_psu2="${PATH_SYSFS_PSU2}/psu_eeprom" + cat ${eeprom_psu2} | hexdump -C +} + +#Get Main Board EEPROM Information +function _i2c_mb_eeprom_get { + echo "=========================================================" + echo "# Description: I2C MB EEPROM Get..." + echo "=========================================================" + _i2c_sys_eeprom_get mb +} + +#Get CPU Board EEPROM Information +function _i2c_cb_eeprom_get { + echo "=========================================================" + echo "# Description: I2C CB EEPROM Get..." + echo "=========================================================" + _i2c_sys_eeprom_get cb +} + +#Get system EEPROM Information +##input: "cb" for cpu board, "mb" for main board +function _i2c_sys_eeprom_get { + local eeprom_dev + + if [ "$1" == "cb" ]; then + eeprom_dev="${PATH_SYS_I2C_DEVICES}/${I2C_BUS_CB_EEPROM}-$(printf "%04x" $I2C_ADDR_CB_EEPROM)/eeprom" + elif [ "$1" == "mb" ]; then + eeprom_dev="${PATH_SYS_I2C_DEVICES}/${I2C_BUS_MB_EEPROM}-$(printf "%04x" $I2C_ADDR_MB_EEPROM)/eeprom" + else + echo "wrong eeprom type" + return + fi + + # check if eeprom device exist in sysfs + if [ ! -f ${eeprom_dev} ]; then + echo "eeprom device not init" + return + fi + + cat ${eeprom_dev} | hexdump -C + echo "Done" +} + +#sync eeprom content between mb and cb eeprom +function _i2c_eeprom_sync { + echo "=========================================================" + echo "# Description: EEPROM sync..." + echo "=========================================================" + + local mb_eeprom_dev="${PATH_SYS_I2C_DEVICES}/${I2C_BUS_MB_EEPROM}-$(printf "%04x" $I2C_ADDR_MB_EEPROM)/eeprom" + local cb_eeprom_dev="${PATH_SYS_I2C_DEVICES}/${I2C_BUS_CB_EEPROM}-$(printf "%04x" $I2C_ADDR_CB_EEPROM)/eeprom" + + # check if eeprom device exist in sysfs + if [[ ! -f ${mb_eeprom_dev} || ! -f ${cb_eeprom_dev} ]]; then + echo "eeprom device not init" + return + fi + + ## check if MB eeprom is empty + if [ ! -z "$(cat ${mb_eeprom_dev} | hexdump -n2 | grep ffff)" ]; then + echo "copy cb eeprom to mb eeprom..." + cat ${cb_eeprom_dev} > ${mb_eeprom_dev} + else + echo "no need to sync" + fi + + echo "Done" +} + +#Set System Status LED +function _i2c_sys_led { + # only green/amber, on/off can't control + if [ "${COLOR_LED}" == "green" ]; then + # set sys_led_g (0.7) = 1 + output_reg=${REG_PORT0_OUT} + mask=0x80 + value=0x80 + elif [ "${COLOR_LED}" == "amber" ]; then + # set sys_led_g (0.7) = 0 + output_reg=${REG_PORT0_OUT} + mask=0x80 + value=0x00 + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + #apply to io expander + _util_i2cset -m ${mask} -y ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${output_reg} ${value} + echo "Done" +} + +#Set FAN LED +function _i2c_fan_led { + if [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "on" ]; then + # set fan_led_en (0.6) = 1 & fan_led_y (0.5) = 0 + output_reg=${REG_PORT0_OUT} + mask=0x60 + value=0x40 + elif [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "off" ]; then + # set fan_led_en (0.6) = 0 & fan_led_y (0.5) = 0 + output_reg=${REG_PORT0_OUT} + mask=0x60 + value=0x00 + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "on" ]; then + # set fan_led_en (0.6) = 1 & fan_led_y (0.5) = 1 + output_reg=${REG_PORT0_OUT} + mask=0x60 + value=0x60 + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "off" ]; then + # set fan_led_en (0.6) = 0 & fan_led_y (0.5) = 1 + output_reg=${REG_PORT0_OUT} + mask=0x60 + value=0x20 + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + #apply to io expander + _util_i2cset -m ${mask} -y ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${output_reg} ${value} + echo "Done" +} + +#Set PSU1 LED +function _i2c_psu1_led { + if [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "on" ]; then + # set psu1_pwr_ok_oe (0.4) = 1 & psu1_led_y (0.3) = 0 + output_reg=${REG_PORT0_OUT} + mask=0x18 + value=0x10 + elif [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "off" ]; then + # set psu1_pwr_ok_oe (0.4) = 0 & psu1_led_y (0.3) = 0 + output_reg=${REG_PORT0_OUT} + mask=0x18 + value=0x00 + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "on" ]; then + # set psu1_pwr_ok_oe (0.4) = 1 & psu1_led_y (0.3) = 1 + output_reg=${REG_PORT0_OUT} + mask=0x18 + value=0x18 + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "off" ]; then + # set psu1_pwr_ok_oe (0.4) = 0 & psu1_led_y (0.3) = 1 + output_reg=${REG_PORT0_OUT} + mask=0x18 + value=0x08 + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + #apply to io expander + _util_i2cset -m ${mask} -y ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${output_reg} ${value} + echo "Done" +} + +#Set PSU2 LED +function _i2c_psu2_led { + if [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "on" ]; then + # set psu0_pwr_ok_oe (0.2) = 1 & psu0_led_y (0.1) = 0 + output_reg=${REG_PORT0_OUT} + mask=0x06 + value=0x04 + elif [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "off" ]; then + # set psu0_pwr_ok_oe (0.2) = 0 & psu0_led_y (0.1) = 0 + output_reg=${REG_PORT0_OUT} + mask=0x06 + value=0x00 + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "on" ]; then + # set psu0_pwr_ok_oe (0.2) = 1 & psu0_led_y (0.1) = 1 + output_reg=${REG_PORT0_OUT} + mask=0x06 + value=0x06 + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "off" ]; then + # set psu0_pwr_ok_oe (0.2) = 0 & psu0_led_y (0.1) = 1 + output_reg=${REG_PORT0_OUT} + mask=0x06 + value=0x02 + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + #apply to io expander + _util_i2cset -m ${mask} -y ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${output_reg} ${value} + echo "Done" +} + +#Set FAN Tray LED +function _i2c_fan_tray_led { + + i2cAddr=${I2C_ADDR_MUX_9535_11} + output_reg=${REG_PORT0_OUT} + + case ${FAN_TRAY} in + 4) + output_reg=${REG_PORT0_OUT} + if [ "${COLOR_LED}" == "green" ]; then + mask=0x01 + elif [ "${COLOR_LED}" == "amber" ]; then + mask=0x02 + fi + ;; + 3) + output_reg=${REG_PORT0_OUT} + if [ "${COLOR_LED}" == "green" ]; then + mask=0x10 + elif [ "${COLOR_LED}" == "amber" ]; then + mask=0x20 + fi + ;; + 2) + output_reg=${REG_PORT1_OUT} + if [ "${COLOR_LED}" == "green" ]; then + mask=0x01 + elif [ "${COLOR_LED}" == "amber" ]; then + mask=0x02 + fi + ;; + 1) + output_reg=${REG_PORT1_OUT} + if [ "${COLOR_LED}" == "green" ]; then + mask=0x10 + elif [ "${COLOR_LED}" == "amber" ]; then + mask=0x20 + fi + ;; + *) + echo "Please input 1~4" + exit + ;; + esac + + if [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "on" ]; then + _util_i2cset -m $mask -y -r ${I2C_BUS_FANTRAY_LED} $i2cAddr ${output_reg} 0x00 + elif [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "off" ]; then + _util_i2cset -m $mask -y -r ${I2C_BUS_FANTRAY_LED} $i2cAddr ${output_reg} 0x33 + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "on" ]; then + _util_i2cset -m $mask -y -r ${I2C_BUS_FANTRAY_LED} $i2cAddr ${output_reg} 0x00 + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "off" ]; then + _util_i2cset -m $mask -y -r ${I2C_BUS_FANTRAY_LED} $i2cAddr ${output_reg} 0x33 + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + echo "Done" +} + +#Get Board Version and Type +function _i2c_board_type_get { + # read input port 1 value from io expander + input_reg=${REG_PORT1_IN} + boardType=`i2cget -y ${I2C_BUS_HW_ID} ${I2C_ADDR_MUX_9539_0} ${input_reg}` + boardBuildRev=$((($boardType) & 0x03)) + boardHwRev=$((($boardType) >> 2 & 0x03)) + boardId=$((($boardType) >> 4)) + printf "MAIN_BOARD BOARD_ID is 0x%02x, HW Rev %d, Build Rev %d\n" $boardId $boardHwRev $boardBuildRev +} + +#Get BMC Board Version and Type +function _i2c_bmc_board_type_get { + # read input port 1 value from io expander + input_reg=${REG_PORT1_IN} + boardType=`i2cget -y ${I2C_BUS_BMC_HW_ID} ${I2C_ADDR_MUX_9555_12} ${input_reg}` + boardBuildRev=$((($boardType) & 0x03)) + boardHwRev=$((($boardType) >> 2 & 0x03)) + boardId=$((($boardType) >> 4)) + printf "BMC_BOARD BOARD_ID is 0x%02x, HW Rev %d, Build Rev %d\n" $boardId $boardHwRev $boardBuildRev +} + +#Get PSU Status +function _i2c_psu_status { + local psu_abs="" + + psu1PwGood=`cat ${PATH_SYSFS_PSU1}/psu_pg` + psu_abs=`cat ${PATH_SYSFS_PSU1}/psu_abs` + if [ "$psu_abs" == "0" ]; then + psu1Exist=1 + else + psu1Exist=0 + fi + + psu2PwGood=`cat ${PATH_SYSFS_PSU2}/psu_pg` + psu_abs=`cat ${PATH_SYSFS_PSU2}/psu_abs` + if [ "$psu_abs" == "0" ]; then + psu2Exist=1 + else + psu2Exist=0 + fi + + printf "PSU1 Exist:%x PSU1 PW Good:%d\n" $psu1Exist $psu1PwGood + printf "PSU2 Exist:%d PSU2 PW Good:%d\n" $psu2Exist $psu2PwGood +} + +#util functions +function _util_i2cset { + if [ "$DEBUG" == "on" ]; then + i2cset $@ + else + i2cset $@ 1>/dev/null + fi +} + +function _util_rmmod { + local mod=$1 + [ "$(lsmod | grep "^$mod ")" != "" ] && rmmod $mod +} + +# get qsfp presence +function _util_get_qsfp_abs { + _qsfp_port_i2c_var_set ${QSFP_PORT} + + #status: 0 -> Down, 1 -> Up (ACTIVE_LOW_EN) + status=`cat /sys/class/gpio/gpio$(( $(($gpioBase + (${QSFP_PORT} - 1) % 16 )) ))/value` +} + +# gpio init util function +function _util_gpio_export { + local gpio_n=$1 + local direction=$2 + local active_low=$3 + local value=$4 + + if [ -z "${gpio_n}" ]; then + echo "[gpio_init] gpio_n(${gpio_n}) is not provided" + return + fi + if [[ ${gpio_n} < 0 || ${gpio_n} > 255 ]]; then + echo "[gpio_init] gpio_n(${gpio_n}) is invalid value" + return + fi + + #export gpio + echo ${gpio_n} > /sys/class/gpio/export + #set gpio direction + echo ${direction} > /sys/class/gpio/gpio${gpio_n}/direction + #set gpio active_low + echo ${active_low} > /sys/class/gpio/gpio${gpio_n}/active_low + #set value + if [ ! -z "${value}" ]; then + echo ${value} > /sys/class/gpio/gpio${gpio_n}/value + fi +} + +# valid input number +function _util_input_check { + # input parameter validation + if [[ $1 -lt $2 || $1 -gt $3 ]]; then + echo "Please input number $2~$3" + exit + fi +} + +#Increase read socket buffer for CoPP Test +function _config_rmem { + echo "109430400" > /proc/sys/net/core/rmem_max +} + +#Main Function +function _main { + tart_time_str=`date` + start_time_sec=$(date +%s) + + if [ "${EXEC_FUNC}" == "help" ]; then + _help + elif [ "${EXEC_FUNC}" == "i2c_init" ]; then + _i2c_init + elif [ "${EXEC_FUNC}" == "i2c_deinit" ]; then + _i2c_deinit + elif [ "${EXEC_FUNC}" == "i2c_fan_speed_init" ]; then + _i2c_fan_speed_init + elif [ "${EXEC_FUNC}" == "i2c_io_exp_init" ]; then + _i2c_io_exp_init + elif [ "${EXEC_FUNC}" == "i2c_gpio_init" ]; then + _i2c_gpio_init + elif [ "${EXEC_FUNC}" == "i2c_gpio_deinit" ]; then + _i2c_gpio_deinit + elif [ "${EXEC_FUNC}" == "i2c_led_test" ]; then + _i2c_led_test + elif [ "${EXEC_FUNC}" == "i2c_mb_eeprom_get" ]; then + _i2c_mb_eeprom_get + elif [ "${EXEC_FUNC}" == "i2c_cb_eeprom_get" ]; then + _i2c_cb_eeprom_get + elif [ "${EXEC_FUNC}" == "i2c_eeprom_sync" ]; then + _i2c_eeprom_sync + elif [ "${EXEC_FUNC}" == "i2c_psu_eeprom_get" ]; then + _i2c_psu_eeprom_get + elif [ "${EXEC_FUNC}" == "i2c_qsfp_eeprom_get" ]; then + _i2c_qsfp_eeprom_get + elif [ "${EXEC_FUNC}" == "i2c_qsfp_eeprom_init" ]; then + _i2c_qsfp_eeprom_init ${QSFP_ACTION} + elif [ "${EXEC_FUNC}" == "i2c_mb_eeprom_init" ]; then + _i2c_mb_eeprom_init ${MB_EEPROM_ACTION} + elif [ "${EXEC_FUNC}" == "i2c_cb_eeprom_init" ]; then + _i2c_cb_eeprom_init ${MB_EEPROM_ACTION} + elif [ "${EXEC_FUNC}" == "i2c_qsfp_status_get" ]; then + _i2c_qsfp_status_get + elif [ "${EXEC_FUNC}" == "i2c_qsfp_type_get" ]; then + _i2c_qsfp_type_get + elif [ "${EXEC_FUNC}" == "i2c_led_psu_status_set" ]; then + _i2c_led_psu_status_set + elif [ "${EXEC_FUNC}" == "i2c_led_fan_status_set" ]; then + _i2c_led_fan_status_set + elif [ "${EXEC_FUNC}" == "i2c_led_fan_tray_status_set" ]; then + _i2c_led_fan_tray_status_set + elif [ "${EXEC_FUNC}" == "i2c_sys_led" ]; then + _i2c_sys_led + elif [ "${EXEC_FUNC}" == "i2c_fan_led" ]; then + _i2c_fan_led + elif [ "${EXEC_FUNC}" == "i2c_fan_tray_led" ]; then + _i2c_fan_tray_led + elif [ "${EXEC_FUNC}" == "i2c_psu1_led" ]; then + _i2c_psu1_led + elif [ "${EXEC_FUNC}" == "i2c_psu2_led" ]; then + _i2c_psu2_led + elif [ "${EXEC_FUNC}" == "i2c_board_type_get" ]; then + _i2c_board_type_get + elif [ "${EXEC_FUNC}" == "i2c_bmc_board_type_get" ]; then + _i2c_bmc_board_type_get + elif [ "${EXEC_FUNC}" == "i2c_psu_status" ]; then + _i2c_psu_status + elif [ "${EXEC_FUNC}" == "i2c_test_all" ]; then + _i2c_init + _i2c_led_test + _i2c_psu_eeprom_get + _i2c_mb_eeprom_get + _i2c_cb_eeprom_get + _i2c_board_type_get + _i2c_bmc_board_type_get + _i2c_psu_status + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + if [ "$DEBUG" == "on" ]; then + echo "-----------------------------------------------------" + end_time_str=`date` + end_time_sec=$(date +%s) + diff_time=$[ ${end_time_sec} - ${start_time_sec} ] + echo "Start Time: ${start_time_str} (${start_time_sec})" + echo "End Time : ${end_time_str} (${end_time_sec})" + echo "Total Execution Time: ${diff_time} sec" + + echo "done!!!" + fi +} + +_main diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/qsfp_monitor.sh b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/qsfp_monitor.sh new file mode 100644 index 000000000000..249f179216a6 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/qsfp_monitor.sh @@ -0,0 +1,104 @@ +#!/bin/bash +# Copyright (C) 2017 Ingrasys, 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 3 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, see . + +INTERVAL=3 +I2C_UTILS="/usr/sbin/i2c_utils.sh" +QSFP_SI_SCRIPT="/usr/sbin/qsfp_si_cfg.sh" +QSFP_ARRAY=(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) + +#QSFP SI monitor +function _qsfp_si_monitor { + local i + local status + for i in {0..31}; + do + status=`${I2C_UTILS} i2c_qsfp_status_get $(expr $i + 1) | egrep '^status=.*$' | sed -e 's/status=//g'` + if [ "${status}" == "1" ]; then + _qsfp_type_check $i + fi + done +} + +#QSFP type +function _qsfp_type_check { + local port=$1 + local qsfp_type=`${I2C_UTILS} i2c_qsfp_type_get $(expr $port + 1)` + local identifier=`echo "$qsfp_type" | grep '^identifier=.*$' | sed -e 's/identifier=//g'` + if [ "${identifier}" == "11" ]; then + connector=`echo "$qsfp_type" | grep '^connector=.*$' | sed -e 's/connector=//g'` + case ${connector} in + 21|23) + #DAC + if [ "${QSFP_ARRAY[$port]}" != "${connector}" ]; then + echo "Change Port $(expr $port + 1) to DAC" + QSFP_ARRAY[$port]=${connector} + ${QSFP_SI_SCRIPT} dac $port >/dev/null + fi + ;; + *) + #Optical + if [ "${QSFP_ARRAY[$port]}" != "${connector}" ]; then + echo "Change Port $(expr $port + 1) to Optical" + QSFP_ARRAY[$port]=${connector} + ${QSFP_SI_SCRIPT} optical $port >/dev/null + fi + ;; + esac + fi +} + +#Docker exist check +function _docker_swss_check { + while true + do + # Check if syncd starts + result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + if [ "$result" == "3" ]; then + return + fi + sleep $INTERVAL + done +} + +#Docker exist check +function _qsfp_si_cfg_script_check { + + if [ -f ${QSFP_SI_SCRIPT} ] && [ -x ${QSFP_SI_SCRIPT} ]; then + echo "SI Script exists. Start monitor." + return + else + echo "SI Script not exist. Exit monitor." + exit + fi +} + +# main function +function _main { + #Check SI Script + _qsfp_si_cfg_script_check + #Check docker swss is running + _docker_swss_check + while true + do + _qsfp_si_monitor + # Sleep while still handling signals + sleep $INTERVAL & + wait $! + done +} + +_main + diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/s9130_32x_monitor.sh b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/s9130_32x_monitor.sh new file mode 100644 index 000000000000..974da6d5001f --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/s9130_32x_monitor.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# Copyright (C) 2016 Ingrasys, 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 3 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, see . + +INTERVAL=5 +I2C_UTILS="/usr/sbin/i2c_utils.sh" + + +# LED status monitor +function _led_monitor { + ${I2C_UTILS} i2c_led_fan_status_set >/dev/null + ${I2C_UTILS} i2c_led_psu_status_set >/dev/null + ${I2C_UTILS} i2c_led_fan_tray_status_set >/dev/null +} + +# main function +function _main { + while true + do + _led_monitor + # Sleep while still handling signals + sleep $INTERVAL & + wait $! + done +} + +_main \ No newline at end of file diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/README.md b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/README.md new file mode 100644 index 000000000000..d1a2d5464aee --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/README.md @@ -0,0 +1,182 @@ +# Ingrasys S9230-64X Platform Driver for SONiC + +Copyright (C) 2016 Ingrasys, 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 3 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, see . + + +## Licensing terms + +The Licensing terms of the files within this project is split 2 parts. +The Linux kernel is released under the GNU General Public License version 2. +All other code is released under the GNU General Public License version 3. +Please see the LICENSE file for copies of both licenses. + +## Contents of this package + + - service/ + > Service config files for platform initialization and monitoring + - utils/ + > Scripts useful during platform bringup and sysfs function + - conf/ + > Platform configure files. + +## Kernel modules and drivers + +The driver for interacting with Ingrasys S9230-64X is contained in the I2C +kernel module and initialization script. The initialization script loads +the modules in the correct order. It has been built and tested against +the Linux 3.16 kernel. + +The initialization script will modprobe the needed modules, navigate to the +module's device directory in sysfs, and write configuration data to +the kernel module. + +### IGB + +This is OOB Ports on front panel for management plane. + +The IGB module must be loaded first on Ingrasys S9230-64X platform. + +### I2C i801 + +The I2C i801 on Ingrasys S9230-64X can be found in +`/sys/bus/i2c/devices/i2c-0/` + +This is I2C bus for power monitor, FAN controller, HWM and thermal sensors. + +### I2C PCA9548 +The PCA9548 module on S9230-64X can be found in +`/sys/bus/i2c/devices/i2c-1/` , `/sys/bus/i2c/devices/i2c-2/`, +`/sys/bus/i2c/devices/i2c-3/`, `/sys/bus/i2c/devices/i2c-4/`, +`/sys/bus/i2c/devices/i2c-5/`, `/sys/bus/i2c/devices/i2c-6/`, +`/sys/bus/i2c/devices/i2c-7/`, `/sys/bus/i2c/devices/i2c-8/` + +The pca9548 module for CPLD get/set functions, PSU information, +fan status and EEPROM. + +## Hardware components + +The hardware components are initialized in the init script on S9230-64X. +The following describes manual initialization as well as interaction. +The examples below are just for Ingrasys S9230-64X platform. + +### Hardware initialization + +When the sonic-platform-ingrasys-s9230-64X package is installed on the S9230-64X, +it is automatically initialized. If you want to manual initialization, the +utility command usage as follows: +``` + i2c_utils.sh i2c_init +``` + +### EEPROM + +The EEPROM is including the board SKU, model name, vendor name, serial number, +and other information can be accessed with the specific eeprom kernel module. +After using `modprobe eeprom_mb` to detect the eeprom, it will show up in sysfs. + +The hexdump utility can be used to decode the raw output of the EEPROM. +For example, +``` + bash# echo "mb_eeprom 0x55" > /sys/bus/i2c/devices/i2c-0/new_device + bash# cat /sys/bus/i2c/drivers/mb_eeprom/0-0055/eeprom | hexdump -C +``` + +### Front panel LEDs + +LEDs can be setup on/off by using i2c utility `/usr/sbin/i2c_utils.sh`. +Utility function command usage as follows: + +``` +Status LED: + i2c_utils.sh i2c_sys_led green|amber + +Fan status LED: + i2c_utils.sh i2c_fan_led green|amber on|off + +PSU1 status LED: + i2c_utils.sh i2c_psu1_led green|amber on|off + +PSU2 status LED: + i2c_utils.sh i2c_psu2_led green|amber on|off + +``` +QSFP Module Port LEDs control by ASIC library. + + +### Fan speed + +Fan speed are controlled by the w83795 kernel module. +It can be found in `/sys/class/hwmon/hwmon7/device/`. +If they were compiled as modules, you will need to modprobe w83795 for +their sysfs entries to show up. Each fan has an `fan_input` file +for reading the fan speed. And `pwm1` setting fan1 to fan4, +`pwm2` setting fan5 to fan8. + +There is docker-platform-monitor container installed fancontrol package that can +automatic control platform fan speed. + + +### Temperature sensors + +There is docker-platform-monitor container installed lm-sensors package that can +monitor platform temperature. And `sensors` command can show each +temperature sensors status. + +### Power supplies + +Power supplies status and its EEPROM info can be used i2c utility +`/usr/sbin/i2c_utils.sh` to get. +The usage as follows: +``` +PSU EEPROM: + i2c_utils.sh i2c_psu_eeprom_get + hexdump -C psu0.rom + hexdump -C psu1.rom + +PSU Status: + i2c_utils.sh i2c_psu_status +``` + +### QSFPs +QSFP modules are managed by the CPLD 1~5 according to port number. +The i2c utility `/usr/sbin/i2c_utils.sh` can be used to get status and +module EEPROM informations. +The usage as follows: +``` +QSFP EEPROM: + i2c_utils.sh i2c_qsfp_eeprom_get [1-64] + +QSFP Insert Event: + i2c_utils.sh i2c_qsfp_status_get [1-64] + 0 => not insert + 1 => inserted +``` + +### SFP+ +SFP+ modules are managed by the CPLD 1~2 according to port number. +The i2c utility `/usr/sbin/i2c_utils.sh` can be used to get status and +module EEPROM informations. +The usage as follows: +``` +SFP EEPROM: + i2c_utils.sh i2c_sfp_eeprom_get [1-2] + +SFP Insert Event: + i2c_utils.sh i2c_sfp_status_get [1-2] + 0 => not insert + 1 => inserted +``` + diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/modules/Makefile b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/modules/Makefile new file mode 100755 index 000000000000..3107674e8712 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/modules/Makefile @@ -0,0 +1,3 @@ +obj-m := eeprom_mb.o +obj-m += ingrasys_s9230_64x_i2c_cpld.o +obj-m += ingrasys_s9230_64x_psu.o diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/modules/eeprom_mb.c b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/modules/eeprom_mb.c new file mode 100755 index 000000000000..528864d93382 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/modules/eeprom_mb.c @@ -0,0 +1,267 @@ +/* + * Copyright (C) 1998, 1999 Frodo Looijaard and + * Philip Edelbrock + * Copyright (C) 2003 Greg Kroah-Hartman + * Copyright (C) 2003 IBM Corp. + * Copyright (C) 2004 Jean Delvare + * + * 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. + */ + +/* enable dev_dbg print out */ +//#define DEBUG + +#include +#include +#include +#include +#include +#include +#include + +/* Addresses to scan */ +static const unsigned short normal_i2c[] = { /*0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57,*/ I2C_CLIENT_END }; + +/* Size of EEPROM in bytes */ +#define EEPROM_SIZE 512 + +#define SLICE_BITS (6) +#define SLICE_SIZE (1 << SLICE_BITS) +#define SLICE_NUM (EEPROM_SIZE/SLICE_SIZE) + +/* Each client has this additional data */ +struct eeprom_data { + struct mutex update_lock; + u8 valid; /* bitfield, bit!=0 if slice is valid */ + unsigned long last_updated[SLICE_NUM]; /* In jiffies, 8 slices */ + u8 data[EEPROM_SIZE]; /* Register values */ +}; + + +static void mb_eeprom_update_client(struct i2c_client *client, u8 slice) +{ + struct eeprom_data *data = i2c_get_clientdata(client); + int i, j; + int ret; + int addr; + + mutex_lock(&data->update_lock); + + if (!(data->valid & (1 << slice)) || + time_after(jiffies, data->last_updated[slice] + 300 * HZ)) { + dev_dbg(&client->dev, "Starting eeprom update, slice %u\n", slice); + + addr = slice << SLICE_BITS; + + ret = i2c_smbus_write_byte_data(client, (u8)((addr >> 8) & 0xFF), (u8)(addr & 0xFF)); + /* select the eeprom address */ + if (ret < 0) { + dev_err(&client->dev, "address set failed\n"); + goto exit; + } + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BYTE)) { + goto exit; + } + + for (i = slice << SLICE_BITS; i < (slice + 1) << SLICE_BITS; i+= SLICE_SIZE) { + for (j = i; j < (i+SLICE_SIZE); j++) { + int res; + + res = i2c_smbus_read_byte(client); + if (res < 0) { + goto exit; + } + + data->data[j] = res & 0xFF; + } + } + + data->last_updated[slice] = jiffies; + data->valid |= (1 << slice); + } +exit: + mutex_unlock(&data->update_lock); +} + +static ssize_t mb_eeprom_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj)); + struct eeprom_data *data = i2c_get_clientdata(client); + u8 slice; + + if (off > EEPROM_SIZE) { + return 0; + } + if (off + count > EEPROM_SIZE) { + count = EEPROM_SIZE - off; + } + if (count == 0) { + return 0; + } + + /* Only refresh slices which contain requested bytes */ + for (slice = off >> SLICE_BITS; slice <= (off + count - 1) >> SLICE_BITS; slice++) { + mb_eeprom_update_client(client, slice); + } + + memcpy(buf, &data->data[off], count); + + return count; +} + +static ssize_t mb_eeprom_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj)); + struct eeprom_data *data = i2c_get_clientdata(client); + int ret; + int i; + u8 cmd; + u16 value16; + + dev_dbg(&client->dev, "mb_eeprom_write off=%d, count=%d\n", (int)off, (int)count); + + if (off > EEPROM_SIZE) { + return 0; + } + if (off + count > EEPROM_SIZE) { + count = EEPROM_SIZE - off; + } + if (count == 0) { + return 0; + } + + mutex_lock(&data->update_lock); + + for(i=0; i < count; i++) { + /* write command */ + cmd = (off >> 8) & 0xff; + value16 = off & 0xff; + value16 |= buf[i] << 8; + ret = i2c_smbus_write_word_data(client, cmd, value16); + + if (ret < 0) { + dev_err(&client->dev, "write address failed at %d \n", (int)off); + goto exit; + } + + off++; + + /* need to wait for write complete */ + udelay(10000); + } +exit: + mutex_unlock(&data->update_lock); + /* force to update client when reading */ + for(i=0; i < SLICE_NUM; i++) { + data->last_updated[i] = 0; + } + + return count; +} + +static struct bin_attribute mb_eeprom_attr = { + .attr = { + .name = "eeprom", + .mode = S_IRUGO | S_IWUSR, + }, + .size = EEPROM_SIZE, + .read = mb_eeprom_read, + .write = mb_eeprom_write, +}; + +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int mb_eeprom_detect(struct i2c_client *client, struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = client->adapter; + + /* EDID EEPROMs are often 24C00 EEPROMs, which answer to all + addresses 0x50-0x57, but we only care about 0x51 and 0x55. So decline + attaching to addresses >= 0x56 on DDC buses */ + if (!(adapter->class & I2C_CLASS_SPD) && client->addr >= 0x56) { + return -ENODEV; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE) + && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { + return -ENODEV; + } + + strlcpy(info->type, "eeprom", I2C_NAME_SIZE); + + return 0; +} + +static int mb_eeprom_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct eeprom_data *data; + int err; + + if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) { + err = -ENOMEM; + goto exit; + } + + memset(data->data, 0xff, EEPROM_SIZE); + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + /* create the sysfs eeprom file */ + err = sysfs_create_bin_file(&client->dev.kobj, &mb_eeprom_attr); + if (err) { + goto exit_kfree; + } + + return 0; + +exit_kfree: + kfree(data); +exit: + return err; +} + +static int mb_eeprom_remove(struct i2c_client *client) +{ + sysfs_remove_bin_file(&client->dev.kobj, &mb_eeprom_attr); + kfree(i2c_get_clientdata(client)); + + return 0; +} + +static const struct i2c_device_id mb_eeprom_id[] = { + { "mb_eeprom", 0 }, + { } +}; + +static struct i2c_driver mb_eeprom_driver = { + .driver = { + .name = "mb_eeprom", + }, + .probe = mb_eeprom_probe, + .remove = mb_eeprom_remove, + .id_table = mb_eeprom_id, + + .class = I2C_CLASS_DDC | I2C_CLASS_SPD, + .detect = mb_eeprom_detect, + .address_list = normal_i2c, +}; + +module_i2c_driver(mb_eeprom_driver); + +MODULE_AUTHOR("Wade "); +MODULE_DESCRIPTION("Ingrasys Mother Borad EEPROM driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/modules/ingrasys_s9230_64x_i2c_cpld.c b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/modules/ingrasys_s9230_64x_i2c_cpld.c new file mode 100644 index 000000000000..7d832fc0149f --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/modules/ingrasys_s9230_64x_i2c_cpld.c @@ -0,0 +1,1259 @@ +/* + * A i2c cpld driver for the ingrasys_s9230_64x + * + * Copyright (C) 2017 Ingrasys Technology Corporation. + * Leo Lin + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ingrasys_s9230_64x_i2c_cpld.h" + +#ifdef DEBUG +#define DEBUG_PRINT(fmt, args...) \ + printk(KERN_INFO "%s:%s[%d]: " fmt "\r\n", \ + __FILE__, __func__, __LINE__, ##args) +#else +#define DEBUG_PRINT(fmt, args...) +#endif + +#define I2C_READ_BYTE_DATA(ret, lock, i2c_client, reg) \ +{ \ + mutex_lock(lock); \ + ret = i2c_smbus_read_byte_data(i2c_client, reg); \ + mutex_unlock(lock); \ +} +#define I2C_WRITE_BYTE_DATA(ret, lock, i2c_client, reg, val) \ +{ \ + mutex_lock(lock); \ + ret = i2c_smbus_write_byte_data(i2c_client, reg, val); \ + mutex_unlock(lock); \ +} + +/* CPLD sysfs attributes index */ +enum s9230_64x_cpld_sysfs_attributes { + CPLD_ACCESS_REG, + CPLD_REGISTER_VAL, + CPLD_PORT_START, + CPLD_PORTS, + CPLD_VERSION, + CPLD_ID, + CPLD_BOARD_TYPE, + CPLD_EXT_BOARD_TYPE, + CPLD_QSFP_PORT_STATUS_1, + CPLD_QSFP_PORT_STATUS_2, + CPLD_QSFP_PORT_STATUS_3, + CPLD_QSFP_PORT_STATUS_4, + CPLD_QSFP_PORT_STATUS_5, + CPLD_QSFP_PORT_STATUS_6, + CPLD_QSFP_PORT_STATUS_7, + CPLD_QSFP_PORT_STATUS_8, + CPLD_QSFP_PORT_STATUS_9, + CPLD_QSFP_PORT_STATUS_10, + CPLD_QSFP_PORT_STATUS_11, + CPLD_QSFP_PORT_STATUS_12, + CPLD_QSFP_PORT_STATUS_13, + CPLD_QSFP_PORT_CONFIG_1, + CPLD_QSFP_PORT_CONFIG_2, + CPLD_QSFP_PORT_CONFIG_3, + CPLD_QSFP_PORT_CONFIG_4, + CPLD_QSFP_PORT_CONFIG_5, + CPLD_QSFP_PORT_CONFIG_6, + CPLD_QSFP_PORT_CONFIG_7, + CPLD_QSFP_PORT_CONFIG_8, + CPLD_QSFP_PORT_CONFIG_9, + CPLD_QSFP_PORT_CONFIG_10, + CPLD_QSFP_PORT_CONFIG_11, + CPLD_QSFP_PORT_CONFIG_12, + CPLD_QSFP_PORT_CONFIG_13, + CPLD_QSFP_PORT_INTERRUPT, + CPLD_SFP_PORT_STATUS, + CPLD_SFP_PORT_CONFIG, + CPLD_10GMUX_CONFIG, + CPLD_BMC_STATUS, + CPLD_BMC_WATCHDOG, + CPLD_USB_STATUS, +}; + +/* CPLD sysfs attributes hook functions */ +static ssize_t read_access_register(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t write_access_register(struct device *dev, + struct device_attribute *da, const char *buf, size_t count); +static ssize_t read_register_value(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t write_register_value(struct device *dev, + struct device_attribute *da, const char *buf, size_t count); +static ssize_t get_qsfp_port_start(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t get_qsfp_ports(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_cpld_version(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_cpld_id(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_board_type(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_ext_board_type(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_qsfp_port_status(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_qsfp_port_config(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t write_qsfp_port_config(struct device *dev, + struct device_attribute *da, const char *buf, size_t count); +static ssize_t read_qsfp_port_interrupt(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_sfp_port_status(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_sfp_port_config(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t write_sfp_port_config(struct device *dev, + struct device_attribute *da, const char *buf, size_t count); +static ssize_t read_10gmux_config(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t write_10gmux_config(struct device *dev, + struct device_attribute *da, const char *buf, size_t count); +static ssize_t read_bmc_status(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t read_bmc_watchdog(struct device *dev, + struct device_attribute *da, char *buf); +static ssize_t write_bmc_watchdog(struct device *dev, + struct device_attribute *da, const char *buf, size_t count); +static ssize_t read_usb_status(struct device *dev, + struct device_attribute *da, char *buf); + +static LIST_HEAD(cpld_client_list); /* client list for cpld */ +static struct mutex list_lock; /* mutex for client list */ + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; + +struct cpld_data { + int index; /* CPLD index */ + struct mutex access_lock; /* mutex for cpld access */ + u8 access_reg; /* register to access */ +}; + +/* CPLD device id and data */ +static const struct i2c_device_id ingrasys_i2c_cpld_id[] = { + { "ingrasys_cpld1", cpld1 }, + { "ingrasys_cpld2", cpld2 }, + { "ingrasys_cpld3", cpld3 }, + { "ingrasys_cpld4", cpld4 }, + { "ingrasys_cpld5", cpld5 }, + {} +}; + +/* Addresses scanned for ingrasys_i2c_cpld */ +static const unsigned short cpld_i2c_addr[] = { 0x33, I2C_CLIENT_END }; + +/* define all support register access of cpld in attribute */ +static SENSOR_DEVICE_ATTR(cpld_access_register, S_IWUSR | S_IRUGO, + read_access_register, write_access_register, CPLD_ACCESS_REG); +static SENSOR_DEVICE_ATTR(cpld_register_value, S_IWUSR | S_IRUGO, + read_register_value, write_register_value, CPLD_REGISTER_VAL); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_start, S_IRUGO, + get_qsfp_port_start, NULL, CPLD_PORT_START); +static SENSOR_DEVICE_ATTR(cpld_qsfp_ports, S_IRUGO, + get_qsfp_ports, NULL, CPLD_PORTS); +static SENSOR_DEVICE_ATTR(cpld_version, S_IRUGO, + read_cpld_version, NULL, CPLD_VERSION); +static SENSOR_DEVICE_ATTR(cpld_id, S_IRUGO, read_cpld_id, NULL, CPLD_ID); +static SENSOR_DEVICE_ATTR(cpld_board_type, S_IRUGO, + read_board_type, NULL, CPLD_BOARD_TYPE); +static SENSOR_DEVICE_ATTR(cpld_ext_board_type, S_IRUGO, + read_ext_board_type, NULL, CPLD_EXT_BOARD_TYPE); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_status_1, S_IRUGO, + read_qsfp_port_status, NULL, CPLD_QSFP_PORT_STATUS_1); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_status_2, S_IRUGO, + read_qsfp_port_status, NULL, CPLD_QSFP_PORT_STATUS_2); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_status_3, S_IRUGO, + read_qsfp_port_status, NULL, CPLD_QSFP_PORT_STATUS_3); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_status_4, S_IRUGO, + read_qsfp_port_status, NULL, CPLD_QSFP_PORT_STATUS_4); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_status_5, S_IRUGO, + read_qsfp_port_status, NULL, CPLD_QSFP_PORT_STATUS_5); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_status_6, S_IRUGO, + read_qsfp_port_status, NULL, CPLD_QSFP_PORT_STATUS_6); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_status_7, S_IRUGO, + read_qsfp_port_status, NULL, CPLD_QSFP_PORT_STATUS_7); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_status_8, S_IRUGO, + read_qsfp_port_status, NULL, CPLD_QSFP_PORT_STATUS_8); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_status_9, S_IRUGO, + read_qsfp_port_status, NULL, CPLD_QSFP_PORT_STATUS_9); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_status_10, S_IRUGO, + read_qsfp_port_status, NULL, CPLD_QSFP_PORT_STATUS_10); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_status_11, S_IRUGO, + read_qsfp_port_status, NULL, CPLD_QSFP_PORT_STATUS_11); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_status_12, S_IRUGO, + read_qsfp_port_status, NULL, CPLD_QSFP_PORT_STATUS_12); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_status_13, S_IRUGO, + read_qsfp_port_status, NULL, CPLD_QSFP_PORT_STATUS_13); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_config_1, S_IWUSR | S_IRUGO, + read_qsfp_port_config, write_qsfp_port_config, CPLD_QSFP_PORT_CONFIG_1); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_config_2, S_IWUSR | S_IRUGO, + read_qsfp_port_config, write_qsfp_port_config, + CPLD_QSFP_PORT_CONFIG_2); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_config_3, S_IWUSR | S_IRUGO, + read_qsfp_port_config, write_qsfp_port_config, + CPLD_QSFP_PORT_CONFIG_3); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_config_4, S_IWUSR | S_IRUGO, + read_qsfp_port_config, write_qsfp_port_config, + CPLD_QSFP_PORT_CONFIG_4); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_config_5, S_IWUSR | S_IRUGO, + read_qsfp_port_config, write_qsfp_port_config, + CPLD_QSFP_PORT_CONFIG_5); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_config_6, S_IWUSR | S_IRUGO, + read_qsfp_port_config, write_qsfp_port_config, + CPLD_QSFP_PORT_CONFIG_6); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_config_7, S_IWUSR | S_IRUGO, + read_qsfp_port_config, write_qsfp_port_config, + CPLD_QSFP_PORT_CONFIG_7); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_config_8, S_IWUSR | S_IRUGO, + read_qsfp_port_config, write_qsfp_port_config, + CPLD_QSFP_PORT_CONFIG_8); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_config_9, S_IWUSR | S_IRUGO, + read_qsfp_port_config, write_qsfp_port_config, + CPLD_QSFP_PORT_CONFIG_9); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_config_10, S_IWUSR | S_IRUGO, + read_qsfp_port_config, write_qsfp_port_config, + CPLD_QSFP_PORT_CONFIG_10); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_config_11, S_IWUSR | S_IRUGO, + read_qsfp_port_config, write_qsfp_port_config, + CPLD_QSFP_PORT_CONFIG_11); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_config_12, S_IWUSR | S_IRUGO, + read_qsfp_port_config, write_qsfp_port_config, + CPLD_QSFP_PORT_CONFIG_12); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_config_13, S_IWUSR | S_IRUGO, + read_qsfp_port_config, write_qsfp_port_config, + CPLD_QSFP_PORT_CONFIG_13); +static SENSOR_DEVICE_ATTR(cpld_qsfp_port_interrupt, S_IRUGO, + read_qsfp_port_interrupt, NULL, CPLD_QSFP_PORT_INTERRUPT); +static SENSOR_DEVICE_ATTR(cpld_sfp_port_status, S_IRUGO, + read_sfp_port_status, NULL, CPLD_SFP_PORT_STATUS); +static SENSOR_DEVICE_ATTR(cpld_sfp_port_config, S_IWUSR | S_IRUGO, + read_sfp_port_config, write_sfp_port_config, CPLD_SFP_PORT_CONFIG); +static SENSOR_DEVICE_ATTR(cpld_10gmux_config, S_IWUSR | S_IRUGO, + read_10gmux_config, write_10gmux_config, + CPLD_10GMUX_CONFIG); +static SENSOR_DEVICE_ATTR(cpld_bmc_status, S_IRUGO, + read_bmc_status, NULL, CPLD_BMC_STATUS); +static SENSOR_DEVICE_ATTR(cpld_bmc_watchdog, S_IWUSR | S_IRUGO, + read_bmc_watchdog, write_bmc_watchdog, + CPLD_BMC_WATCHDOG); +static SENSOR_DEVICE_ATTR(cpld_usb_status, S_IRUGO, + read_usb_status, NULL, CPLD_USB_STATUS); + + +/* define support attributes of cpldx , total 5 */ +/* cpld 1 */ +static struct attribute *s9230_64x_cpld1_attributes[] = { + &sensor_dev_attr_cpld_access_register.dev_attr.attr, + &sensor_dev_attr_cpld_register_value.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_start.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_ports.dev_attr.attr, + &sensor_dev_attr_cpld_version.dev_attr.attr, + &sensor_dev_attr_cpld_id.dev_attr.attr, + &sensor_dev_attr_cpld_board_type.dev_attr.attr, + &sensor_dev_attr_cpld_ext_board_type.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_1.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_2.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_3.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_4.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_5.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_6.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_7.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_8.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_9.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_10.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_11.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_12.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_1.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_2.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_3.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_4.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_5.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_6.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_7.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_8.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_9.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_10.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_11.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_12.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_interrupt.dev_attr.attr, + &sensor_dev_attr_cpld_sfp_port_status.dev_attr.attr, + &sensor_dev_attr_cpld_sfp_port_config.dev_attr.attr, + &sensor_dev_attr_cpld_10gmux_config.dev_attr.attr, + &sensor_dev_attr_cpld_bmc_status.dev_attr.attr, + &sensor_dev_attr_cpld_bmc_watchdog.dev_attr.attr, + &sensor_dev_attr_cpld_usb_status.dev_attr.attr, + NULL +}; +/* cpld 2 */ +static struct attribute *s9230_64x_cpld2_attributes[] = { + &sensor_dev_attr_cpld_access_register.dev_attr.attr, + &sensor_dev_attr_cpld_register_value.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_start.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_ports.dev_attr.attr, + &sensor_dev_attr_cpld_version.dev_attr.attr, + &sensor_dev_attr_cpld_id.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_1.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_2.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_3.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_4.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_5.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_6.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_7.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_8.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_9.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_10.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_11.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_12.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_13.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_1.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_2.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_3.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_4.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_5.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_6.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_7.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_8.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_9.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_10.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_11.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_12.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_13.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_interrupt.dev_attr.attr, + &sensor_dev_attr_cpld_sfp_port_status.dev_attr.attr, + &sensor_dev_attr_cpld_sfp_port_config.dev_attr.attr, + NULL +}; +/* cpld 3 / cpld 4 / cpld 5 */ +static struct attribute *s9230_64x_cpld345_attributes[] = { +&sensor_dev_attr_cpld_access_register.dev_attr.attr, + &sensor_dev_attr_cpld_register_value.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_start.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_ports.dev_attr.attr, + &sensor_dev_attr_cpld_version.dev_attr.attr, + &sensor_dev_attr_cpld_id.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_1.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_2.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_3.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_4.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_5.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_6.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_7.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_8.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_9.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_10.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_11.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_12.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_status_13.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_1.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_2.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_3.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_4.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_5.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_6.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_7.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_8.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_9.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_10.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_11.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_12.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_config_13.dev_attr.attr, + &sensor_dev_attr_cpld_qsfp_port_interrupt.dev_attr.attr, + NULL +}; + +/* cpld 1 attributes group */ +static const struct attribute_group s9230_64x_cpld1_group = { + .attrs = s9230_64x_cpld1_attributes, +}; +/* cpld 2 attributes group */ +static const struct attribute_group s9230_64x_cpld2_group = { + .attrs = s9230_64x_cpld2_attributes, +}; +/* cpld 3/4/5 attributes group */ +static const struct attribute_group s9230_64x_cpld345_group = { + .attrs = s9230_64x_cpld345_attributes, +}; + +/* read access register from cpld data */ +static ssize_t read_access_register(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg = data->access_reg; + + return sprintf(buf, "0x%x\n", reg); +} + +/* write access register to cpld data */ +static ssize_t write_access_register(struct device *dev, + struct device_attribute *da, + const char *buf, + size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + + if (kstrtou8(buf, 0, ®) < 0) + return -EINVAL; + + data->access_reg = reg; + return count; +} + +/* read the value of access register in cpld data */ +static ssize_t read_register_value(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg = data->access_reg; + int reg_val; + + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + + if (reg_val < 0) + return -1; + + return sprintf(buf, "0x%x\n", reg_val); +} + +/* wrtie the value to access register in cpld data */ +static ssize_t write_register_value(struct device *dev, + struct device_attribute *da, + const char *buf, + size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + int ret = -EIO; + u8 reg = data->access_reg; + u8 reg_val; + + if (kstrtou8(buf, 0, ®_val) < 0) + return -EINVAL; + + I2C_WRITE_BYTE_DATA(ret, &data->access_lock, client, reg, reg_val); + + return count; +} + +/* get qsfp port start number of the cpld device */ +/* the start number use to tranlate qsfp port to cpld port */ +/* the cpld port use to access the qsfp port register in cpld */ +static ssize_t get_qsfp_port_start(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + int port_base_num; + + if (attr->index == CPLD_PORT_START) { + if (data->index == cpld1) { + port_base_num = 1; + } else { + port_base_num = CPLD_1_PORT_NUM + + CPLD_2_PORT_NUM*(data->index - 1) + 1; + } + return sprintf(buf, "%d\n", port_base_num); + } + return -1; +} + +/* get total qsfp port which contain register in the cpld device */ +static ssize_t get_qsfp_ports(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + int ports; + + if (attr->index == CPLD_PORTS) { + if (data->index == cpld1) + ports = CPLD_1_PORT_NUM; + else + ports = CPLD_2_PORT_NUM; + return sprintf(buf, "%d\n", ports); + } + return -1; +} + +/* get cpdl version register value */ +static ssize_t read_cpld_version(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_VERSION) { + reg = CPLD_VERSION_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* get cpdl id register value */ +static ssize_t read_cpld_id(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_ID) { + reg = CPLD_ID_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* get board type register value */ +static ssize_t read_board_type(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_BOARD_TYPE) { + reg = CPLD_BOARD_TYPE_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* get extend board type register value */ +static ssize_t read_ext_board_type(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_EXT_BOARD_TYPE) { + reg = CPLD_EXT_BOARD_TYPE_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* get qsfp port status register value */ +static ssize_t read_qsfp_port_status(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index >= CPLD_QSFP_PORT_STATUS_1 && + attr->index <= CPLD_QSFP_PORT_STATUS_13) { + reg = CPLD_QSFP_PORT_STATUS_BASE_REG + + (attr->index - CPLD_QSFP_PORT_STATUS_1); + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* get qsfp port config register value */ +static ssize_t read_qsfp_port_config(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index >= CPLD_QSFP_PORT_CONFIG_1 && + attr->index <= CPLD_QSFP_PORT_CONFIG_13) { + reg = CPLD_QSFP_PORT_CONFIG_BASE_REG + + (attr->index - CPLD_QSFP_PORT_CONFIG_1); + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* set value to qsfp port config register */ +static ssize_t write_qsfp_port_config(struct device *dev, + struct device_attribute *da, + const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg, reg_val; + int ret; + + if (kstrtou8(buf, 0, ®_val) < 0) + return -EINVAL; + + if (attr->index >= CPLD_QSFP_PORT_CONFIG_1 && + attr->index <= CPLD_QSFP_PORT_CONFIG_13) { + reg = CPLD_QSFP_PORT_CONFIG_BASE_REG + + (attr->index - CPLD_QSFP_PORT_CONFIG_1); + I2C_WRITE_BYTE_DATA(ret, &data->access_lock, + client, reg, reg_val); + } + return count; +} + +/* get qsfp port interrupt register value */ +static ssize_t read_qsfp_port_interrupt(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_QSFP_PORT_INTERRUPT) { + reg = CPLD_QSFP_PORT_INTERRUPT_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* get sfp port status register value */ +static ssize_t read_sfp_port_status(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_SFP_PORT_STATUS) { + reg = CPLD_SFP_PORT_STATUS_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* get sfp port config register value */ +static ssize_t read_sfp_port_config(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_SFP_PORT_CONFIG) { + reg = CPLD_SFP_PORT_CONFIG_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* set value to sfp port config register */ +static ssize_t write_sfp_port_config(struct device *dev, + struct device_attribute *da, + const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg, reg_val; + int ret; + + if (kstrtou8(buf, 0, ®_val) < 0) + return -EINVAL; + + if (attr->index == CPLD_SFP_PORT_CONFIG) { + reg = CPLD_SFP_PORT_CONFIG_REG; + I2C_WRITE_BYTE_DATA(ret, &data->access_lock, + client, reg, reg_val); + } + return count; +} + +/* get 10g mux config register value */ +static ssize_t read_10gmux_config(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_10GMUX_CONFIG) { + reg = CPLD_10GMUX_CONFIG_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* set value to 10g mux config register */ +static ssize_t write_10gmux_config(struct device *dev, + struct device_attribute *da, + const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg, reg_val; + int ret; + + if (kstrtou8(buf, 0, ®_val) < 0) + return -EINVAL; + + if (attr->index == CPLD_10GMUX_CONFIG) { + reg = CPLD_10GMUX_CONFIG_REG; + I2C_WRITE_BYTE_DATA(ret, &data->access_lock, + client, reg, reg_val); + } + return count; +} + +/* get bmc status register value */ +static ssize_t read_bmc_status(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_BMC_STATUS) { + reg = CPLD_BMC_STATUS_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* get bmc watchdog register value */ +static ssize_t read_bmc_watchdog(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_BMC_WATCHDOG) { + reg = CPLD_BMC_WATCHDOG_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* set value to bmc watchdog register */ +static ssize_t write_bmc_watchdog(struct device *dev, + struct device_attribute *da, + const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg, reg_val; + int ret; + + if (kstrtou8(buf, 0, ®_val) < 0) + return -EINVAL; + + if (attr->index == CPLD_BMC_WATCHDOG) { + reg = CPLD_BMC_WATCHDOG_REG; + I2C_WRITE_BYTE_DATA(ret, &data->access_lock, + client, reg, reg_val); + } + return count; +} + +/* get usb status register value */ +static ssize_t read_usb_status(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + u8 reg; + int reg_val; + + if (attr->index == CPLD_USB_STATUS) { + reg = CPLD_USB_STATUS_REG; + I2C_READ_BYTE_DATA(reg_val, &data->access_lock, client, reg); + if (reg_val < 0) + return -1; + return sprintf(buf, "0x%02x\n", reg_val); + } + return -1; +} + +/* add valid cpld client to list */ +static void ingrasys_i2c_cpld_add_client(struct i2c_client *client) +{ + struct cpld_client_node *node = NULL; + + node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); + if (!node) { + dev_info(&client->dev, + "Can't allocate cpld_client_node for index %d\n", + client->addr); + return; + } + + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &cpld_client_list); + mutex_unlock(&list_lock); +} + +/* remove exist cpld client in list */ +static void ingrasys_i2c_cpld_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + list_for_each(list_node, &cpld_client_list) { + cpld_node = list_entry(list_node, + struct cpld_client_node, list); + + if (cpld_node->client == client) { + found = 1; + break; + } + } + + if (found) { + list_del(list_node); + kfree(cpld_node); + } + mutex_unlock(&list_lock); +} + +/* cpld drvier probe */ +static int ingrasys_i2c_cpld_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int status; + struct cpld_data *data = NULL; + int ret = -EPERM; + int err; + int idx; + + data = kzalloc(sizeof(struct cpld_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + /* init cpld data for client */ + i2c_set_clientdata(client, data); + mutex_init(&data->access_lock); + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_info(&client->dev, + "i2c_check_functionality failed (0x%x)\n", + client->addr); + status = -EIO; + goto exit; + } + + /* get cpld id from device */ + ret = i2c_smbus_read_byte_data(client, CPLD_ID_REG); + + if (ret < 0) { + dev_info(&client->dev, + "fail to get cpld id (0x%x) at addr (0x%x)\n", + CPLD_ID_REG, client->addr); + status = -EIO; + goto exit; + } + + CPLD_ID_ID_GET(ret, idx); + + if (INVALID(idx, cpld1, cpld5)) { + dev_info(&client->dev, + "cpld id %d(device) not valid\n", idx); + //status = -EPERM; + //goto exit; + } + +#if 0 + /* change client name for each cpld with index */ + snprintf(client->name, sizeof(client->name), "%s_%d", client->name, + data->index); +#endif + + data->index = dev_id->driver_data; + + /* register sysfs hooks for different cpld group */ + dev_info(&client->dev, "probe cpld with index %d\n", data->index); + switch (data->index) { + case cpld1: + status = sysfs_create_group(&client->dev.kobj, + &s9230_64x_cpld1_group); + break; + case cpld2: + status = sysfs_create_group(&client->dev.kobj, + &s9230_64x_cpld2_group); + break; + case cpld3: + case cpld4: + case cpld5: + status = sysfs_create_group(&client->dev.kobj, + &s9230_64x_cpld345_group); + break; + default: + status = -EINVAL; + } + + if (status) + goto exit; + + dev_info(&client->dev, "chip found\n"); + + /* add probe chip to client list */ + ingrasys_i2c_cpld_add_client(client); + + return 0; +exit: + sysfs_remove_group(&client->dev.kobj, &s9230_64x_cpld345_group); + return status; +} + +/* cpld drvier remove */ +static int ingrasys_i2c_cpld_remove(struct i2c_client *client) +{ + struct cpld_data *data = i2c_get_clientdata(client); + + switch (data->index) { + case cpld1: + sysfs_remove_group(&client->dev.kobj, &s9230_64x_cpld1_group); + break; + case cpld2: + sysfs_remove_group(&client->dev.kobj, &s9230_64x_cpld2_group); + break; + case cpld3: + case cpld4: + case cpld5: + sysfs_remove_group(&client->dev.kobj, + &s9230_64x_cpld345_group); + break; + } + + ingrasys_i2c_cpld_remove_client(client); + return 0; +} + +MODULE_DEVICE_TABLE(i2c, ingrasys_i2c_cpld_id); + +static struct i2c_driver ingrasys_i2c_cpld_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "ingrasys_i2c_cpld", + }, + .probe = ingrasys_i2c_cpld_probe, + .remove = ingrasys_i2c_cpld_remove, + .id_table = ingrasys_i2c_cpld_id, + .address_list = cpld_i2c_addr, +}; + +/* provid cpld register read */ +/* cpld_idx indicate the index of cpld device */ +int ingrasys_i2c_cpld_read(u8 cpld_idx, + u8 reg) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EPERM; + struct cpld_data *data; + + list_for_each(list_node, &cpld_client_list) { + cpld_node = list_entry(list_node, + struct cpld_client_node, list); + data = i2c_get_clientdata(cpld_node->client); + if (data->index == cpld_idx) { + DEBUG_PRINT("cpld_idx=%d, read reg 0x%02x", + cpld_idx, reg); + I2C_READ_BYTE_DATA(ret, &data->access_lock, + cpld_node->client, reg); + DEBUG_PRINT("cpld_idx=%d, read reg 0x%02x = 0x%02x", + cpld_idx, reg, ret); + break; + } + } + + return ret; +} +EXPORT_SYMBOL(ingrasys_i2c_cpld_read); + +/* provid cpld register write */ +/* cpld_idx indicate the index of cpld device */ +int ingrasys_i2c_cpld_write(u8 cpld_idx, + u8 reg, + u8 value) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EIO; + struct cpld_data *data; + + list_for_each(list_node, &cpld_client_list) { + cpld_node = list_entry(list_node, + struct cpld_client_node, list); + data = i2c_get_clientdata(cpld_node->client); + + if (data->index == cpld_idx) { + I2C_WRITE_BYTE_DATA(ret, &data->access_lock, + cpld_node->client, + reg, value); + DEBUG_PRINT("cpld_idx=%d, write reg 0x%02x val 0x%02x, ret=%d", + cpld_idx, reg, value, ret); + break; + } + } + + return ret; +} +EXPORT_SYMBOL(ingrasys_i2c_cpld_write); + +/* provid qsfp port status register read */ +/* port_num indicate the front panel qsfp port number */ +int ingrasys_i2c_cpld_get_qsfp_port_status_val(u8 port_num) +{ + u8 cpld_idx, cpld_port, reg; + int reg_val; + + if (INVALID(port_num, QSFP_MIN_PORT_NUM, QSFP_MAX_PORT_NUM)) { + DEBUG_PRINT("invalid input value %d", port_num); + return -1; + } + QSFP_TO_CPLD_IDX(port_num, cpld_idx, cpld_port); + reg = QSFP_PORT_STATUS_REG(cpld_port); + DEBUG_PRINT("port_num=%d, cpld_idx=%d, cpld_port=%d, reg=0x%x", + port_num, cpld_idx, cpld_port, reg); + reg_val = ingrasys_i2c_cpld_read(cpld_idx, reg); + return reg_val; +} +EXPORT_SYMBOL(ingrasys_i2c_cpld_get_qsfp_port_status_val); + +/* provid qsfp port config register read */ +/* port_num indicate the front panel qsfp port number */ +int ingrasys_i2c_cpld_get_qsfp_port_config_val(u8 port_num) +{ + u8 cpld_idx, cpld_port, reg; + int reg_val; + + if (INVALID(port_num, QSFP_MIN_PORT_NUM, QSFP_MAX_PORT_NUM)) { + DEBUG_PRINT("invalid input value %d", port_num); + return -1; + } + QSFP_TO_CPLD_IDX(port_num, cpld_idx, cpld_port); + reg = QSFP_PORT_CONFIG_REG(cpld_port); + DEBUG_PRINT("port_num=%d, cpld_idx=%d, cpld_port=%d, reg=0x%x", + port_num, cpld_idx, cpld_port, reg); + reg_val = ingrasys_i2c_cpld_read(cpld_idx, reg); + return reg_val; +} +EXPORT_SYMBOL(ingrasys_i2c_cpld_get_qsfp_port_config_val); + +/* provid qsfp port config register write */ +/* port_num indicate the front panel qsfp port number */ +int ingrasys_i2c_cpld_set_qsfp_port_config_val(u8 port_num, + u8 reg_val) +{ + u8 cpld_idx, cpld_port, reg, ret; + + if (INVALID(port_num, QSFP_MIN_PORT_NUM, QSFP_MAX_PORT_NUM)) { + DEBUG_PRINT("invalid input value %d", port_num); + return -1; + } + QSFP_TO_CPLD_IDX(port_num, cpld_idx, cpld_port); + reg = QSFP_PORT_CONFIG_REG(cpld_port); + DEBUG_PRINT("port_num=%d, cpld_idx=%d, cpld_port=%d, reg=0x%x", + port_num, cpld_idx, cpld_port, reg); + ret = ingrasys_i2c_cpld_write(cpld_idx, reg, reg_val); + return ret; +} +EXPORT_SYMBOL(ingrasys_i2c_cpld_set_qsfp_port_config_val); + +/* provid sfp port status register read */ +/* port_num indicate the front panel qsfp port number */ +int ingrasys_i2c_cpld_get_sfp_port_status_val(u8 port_num) +{ + u8 cpld_idx, reg; + int reg_val; + + if (INVALID(port_num, SFP_MIN_PORT_NUM, SFP_MAX_PORT_NUM)) { + DEBUG_PRINT("invalid input value %d", port_num); + return -1; + } + SFP_TO_CPLD_IDX(port_num, cpld_idx); + reg = CPLD_SFP_PORT_STATUS_REG; + DEBUG_PRINT("port_num=%d, cpld_idx=%d, reg=0x%x", + port_num, cpld_idx, reg); + reg_val = ingrasys_i2c_cpld_read(cpld_idx, reg); + return reg_val; +} +EXPORT_SYMBOL(ingrasys_i2c_cpld_get_sfp_port_status_val); + +/* provid qsfp port config register read */ +/* port_num indicate the front panel qsfp port number */ +int ingrasys_i2c_cpld_get_sfp_port_config_val(u8 port_num) +{ + u8 cpld_idx, reg; + int reg_val; + + if (INVALID(port_num, SFP_MIN_PORT_NUM, SFP_MAX_PORT_NUM)) { + DEBUG_PRINT("invalid input value %d", port_num); + return -1; + } + SFP_TO_CPLD_IDX(port_num, cpld_idx); + reg = CPLD_SFP_PORT_CONFIG_REG; + DEBUG_PRINT("port_num=%d, cpld_idx=%d, reg=0x%x", + port_num, cpld_idx, reg); + reg_val = ingrasys_i2c_cpld_read(cpld_idx, reg); + return reg_val; +} +EXPORT_SYMBOL(ingrasys_i2c_cpld_get_sfp_port_config_val); + +/* provid qsfp port config register write */ +/* port_num indicate the front panel qsfp port number */ +int ingrasys_i2c_cpld_set_sfp_port_config_val(u8 port_num, + u8 reg_val) +{ + u8 cpld_idx, reg, ret; + + if (INVALID(port_num, SFP_MIN_PORT_NUM, SFP_MAX_PORT_NUM)) { + DEBUG_PRINT("invalid input value %d", port_num); + return -1; + } + SFP_TO_CPLD_IDX(port_num, cpld_idx); + reg = CPLD_SFP_PORT_CONFIG_REG; + DEBUG_PRINT("port_num=%d, cpld_idx=%d, reg=0x%x", + port_num, cpld_idx, reg); + ret = ingrasys_i2c_cpld_write(cpld_idx, reg, reg_val); + return ret; +} +EXPORT_SYMBOL(ingrasys_i2c_cpld_set_sfp_port_config_val); + +static int __init ingrasys_i2c_cpld_init(void) +{ + mutex_init(&list_lock); + return i2c_add_driver(&ingrasys_i2c_cpld_driver); +} + +static void __exit ingrasys_i2c_cpld_exit(void) +{ + i2c_del_driver(&ingrasys_i2c_cpld_driver); +} + +MODULE_AUTHOR("Leo Lin "); +MODULE_DESCRIPTION("ingrasys_i2c_cpld driver"); +MODULE_LICENSE("GPL"); + +module_init(ingrasys_i2c_cpld_init); +module_exit(ingrasys_i2c_cpld_exit); + diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/modules/ingrasys_s9230_64x_i2c_cpld.h b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/modules/ingrasys_s9230_64x_i2c_cpld.h new file mode 100644 index 000000000000..e0e53174d675 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/modules/ingrasys_s9230_64x_i2c_cpld.h @@ -0,0 +1,223 @@ +/* header file for i2c cpld driver of ingrasys_s9230_64x + * + * Copyright (C) 2017 Ingrasys Technology Corporation. + * Leo Lin + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef INGRASYS_S9230_64X_I2C_CPLD_H +#define INGRASYS_S9230_64X_I2C_CPLD_H + +/* CPLD device index value */ +enum cpld_id { + cpld1, + cpld2, + cpld3, + cpld4, + cpld5 +}; + +/* port number on CPLD */ +#define CPLD_1_PORT_NUM 12 +#define CPLD_2_PORT_NUM 13 + +/* QSFP port number */ +#define QSFP_MAX_PORT_NUM 64 +#define QSFP_MIN_PORT_NUM 1 + +/* SFP+ port number */ +#define SFP_MAX_PORT_NUM 2 +#define SFP_MIN_PORT_NUM 1 + + +/* CPLD registers */ +#define CPLD_BOARD_TYPE_REG 0x0 +#define CPLD_EXT_BOARD_TYPE_REG 0x7 +#define CPLD_VERSION_REG 0x1 +#define CPLD_ID_REG 0x2 +#define CPLD_QSFP_PORT_STATUS_BASE_REG 0x20 +#define CPLD_QSFP_PORT_CONFIG_BASE_REG 0x30 +#define CPLD_QSFP_PORT_INTERRUPT_REG 0x40 +#define CPLD_SFP_PORT_STATUS_REG 0x2F +#define CPLD_SFP_PORT_CONFIG_REG 0x3F +#define CPLD_QSFP_PORT_INTERRUPT_REG 0x40 +#define CPLD_10GMUX_CONFIG_REG 0x41 +#define CPLD_BMC_STATUS_REG 0x42 +#define CPLD_BMC_WATCHDOG_REG 0x43 +#define CPLD_USB_STATUS_REG 0x44 +#define CPLD_REST_CONTROL_REG 0x4A + + +/* bit definition for register value */ +enum CPLD_QSFP_PORT_STATUS_BITS { + CPLD_QSFP_PORT_STATUS_INT_BIT, + CPLD_QSFP_PORT_STATUS_ABS_BIT, +}; +enum CPLD_QSFP_PORT_CONFIG_BITS { + CPLD_QSFP_PORT_CONFIG_RESET_BIT, + CPLD_QSFP_PORT_CONFIG_RESERVE_BIT, + CPLD_QSFP_PORT_CONFIG_LPMODE_BIT, +}; +enum CPLD_SFP_PORT_STATUS_BITS { + CPLD_SFP_PORT_STATUS_PRESENT_BIT, + CPLD_SFP_PORT_STATUS_TXFAULT_BIT, + CPLD_SFP_PORT_STATUS_RXLOS_BIT, +}; +enum CPLD_SFP_PORT_CONFIG_BITS { + CPLD_SFP_PORT_CONFIG_TXDIS_BIT, + CPLD_SFP_PORT_CONFIG_RS_BIT, + CPLD_SFP_PORT_CONFIG_TS_BIT, +}; +enum CPLD_10GMUX_CONFIG_BITS { + CPLD_10GMUX_CONFIG_ENSMB_BIT, + CPLD_10GMUX_CONFIG_ENINPUT_BIT, + CPLD_10GMUX_CONFIG_SEL1_BIT, + CPLD_10GMUX_CONFIG_SEL0_BIT, +}; +enum CPLD_BMC_WATCHDOG_BITS { + CPLD_10GMUX_CONFIG_ENTIMER_BIT, + CPLD_10GMUX_CONFIG_TIMEOUT_BIT, +}; +enum CPLD_RESET_CONTROL_BITS { + CPLD_RESET_CONTROL_SWRST_BIT, + CPLD_RESET_CONTROL_CP2104RST_BIT, + CPLD_RESET_CONTROL_82P33814RST_BIT, + CPLD_RESET_CONTROL_BMCRST_BIT, +}; + +/* bit field structure for register value */ +struct cpld_reg_board_type_t { + u8 build_rev:2; + u8 hw_rev:2; + u8 board_id:4; +}; + +struct cpld_reg_version_t { + u8 revision:6; + u8 release:1; + u8 reserve:1; +}; + +struct cpld_reg_id_t { + u8 id:3; + u8 release:5; +}; + +/* common manipulation */ +#define INVALID(i, min, max) ((i < min) || (i > max) ? 1u : 0u) +#define READ_BIT(val, bit) ((0u == (val & (1<bf_name) +#define READ_BF_1(bf_struct, val, bf_name, bf_value) \ + bf_struct bf; \ + bf.data = val; \ + bf_value = bf.bf_name +#define BOARD_TYPE_BUILD_REV_GET(val, res) \ + READ_BF(cpld_reg_board_type_t, val, build_rev, res) +#define BOARD_TYPE_HW_REV_GET(val, res) \ + READ_BF(cpld_reg_board_type_t, val, hw_rev, res) +#define BOARD_TYPE_BOARD_ID_GET(val, res) \ + READ_BF(cpld_reg_board_type_t, val, board_id, res) +#define CPLD_VERSION_REV_GET(val, res) \ + READ_BF(cpld_reg_version_t, val, revision, res) +#define CPLD_VERSION_REL_GET(val, res) \ + READ_BF(cpld_reg_version_t, val, release, res) +#define CPLD_ID_ID_GET(val, res) \ + READ_BF(cpld_reg_id_t, val, id, res) +#define CPLD_ID_REL_GET(val, res) \ + READ_BF(cpld_reg_id_t, val, release, res) +/* QSFP/SFP registers manipulation */ +#define QSFP_TO_CPLD_IDX(qsfp_port, cpld_index, cpld_port) \ +{ \ + if (QSFP_MIN_PORT_NUM <= qsfp_port && qsfp_port <= CPLD_1_PORT_NUM) { \ + cpld_index = cpld1; \ + cpld_port = qsfp_port - 1; \ + } else if (CPLD_1_PORT_NUM < qsfp_port \ + && qsfp_port <= QSFP_MAX_PORT_NUM) { \ + cpld_index = cpld2 + (qsfp_port - 1 - CPLD_1_PORT_NUM) \ + / CPLD_2_PORT_NUM; \ + cpld_port = (qsfp_port - 1 - CPLD_1_PORT_NUM) % \ + CPLD_2_PORT_NUM; \ + } else { \ + cpld_index = 0; \ + cpld_port = 0; \ + } \ +} +#define SFP_TO_CPLD_IDX(sfp_port, cpld_index) \ + (cpld_index = sfp_port - SFP_MIN_PORT_NUM) +#define QSFP_PORT_STATUS_REG(cpld_port) \ + (CPLD_QSFP_PORT_STATUS_BASE_REG + cpld_port) +#define QSFP_PORT_CONFIG_REG(cpld_port) \ + (CPLD_QSFP_PORT_CONFIG_BASE_REG + cpld_port) +#define QSFP_PORT_INT_BIT_GET(port_status_value) \ + READ_BIT(port_status_value, CPLD_QSFP_PORT_STATUS_INT_BIT) +#define QSFP_PORT_ABS_BIT_GET(port_status_value) \ + READ_BIT(port_status_value, CPLD_QSFP_PORT_STATUS_ABS_BIT) +#define QSFP_PORT_RESET_BIT_GET(port_config_value) \ + READ_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_RESET_BIT) +#define QSFP_PORT_LPMODE_BIT_GET(port_config_value) \ + READ_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_LPMODE_BIT) +#define QSFP_PORT_RESET_BIT_SET(port_config_value) \ + SET_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_RESET_BIT) +#define QSFP_PORT_RESET_BIT_CLEAR(port_config_value) \ + CLEAR_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_RESET_BIT) +#define QSFP_PORT_LPMODE_BIT_SET(port_config_value) \ + SET_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_LPMODE_BIT) +#define QSFP_PORT_LPMODE_BIT_CLEAR(port_config_value) \ + CLEAR_BIT(port_config_value, CPLD_QSFP_PORT_CONFIG_LPMODE_BIT) +#define SFP_PORT_PRESENT_BIT_GET(port_status_value) \ + READ_BIT(port_status_value, CPLD_SFP_PORT_STATUS_PRESENT_BIT) + +#define SFP_PORT_TXFAULT_BIT_GET(port_status_value) \ + READ_BIT(port_status_value, CPLD_SFP_PORT_STATUS_TXFAULT_BIT) +#define SFP_PORT_RXLOS_BIT_GET(port_status_value) \ + READ_BIT(port_status_value, CPLD_SFP_PORT_STATUS_RXLOS_BIT) +#define SFP_PORT_TXDIS_BIT_GET(port_status_value) \ + READ_BIT(port_status_value, CPLD_SFP_PORT_CONFIG_TXDIS_BIT) +#define SFP_PORT_RS_BIT_GET(port_config_value) \ + READ_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_RS_BIT) +#define SFP_PORT_TS_BIT_GET(port_config_value) \ + READ_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_TS_BIT) +#define SFP_PORT_TXDIS_BIT_SET(port_config_value) \ + SET_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_TXDIS_BIT) +#define SFP_PORT_TXDIS_BIT_CLEAR(port_config_value) \ + CLEAR_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_TXDIS_BIT) +#define SFP_PORT_RS_BIT_SET(port_config_value) \ + SET_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_RS_BIT) +#define SFP_PORT_RS_BIT_CLEAR(port_config_value) \ + CLEAR_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_RS_BIT) +#define SFP_PORT_TS_BIT_SET(port_config_value) \ + SET_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_TS_BIT) +#define SFP_PORT_TS_BIT_CLEAR(port_config_value) \ + CLEAR_BIT(port_config_value, CPLD_SFP_PORT_CONFIG_TS_BIT) + +/* CPLD access functions */ +extern int ingrasys_i2c_cpld_get_qsfp_port_status_val(u8 port_num); +extern int ingrasys_i2c_cpld_get_qsfp_port_config_val(u8 port_num); +extern int ingrasys_i2c_cpld_set_qsfp_port_config_val(u8 port_num, u8 reg_val); +extern int ingrasys_i2c_cpld_get_sfp_port_status_val(u8 port_num); +extern int ingrasys_i2c_cpld_get_sfp_port_config_val(u8 port_num); +extern int ingrasys_i2c_cpld_set_sfp_port_config_val(u8 port_num, u8 reg_val); +extern u8 fp_port_to_phy_port(u8 fp_port); +#endif + diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/modules/ingrasys_s9230_64x_platform.h b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/modules/ingrasys_s9230_64x_platform.h new file mode 100644 index 000000000000..a14853fdae9c --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/modules/ingrasys_s9230_64x_platform.h @@ -0,0 +1,148 @@ +#ifndef _S9230_64X_PLATFORM_H +#define _S9230_64X_PLATFORM_H + +#include + +// remove debug before release +#define DEBUG + +enum bus_order { + I2C_BUS_MAIN, + MUX_9548_0_CH0, + MUX_9548_0_CH1, + MUX_9548_0_CH2, + MUX_9548_0_CH3, + MUX_9548_0_CH4, + MUX_9548_0_CH5, + MUX_9548_0_CH6, + MUX_9548_0_CH7, + MUX_9548_1_CH0, + MUX_9548_1_CH1, + MUX_9548_1_CH2, + MUX_9548_1_CH3, + MUX_9548_1_CH4, + MUX_9548_1_CH5, + MUX_9548_1_CH6, + MUX_9548_1_CH7, + MUX_9546_0_CH0, + MUX_9546_0_CH1, + MUX_9546_0_CH2, + MUX_9546_0_CH3, + MUX_9546_1_CH0, + MUX_9546_1_CH1, + MUX_9546_1_CH2, + MUX_9546_1_CH3, + MUX_9548_2_CH0, + MUX_9548_2_CH1, + MUX_9548_2_CH2, + MUX_9548_2_CH3, + MUX_9548_2_CH4, + MUX_9548_2_CH5, + MUX_9548_2_CH6, + MUX_9548_2_CH7, + MUX_9548_3_CH0, + MUX_9548_3_CH1, + MUX_9548_3_CH2, + MUX_9548_3_CH3, + MUX_9548_3_CH4, + MUX_9548_3_CH5, + MUX_9548_3_CH6, + MUX_9548_3_CH7, + MUX_9548_4_CH0, + MUX_9548_4_CH1, + MUX_9548_4_CH2, + MUX_9548_4_CH3, + MUX_9548_4_CH4, + MUX_9548_4_CH5, + MUX_9548_4_CH6, + MUX_9548_4_CH7, + MUX_9548_5_CH0, + MUX_9548_5_CH1, + MUX_9548_5_CH2, + MUX_9548_5_CH3, + MUX_9548_5_CH4, + MUX_9548_5_CH5, + MUX_9548_5_CH6, + MUX_9548_5_CH7, + MUX_9548_6_CH0, + MUX_9548_6_CH1, + MUX_9548_6_CH2, + MUX_9548_6_CH3, + MUX_9548_6_CH4, + MUX_9548_6_CH5, + MUX_9548_6_CH6, + MUX_9548_6_CH7, + MUX_9548_7_CH0, + MUX_9548_7_CH1, + MUX_9548_7_CH2, + MUX_9548_7_CH3, + MUX_9548_7_CH4, + MUX_9548_7_CH5, + MUX_9548_7_CH6, + MUX_9548_7_CH7, + MUX_9548_8_CH0, + MUX_9548_8_CH1, + MUX_9548_8_CH2, + MUX_9548_8_CH3, + MUX_9548_8_CH4, + MUX_9548_8_CH5, + MUX_9548_8_CH6, + MUX_9548_8_CH7, + MUX_9548_9_CH0, + MUX_9548_9_CH1, + MUX_9548_9_CH2, + MUX_9548_9_CH3, + MUX_9548_9_CH4, + MUX_9548_9_CH5, + MUX_9548_9_CH6, + MUX_9548_9_CH7, + MUX_9548_10_CH0, + MUX_9548_10_CH1, + MUX_9548_10_CH2, + MUX_9548_10_CH3, + MUX_9548_10_CH4, + MUX_9548_10_CH5, + MUX_9548_10_CH6, + MUX_9548_10_CH7, +}; + +#define I2C_ADDR_MUX_9555_0 (0x20) +#define I2C_ADDR_MUX_9555_1 (0x24) +#define I2C_ADDR_MUX_9555_2 (0x25) +#define I2C_ADDR_MUX_9555_3 (0x26) +#define I2C_ADDR_MUX_9539_0 (0x76) +#define I2C_ADDR_MUX_9539_1 (0x76) +#define I2C_BUS_FAN_STATUS (I2C_BUS_MAIN) +#define I2C_BUS_SYS_LED (MUX_9548_1_CH1) + +#define NUM_OF_I2C_MUX (11) +#define NUM_OF_CPLD (5) +#define NUM_OF_QSFP_PORT (64) +#define NUM_OF_SFP_PORT (2) +#define QSFP_EEPROM_I2C_ADDR (0x50) + +enum gpio_reg { + REG_PORT0_IN, + REG_PORT1_IN, + REG_PORT0_OUT, + REG_PORT1_OUT, + REG_PORT0_POL, + REG_PORT1_POL, + REG_PORT0_DIR, + REG_PORT1_DIR, +}; + +struct ing_i2c_board_info { + int ch; + int size; + struct i2c_board_info *board_info; +}; + +struct i2c_init_data { + __u16 ch; + __u16 addr; + __u8 reg; + __u8 value; +}; + +#endif diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/modules/ingrasys_s9230_64x_psu.c b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/modules/ingrasys_s9230_64x_psu.c new file mode 100644 index 000000000000..a163a7cafcd2 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/modules/ingrasys_s9230_64x_psu.c @@ -0,0 +1,407 @@ +/* + * S9230-64x PSU driver + * + * Copyright (C) 2017 Ingrasys, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ingrasys_s9230_64x_platform.h" + +static ssize_t show_psu_eeprom(struct device *dev, + struct device_attribute *da, + char *buf); +static struct s9230_psu_data *s9230_psu_update_status(struct device *dev); +static struct s9230_psu_data *s9230_psu_update_eeprom(struct device *dev); +static int s9230_psu_read_block(struct i2c_client *client, + u8 command, + u8 *data, + int data_len); + + +#define DRIVER_NAME "psu" + +// Addresses scanned +static const unsigned short normal_i2c[] = { 0x50, I2C_CLIENT_END }; + +/* PSU EEPROM SIZE */ +#define EEPROM_SZ 256 +#define READ_EEPROM 1 +#define NREAD_EEPROM 0 + +static struct i2c_client pca9555_client; + +/* pca9555 gpio pin mapping */ +#define PSU2_PWROK 0 +#define PSU2_PRSNT_L 1 +#define PSU2_PWRON_L 2 +#define PSU1_PWROK 3 +#define PSU1_PRSNT_L 4 +#define PSU1_PWRON_L 5 +#define TMP_75_INT_L 6 + +/* Driver Private Data */ +struct s9230_psu_data { + struct device *hwmon_dev; + struct mutex lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 index; /* PSU index */ + s32 status; /* IO expander value */ + char eeprom[EEPROM_SZ]; /* psu eeprom data */ + char psuABS; /* PSU absent */ + char psuPG; /* PSU power good */ +}; + +enum s9230_psu_sysfs_attributes { + PSU_POWER_GOOD, + PSU_ABSENT, + PSU_EEPROM +}; + +enum psu_index +{ + s9230_psu1, + s9230_psu2 +}; + +/* + * display power good attribute + */ +static ssize_t +show_psu_pg(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct s9230_psu_data *data = s9230_psu_update_status(dev); + unsigned int value; + + mutex_lock(&data->lock); + value = data->psuPG; + mutex_unlock(&data->lock); + + return sprintf(buf, "%d\n", value); +} + +/* + * display power absent attribute + */ +static ssize_t +show_psu_abs(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct s9230_psu_data *data = s9230_psu_update_status(dev); + unsigned int value; + + mutex_lock(&data->lock); + value = data->psuABS; + mutex_unlock(&data->lock); + + return sprintf(buf, "%d\n", value); +} + + +/* + * sysfs attributes for psu + */ +static SENSOR_DEVICE_ATTR(psu_pg, S_IRUGO, show_psu_pg, NULL, PSU_POWER_GOOD); +static SENSOR_DEVICE_ATTR(psu_abs, S_IRUGO, show_psu_abs, NULL, PSU_ABSENT); +static SENSOR_DEVICE_ATTR(psu_eeprom, S_IRUGO, show_psu_eeprom, NULL, PSU_EEPROM); + +static struct attribute *s9230_psu_attributes[] = { + &sensor_dev_attr_psu_pg.dev_attr.attr, + &sensor_dev_attr_psu_abs.dev_attr.attr, + &sensor_dev_attr_psu_eeprom.dev_attr.attr, + NULL +}; + +/* + * display psu eeprom content + */ +static ssize_t +show_psu_eeprom(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct s9230_psu_data *data = s9230_psu_update_eeprom(dev); + + memcpy(buf, (char *)data->eeprom, EEPROM_SZ); + return EEPROM_SZ; +} + +static const struct attribute_group s9230_psu_group = { + .attrs = s9230_psu_attributes, +}; + +/* + * check gpio expander is accessible + */ +static int +pca9555_detect(struct i2c_client *client) +{ + if (i2c_smbus_read_byte_data(client, REG_PORT0_DIR) < 0) { + return -ENODEV; + } + + return 0; +} + +/* + * client address init + */ +static void +i2c_devices_client_address_init(struct i2c_client *client) +{ + pca9555_client = *client; + pca9555_client.addr = 0x25; +} + +static int +s9230_psu_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct s9230_psu_data *data; + int status, err; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct s9230_psu_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + memset(data, 0, sizeof(struct s9230_psu_data)); + i2c_set_clientdata(client, data); + data->valid = 0; + data->index = dev_id->driver_data; + mutex_init(&data->lock); + + i2c_devices_client_address_init(client); + + err = pca9555_detect(&pca9555_client); + if (err) { + return err; + } + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &s9230_psu_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &s9230_psu_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int +s9230_psu_remove(struct i2c_client *client) +{ + struct s9230_psu_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &s9230_psu_group); + kfree(data); + + return 0; +} + + +/* + * psu eeprom read utility + */ +static int +s9230_psu_read_block(struct i2c_client *client, + u8 command, + u8 *data, + int data_len) +{ + int i=0, ret=0; + int blk_max = 32; //max block read size + + /* read eeprom, 32 * 8 = 256 bytes */ + for (i=0; i < EEPROM_SZ/blk_max; i++) { + ret = i2c_smbus_read_i2c_block_data(client, (i*blk_max), blk_max, + data + (i*blk_max)); + if (ret < 0) { + return ret; + } + } + return ret; +} + +/* + * update eeprom content + */ +static struct s9230_psu_data +*s9230_psu_update_eeprom(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct s9230_psu_data *data = i2c_get_clientdata(client); + s32 status = 0; + int psu_pwrok = 0; + int psu_prsnt_l = 0; + + mutex_lock(&data->lock); + + if (time_after(jiffies, data->last_updated + 300 * HZ) + || !data->valid) { + + /* Read psu status */ + + status = i2c_smbus_read_word_data(&(pca9555_client), REG_PORT0_IN); + data->status = status; + + /*read psu status from io expander*/ + + if (data->index == s9230_psu1) { + psu_pwrok = PSU1_PWROK; + psu_prsnt_l = PSU1_PRSNT_L; + } else { + psu_pwrok = PSU2_PWROK; + psu_prsnt_l = PSU2_PRSNT_L; + } + data->psuPG = (status >> psu_pwrok) & 0x1; + data->psuABS = (status >> psu_prsnt_l) & 0x1; + + /* Read eeprom */ + if (!data->psuABS) { + //clear local eeprom data + memset(data->eeprom, 0, EEPROM_SZ); + + //read eeprom + status = s9230_psu_read_block(client, 0, data->eeprom, + ARRAY_SIZE(data->eeprom)); + + if (status < 0) { + memset(data->eeprom, 0, EEPROM_SZ); + dev_err(&client->dev, "Read eeprom failed, status=(%d)\n", status); + } else { + data->valid = 1; + } + } else { + memset(data->eeprom, 0, EEPROM_SZ); + } + data->last_updated = jiffies; + } + + mutex_unlock(&data->lock); + + return data; +} + +/* + * update psu status + */ +static struct s9230_psu_data +*s9230_psu_update_status(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct s9230_psu_data *data = i2c_get_clientdata(client); + s32 status = 0; + int psu_pwrok = 0; + int psu_prsnt_l = 0; + + mutex_lock(&data->lock); + + /* Read psu status */ + + status = i2c_smbus_read_word_data(&(pca9555_client), REG_PORT0_IN); + data->status = status; + + /*read psu status from io expander*/ + + if (data->index == s9230_psu1) { + psu_pwrok = PSU1_PWROK; + psu_prsnt_l = PSU1_PRSNT_L; + } else { + psu_pwrok = PSU2_PWROK; + psu_prsnt_l = PSU2_PRSNT_L; + } + data->psuPG = (status >> psu_pwrok) & 0x1; + data->psuABS = (status >> psu_prsnt_l) & 0x1; + + mutex_unlock(&data->lock); + + return data; +} + +static const struct i2c_device_id s9230_psu_id[] = { + { "psu1", s9230_psu1 }, + { "psu2", s9230_psu2 }, + {} +}; + +MODULE_DEVICE_TABLE(i2c, s9230_psu_id); + +static struct i2c_driver s9230_psu_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = DRIVER_NAME, + }, + .probe = s9230_psu_probe, + .remove = s9230_psu_remove, + .id_table = s9230_psu_id, + .address_list = normal_i2c, +}; + +static int __init s9230_psu_init(void) +{ + return i2c_add_driver(&s9230_psu_driver); +} + +static void __exit s9230_psu_exit(void) +{ + i2c_del_driver(&s9230_psu_driver); +} + +module_init(s9230_psu_init); +module_exit(s9230_psu_exit); + +MODULE_AUTHOR("Jason Tsai "); +MODULE_DESCRIPTION("S9230-64X psu driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/service/qsfp-monitor.service b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/service/qsfp-monitor.service new file mode 100644 index 000000000000..cf4a6a8ad41e --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/service/qsfp-monitor.service @@ -0,0 +1,15 @@ +[Unit] +Description= This QSFP Monitor service is to setup QSFP SI. +Requires=s9230-64x-monitor.service +After=s9230-64x-monitor.service + +[Service] +ExecStart=/usr/sbin/qsfp_monitor.sh +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/service/s9230-64x-monitor.service b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/service/s9230-64x-monitor.service new file mode 100644 index 000000000000..5caf968e659a --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/service/s9230-64x-monitor.service @@ -0,0 +1,19 @@ +[Unit] +Description= This Platform Monitor service is to initialize platform and monitor platform. +Before=platform-monitor.service +After=sysinit.target +Wants=fancontrol.service +Wants=qsfp-monitor.service +DefaultDependencies=no + +[Service] +ExecStartPre=/usr/sbin/i2c_utils.sh i2c_init +ExecStart=/usr/sbin/s9230_64x_monitor.sh +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/i2c_utils.sh b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/i2c_utils.sh new file mode 100755 index 000000000000..32506ce20863 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/i2c_utils.sh @@ -0,0 +1,1850 @@ +#!/bin/bash + +# Copyright (C) 2016 Ingrasys, 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 3 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, see . + +# trun on for more debug output +#DEBUG="on" + +VERSION="1.0.0" +TRUE=200 +FALSE=404 + +EXEC_FUNC=${1} +COLOR_LED=${2} +QSFP_PORT=${2} +SFP_PORT=${2} +QSFP_ACTION=${2} +SFP_ACTION=${2} +MB_EEPROM_ACTION=${2} +TARGET_10G_MUX=${2} +ONOFF_LED=${3} +FAN_TRAY=${4} + +############################################################ +# Distributor ID: Debian +# Description: Debian GNU/Linux 8.6 (jessie) +# Release: 8.6 +# Codename: jessie +# Linux debian 3.16.0-4-amd64 #1 +# SMP Debian 3.16.36-1+deb8u1 (2016-09-03) x86_64 GNU/Linux +############################################################ + +# Color Definition +COLOR_TITLE="\e[1;32m" ### Green ### +COLOR_WARNING="\e[1;33m" ### Yellow ### +COLOR_ERROR="\e[1;31m" ### Red ### +COLOR_END="\e[0m" ### END ### + +NUM_I801_DEVICE=0 + +# PCA9548#0 0x70 +NUM_MUX_9548_0_CH0=$(( ${NUM_I801_DEVICE} + 1 )) # CPLD1 +NUM_MUX_9548_0_CH1=$(( ${NUM_I801_DEVICE} + 2 )) # CPLD2 +NUM_MUX_9548_0_CH2=$(( ${NUM_I801_DEVICE} + 3 )) # CPLD3 +NUM_MUX_9548_0_CH3=$(( ${NUM_I801_DEVICE} + 4 )) # CPLD4 +NUM_MUX_9548_0_CH4=$(( ${NUM_I801_DEVICE} + 5 )) # CPLD5 +NUM_MUX_9548_0_CH5=$(( ${NUM_I801_DEVICE} + 6 )) # LM75_1 LM75_2 +NUM_MUX_9548_0_CH6=$(( ${NUM_I801_DEVICE} + 7 )) # LM75_3 LM75_4 + +# PCA9548#1 0x73 +NUM_MUX_9548_1_CH0=$(( ${NUM_I801_DEVICE} + 9 )) # UCD9090 +NUM_MUX_9548_1_CH1=$(( ${NUM_I801_DEVICE} + 10 )) # PCA9539 0x76 for FP LED & HW ID +NUM_MUX_9548_1_CH2=$(( ${NUM_I801_DEVICE} + 11 )) # PCA9539 0x76 for SYS control +NUM_MUX_9548_1_CH4=$(( ${NUM_I801_DEVICE} + 13 )) # 10G Mux +NUM_MUX_9548_1_CH7=$(( ${NUM_I801_DEVICE} + 16 )) # HWM & TMP75 on BMC + +# PCA9546#0 0X72 +NUM_MUX_9546_0_CH0=$(( ${NUM_I801_DEVICE} + 17 )) # PSU1 0x58 +NUM_MUX_9546_0_CH1=$(( ${NUM_I801_DEVICE} + 18 )) # PSU2 0x58 +NUM_MUX_9546_0_CH2=$(( ${NUM_I801_DEVICE} + 19 )) # PCA9548#2 0x71 +NUM_MUX_9546_0_CH3=$(( ${NUM_I801_DEVICE} + 20 )) # PCA9546#1 0x71 + +# PCA9546#1 0X71 +NUM_MUX_9546_1_CH0=$(( ${NUM_I801_DEVICE} + 21 )) # SFP0 EEPROM 0x50 +NUM_MUX_9546_1_CH1=$(( ${NUM_I801_DEVICE} + 22 )) # SFP1 EEPROM 0x50 + +# PCA9548#2 0X71 +NUM_MUX_9548_2_CH0=$(( ${NUM_I801_DEVICE} + 25 )) # PCA9548#3 0x74 +NUM_MUX_9548_2_CH1=$(( ${NUM_I801_DEVICE} + 26 )) # PCA9548#4 0x74 +NUM_MUX_9548_2_CH2=$(( ${NUM_I801_DEVICE} + 27 )) # PCA9548#5 0x74 +NUM_MUX_9548_2_CH3=$(( ${NUM_I801_DEVICE} + 28 )) # PCA9548#6 0x74 +NUM_MUX_9548_2_CH4=$(( ${NUM_I801_DEVICE} + 29 )) # PCA9548#7 0x74 +NUM_MUX_9548_2_CH5=$(( ${NUM_I801_DEVICE} + 30 )) # PCA9548#8 0x74 +NUM_MUX_9548_2_CH6=$(( ${NUM_I801_DEVICE} + 31 )) # PCA9548#9 0x74 +NUM_MUX_9548_2_CH7=$(( ${NUM_I801_DEVICE} + 32 )) # PCA9548#10 0x74 + +# PCA9548#3~10 0X74 +NUM_MUX_9548_3_CH0=$(( ${NUM_I801_DEVICE} + 33 )) # QSFP 0 EEPROM +NUM_MUX_9548_4_CH0=$(( ${NUM_I801_DEVICE} + 41 )) # QSFP 8 EEPROM +NUM_MUX_9548_5_CH0=$(( ${NUM_I801_DEVICE} + 49 )) # QSFP 16 EEPROM +NUM_MUX_9548_6_CH0=$(( ${NUM_I801_DEVICE} + 57 )) # QSFP 24 EEPROM +NUM_MUX_9548_7_CH0=$(( ${NUM_I801_DEVICE} + 65 )) # QSFP 32 EEPROM +NUM_MUX_9548_8_CH0=$(( ${NUM_I801_DEVICE} + 73 )) # QSFP 40 EEPROM +NUM_MUX_9548_9_CH0=$(( ${NUM_I801_DEVICE} + 81 )) # QSFP 48 EEPROM +NUM_MUX_9548_10_CH0=$(( ${NUM_I801_DEVICE} + 89 )) # QSFP 56 EEPROM + +# MUX Alias +I2C_BUS_MAIN=${NUM_I801_DEVICE} +I2C_BUS_HWM=${NUM_MUX_9548_1_CH7} +I2C_BUS_FAN_STATUS=${I2C_BUS_MAIN} +I2C_BUS_SYS_LED=${NUM_MUX_9548_1_CH1} +I2C_BUS_HW_ID=${NUM_MUX_9548_1_CH1} +I2C_BUS_BMC_HW_ID=${I2C_BUS_MAIN} +I2C_BUS_PSU_STAT=${I2C_BUS_MAIN} +I2C_BUS_FANTRAY_LED=${I2C_BUS_MAIN} +I2C_BUS_MB_EEPROM=${I2C_BUS_MAIN} +I2C_BUS_CB_EEPROM=${I2C_BUS_MAIN} +I2C_BUS_PSU1_EEPROM=${NUM_MUX_9546_0_CH1} +I2C_BUS_PSU2_EEPROM=${NUM_MUX_9546_0_CH0} +I2C_BUS_CPLD1=${NUM_MUX_9548_0_CH0} +I2C_BUS_CPLD2=${NUM_MUX_9548_0_CH1} +I2C_BUS_CPLD3=${NUM_MUX_9548_0_CH2} +I2C_BUS_CPLD4=${NUM_MUX_9548_0_CH3} +I2C_BUS_CPLD5=${NUM_MUX_9548_0_CH4} +I2C_BUS_10GMUX=${NUM_MUX_9548_1_CH4} + +# I2C BUS path +PATH_SYS_I2C_DEVICES="/sys/bus/i2c/devices" +PATH_HWMON_ROOT_DEVICES="/sys/class/hwmon" +# TODO: need to verify HWM deivce path after board ready +PATH_HWMON_W83795_DEVICE="${PATH_HWMON_ROOT_DEVICES}/hwmon7" +PATH_I801_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_I801_DEVICE}" +PATH_MUX_9548_0_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_0_CH0}" +PATH_MUX_9548_0_CH1="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_0_CH1}" +PATH_MUX_9548_0_CH2="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_0_CH2}" +PATH_MUX_9548_0_CH3="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_0_CH3}" +PATH_MUX_9548_0_CH4="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_0_CH4}" +PATH_MUX_9548_0_CH5="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_0_CH5}" +PATH_MUX_9548_0_CH6="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_0_CH6}" +PATH_MUX_9548_1_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CH0}" +PATH_MUX_9548_1_CH1="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CH1}" +PATH_MUX_9548_1_CH2="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CH2}" +PATH_MUX_9548_1_CH7="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_1_CH7}" +PATH_MUX_9546_0_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9546_0_CH0}" +PATH_MUX_9546_0_CH1="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9546_0_CH1}" +PATH_MUX_9546_0_CH2="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9546_0_CH2}" +PATH_MUX_9546_0_CH3="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9546_0_CH3}" +PATH_MUX_9546_1_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9546_1_CH0}" +PATH_MUX_9546_1_CH1="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9546_1_CH1}" +PATH_MUX_9548_2_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_2_CH0}" +PATH_MUX_9548_2_CH1="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_2_CH1}" +PATH_MUX_9548_2_CH2="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_2_CH2}" +PATH_MUX_9548_2_CH3="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_2_CH3}" +PATH_MUX_9548_2_CH4="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_2_CH4}" +PATH_MUX_9548_2_CH5="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_2_CH5}" +PATH_MUX_9548_2_CH6="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_2_CH6}" +PATH_MUX_9548_2_CH7="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_2_CH7}" +PATH_MUX_9548_3_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_3_CH0}" +PATH_MUX_9548_4_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_4_CH0}" +PATH_MUX_9548_5_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_5_CH0}" +PATH_MUX_9548_6_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_6_CH0}" +PATH_MUX_9548_7_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_7_CH0}" +PATH_MUX_9548_8_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_8_CH0}" +PATH_MUX_9548_9_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_9_CH0}" +PATH_MUX_9548_10_CH0="${PATH_SYS_I2C_DEVICES}/i2c-${NUM_MUX_9548_10_CH0}" +PATH_CPLD1_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_CPLD1}" +PATH_CPLD2_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_CPLD2}" +PATH_CPLD3_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_CPLD3}" +PATH_CPLD4_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_CPLD4}" +PATH_CPLD5_DEVICE="${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_CPLD5}" +PATH_10GMUX=${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_10GMUX} + + +# I2C Address +### I2C MUX +I2C_ADDR_MUX_9548_0=0x70 +I2C_ADDR_MUX_9548_1=0x73 +I2C_ADDR_MUX_9546_0=0x72 +I2C_ADDR_MUX_9546_1=0x71 +I2C_ADDR_MUX_9548_2=0x71 +I2C_ADDR_MUX_9548_3=0x74 +I2C_ADDR_MUX_9548_4=0x74 +I2C_ADDR_MUX_9548_5=0x74 +I2C_ADDR_MUX_9548_6=0x74 +I2C_ADDR_MUX_9548_7=0x74 +I2C_ADDR_MUX_9548_8=0x74 +I2C_ADDR_MUX_9548_9=0x74 +I2C_ADDR_MUX_9548_10=0x74 + +### GPIO Expander +I2C_ADDR_MUX_9539_0=0x76 # LED & HW ID +I2C_ADDR_MUX_9539_1=0x76 # SYS config +I2C_ADDR_MUX_9539_2=0x77 # on CPU board, STATUS and ERR from CPLD +I2C_ADDR_MUX_9555_0=0x20 # on FAN board, fan status and led config +I2C_ADDR_MUX_9555_1=0x24 # on BMC board, INT and HW ID +I2C_ADDR_MUX_9555_2=0x25 # on BMC board, PSU status +I2C_ADDR_MUX_9555_3=0x26 # on BMC board, RST and SEL +I2C_ADDR_MUX_9555_3=0x26 # on BMC board, RST and SEL + + +### peripheral +I2C_ADDR_MB_EEPROM=0x55 # on main board +I2C_ADDR_CB_EEPROM=0x51 # on cpu board +I2C_ADDR_UCD9090=0x34 +I2C_ADDR_W83795=0x2F +I2C_ADDR_PSU1_EEPROM=0x50 +I2C_ADDR_PSU2_EEPROM=0x50 +I2C_ADDR_LM75_1=0x4D # Rear Panel +I2C_ADDR_LM75_2=0x4E # Rear MAC +I2C_ADDR_LM75_3=0x4D # Front Panel +I2C_ADDR_LM75_4=0x4E # Front MAC +I2C_ADDR_TMP75_CB=0x4F # on cpu board +I2C_ADDR_TMP75_BB=0x4A # on bmc board +I2C_ADDR_QSFP_EEPROM=0x50 +I2C_ADDR_SFP_EEPROM=0x50 +I2C_ADDR_CPLD=0x33 +I2C_ADDR_10GMUX=0x67 + +#sysfs +PATH_SYSFS_PSU1="${PATH_SYS_I2C_DEVICES}/${I2C_BUS_PSU1_EEPROM}-$(printf "%04x" $I2C_ADDR_PSU1_EEPROM)" +PATH_SYSFS_PSU2="${PATH_SYS_I2C_DEVICES}/${I2C_BUS_PSU2_EEPROM}-$(printf "%04x" $I2C_ADDR_PSU2_EEPROM)" + +#ACTIVE LOW enable flag +ACTIVE_LOW_EN=1 +ACTIVE_HIGH_EN=0 +#GPIO Direction In/Out +DIR_IN=in +DIR_OUT=out + +#Power Supply Status +PSU_DC_ON=1 +PSU_DC_OFF=0 +PSU_EXIST=1 +PSU_NOT_EXIST=0 + +# IO expander register +# direction +REG_PORT0_DIR=6 +REG_PORT1_DIR=7 +# polarity +REG_PORT0_POL=4 +REG_PORT1_POL=5 +# output +REG_PORT0_OUT=2 +REG_PORT1_OUT=3 +# input +REG_PORT0_IN=0 +REG_PORT1_IN=1 + +# qsfp port number range +MIN_QSFP_PORT_NUM=1 +MAX_QSFP_PORT_NUM=64 + +# sfp+ port number range +MIN_SFP_PORT_NUM=1 +MAX_SFP_PORT_NUM=2 + +# CPLD access +# port status +CPLD_QSFP_STATUS_KEY=cpld_qsfp_port_status +CPLD_SFP_STATUS_KEY=cpld_sfp_port_status +# bit define +CPLD_QSFP_STATUS_ABS_BIT=1 +CPLD_SFP_STATUS_PRES_BIT=0 + +# Help usage function +function _help { + echo "=========================================================" + echo "# Description: Help Function" + echo "=========================================================" + echo "----------------------------------------------------" + echo "EX : ${0} help" + echo " : ${0} i2c_init" + echo " : ${0} i2c_deinit" + echo " : ${0} i2c_fan_speed_init" + echo " : ${0} i2c_io_exp_init" + echo " : ${0} i2c_led_test" + echo " : ${0} i2c_psu_eeprom_get" + echo " : ${0} i2c_mb_eeprom_get" + echo " : ${0} i2c_cb_eeprom_get" + #echo " : ${0} i2c_eeprom_sync" + echo " : ${0} i2c_qsfp_eeprom_get [${MIN_QSFP_PORT_NUM}-${MAX_QSFP_PORT_NUM}]" + echo " : ${0} i2c_sfp_eeprom_get [${MIN_SFP_PORT_NUM}-${MAX_SFP_PORT_NUM}]" + echo " : ${0} i2c_qsfp_eeprom_init new|delete" + echo " : ${0} i2c_sfp_eeprom_init new|delete" + echo " : ${0} i2c_mb_eeprom_init new|delete" + echo " : ${0} i2c_cb_eeprom_init new|delete" + echo " : ${0} i2c_qsfp_status_get [${MIN_QSFP_PORT_NUM}-${MAX_QSFP_PORT_NUM}]" + echo " : ${0} i2c_sfp_status_get [${MIN_SFP_PORT_NUM}-${MAX_SFP_PORT_NUM}]" + echo " : ${0} i2c_qsfp_type_get [${MIN_QSFP_PORT_NUM}-${MAX_QSFP_PORT_NUM}]" + echo " : ${0} i2c_sfp_type_get [${MIN_SFP_PORT_NUM}-${MAX_SFP_PORT_NUM}]" + echo " : ${0} i2c_board_type_get" + echo " : ${0} i2c_bmc_board_type_get" + echo " : ${0} i2c_cpld_version" + echo " : ${0} i2c_psu_status" + echo " : ${0} i2c_led_psu_status_set" + echo " : ${0} i2c_led_fan_status_set" + echo " : ${0} i2c_led_fan_tray_status_set" + echo " : ${0} i2c_test_all" + echo " : ${0} i2c_sys_led green|amber" + echo " : ${0} i2c_fan_led green|amber|off" + echo " : ${0} i2c_psu1_led green|amber|off" + echo " : ${0} i2c_psu2_led green|amber|off" + echo " : ${0} i2c_fan_tray_led green|amber on|off [1-4]" + echo " : ${0} i2c_10g_mux cpu|fp" + echo "----------------------------------------------------" +} + +#Pause function +function _pause { + read -p "$*" +} + +#Retry command function +function _retry { + local i + for i in {1..5}; + do + eval "${*}" && break || echo "retry"; sleep 1; + done +} + +#logical(front panel) to physical (falcon core) port mapping +function _port_logic2phy { + + local logic_port=$1 + local phy_port=0 + + if (( $logic_port >=1 && $logic_port <= 32 )) ; then + phy_port=$(( (logic_port-1)/2*4 + (logic_port-1)%2 + 1)) + elif (( $logic_port >=33 && $logic_port <= 64 )) ; then + phy_port=$(( (((logic_port-1)%32))/2*4 + (logic_port-1)%2 + 3)) + fi + + echo $phy_port +} + +#I2C Init +function _i2c_init { + echo "=========================================================" + echo "# Description: I2C Init" + echo "=========================================================" + + #rmmod i2c_ismt + _util_rmmod i2c_i801 + modprobe i2c_i801 + modprobe i2c_dev + modprobe i2c_mux_pca954x force_deselect_on_exit=1 + + # add MUX PCA9548#0 on I801, assume to be i2c-1~8 + if [ ! -e ${PATH_MUX_9548_0_CH0} ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_0}' > ${PATH_I801_DEVICE}/new_device" + else + echo "pca9548 ${I2C_ADDR_MUX_9548_0} already init." + fi + + # add MUX PCA9548#1 on I801, assume to be i2c-9~16 + if [ ! -e ${PATH_MUX_9548_1_CH0} ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_1}' > ${PATH_I801_DEVICE}/new_device" + else + echo "pca9548 ${I2C_ADDR_MUX_9548_1} already init." + fi + + # add MUX PCA9546#0 on I801, assume to be i2c-17~20 + if [ ! -e ${PATH_MUX_9546_0_CH0} ]; then + _retry "echo 'pca9546 ${I2C_ADDR_MUX_9546_0}' > ${PATH_I801_DEVICE}/new_device" + else + echo "pca9546 ${I2C_ADDR_MUX_9546_0} already init." + fi + + # add MUX PCA9546#1 on PCA9546#0 CH3, assume to be i2c-21~24 + if [ ! -e ${PATH_MUX_9546_1_CH0} ]; then + _retry "echo 'pca9546 ${I2C_ADDR_MUX_9546_1}' > ${PATH_MUX_9546_0_CH3}/new_device" + else + echo "pca9546 ${I2C_ADDR_MUX_9546_1} already init." + fi + + # add MUX PCA9548#2 on PCA9546#0 CH2, assume to be i2c-25~32 + if [ ! -e ${PATH_MUX_9548_2_CH0} ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_2}' > ${PATH_MUX_9546_0_CH2}/new_device" + else + echo "pca9548 ${I2C_ADDR_MUX_9548_2} already init." + fi + + # add MUX PCA9548#3 on PCA9548#2 CH0, assume to be i2c-33~40 + if [ ! -e ${PATH_MUX_9548_3_CH0} ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_3}' > ${PATH_MUX_9548_2_CH0}/new_device" + else + echo "pca9548 ${I2C_ADDR_MUX_9548_3} already init." + fi + + # add MUX PCA9548#4 on PCA9548#2 CH1, assume to be i2c-41~48 + if [ ! -e ${PATH_MUX_9548_4_CH0} ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_4}' > ${PATH_MUX_9548_2_CH1}/new_device" + else + echo "pca9548 ${I2C_ADDR_MUX_9548_4} already init." + fi + + # add MUX PCA9548#5 on PCA9548#2 CH2, assume to be i2c-49~56 + if [ ! -e ${PATH_MUX_9548_5_CH0} ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_5}' > ${PATH_MUX_9548_2_CH2}/new_device" + else + echo "pca9548 ${I2C_ADDR_MUX_9548_5} already init." + fi + + # add MUX PCA9548#6 on PCA9548#2 CH3, assume to be i2c-57~64 + if [ ! -e ${PATH_MUX_9548_6_CH0} ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_6}' > ${PATH_MUX_9548_2_CH3}/new_device" + else + echo "pca9548 ${I2C_ADDR_MUX_9548_6} already init." + fi + + # add MUX PCA9548#7 on PCA9548#2 CH4, assume to be i2c-65~72 + if [ ! -e ${PATH_MUX_9548_7_CH0} ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_7}' > ${PATH_MUX_9548_2_CH4}/new_device" + else + echo "pca9548 ${I2C_ADDR_MUX_9548_7} already init." + fi + + # add MUX PCA9548#8 on PCA9548#2 CH5, assume to be i2c-73~80 + if [ ! -e ${PATH_MUX_9548_8_CH0} ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_8}' > ${PATH_MUX_9548_2_CH5}/new_device" + else + echo "pca9548 ${I2C_ADDR_MUX_9548_8} already init." + fi + + # add MUX PCA9548#9 on PCA9548#2 CH6, assume to be i2c-81~88 + if [ ! -e ${PATH_MUX_9548_9_CH0} ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_9}' > ${PATH_MUX_9548_2_CH6}/new_device" + else + echo "pca9548 ${I2C_ADDR_MUX_9548_9} already init." + fi + + # add MUX PCA9548#10 on PCA9548#2 CH7, assume to be i2c-89~96 + if [ ! -e ${PATH_MUX_9548_10_CH0} ]; then + _retry "echo 'pca9548 ${I2C_ADDR_MUX_9548_10}' > ${PATH_MUX_9548_2_CH7}/new_device" + else + echo "pca9548 ${I2C_ADDR_MUX_9548_10} already init." + fi + + _i2c_hwm_init + _util_rmmod eeprom + modprobe eeprom_mb + modprobe gpio-pca953x + _i2c_io_exp_init + _i2c_sensors_init + _i2c_cpld_init + _i2c_psu_init + + _i2c_qsfp_eeprom_init "new" + _i2c_sfp_eeprom_init "new" + _i2c_mb_eeprom_init "new" + _i2c_cb_eeprom_init "new" + _i2c_fan_speed_init + _i2c_led_psu_status_set + _i2c_led_fan_status_set + + # trun on sys led + echo "led_sys setup..." + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_sys_led + + _config_rmem +} + +#I2C Deinit +function _i2c_deinit { + echo "i2c deinit..." + for mod in coretemp jc42 w83795 eeprom eeprom_mb gpio-pca953x i2c_mux_pca954x i2c_i801 ingrasys_s9230_64x_psu; + do + _util_rmmod $mod + done + echo "Done" +} + +function _i2c_cpld_init { + echo "CPLD init..." + _util_rmmod ingrasys_s9230_64x_i2c_cpld + modprobe ingrasys_s9230_64x_i2c_cpld + + # add cpld 1~5 to sysfs + for i in {1..5}; + do + local cpld_bus="I2C_BUS_CPLD${i}" + local cpld_path="PATH_CPLD${i}_DEVICE" + dev_path="${PATH_SYS_I2C_DEVICES}/${!cpld_bus}-$(printf "%04x" ${I2C_ADDR_CPLD})" + if ! [ -L ${dev_path} ]; then + echo "ingrasys_cpld${i} ${I2C_ADDR_CPLD}" > ${!cpld_path}/new_device + else + echo "${dev_path} already exist" + fi + done + + echo "Done" +} + +function _i2c_sensors_init { + echo "SENSORS init..." + local dev_path + # to make sure hwmon index in sysfs as expected, + # need to remove kernel module and then probe them in expected order + # remove all sensors kernel module + _util_rmmod coretemp + _util_rmmod jc42 + _util_rmmod w83795 + # probe coretemp kernel module + modprobe coretemp + # probe hwmon kernel module + modprobe w83795 + # add lm75 to sysfs + ####Main board thermal + ####lm75_1 + dev_path="${PATH_SYS_I2C_DEVICES}/${NUM_MUX_9548_0_CH5}-$(printf "%04x" ${I2C_ADDR_LM75_1})" + if ! [ -L ${dev_path} ]; then + echo "lm75 ${I2C_ADDR_LM75_1}" > ${PATH_MUX_9548_0_CH5}/new_device # hwmon1 + else + echo "${dev_path} already exist" + fi + ####lm75_2 + dev_path="${PATH_SYS_I2C_DEVICES}/${NUM_MUX_9548_0_CH5}-$(printf "%04x" ${I2C_ADDR_LM75_2})" + if ! [ -L ${dev_path} ]; then + echo "lm75 ${I2C_ADDR_LM75_2}" > ${PATH_MUX_9548_0_CH5}/new_device #hwmon2 + else + echo "${dev_path} already exist" + fi + ####lm75_3 + dev_path="${PATH_SYS_I2C_DEVICES}/${NUM_MUX_9548_0_CH6}-$(printf "%04x" ${I2C_ADDR_LM75_3})" + if ! [ -L ${dev_path} ]; then + echo "lm75 ${I2C_ADDR_LM75_1}" > ${PATH_MUX_9548_0_CH6}/new_device # hwmon3 + else + echo "${dev_path} already exist" + fi + ####lm75_4 + dev_path="${PATH_SYS_I2C_DEVICES}/${NUM_MUX_9548_0_CH6}-$(printf "%04x" ${I2C_ADDR_LM75_4})" + if ! [ -L ${dev_path} ]; then + echo "lm75 ${I2C_ADDR_LM75_4}" > ${PATH_MUX_9548_0_CH6}/new_device #hwmon4 + else + echo "${dev_path} already exist" + fi + ####BMC board thermal + dev_path="${PATH_SYS_I2C_DEVICES}/${NUM_MUX_9548_1_CH7}-$(printf "%04x" ${I2C_ADDR_TMP75_BB})" + if ! [ -L ${dev_path} ]; then + echo "tmp75 ${I2C_ADDR_TMP75_BB}" > ${PATH_MUX_9548_1_CH7}/new_device #hwmon5 + else + echo "${dev_path} already exist" + fi + ####CPU board thermal + dev_path="${PATH_SYS_I2C_DEVICES}/${I2C_BUS_MAIN}-$(printf "%04x" ${I2C_ADDR_TMP75_CB})" + if ! [ -L ${dev_path} ]; then + echo "tmp75 ${I2C_ADDR_TMP75_CB}" > ${PATH_I801_DEVICE}/new_device #hwmon6 + else + echo "${dev_path} already exist" + fi + # add w83795 to sysfs + dev_path="${PATH_SYS_I2C_DEVICES}/${NUM_MUX_9548_1_CH7}-$(printf "%04x" ${I2C_ADDR_W83795})" + if ! [ -L ${dev_path} ]; then + echo "w83795adg ${I2C_ADDR_W83795}" > ${PATH_MUX_9548_1_CH7}/new_device #hwmon7 + else + echo "${dev_path} already exist" + fi + + # probe jc42 kernel module + modprobe jc42 + + echo "Done" +} + +#FAN Speed Init +function _i2c_fan_speed_init { + echo -n "FAN SPEED INIT..." + if [ -e "${PATH_HWMON_W83795_DEVICE}" ]; then + # init fan speed + echo 120 > ${PATH_HWMON_W83795_DEVICE}/device/pwm2 + echo "SUCCESS" + else + echo "FAIL" + fi +} + +# HWM init +function _i2c_hwm_init { + echo "HWM INIT..." + # select bank0 + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x00 0x80 + # SW reset, Disable monitor + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x01 0x9C + # disable TR5/TR6 DTS + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x04 0x0 + # enable FANIN1~8 + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x06 0xFF + # disable FANIN9~14 + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x07 0x00 + # CLKIN clock frequency set as 48Mhz + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x01 0x1C + # select bank 2 + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x00 0x82 + # set PWM mode in FOMC + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x0F 0x00 + # set 25KHz fan output frequency in F1OPFP&F2OPFP + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x18 0x84 + _util_i2cset -y -r ${I2C_BUS_HWM} ${I2C_ADDR_W83795} 0x19 0x84 +} + +#IO Expander Init +function _i2c_io_exp_init { + echo "=========================================================" + echo "# Description: I2C IO Expender Init" + echo "=========================================================" + + # need to init BMC io expander first due to some io expander are reset default + echo "Init BMC INT & HW ID IO Expander" + # all input + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_1} ${REG_PORT0_DIR} 0xFF + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_1} ${REG_PORT1_DIR} 0xFF + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_1} ${REG_PORT0_POL} 0x00 + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_1} ${REG_PORT1_POL} 0x00 + + echo "Init BMC PSU status IO Expander" + # PWRON default 0 (ACTIVE_LOW) + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_2} ${REG_PORT0_OUT} 0x00 + # default 0 (ACTIVE_LOW) + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_2} ${REG_PORT1_OUT} 0x00 + # I/O 0.2 0.5 output(PWRON), rest input + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_2} ${REG_PORT0_DIR} 0xDB + # I/O 1.0~1.1 input, 1.2~1.4 output (1.5~1.7 not enable) + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_2} ${REG_PORT1_DIR} 0xE3 + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_2} ${REG_PORT0_POL} 0x00 + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_2} ${REG_PORT1_POL} 0x00 + + echo "Init BMC RST and SEL IO Expander" + # RST default is 1 (ACTIVE_LOW) + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_3} ${REG_PORT0_OUT} 0x3F + # SEL default is 0 (HOST), EN default is 1 (ACTIVE_HIGH) + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_3} ${REG_PORT1_OUT} 0x1F + # I/O 0.0~0.5 output, 0.6~0.7 not use + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_3} ${REG_PORT0_DIR} 0xC0 + # all output + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_3} ${REG_PORT1_DIR} 0x00 + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_3} ${REG_PORT0_POL} 0x00 + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9555_3} ${REG_PORT1_POL} 0x00 + + echo "Init System LED & HW ID IO Expander" + # I/O_0.x for System LED default 0, I/O_1.x for HW ID + _util_i2cset -y -r ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${REG_PORT0_OUT} 0x00 + # System LED => all output + _util_i2cset -y -r ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${REG_PORT0_DIR} 0x00 + # HW ID => all input + _util_i2cset -y -r ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${REG_PORT1_DIR} 0xFF + _util_i2cset -y -r ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${REG_PORT0_POL} 0x00 + _util_i2cset -y -r ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${REG_PORT1_POL} 0x00 + + echo "Init FAN Board Status IO Expander" + # LED_G_H set to 1, LED_Y_G set to 0 (ACTIVE_HIGH) + _util_i2cset -y -r ${I2C_BUS_FAN_STATUS} ${I2C_ADDR_MUX_9555_0} ${REG_PORT0_OUT} 0x11 + _util_i2cset -y -r ${I2C_BUS_FAN_STATUS} ${I2C_ADDR_MUX_9555_0} ${REG_PORT1_OUT} 0x11 + # DIR/ABS is input, LED_Y/LED_G is output + _util_i2cset -y -r ${I2C_BUS_FAN_STATUS} ${I2C_ADDR_MUX_9555_0} ${REG_PORT0_DIR} 0xCC + _util_i2cset -y -r ${I2C_BUS_FAN_STATUS} ${I2C_ADDR_MUX_9555_0} ${REG_PORT1_DIR} 0xCC + _util_i2cset -y -r ${I2C_BUS_FAN_STATUS} ${I2C_ADDR_MUX_9555_0} ${REG_PORT0_POL} 0x00 + _util_i2cset -y -r ${I2C_BUS_FAN_STATUS} ${I2C_ADDR_MUX_9555_0} ${REG_PORT1_POL} 0x00 + + echo "Init System SEL and RST IO Expander" + # RST 0.0~0.3 default 1 (ACTIVE low), rest default 0 + # SEL set to value 0 (host) + # LED_CLR set to 0 will clear all switch LED bitmap, set to 1 here + _util_i2cset -y -r ${NUM_MUX_9548_1_CH2} ${I2C_ADDR_MUX_9539_1} ${REG_PORT0_OUT} 0x0F + # RST 1.6~1.7 default 1 (ACTIVE low), INT 1.0~1.4 default 1 (ACTIVE low) + _util_i2cset -y -r ${NUM_MUX_9548_1_CH2} ${I2C_ADDR_MUX_9539_1} ${REG_PORT1_OUT} 0xDF + # all output, but MAC_RST_L 0.0 need to set as input to prevent reboot issue + _util_i2cset -y -r ${NUM_MUX_9548_1_CH2} ${I2C_ADDR_MUX_9539_1} ${REG_PORT0_DIR} 0x09 + # RST 1.5 !~ 1.7 output, rest are input + _util_i2cset -y -r ${NUM_MUX_9548_1_CH2} ${I2C_ADDR_MUX_9539_1} ${REG_PORT1_DIR} 0x1F + _util_i2cset -y -r ${NUM_MUX_9548_1_CH2} ${I2C_ADDR_MUX_9539_1} ${REG_PORT0_POL} 0x00 + _util_i2cset -y -r ${NUM_MUX_9548_1_CH2} ${I2C_ADDR_MUX_9539_1} ${REG_PORT1_POL} 0x00 + + echo "Init CPU CPLD IO Expander" + # all input + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9539_2} ${REG_PORT0_DIR} 0xFF + # all input + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9539_2} ${REG_PORT1_DIR} 0xFF + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9539_2} ${REG_PORT0_POL} 0x00 + _util_i2cset -y -r ${I2C_BUS_MAIN} ${I2C_ADDR_MUX_9539_2} ${REG_PORT1_POL} 0x00 +} + +#Set FAN Tray LED +function _i2c_led_fan_tray_status_set { + echo "FAN Tray Status Setup" + #FAN Status get + FAN1_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan1_alarm` + FAN2_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan3_alarm` + FAN3_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan5_alarm` + FAN4_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan7_alarm` + + # check if io expander for fan tray exist + result=`i2cget -y ${I2C_BUS_FANTRAY_LED} ${I2C_ADDR_MUX_9555_0} ${REG_PORT0_IN} 2>/dev/null` + err_code=$? + if [ "$err_code" != "0" ]; then + echo "fan tray not exist!" + return + fi + + for FAN_TRAY in {1..4}; + do + FAN_ALARM="FAN${FAN_TRAY}_ALARM" + if [ "${!FAN_ALARM}" == "0" ]; then + COLOR_LED="green" + ONOFF_LED="on" + _i2c_fan_tray_led + + COLOR_LED="amber" + ONOFF_LED="off" + _i2c_fan_tray_led + + echo "set [FAN TRAY ${FAN_TRAY}] [Green]=on [Amber]=off" + else + COLOR_LED="green" + ONOFF_LED="off" + _i2c_fan_tray_led + + COLOR_LED="amber" + ONOFF_LED="on" + _i2c_fan_tray_led + + echo "set [FAN TRAY ${FAN_TRAY}] [Green]=off [Amber]=on" + fi + done +} + +#Set FAN LED +function _i2c_led_fan_status_set { + echo "FAN Status Setup" + #PSU Status set + FAN1_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan1_alarm` + FAN3_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan3_alarm` + FAN5_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan5_alarm` + FAN7_ALARM=`cat ${PATH_HWMON_W83795_DEVICE}/device/fan7_alarm` + + echo "led_fan setup..." + # all fan ok + if [ "${FAN1_ALARM}" == "0" ] \ + && [ "${FAN3_ALARM}" == "0" ] \ + && [ "${FAN5_ALARM}" == "0" ] \ + && [ "${FAN7_ALARM}" == "0" ]; then + COLOR_LED="green" + echo "${COLOR_LED}" + _i2c_fan_led + # all fan fail + elif [ "${FAN1_ALARM}" == "1" ] \ + && [ "${FAN3_ALARM}" == "1" ] \ + && [ "${FAN5_ALARM}" == "1" ] \ + && [ "${FAN7_ALARM}" == "1" ] ; then + COLOR_LED="amber" + echo "${COLOR_LED}" + _i2c_fan_led + # partial fan fail + else + COLOR_LED="amber" + echo "${COLOR_LED}" + _i2c_fan_led + fi +} + +#Set Power Supply LED +function _i2c_led_psu_status_set { + echo "PSU LED Status Setup" + + #PSU Status set + _i2c_psu_status + + #PSU1 Status + echo "led_psu1 setup..." + if [ "${psu1Exist}" == ${PSU_EXIST} ]; then + if [ "${psu1PwGood}" == ${PSU_DC_ON} ]; then + COLOR_LED="green" + echo "${COLOR_LED}" + _i2c_psu1_led + else + COLOR_LED="amber" + echo "${COLOR_LED}" + _i2c_psu1_led + fi + else + COLOR_LED="off" + echo "${COLOR_LED}" + _i2c_psu1_led + fi + + #PSU2 Status + echo "led_psu2 setup..." + if [ "${psu2Exist}" == ${PSU_EXIST} ]; then + if [ "${psu2PwGood}" == ${PSU_DC_ON} ]; then + COLOR_LED="green" + echo "${COLOR_LED}" + _i2c_psu2_led + else + COLOR_LED="amber" + echo "${COLOR_LED}" + _i2c_psu2_led + fi + else + COLOR_LED="off" + echo "${COLOR_LED}" + _i2c_psu2_led + fi +} + +#LED Test +function _i2c_led_test { + echo "=========================================================" + echo "# Description: I2C SYSTEM LED TEST..." + echo "=========================================================" + local output_reg=${REG_PORT0_OUT} + local mask=0xFF + local value=0xFF + + #sys led (green) + # set sys_led_g (0.7) = 1 + mask=0x80 + value=0x80 + _util_i2cset -m ${mask} -y ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${output_reg} ${value} + _pause 'Check SYS LED green light and Press [Enter] key to continue...' + #sys led (amber) + # set sys_led_g (0.7) = 0 + mask=0x80 + value=0x00 + _util_i2cset -m ${mask} -y ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${output_reg} ${value} + _pause 'Check SYS LED amber light and Press [Enter] key to continue...' + + #FAN led (green) + # set fan_led_en (0.6) = 1 & fan_led_y (0.5) = 0 + mask=0x60 + value=0x60 + _util_i2cset -m ${mask} -y ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${output_reg} ${value} + _pause 'Check FAN LED green light and Press [Enter] key to continue...' + #FAN led (amber) + # set fan_led_en (0.6) = 1 & fan_led_y (0.5) = 1 + mask=0x60 + value=0x40 + _util_i2cset -m ${mask} -y ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${output_reg} ${value} + _pause 'Check FAN LED amber light and Press [Enter] key to continue...' + + #PSU1 led (green) + # set psu1_pwr_ok_oe (0.4) = 1 & psu1_led_y (0.3) = 0 + mask=0x18 + value=0x18 + _util_i2cset -m ${mask} -y ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${output_reg} ${value} + _pause 'Check PSU1 LED green light and Press [Enter] key to continue...' + #PSU1 led (amber) + # set psu1_pwr_ok_oe (0.4) = 1 & psu1_led_y (0.3) = 1 + mask=0x18 + value=0x10 + _util_i2cset -m ${mask} -y ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${output_reg} ${value} + _pause 'Check PSU1 LED amber light and Press [Enter] key to continue...' + + #PSU2 led (green) + # set psu0_pwr_ok_oe (0.2) = 1 & psu0_led_y (0.1) = 0 + mask=0x06 + value=0x06 + _util_i2cset -m ${mask} -y ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${output_reg} ${value} + _pause 'Check PSU2 LED green light and Press [Enter] key to continue...' + #PSU2 led (amber) + # set psu0_pwr_ok_oe (0.2) = 1 & psu0_led_y (0.1) = 1 + mask=0x06 + value=0x04 + _util_i2cset -m ${mask} -y ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${output_reg} ${value} + _pause 'Check PSU2 LED amber light and Press [Enter] key to continue...' + + #Turn OFF All LED (can't trun off system led) + # set set fan_led_en (0.6), psu1_pwr_ok_oe (0.4), psu0_pwr_ok_oe (0.2) = 0 + mask=0xFF + value=$((2#00000011)) + _util_i2cset -m ${mask} -y ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${output_reg} ${value} + _pause 'Check turn off all LEDs (exclude SYS LED) and Press [Enter] key to continue...' + + # restore sys led + COLOR_LED="green" + ONOFF_LED="on" + echo "${COLOR_LED} ${ONOFF_LED}" + _i2c_sys_led +} + +#Set QSFP Port cpld variable +function _qsfp_cpld_var_set { + local port=$1 + local reg_port_base + local reg_port_shift + if [[ $1 -le 12 && $1 -ge 1 ]]; then + cpld_index=1 + reg_port_base=0 + elif [[ $1 -le 25 && $1 -ge 13 ]]; then + cpld_index=2 + reg_port_base=12 + elif [[ $1 -le 38 && $1 -ge 26 ]]; then + cpld_index=3 + reg_port_base=25 + elif [[ $1 -le 51 && $1 -ge 39 ]]; then + cpld_index=4 + reg_port_base=38 + elif [[ $1 -le 64 && $1 -ge 52 ]]; then + cpld_index=5 + reg_port_base=51 + else + echo "invalid port number" + fi + + cpld_port_index=$(( $port - $reg_port_base )) +} + +#Set QSFP Port eeporm variable +function _qsfp_eeprom_var_set { + local port=$1 + local eeprombusbase + local eeprombusshift + # port 1 => zqsfp0 + # port 2 => zqsfp1 + # ... + local port_group=$(( ($port - 1) / 8 )) + + case ${port_group} in + 0) + eeprombusbase=${NUM_MUX_9548_3_CH0} + ;; + 1) + eeprombusbase=${NUM_MUX_9548_4_CH0} + ;; + 2) + eeprombusbase=${NUM_MUX_9548_5_CH0} + ;; + 3) + eeprombusbase=${NUM_MUX_9548_6_CH0} + ;; + 4) + eeprombusbase=${NUM_MUX_9548_7_CH0} + ;; + 5) + eeprombusbase=${NUM_MUX_9548_8_CH0} + ;; + 6) + eeprombusbase=${NUM_MUX_9548_9_CH0} + ;; + 7) + eeprombusbase=${NUM_MUX_9548_10_CH0} + ;; + *) + ;; + esac + + eeprombusshift=$(( (${port} - 1) % 8)) + eepromBus=$(( ${eeprombusbase} + ${eeprombusshift} )) + eepromAddr=${I2C_ADDR_QSFP_EEPROM} +} + + +#Set SFP Port cpld variable +function _sfp_cpld_var_set { + local port=$1 + case ${port} in + 1) + cpld_index=1 + ;; + 2) + cpld_index=2 + ;; + *) + ;; + esac +} + +#Set QSFP Port eeporm variable +function _sfp_eeprom_var_set { + local port=$1 + + case ${port} in + 1) + eepromBus=${NUM_MUX_9546_1_CH0} + ;; + 2) + eepromBus=${NUM_MUX_9546_1_CH1} + ;; + *) + ;; + esac + + eepromAddr=${I2C_ADDR_SFP_EEPROM} +} + +#Get QSFP EEPROM Information +function _i2c_qsfp_eeprom_get { + local phy_port=0 + + #get physical port + phy_port=$(_port_logic2phy $QSFP_PORT) + + # input parameter validation + _util_input_check ${QSFP_PORT} ${MIN_QSFP_PORT_NUM} ${MAX_QSFP_PORT_NUM} + + _qsfp_eeprom_var_set ${phy_port} + + _util_get_qsfp_abs + + if [ $status = 0 ]; then + exit + fi + + + cat ${PATH_SYS_I2C_DEVICES}/$eepromBus-$(printf "%04x" $eepromAddr)/eeprom | hexdump -C +} + +#Init QSFP EEPROM +function _i2c_qsfp_eeprom_init { + echo "QSFP EEPROM INIT..." + + #Action check + action=$1 + if [ -z "${action}" ]; then + echo "No action, skip" + return + elif [ "${action}" != "new" ] && [ "${action}" != "delete" ]; then + echo "Error action, skip" + return + fi + + #Init 1-64 ports EEPROM + local i + for i in {1..64}; + do + _qsfp_eeprom_var_set ${i} + + if [ "${action}" == "new" ] && \ + ! [ -L ${PATH_SYS_I2C_DEVICES}/$eepromBus-$(printf "%04x" $eepromAddr) ]; then + echo "sff8436 $eepromAddr" > ${PATH_SYS_I2C_DEVICES}/i2c-$eepromBus/new_device + elif [ "${action}" == "delete" ] && \ + [ -L ${PATH_SYS_I2C_DEVICES}/$eepromBus-$(printf "%04x" $eepromAddr) ]; then + echo "$eepromAddr" > ${PATH_SYS_I2C_DEVICES}/i2c-$eepromBus/delete_device + fi + done + echo "Done" +} + +#Get SFP EEPROM Information +function _i2c_sfp_eeprom_get { + + # input parameter validation + _util_input_check ${SFP_PORT} ${MIN_SFP_PORT_NUM} ${MAX_SFP_PORT_NUM} + _util_get_sfp_pres + + if [ $status = 0 ]; then + exit + fi + + _sfp_eeprom_var_set ${SFP_PORT} + + cat ${PATH_SYS_I2C_DEVICES}/$eepromBus-$(printf "%04x" $eepromAddr)/eeprom | hexdump -C +} + +#Init SFP EEPROM +function _i2c_sfp_eeprom_init { + echo "SFP EEPROM INIT..." + + #Action check + action=$1 + if [ -z "${action}" ]; then + echo "No action, skip" + return + elif [ "${action}" != "new" ] && [ "${action}" != "delete" ]; then + echo "Error action, skip" + return + fi + + #Init 1-2 sfp+ EEPROM + local i + for i in {1..2}; + do + _sfp_eeprom_var_set ${i} + + if [ "${action}" == "new" ] && \ + ! [ -L ${PATH_SYS_I2C_DEVICES}/$eepromBus-$(printf "%04x" $eepromAddr) ]; then + echo "sff8436 $eepromAddr" > ${PATH_SYS_I2C_DEVICES}/i2c-$eepromBus/new_device + elif [ "${action}" == "delete" ] && \ + [ -L ${PATH_SYS_I2C_DEVICES}/$eepromBus-$(printf "%04x" $eepromAddr) ]; then + echo "$eepromAddr" > ${PATH_SYS_I2C_DEVICES}/i2c-$eepromBus/delete_device + fi + done + echo "Done" +} + +#Init Main Board EEPROM +function _i2c_mb_eeprom_init { + echo -n "Main Board EEPROM INIT..." + + #Action check + action=$1 + if [ -z "${action}" ]; then + echo "No action, skip" + return + elif [ "${action}" != "new" ] && [ "${action}" != "delete" ]; then + echo "Error action, skip" + return + fi + + #Init mb EEPROM + if [ "${action}" == "new" ] && \ + ! [ -L ${PATH_SYS_I2C_DEVICES}/${I2C_BUS_MB_EEPROM}-$(printf "%04x" $I2C_ADDR_MB_EEPROM) ]; then + echo "mb_eeprom ${I2C_ADDR_MB_EEPROM}" > ${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_MB_EEPROM}/new_device + elif [ "${action}" == "delete" ] && \ + [ -L ${PATH_SYS_I2C_DEVICES}/${I2C_BUS_MB_EEPROM}-$(printf "%04x" $I2C_ADDR_MB_EEPROM) ]; then + echo "$I2C_ADDR_MB_EEPROM" > ${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_MB_EEPROM}/delete_device + fi + echo "Done" +} + +#Init CPU Board EEPROM +function _i2c_cb_eeprom_init { + echo -n "CPU Board EEPROM INIT..." + + #Action check + action=$1 + if [ -z "${action}" ]; then + echo "No action, skip" + return + elif [ "${action}" != "new" ] && [ "${action}" != "delete" ]; then + echo "Error action, skip" + return + fi + + #Init cpu EEPROM + if [ "${action}" == "new" ] && \ + ! [ -L ${PATH_SYS_I2C_DEVICES}/${I2C_BUS_CB_EEPROM}-$(printf "%04x" $I2C_ADDR_CB_EEPROM) ]; then + echo "mb_eeprom ${I2C_ADDR_CB_EEPROM}" > ${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_CB_EEPROM}/new_device + elif [ "${action}" == "delete" ] && \ + [ -L ${PATH_SYS_I2C_DEVICES}/${I2C_BUS_CB_EEPROM}-$(printf "%04x" $I2C_ADDR_CB_EEPROM) ]; then + echo "$I2C_ADDR_CB_EEPROM" > ${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_CB_EEPROM}/delete_device + fi + echo "Done" +} + +#Init PSU Kernel Module +function _i2c_psu_init { + echo "=========================================================" + echo "# Description: I2C PSU Init" + echo "=========================================================" + modprobe ingrasys_s9230_64x_psu + + echo "psu1 ${I2C_ADDR_PSU1_EEPROM}" > ${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_PSU1_EEPROM}/new_device + echo "psu2 ${I2C_ADDR_PSU2_EEPROM}" > ${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_PSU2_EEPROM}/new_device +} + +#Deinit PSU Kernel Module +function _i2c_psu_deinit { + echo "${I2C_ADDR_PSU1_EEPROM}" > ${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_PSU1_EEPROM}/delete_device + echo "${I2C_ADDR_PSU2_EEPROM}" > ${PATH_SYS_I2C_DEVICES}/i2c-${I2C_BUS_PSU2_EEPROM}/delete_device + _util_rmmod ingrasys_s9230_64x_psu +} + +#get QSFP Status +function _i2c_qsfp_status_get { + + # input parameter validation + _util_input_check ${QSFP_PORT} ${MIN_QSFP_PORT_NUM} ${MAX_QSFP_PORT_NUM} + + local stat + _util_get_qsfp_abs + echo "status=$status" +} + +#get QSFP Type +function _i2c_qsfp_type_get { + local phy_port=0 + + phy_port=$(_port_logic2phy ${QSFP_PORT}) + + # input parameter validation + _util_input_check ${QSFP_PORT} ${MIN_QSFP_PORT_NUM} ${MAX_QSFP_PORT_NUM} + + #_qsfp_eeprom_var_set ${QSFP_PORT} + _qsfp_eeprom_var_set ${phy_port} + + #Get QSFP EEPROM info + qsfp_info=$(base64 ${PATH_SYS_I2C_DEVICES}/$eepromBus-$(printf "%04x" $eepromAddr)/eeprom) + + identifier=$(echo $qsfp_info | base64 -d -i | hexdump -s 128 -n 1 -e '"%x"') + connector=$(echo $qsfp_info | base64 -d -i | hexdump -s 130 -n 1 -e '"%x"') + transceiver=$(echo $qsfp_info | base64 -d -i | hexdump -s 131 -n 1 -e '"%x"') + + echo "identifier=$identifier" + echo "connector=$connector" + echo "transceiver=$transceiver" +} + +function _i2c_sfp_status_get { + + # input parameter validation + _util_input_check ${SFP_PORT} ${MIN_SFP_PORT_NUM} ${MAX_SFP_PORT_NUM} + + local stat + _util_get_sfp_pres + #status: 0 -> Down, 1 -> Up + if [ $status = 0 ]; then + stat="down" + else + stat="up" + fi + echo "status is $stat" +} + +#get SFP Type +function _i2c_sfp_type_get { + + # input parameter validation + _util_input_check ${SFP_PORT} ${MIN_SFP_PORT_NUM} ${MAX_SFP_PORT_NUM} + + _sfp_eeprom_var_set ${SFP_PORT} + + #Get QSFP EEPROM info + sfp_info=$(base64 ${PATH_SYS_I2C_DEVICES}/$eepromBus-$(printf "%04x" $eepromAddr)/eeprom) + + identifier=$(echo $sfp_info | base64 -d -i | hexdump -s 128 -n 1 -e '"%x"') + connector=$(echo $sfp_info | base64 -d -i | hexdump -s 130 -n 1 -e '"%x"') + transceiver=$(echo $sfp_info | base64 -d -i | hexdump -s 131 -n 1 -e '"%x"') + + echo "identifier=$identifier" + echo "connector=$connector" + echo "transceiver=$transceiver" +} + +#Get PSU EEPROM Information +function _i2c_psu_eeprom_get { + local eeprom_psu1="" + local eeprom_psu2="" + + echo "=========================================================" + echo "# Description: I2C PSU EEPROM Get..." + echo "=========================================================" + + eeprom_psu1="${PATH_SYSFS_PSU1}/psu_eeprom" + cat ${eeprom_psu1} | hexdump -C + + eeprom_psu2="${PATH_SYSFS_PSU2}/psu_eeprom" + cat ${eeprom_psu2} | hexdump -C +} + +#Get Main Board EEPROM Information +function _i2c_mb_eeprom_get { + echo "=========================================================" + echo "# Description: I2C MB EEPROM Get..." + echo "=========================================================" + _i2c_sys_eeprom_get mb +} + +#Get CPU Board EEPROM Information +function _i2c_cb_eeprom_get { + echo "=========================================================" + echo "# Description: I2C CB EEPROM Get..." + echo "=========================================================" + _i2c_sys_eeprom_get cb +} + +#Get system EEPROM Information +##input: "cb" for cpu board, "mb" for main board +function _i2c_sys_eeprom_get { + local eeprom_dev + + if [ "$1" == "cb" ]; then + eeprom_dev="${PATH_SYS_I2C_DEVICES}/${I2C_BUS_CB_EEPROM}-$(printf "%04x" $I2C_ADDR_CB_EEPROM)/eeprom" + elif [ "$1" == "mb" ]; then + eeprom_dev="${PATH_SYS_I2C_DEVICES}/${I2C_BUS_MB_EEPROM}-$(printf "%04x" $I2C_ADDR_MB_EEPROM)/eeprom" + else + echo "wrong eeprom type" + return + fi + + # check if eeprom device exist in sysfs + if [ ! -f ${eeprom_dev} ]; then + echo "eeprom device not init" + return + fi + + cat ${eeprom_dev} | hexdump -C + echo "Done" +} + +#sync eeprom content between mb and cb eeprom +function _i2c_eeprom_sync { + echo "=========================================================" + echo "# Description: EEPROM sync..." + echo "=========================================================" + + local mb_eeprom_dev="${PATH_SYS_I2C_DEVICES}/${I2C_BUS_MB_EEPROM}-$(printf "%04x" $I2C_ADDR_MB_EEPROM)/eeprom" + local cb_eeprom_dev="${PATH_SYS_I2C_DEVICES}/${I2C_BUS_CB_EEPROM}-$(printf "%04x" $I2C_ADDR_CB_EEPROM)/eeprom" + + # check if eeprom device exist in sysfs + if [[ ! -f ${mb_eeprom_dev} || ! -f ${cb_eeprom_dev} ]]; then + echo "eeprom device not init" + return + fi + + ## check if MB eeprom is empty + if [ ! -z "$(cat ${mb_eeprom_dev} | hexdump -n2 | grep ffff)" ]; then + echo "copy cb eeprom to mb eeprom..." + cat ${cb_eeprom_dev} > ${mb_eeprom_dev} + else + echo "no need to sync" + fi + + echo "Done" +} + +#Set System Status LED +function _i2c_sys_led { + # only green/amber, on/off can't control + if [ "${COLOR_LED}" == "green" ]; then + # set sys_led_g (0.7) = 1 + output_reg=${REG_PORT0_OUT} + mask=0x80 + value=0x80 + elif [ "${COLOR_LED}" == "amber" ]; then + # set sys_led_g (0.7) = 0 + output_reg=${REG_PORT0_OUT} + mask=0x80 + value=0x00 + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + #apply to io expander + _util_i2cset -m ${mask} -y ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${output_reg} ${value} + echo "Done" +} + +#Set FAN LED +function _i2c_fan_led { + if [ "${COLOR_LED}" == "green" ]; then + # set fan_led_en (0.6) = 1 & fan_led_y (0.5) = 0 + output_reg=${REG_PORT0_OUT} + mask=0x60 + value=0x60 + elif [ "${COLOR_LED}" == "amber" ]; then + # set fan_led_en (0.6) = 1 & fan_led_y (0.5) = 1 + output_reg=${REG_PORT0_OUT} + mask=0x60 + value=0x40 + elif [ "${COLOR_LED}" == "off" ]; then + # set fan_led_en (0.6) = 0 & fan_led_y (0.5) = 0 + output_reg=${REG_PORT0_OUT} + mask=0x60 + value=0x00 + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + #apply to io expander + _util_i2cset -m ${mask} -y ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${output_reg} ${value} + echo "Done" +} + +#Set PSU1 LED +function _i2c_psu1_led { + if [ "${COLOR_LED}" == "green" ]; then + # set psu1_pwr_ok_oe (0.4) = 1 & psu1_led_y (0.3) = 0 + output_reg=${REG_PORT0_OUT} + mask=0x18 + value=0x18 + elif [ "${COLOR_LED}" == "amber" ]; then + # set psu1_pwr_ok_oe (0.4) = 1 & psu1_led_y (0.3) = 1 + output_reg=${REG_PORT0_OUT} + mask=0x18 + value=0x10 + elif [ "${COLOR_LED}" == "off" ]; then + # set psu1_pwr_ok_oe (0.4) = 0 & psu1_led_y (0.3) = 0 + output_reg=${REG_PORT0_OUT} + mask=0x18 + value=0x00 + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + #apply to io expander + _util_i2cset -m ${mask} -y ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${output_reg} ${value} + echo "Done" +} + +#Set PSU2 LED +function _i2c_psu2_led { + if [ "${COLOR_LED}" == "green" ]; then + # set psu0_pwr_ok_oe (0.2) = 1 & psu0_led_y (0.1) = 0 + output_reg=${REG_PORT0_OUT} + mask=0x06 + value=0x06 + elif [ "${COLOR_LED}" == "amber" ]; then + # set psu0_pwr_ok_oe (0.2) = 1 & psu0_led_y (0.1) = 1 + output_reg=${REG_PORT0_OUT} + mask=0x06 + value=0x04 + elif [ "${COLOR_LED}" == "off" ]; then + # set psu0_pwr_ok_oe (0.2) = 0 & psu0_led_y (0.1) = 0 + output_reg=${REG_PORT0_OUT} + mask=0x06 + value=0x00 + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + #apply to io expander + _util_i2cset -m ${mask} -y ${I2C_BUS_SYS_LED} ${I2C_ADDR_MUX_9539_0} ${output_reg} ${value} + echo "Done" +} + +#Set FAN Tray LED +function _i2c_fan_tray_led { + + i2cAddr=${I2C_ADDR_MUX_9555_0} + output_reg=${REG_PORT0_OUT} + + case ${FAN_TRAY} in + 1) + output_reg=${REG_PORT0_OUT} + if [ "${COLOR_LED}" == "green" ]; then + mask=0x01 + elif [ "${COLOR_LED}" == "amber" ]; then + mask=0x02 + fi + ;; + 2) + output_reg=${REG_PORT0_OUT} + if [ "${COLOR_LED}" == "green" ]; then + mask=0x10 + elif [ "${COLOR_LED}" == "amber" ]; then + mask=0x20 + fi + ;; + 3) + output_reg=${REG_PORT1_OUT} + if [ "${COLOR_LED}" == "green" ]; then + mask=0x01 + elif [ "${COLOR_LED}" == "amber" ]; then + mask=0x02 + fi + ;; + 4) + output_reg=${REG_PORT1_OUT} + if [ "${COLOR_LED}" == "green" ]; then + mask=0x10 + elif [ "${COLOR_LED}" == "amber" ]; then + mask=0x20 + fi + ;; + *) + echo "Please input 1~4" + exit + ;; + esac + + # LED PIN value is ACTIVE HIGH + if [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "on" ]; then + _util_i2cset -m $mask -y -r ${I2C_BUS_FANTRAY_LED} $i2cAddr ${output_reg} 0xff + elif [ "${COLOR_LED}" == "green" ] && [ "${ONOFF_LED}" == "off" ]; then + _util_i2cset -m $mask -y -r ${I2C_BUS_FANTRAY_LED} $i2cAddr ${output_reg} 0x00 + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "on" ]; then + _util_i2cset -m $mask -y -r ${I2C_BUS_FANTRAY_LED} $i2cAddr ${output_reg} 0xff + elif [ "${COLOR_LED}" == "amber" ] && [ "${ONOFF_LED}" == "off" ]; then + _util_i2cset -m $mask -y -r ${I2C_BUS_FANTRAY_LED} $i2cAddr ${output_reg} 0x00 + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + echo "Done" +} + +#Get Board Version and Type +function _i2c_board_type_get { + # read input port 1 value from io expander + input_reg=${REG_PORT1_IN} + boardType=`i2cget -y ${I2C_BUS_HW_ID} ${I2C_ADDR_MUX_9539_0} ${input_reg}` + boardBuildRev=$((($boardType) & 0x03)) + boardHwRev=$((($boardType) >> 2 & 0x03)) + boardId=$((($boardType) >> 4)) + printf "MAIN_BOARD BOARD_ID is 0x%02x, HW Rev 0x%02x, Build Rev 0x%02x\n" $boardId $boardHwRev $boardBuildRev +} + +#Get BMC Board Version and Type +function _i2c_bmc_board_type_get { + # read input port 1 value from io expander + input_reg=${REG_PORT1_IN} + boardType=`i2cget -y ${I2C_BUS_BMC_HW_ID} ${I2C_ADDR_MUX_9555_1} ${input_reg}` + boardBuildRev=$((($boardType) & 0x03)) + boardHwRev=$((($boardType) >> 2 & 0x03)) + boardId=$((($boardType) >> 4)) + printf "BMC_BOARD BOARD_ID is 0x%02x, HW Rev 0x%02x, Build Rev 0x%02x\n" $boardId $boardHwRev $boardBuildRev +} + +#Get CPLD Version +function _i2c_cpld_version { + echo "=========================================================" + echo "# Description: CPLD Version" + echo "=========================================================" + + for i in {1..5}; + do + local cpld_bus="I2C_BUS_CPLD${i}" + local cpld_path="PATH_CPLD${i}_DEVICE" + local file_path="${PATH_SYS_I2C_DEVICES}/${!cpld_bus}-$(printf "%04x" ${I2C_ADDR_CPLD})/cpld_version" + printf "[CPLD %d] %s\n" ${i} $(cat ${file_path}) + done +} + +#Get PSU Status +function _i2c_psu_status { + local psu_abs="" + + psu1PwGood=`cat ${PATH_SYSFS_PSU1}/psu_pg` + psu_abs=`cat ${PATH_SYSFS_PSU1}/psu_abs` + if [ "$psu_abs" == "0" ]; then + psu1Exist=1 + else + psu1Exist=0 + fi + + psu2PwGood=`cat ${PATH_SYSFS_PSU2}/psu_pg` + psu_abs=`cat ${PATH_SYSFS_PSU2}/psu_abs` + if [ "$psu_abs" == "0" ]; then + psu2Exist=1 + else + psu2Exist=0 + fi + + printf "PSU1 Exist:%x PSU1 PW Good:%d\n" $psu1Exist $psu1PwGood + printf "PSU2 Exist:%d PSU2 PW Good:%d\n" $psu2Exist $psu2PwGood +} + +#Get register value from CPLD +function _i2c_cpld_reg_read { + local idx=$1 + local file_name=$2 + local cpld_i2c_addr=${I2C_ADDR_CPLD} + local reg_file_path + + case ${idx} in + 1) + cpld_i2c_bus=${I2C_BUS_CPLD1} + ;; + 2) + cpld_i2c_bus=${I2C_BUS_CPLD2} + ;; + 3) + cpld_i2c_bus=${I2C_BUS_CPLD3} + ;; + 4) + cpld_i2c_bus=${I2C_BUS_CPLD4} + ;; + 5) + cpld_i2c_bus=${I2C_BUS_CPLD5} + ;; + *) + echo "invalid cpld index" + exit + ;; + esac + + reg_file_path="${PATH_SYS_I2C_DEVICES}/${cpld_i2c_bus}-$(printf "%04x" ${cpld_i2c_addr})/${file_name}" + cpld_reg_val=`cat ${reg_file_path}` +} + +#util functions +function _util_i2cset { + if [ "$DEBUG" == "on" ]; then + i2cset $@ + else + i2cset $@ 1>/dev/null + fi +} + +function _i2c_set { + local i2c_bus=$1 + local i2c_addr=$2 + local reg=$3 + local mask=$4 + local value=$5 + + echo `i2cset -m $mask -y -r ${i2c_bus} ${i2c_addr} ${reg} ${value}` +} + +function _util_rmmod { + local mod=$1 + [ "$(lsmod | grep "^$mod ")" != "" ] && rmmod $mod +} + +# get qsfp presence +function _util_get_qsfp_abs { + local phy_port=0 + + #get physical port + phy_port=$(_port_logic2phy $QSFP_PORT) + + # read status from cpld + #_qsfp_cpld_var_set ${QSFP_PORT} + _qsfp_cpld_var_set ${phy_port} + cpld_reg_file_name="${CPLD_QSFP_STATUS_KEY}_${cpld_port_index}" + _i2c_cpld_reg_read ${cpld_index} ${cpld_reg_file_name} + #status: 0 -> Down, 1 -> Up (ACTIVE_LOW in ABS_BIT) + status=$(( $(( $((${cpld_reg_val})) & (1 << ($CPLD_QSFP_STATUS_ABS_BIT)) ))?0:1 )) +} + +# get sfp presence +function _util_get_sfp_pres { + + # read status from cpld + _sfp_cpld_var_set ${SFP_PORT} + cpld_reg_file_name="${CPLD_SFP_STATUS_KEY}" + _i2c_cpld_reg_read ${cpld_index} ${cpld_reg_file_name} + #status: 0 -> Down, 1 -> Up (ACTIVE_LOW in PRES_BIT) + status=$(( $(( $((${cpld_reg_val})) & (1 << ($CPLD_SFP_STATUS_PRES_BIT)) ))?0:1 )) +} + +# valid input number +function _util_input_check { + # input parameter validation + if [[ $1 -lt $2 || $1 -gt $3 ]]; then + echo "Please input number $2~$3" + exit + fi +} + +# clear all switch port led bitmap +function _util_port_led_clear { + echo "port led clear..." + # gpio pin on GPIO MUX PCA9539#1 I/O 0.2 + # pull low to reset bitamp + output_reg=${REG_PORT0_OUT} + mask=0x04 + value=0x00 + _util_i2cset -m ${mask} -y ${NUM_MUX_9548_1_CH2} ${I2C_ADDR_MUX_9539_1} ${output_reg} ${value} + echo "Done" +} + +#Increase read socket buffer for CoPP Test +function _config_rmem { + echo "109430400" > /proc/sys/net/core/rmem_max +} + +#Set 10G Mux to CPU or Front Panel +function _i2c_10g_mux { + + echo "=========================================================" + echo "# Description: 10G Mux" + echo "=========================================================" + + local target=${TARGET_10G_MUX} + local i2c_bus=${I2C_BUS_10GMUX} + local i2c_addr=${I2C_ADDR_10GMUX} + local reg=0 + local mask=0xff + local value=0 + local file_10g_mux="${PATH_CPLD1_DEVICE}/${I2C_BUS_CPLD1}-$(printf "%04x" ${I2C_ADDR_CPLD})/cpld_10gmux_config" + + #get current 10g mux register value on CPLD + value=`cat ${file_10g_mux}` + + if [ "${target}" == "cpu" ]; then + #Set XE0: slave address access + _i2c_set $i2c_bus $i2c_addr 0x06 $mask 0x18 + #Set XE0: CH4 D_IN0-S_OUTA0 EQ + _i2c_set $i2c_bus $i2c_addr 0x2c $mask 0x00 + #Set XE0: CH5 NC-S_OUTB0 DEM + _i2c_set $i2c_bus $i2c_addr 0x35 $mask 0x80 + #Set XE0: CH5 NC-S_OUTB0 VOD + _i2c_set $i2c_bus $i2c_addr 0x34 $mask 0xab + #Set XE0: CH1 D_OUT0-S_INB0 EQ + _i2c_set $i2c_bus $i2c_addr 0x16 $mask 0x01 + #Set XE0: CH1 D_OUT0-S_INB0 DEM + _i2c_set $i2c_bus $i2c_addr 0x18 0x1f 0x80 + #Set XE0: CH1 D_OUT0-S_INB0 VOD + _i2c_set $i2c_bus $i2c_addr 0x17 $mask 0xab + #Set XE1: CH6 D_IN1-S_OUTA1 EQ + _i2c_set $i2c_bus $i2c_addr 0x3a $mask 0x00 + #Set XE1: CH7 NC-S_OUTB1 EQ + _i2c_set $i2c_bus $i2c_addr 0x41 $mask 0x00 + #Set XE1: CH7 NC-S_OUTB1 DEM + _i2c_set $i2c_bus $i2c_addr 0x43 $mask 0x80 + #Set XE1: CH7 NC-S_OUTB1 VOD + _i2c_set $i2c_bus $i2c_addr 0x42 $mask 0xab + #Set XE1: CH3 D_OUT1-S_INB1 EQ + _i2c_set $i2c_bus $i2c_addr 0x24 $mask 0x01 + #Set XE1: CH3 D_OUT1-S_INB1 DEM + _i2c_set $i2c_bus $i2c_addr 0x26 $mask 0x80 + #Set XE1: CH3 D_OUT1-S_INB1 VOD + _i2c_set $i2c_bus $i2c_addr 0x25 $mask 0xab + #Enable auto negotiation of XE ports + eval "npx_diag 'phy set mdio portlist=129,130 devad=0x7 addr=0x11 data=0x80'" + eval "npx_diag 'phy set mdio portlist=129,130 devad=0x7 addr=0x10 data=0x01'" + eval "npx_diag 'phy set mdio portlist=129,130 devad=0x7 addr=0x0 data=0x3200'" + eval "npx_diag 'phy set mdio portlist=129,130 devad=0x1 addr=0x96 data=0x2'" + #delay 1 sec + sleep 1 + + #switch 10G MUX to cpu on CPLD + value=$(( value & 0xf3 )) + echo "$(printf 0x"%x" ${value})" > ${file_10g_mux} + + echo "Switch 10G Mux to [CPU]" + + elif [ "${COLOR_LED}" == "fp" ]; then + #Set XE0: slave address access + _i2c_set $i2c_bus $i2c_addr 0x06 $mask 0x18 + #Set XE0: CH4 D_IN0-S_OUTA0 EQ + _i2c_set $i2c_bus $i2c_addr 0x2c $mask 0x00 + #Set XE0: CH4 D_IN0-S_OUTA0 DEM + _i2c_set $i2c_bus $i2c_addr 0x2e $mask 0x80 + #Set XE0: CH4 D_IN0-S_OUTA0 VOD + _i2c_set $i2c_bus $i2c_addr 0x2d $mask 0xab + #Set XE0: CH0 NC-S_INA0 EQ + _i2c_set $i2c_bus $i2c_addr 0x0f $mask 0x00 + #Set XE0: CH1 D_OUT0-S_INB0 DEM + _i2c_set $i2c_bus $i2c_addr 0x18 0x18 0x80 + #Set XE0: CH1 D_OUT0-S_INB0 VOD + _i2c_set $i2c_bus $i2c_addr 0x17 $mask 0xab + #Set XE1: CH6 D_IN1-S_OUTA1 EQ + _i2c_set $i2c_bus $i2c_addr 0x3a $mask 0x00 + #Set XE1: CH6 D_IN1-S_OUTA1 DEM + _i2c_set $i2c_bus $i2c_addr 0x3c $mask 0x80 + #Set XE1: CH6 D_IN1-S_OUTA1 VOD + _i2c_set $i2c_bus $i2c_addr 0x3b $mask 0xab + #Set XE1: CH2 NC-S_INA1 EQ + _i2c_set $i2c_bus $i2c_addr 0x1d $mask 0x00 + #Set XE1: CH3 D_OUT1-S_INB1 DEM + _i2c_set $i2c_bus $i2c_addr 0x26 $mask 0x80 + #Set XE1: CH3 D_OUT1-S_INB1 VOD + _i2c_set $i2c_bus $i2c_addr 0x25 $mask 0xab + #Enable auto negotiation of XE ports + eval "npx_diag 'phy set mdio portlist=129,130 devad=0x7 addr=0x11 data=0x0'" + eval "npx_diag 'phy set mdio portlist=129,130 devad=0x7 addr=0x10 data=0x0'" + eval "npx_diag 'phy set mdio portlist=129,130 devad=0x7 addr=0x0 data=0x2200'" + eval "npx_diag 'phy set mdio portlist=129,130 devad=0x1 addr=0x96 data=0x2200'" + #delay 1 sec + sleep 1 + + #switch 10G MUX to front panel on CPLD + value=$(( value | 0x0c )) + echo "$(printf 0x"%x" ${value})" > ${file_10g_mux} + + echo "Switch 10G Mux to [Front Panel]" + else + echo "invalid target, please set target to cpu/fp" + fi +} + +#Main Function +function _main { + tart_time_str=`date` + start_time_sec=$(date +%s) + + if [ "${EXEC_FUNC}" == "help" ]; then + _help + elif [ "${EXEC_FUNC}" == "i2c_init" ]; then + _i2c_init + elif [ "${EXEC_FUNC}" == "i2c_deinit" ]; then + _i2c_deinit + elif [ "${EXEC_FUNC}" == "i2c_fan_speed_init" ]; then + _i2c_fan_speed_init + elif [ "${EXEC_FUNC}" == "i2c_io_exp_init" ]; then + _i2c_io_exp_init + elif [ "${EXEC_FUNC}" == "i2c_led_test" ]; then + _i2c_led_test + elif [ "${EXEC_FUNC}" == "i2c_mb_eeprom_get" ]; then + _i2c_mb_eeprom_get + elif [ "${EXEC_FUNC}" == "i2c_cb_eeprom_get" ]; then + _i2c_cb_eeprom_get + elif [ "${EXEC_FUNC}" == "i2c_eeprom_sync" ]; then + _i2c_eeprom_sync + elif [ "${EXEC_FUNC}" == "i2c_psu_eeprom_get" ]; then + _i2c_psu_eeprom_get + elif [ "${EXEC_FUNC}" == "i2c_qsfp_eeprom_get" ]; then + _i2c_qsfp_eeprom_get + elif [ "${EXEC_FUNC}" == "i2c_sfp_eeprom_get" ]; then + _i2c_sfp_eeprom_get + elif [ "${EXEC_FUNC}" == "i2c_qsfp_eeprom_init" ]; then + _i2c_qsfp_eeprom_init ${QSFP_ACTION} + elif [ "${EXEC_FUNC}" == "i2c_sfp_eeprom_init" ]; then + _i2c_sfp_eeprom_init ${SFP_ACTION} + elif [ "${EXEC_FUNC}" == "i2c_mb_eeprom_init" ]; then + _i2c_mb_eeprom_init ${MB_EEPROM_ACTION} + elif [ "${EXEC_FUNC}" == "i2c_cb_eeprom_init" ]; then + _i2c_cb_eeprom_init ${MB_EEPROM_ACTION} + elif [ "${EXEC_FUNC}" == "i2c_qsfp_status_get" ]; then + _i2c_qsfp_status_get + elif [ "${EXEC_FUNC}" == "i2c_sfp_status_get" ]; then + _i2c_sfp_status_get + elif [ "${EXEC_FUNC}" == "i2c_qsfp_type_get" ]; then + _i2c_qsfp_type_get + elif [ "${EXEC_FUNC}" == "i2c_sfp_type_get" ]; then + _i2c_sfp_type_get + elif [ "${EXEC_FUNC}" == "i2c_led_psu_status_set" ]; then + _i2c_led_psu_status_set + elif [ "${EXEC_FUNC}" == "i2c_led_fan_status_set" ]; then + _i2c_led_fan_status_set + elif [ "${EXEC_FUNC}" == "i2c_led_fan_tray_status_set" ]; then + _i2c_led_fan_tray_status_set + elif [ "${EXEC_FUNC}" == "i2c_sys_led" ]; then + _i2c_sys_led + elif [ "${EXEC_FUNC}" == "i2c_fan_led" ]; then + _i2c_fan_led + elif [ "${EXEC_FUNC}" == "i2c_fan_tray_led" ]; then + _i2c_fan_tray_led + elif [ "${EXEC_FUNC}" == "i2c_psu1_led" ]; then + _i2c_psu1_led + elif [ "${EXEC_FUNC}" == "i2c_psu2_led" ]; then + _i2c_psu2_led + elif [ "${EXEC_FUNC}" == "i2c_board_type_get" ]; then + _i2c_board_type_get + elif [ "${EXEC_FUNC}" == "i2c_bmc_board_type_get" ]; then + _i2c_bmc_board_type_get + elif [ "${EXEC_FUNC}" == "i2c_cpld_version" ]; then + _i2c_cpld_version + elif [ "${EXEC_FUNC}" == "i2c_psu_status" ]; then + _i2c_psu_status + elif [ "${EXEC_FUNC}" == "i2c_test_all" ]; then + _i2c_init + _i2c_led_test + _i2c_psu_eeprom_get + _i2c_mb_eeprom_get + _i2c_cb_eeprom_get + _i2c_board_type_get + _i2c_bmc_board_type_get + _i2c_cpld_version + _i2c_psu_status + elif [ "${EXEC_FUNC}" == "i2c_10g_mux" ]; then + _i2c_10g_mux + else + echo "Invalid Parameters, Exit!!!" + _help + exit ${FALSE} + fi + + if [ "$DEBUG" == "on" ]; then + echo "-----------------------------------------------------" + end_time_str=`date` + end_time_sec=$(date +%s) + diff_time=$[ ${end_time_sec} - ${start_time_sec} ] + echo "Start Time: ${start_time_str} (${start_time_sec})" + echo "End Time : ${end_time_str} (${end_time_sec})" + echo "Total Execution Time: ${diff_time} sec" + + echo "done!!!" + fi +} + +_main diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/qsfp_monitor.sh b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/qsfp_monitor.sh new file mode 100755 index 000000000000..23a3fd066bee --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/qsfp_monitor.sh @@ -0,0 +1,105 @@ +#!/bin/bash +# Copyright (C) 2017 Ingrasys, 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 3 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, see . + +INTERVAL=3 +I2C_UTILS="/usr/sbin/i2c_utils.sh" +QSFP_SI_SCRIPT="/usr/sbin/qsfp_si_cfg.sh" +QSFP_ARRAY=(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \ + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) + +#QSFP SI monitor +function _qsfp_si_monitor { + local i + local status + for i in {0..63}; + do + status=`${I2C_UTILS} i2c_qsfp_status_get $(expr $i + 1) | egrep '^status=.*$' | sed -e 's/status=//g'` + if [ "${status}" == "1" ]; then + _qsfp_type_check $i + fi + done +} + +#QSFP type +function _qsfp_type_check { + local port=$1 + local qsfp_type=`${I2C_UTILS} i2c_qsfp_type_get $(expr $port + 1)` + local identifier=`echo "$qsfp_type" | grep '^identifier=.*$' | sed -e 's/identifier=//g'` + if [ "${identifier}" == "11" ]; then + connector=`echo "$qsfp_type" | grep '^connector=.*$' | sed -e 's/connector=//g'` + case ${connector} in + 21|23) + #DAC + if [ "${QSFP_ARRAY[$port]}" != "${connector}" ]; then + echo "Change Port $(expr $port + 1) to DAC" + QSFP_ARRAY[$port]=${connector} + ${QSFP_SI_SCRIPT} dac $port >/dev/null + fi + ;; + *) + #Optical + if [ "${QSFP_ARRAY[$port]}" != "${connector}" ]; then + echo "Change Port $(expr $port + 1) to Optical" + QSFP_ARRAY[$port]=${connector} + ${QSFP_SI_SCRIPT} optical $port >/dev/null + fi + ;; + esac + fi +} + +#Docker exist check +function _docker_swss_check { + while true + do + # Check if syncd starts + result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + if [ "$result" == "3" ]; then + return + fi + sleep $INTERVAL + done +} + +#Docker exist check +function _qsfp_si_cfg_script_check { + + if [ -f ${QSFP_SI_SCRIPT} ] && [ -x ${QSFP_SI_SCRIPT} ]; then + echo "SI Script exists. Start monitor." + return + else + echo "SI Script not exist. Exit monitor." + exit + fi +} + +# main function +function _main { + #Check SI Script + _qsfp_si_cfg_script_check + #Check docker swss is running + _docker_swss_check + while true + do + _qsfp_si_monitor + # Sleep while still handling signals + sleep $INTERVAL & + wait $! + done +} + +_main + diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/s9230_64x_monitor.sh b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/s9230_64x_monitor.sh new file mode 100755 index 000000000000..8bfb22328003 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/s9230_64x_monitor.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# Copyright (C) 2016 Ingrasys, 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 3 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, see . + +INTERVAL=5 +I2C_UTILS="/usr/sbin/i2c_utils.sh" + + +# LED status monitor +function _led_monitor { + ${I2C_UTILS} i2c_led_fan_status_set >/dev/null + ${I2C_UTILS} i2c_led_psu_status_set >/dev/null + ${I2C_UTILS} i2c_led_fan_tray_status_set >/dev/null +} + +# main function +function _main { + while true + do + _led_monitor + # Sleep while still handling signals + sleep $INTERVAL & + wait $! + done +} + +_main From 03e27da2aaf1a217c04417b204afdbb3e09c2629 Mon Sep 17 00:00:00 2001 From: lguohan Date: Mon, 24 Sep 2018 09:02:52 -0700 Subject: [PATCH 140/219] [broadcom]: update sai to 3.1.3.4-17 (#2070) Signed-off-by: Guohan Lu --- platform/broadcom/sai.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 68742dea25b9..4000aec1a778 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,9 +1,9 @@ -BRCM_SAI = libsaibcm_3.1.3.4-16_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/libsaibcm_3.1.3.4-16_amd64.deb?sv=2015-04-05&sr=b&sig=p7e4USdBWxIKYxP22t7yb%2BKtzlWBidZxQF1HZ%2FDs16I%3D&se=2155-07-13T04%3A43%3A02Z&sp=r" +BRCM_SAI = libsaibcm_3.1.3.4-17_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/libsaibcm_3.1.3.4-17_amd64.deb?sv=2015-04-05&sr=b&sig=wDTUZwUF05gxdoB%2BHVZeB8uQQWq3qFmvM5VLliLHA8E%3D&se=2155-08-17T07%3A45%3A56Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.1.3.4-16_amd64.deb +BRCM_SAI_DEV = libsaibcm-dev_3.1.3.4-17_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/libsaibcm-dev_3.1.3.4-16_amd64.deb?sv=2015-04-05&sr=b&sig=80iUtmr%2BbdWg7p5Zst%2FQrWuukgSx0TME2fRPPIhfLMQ%3D&se=2155-07-12T21%3A32%3A56Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/libsaibcm-dev_3.1.3.4-17_amd64.deb?sv=2015-04-05&sr=b&sig=l%2Bvb%2F4%2FCB8IEz70msUGMYsWCpeDPp7slxwZeiKqnNAo%3D&se=2155-08-17T07%3A43%3A58Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) From 48a0e149ffffc6c3f401e928693ae9c44c80fa31 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Mon, 24 Sep 2018 14:56:37 -0700 Subject: [PATCH 141/219] [hwsku-init] Introduce mechanism to run HWSKU specific initialization code (#2072) When there is HWSKU specific initialization needs to be performed, please add hwsku-init script under device folder, it will be invoked by swss before any subsequent initializations. Signed-off-by: Ying Xie --- dockers/docker-orchagent/start.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dockers/docker-orchagent/start.sh b/dockers/docker-orchagent/start.sh index 0321bf8428f4..1b6b8e7959bf 100755 --- a/dockers/docker-orchagent/start.sh +++ b/dockers/docker-orchagent/start.sh @@ -6,6 +6,11 @@ sonic-cfggen -d -t /usr/share/sonic/templates/switch.json.j2 > /etc/swss/config. sonic-cfggen -d -t /usr/share/sonic/templates/ipinip.json.j2 > /etc/swss/config.d/ipinip.json sonic-cfggen -d -t /usr/share/sonic/templates/ports.json.j2 > /etc/swss/config.d/ports.json +# Executed HWSKU specific initialization tasks. +if [ -x /usr/share/sonic/hwsku/hwsku-init ]; then + /usr/share/sonic/hwsku/hwsku-init +fi + export platform=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` rm -f /var/run/rsyslogd.pid From b066c7c2756a456d910dc8a57270dc5dc45231d6 Mon Sep 17 00:00:00 2001 From: zzhiyuan Date: Tue, 25 Sep 2018 00:59:01 -0700 Subject: [PATCH 142/219] [devices]: Add new hwsku Arista-7050-Q31S4 (#2077) --- .../Arista-7050-Q31S4/buffers.json.j2 | 138 ++++ .../Arista-7050-Q31S4/hwsku-init | 1 + .../Arista-7050-Q31S4/port_config.ini | 36 + .../Arista-7050-Q31S4/qos.json | 144 ++++ .../Arista-7050-Q31S4/sai.profile | 1 + .../td2-a7050-q31s4-31x40G-4x10G.config.bcm | 676 ++++++++++++++++++ .../Arista-7050-QX-32S/hwsku-init | 1 + 7 files changed, 997 insertions(+) create mode 100644 device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/buffers.json.j2 create mode 100644 device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/hwsku-init create mode 100644 device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/port_config.ini create mode 100644 device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/qos.json create mode 100644 device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/sai.profile create mode 100644 device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/td2-a7050-q31s4-31x40G-4x10G.config.bcm create mode 100644 device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/hwsku-init diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/buffers.json.j2 b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/buffers.json.j2 new file mode 100644 index 000000000000..ff8125e18719 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/buffers.json.j2 @@ -0,0 +1,138 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '300m' %} +{% set default_speed = '100G' %} +{% set default_ports_num = 32 -%} + +{# 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 = [] %} + {% if PORT.append("Ethernet0") %}{% endif %} + {% if PORT.append("Ethernet1") %}{% endif %} + {% if PORT.append("Ethernet2") %}{% endif %} + {% if PORT.append("Ethernet3") %}{% endif %} + {% for port_idx in range(1,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% 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 %} + } + }, + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "8072396", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xon":"18432", + "xoff":"40560", + "size":"41808", + "dynamic_th":"-3", + "xon_offset":"2496" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, + "BUFFER_PG": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" + }, + "{{ port_names }}|0-1": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "{{ port_names }}|5": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-1": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "{{ port_names }}|5": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +} diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/hwsku-init b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/hwsku-init new file mode 100644 index 000000000000..c005241e4b6a --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/hwsku-init @@ -0,0 +1 @@ +echo 1 > /sys/devices/pci0000:00/0000:00:02.2/0000:02:00.0/mux diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/port_config.ini b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/port_config.ini new file mode 100644 index 000000000000..dafdb570e9cc --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/port_config.ini @@ -0,0 +1,36 @@ +# name lanes alias index +Ethernet0 9 Ethernet1 1 +Ethernet1 10 Ethernet2 2 +Ethernet2 11 Ethernet3 3 +Ethernet3 12 Ethernet4 4 +Ethernet4 13,14,15,16 Ethernet6/1 6 +Ethernet8 17,18,19,20 Ethernet7/1 7 +Ethernet12 21,22,23,24 Ethernet8/1 8 +Ethernet16 29,30,31,32 Ethernet9/1 9 +Ethernet20 25,26,27,28 Ethernet10/1 10 +Ethernet24 33,34,35,36 Ethernet11/1 11 +Ethernet28 37,38,39,40 Ethernet12/1 12 +Ethernet32 45,46,47,48 Ethernet13/1 13 +Ethernet36 41,42,43,44 Ethernet14/1 14 +Ethernet40 49,50,51,52 Ethernet15/1 15 +Ethernet44 53,54,55,56 Ethernet16/1 16 +Ethernet48 69,70,71,72 Ethernet17/1 17 +Ethernet52 65,66,67,68 Ethernet18/1 18 +Ethernet56 73,74,75,76 Ethernet19/1 19 +Ethernet60 77,78,79,80 Ethernet20/1 20 +Ethernet64 93,94,95,96 Ethernet21/1 21 +Ethernet68 89,90,91,92 Ethernet22/1 22 +Ethernet72 97,98,99,100 Ethernet23/1 23 +Ethernet76 101,102,103,104 Ethernet24/1 24 +Ethernet80 109,110,111,112 Ethernet25/1 25 +Ethernet84 105,106,107,108 Ethernet26/1 26 +Ethernet88 121,122,123,124 Ethernet27/1 27 +Ethernet92 125,126,127,128 Ethernet28/1 28 +Ethernet96 61,62,63,64 Ethernet29 29 +Ethernet100 57,58,59,60 Ethernet30 30 +Ethernet104 81,82,83,84 Ethernet31 31 +Ethernet108 85,86,87,88 Ethernet32 32 +Ethernet112 117,118,119,120 Ethernet33 33 +Ethernet116 113,114,115,116 Ethernet34 34 +Ethernet120 1,2,3,4 Ethernet35 35 +Ethernet124 5,6,7,8 Ethernet36 36 diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/qos.json b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/qos.json new file mode 100644 index 000000000000..243ddd69a916 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/qos.json @@ -0,0 +1,144 @@ +{ + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4", + "5": "5" + } + }, + "MAP_PFC_PRIORITY_TO_QUEUE": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4", + "5": "5" + } + }, + "TC_TO_QUEUE_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4", + "5": "5" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"3", + "4":"4", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"5", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "SCHEDULER": { + "scheduler.0" : { + "type":"DWRR", + "weight": "20" + } + }, + "PORT_QOS_MAP": { + "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable": "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "wred_red_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"2097152", + "red_min_threshold":"1048576", + "yellow_max_threshold":"2097152", + "yellow_min_threshold":"1048576", + "green_max_threshold":"2097152", + "green_min_threshold":"1048576", + "green_drop_probability":"5", + "yellow_drop_probability":"5", + "red_drop_probability":"5" + } + }, + "QUEUE": { + "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3-4" : { + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0" : { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, + "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|1" : { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, + "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|5" : { + "scheduler" : "[SCHEDULER|scheduler.0]" + } + } +} diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/sai.profile b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/sai.profile new file mode 100644 index 000000000000..9a50433cabdc --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-a7050-q31s4-31x40G-4x10G.config.bcm diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/td2-a7050-q31s4-31x40G-4x10G.config.bcm b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/td2-a7050-q31s4-31x40G-4x10G.config.bcm new file mode 100644 index 000000000000..9be3064af257 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/td2-a7050-q31s4-31x40G-4x10G.config.bcm @@ -0,0 +1,676 @@ +arl_clean_timeout_usec=15000000 +bcm_num_cos.0=8 +bcm_stat_flags=1 +bcm_stat_jumbo.0=9236 +cdma_timeout_usec.0=15000000 +dma_desc_timeout_usec.0=15000000 +higig2_hdr_mode.0=1 +ipv6_lpm_128b_enable.0=2 +l2xmsg_mode.0=1 +max_vp_lags.0=0 +mdio_output_delay=0x0d +miim_intr_enable.0=0 +module_64ports.0=0 +os=unix +pbmp_oversubscribe.0=0x1fffffffffffffffffffffffffe +pbmp_xport_xe.0=0x1fffffffffffffffffffffffffe +phy_an_c37_1.0=3 +phy_an_c37_5.0=3 +phy_an_c37_9.0=3 +phy_an_c37_13.0=3 +phy_an_c37_17.0=3 +phy_an_c37_21.0=3 +phy_an_c37_25.0=3 +phy_an_c37_29.0=3 +phy_an_c37_33.0=3 +phy_an_c37_37.0=3 +phy_an_c37_41.0=3 +phy_an_c37_45.0=3 +phy_an_c37_49.0=3 +phy_an_c37_53.0=3 +phy_an_c37_57.0=3 +phy_an_c37_61.0=3 +phy_an_c37_65.0=3 +phy_an_c37_69.0=3 +phy_an_c37_73.0=3 +phy_an_c37_77.0=3 +phy_an_c37_81.0=3 +phy_an_c37_85.0=3 +phy_an_c37_89.0=3 +phy_an_c37_93.0=3 +phy_an_c37_97.0=0 +phy_an_c37_98.0=0 +phy_an_c37_99.0=0 +phy_an_c37_100.0=0 +phy_an_c37_101.0=0 +phy_an_c37_102.0=0 +phy_an_c37_103.0=0 +phy_an_c37_104.0=0 +phy_an_c73_1.0=0 +phy_an_c73_5.0=0 +phy_an_c73_9.0=0 +phy_an_c73_13.0=0 +phy_an_c73_17.0=0 +phy_an_c73_21.0=0 +phy_an_c73_25.0=0 +phy_an_c73_29.0=0 +phy_an_c73_33.0=0 +phy_an_c73_37.0=0 +phy_an_c73_41.0=0 +phy_an_c73_45.0=0 +phy_an_c73_49.0=0 +phy_an_c73_53.0=0 +phy_an_c73_57.0=0 +phy_an_c73_61.0=0 +phy_an_c73_65.0=0 +phy_an_c73_69.0=0 +phy_an_c73_73.0=0 +phy_an_c73_77.0=0 +phy_an_c73_81.0=0 +phy_an_c73_85.0=0 +phy_an_c73_89.0=0 +phy_an_c73_93.0=0 +phy_an_c73_97.0=2 +phy_an_c73_98.0=2 +phy_an_c73_99.0=2 +phy_an_c73_100.0=2 +phy_an_c73_101.0=2 +phy_an_c73_102.0=2 +phy_an_c73_103.0=2 +phy_an_c73_104.0=2 +phy_xaui_rx_polarity_flip_1.0=0x0 +phy_xaui_rx_polarity_flip_5.0=0x0 +phy_xaui_rx_polarity_flip_9.0=0x4 +phy_xaui_rx_polarity_flip_13.0=0x0 +phy_xaui_rx_polarity_flip_17.0=0xb +phy_xaui_rx_polarity_flip_21.0=0x3 +phy_xaui_rx_polarity_flip_25.0=0xb +phy_xaui_rx_polarity_flip_29.0=0xf +phy_xaui_rx_polarity_flip_33.0=0xb +phy_xaui_rx_polarity_flip_37.0=0x3 +phy_xaui_rx_polarity_flip_41.0=0xb +phy_xaui_rx_polarity_flip_45.0=0x0 +phy_xaui_rx_polarity_flip_49.0=0x4 +phy_xaui_rx_polarity_flip_53.0=0xc +phy_xaui_rx_polarity_flip_57.0=0x4 +phy_xaui_rx_polarity_flip_61.0=0x0 +phy_xaui_rx_polarity_flip_65.0=0xb +phy_xaui_rx_polarity_flip_69.0=0x3 +phy_xaui_rx_polarity_flip_73.0=0xb +phy_xaui_rx_polarity_flip_77.0=0xf +phy_xaui_rx_polarity_flip_81.0=0xb +phy_xaui_rx_polarity_flip_85.0=0x3 +phy_xaui_rx_polarity_flip_89.0=0x4 +phy_xaui_rx_polarity_flip_93.0=0x0 +phy_xaui_rx_polarity_flip_97.0=0xb +phy_xaui_rx_polarity_flip_98.0=0x3 +phy_xaui_rx_polarity_flip_99.0=0x4 +phy_xaui_rx_polarity_flip_100.0=0x0 +phy_xaui_rx_polarity_flip_101.0=0x0 +phy_xaui_rx_polarity_flip_102.0=0xe +phy_xaui_rx_polarity_flip_103.0=0x0 +phy_xaui_rx_polarity_flip_104.0=0x0 +phy_xaui_tx_polarity_flip_1.0=0x0 +phy_xaui_tx_polarity_flip_5.0=0x0 +phy_xaui_tx_polarity_flip_9.0=0x2 +phy_xaui_tx_polarity_flip_13.0=0x0 +phy_xaui_tx_polarity_flip_17.0=0xd +phy_xaui_tx_polarity_flip_21.0=0xc +phy_xaui_tx_polarity_flip_25.0=0xd +phy_xaui_tx_polarity_flip_29.0=0xf +phy_xaui_tx_polarity_flip_33.0=0xd +phy_xaui_tx_polarity_flip_37.0=0xc +phy_xaui_tx_polarity_flip_41.0=0xd +phy_xaui_tx_polarity_flip_45.0=0x0 +phy_xaui_tx_polarity_flip_49.0=0x2 +phy_xaui_tx_polarity_flip_53.0=0x3 +phy_xaui_tx_polarity_flip_57.0=0x2 +phy_xaui_tx_polarity_flip_61.0=0x0 +phy_xaui_tx_polarity_flip_65.0=0xd +phy_xaui_tx_polarity_flip_69.0=0xc +phy_xaui_tx_polarity_flip_73.0=0xd +phy_xaui_tx_polarity_flip_77.0=0xf +phy_xaui_tx_polarity_flip_81.0=0xd +phy_xaui_tx_polarity_flip_85.0=0xc +phy_xaui_tx_polarity_flip_89.0=0x2 +phy_xaui_tx_polarity_flip_93.0=0x0 +phy_xaui_tx_polarity_flip_97.0=0xd +phy_xaui_tx_polarity_flip_98.0=0xc +phy_xaui_tx_polarity_flip_99.0=0x2 +phy_xaui_tx_polarity_flip_100.0=0x0 +phy_xaui_tx_polarity_flip_101.0=0x0 +phy_xaui_tx_polarity_flip_102.0=0x7 +phy_xaui_tx_polarity_flip_103.0=0x2 +phy_xaui_tx_polarity_flip_104.0=0x0 +port_init_autoneg_1.0=0 +port_init_autoneg_5.0=0 +port_init_autoneg_9.0=0 +port_init_autoneg_13.0=0 +port_init_autoneg_17.0=0 +port_init_autoneg_21.0=0 +port_init_autoneg_25.0=0 +port_init_autoneg_29.0=0 +port_init_autoneg_33.0=0 +port_init_autoneg_37.0=0 +port_init_autoneg_41.0=0 +port_init_autoneg_45.0=0 +port_init_autoneg_49.0=0 +port_init_autoneg_53.0=0 +port_init_autoneg_57.0=0 +port_init_autoneg_61.0=0 +port_init_autoneg_65.0=0 +port_init_autoneg_69.0=0 +port_init_autoneg_73.0=0 +port_init_autoneg_77.0=0 +port_init_autoneg_81.0=0 +port_init_autoneg_85.0=0 +port_init_autoneg_89.0=0 +port_init_autoneg_93.0=0 +port_init_autoneg_97.0=0 +port_init_autoneg_98.0=0 +port_init_autoneg_99.0=0 +port_init_autoneg_100.0=0 +port_init_autoneg_101.0=0 +port_init_autoneg_102.0=0 +port_init_autoneg_103.0=0 +port_init_autoneg_104.0=0 +port_init_cl72.0=0 +portmap_1.0=9:10 +portmap_2.0=10:10 +portmap_3.0=11:10 +portmap_4.0=12:10 +portmap_5.0=13:40 +portmap_9.0=17:40 +portmap_13.0=21:40 +portmap_17.0=29:40 +portmap_21.0=25:40 +portmap_25.0=33:40 +portmap_29.0=37:40 +portmap_33.0=45:40 +portmap_37.0=41:40 +portmap_41.0=49:40 +portmap_45.0=53:40 +portmap_49.0=69:40 +portmap_53.0=65:40 +portmap_57.0=73:40 +portmap_61.0=77:40 +portmap_65.0=93:40 +portmap_69.0=89:40 +portmap_73.0=97:40 +portmap_77.0=101:40 +portmap_81.0=109:40 +portmap_85.0=105:40 +portmap_89.0=121:40 +portmap_93.0=125:40 +portmap_97.0=61:40 +portmap_98.0=57:40 +portmap_99.0=81:40 +portmap_100.0=85:40 +portmap_101.0=117:40 +portmap_102.0=113:40 +portmap_103.0=1:40 +portmap_104.0=5:40 +scache_filename=/tmp/scache +schan_intr_enable=0 +serdes_firmware_mode_1.0=2 +serdes_firmware_mode_5.0=2 +serdes_firmware_mode_9.0=2 +serdes_firmware_mode_13.0=2 +serdes_firmware_mode_17.0=2 +serdes_firmware_mode_21.0=2 +serdes_firmware_mode_25.0=2 +serdes_firmware_mode_29.0=2 +serdes_firmware_mode_33.0=2 +serdes_firmware_mode_37.0=2 +serdes_firmware_mode_41.0=2 +serdes_firmware_mode_45.0=2 +serdes_firmware_mode_49.0=2 +serdes_firmware_mode_53.0=2 +serdes_firmware_mode_57.0=2 +serdes_firmware_mode_61.0=2 +serdes_firmware_mode_65.0=2 +serdes_firmware_mode_69.0=2 +serdes_firmware_mode_73.0=2 +serdes_firmware_mode_77.0=2 +serdes_firmware_mode_81.0=2 +serdes_firmware_mode_85.0=2 +serdes_firmware_mode_89.0=2 +serdes_firmware_mode_93.0=2 +serdes_firmware_mode_97.0=2 +serdes_firmware_mode_98.0=2 +serdes_firmware_mode_99.0=2 +serdes_firmware_mode_100.0=2 +serdes_firmware_mode_101.0=2 +serdes_firmware_mode_102.0=2 +serdes_firmware_mode_103.0=2 +serdes_firmware_mode_104.0=2 +stable_size=0x2000000 +tdma_timeout_usec.0=15000000 +tslam_timeout_usec.0=15000000 +xgxs_lcpll_xtal_refclk.0=1 +xgxs_rx_lane_map_1.0=0x0123 +xgxs_rx_lane_map_5.0=0x0321 +xgxs_rx_lane_map_9.0=0x1302 +xgxs_rx_lane_map_13.0=0x0213 +xgxs_rx_lane_map_17.0=0x1302 +xgxs_rx_lane_map_21.0=0x1302 +xgxs_rx_lane_map_25.0=0x1302 +xgxs_rx_lane_map_29.0=0x0213 +xgxs_rx_lane_map_33.0=0x1302 +xgxs_rx_lane_map_37.0=0x1302 +xgxs_rx_lane_map_41.0=0x1302 +xgxs_rx_lane_map_45.0=0x0213 +xgxs_rx_lane_map_49.0=0x1302 +xgxs_rx_lane_map_53.0=0x1302 +xgxs_rx_lane_map_57.0=0x1302 +xgxs_rx_lane_map_61.0=0x0213 +xgxs_rx_lane_map_65.0=0x1302 +xgxs_rx_lane_map_69.0=0x1302 +xgxs_rx_lane_map_73.0=0x1302 +xgxs_rx_lane_map_77.0=0x0213 +xgxs_rx_lane_map_81.0=0x1302 +xgxs_rx_lane_map_85.0=0x1302 +xgxs_rx_lane_map_89.0=0x1302 +xgxs_rx_lane_map_93.0=0x0213 +xgxs_rx_lane_map_97.0=0x1302 +xgxs_rx_lane_map_98.0=0x1302 +xgxs_rx_lane_map_99.0=0x1302 +xgxs_rx_lane_map_100.0=0x0213 +xgxs_rx_lane_map_101.0=0x0213 +xgxs_rx_lane_map_102.0=0x1302 +xgxs_rx_lane_map_103.0=0x0123 +xgxs_rx_lane_map_104.0=0x2031 +xgxs_tx_lane_map_1.0=0x3210 +xgxs_tx_lane_map_5.0=0x0321 +xgxs_tx_lane_map_9.0=0x2031 +xgxs_tx_lane_map_13.0=0x0213 +xgxs_tx_lane_map_17.0=0x2031 +xgxs_tx_lane_map_21.0=0x2031 +xgxs_tx_lane_map_25.0=0x2031 +xgxs_tx_lane_map_29.0=0x0213 +xgxs_tx_lane_map_33.0=0x2031 +xgxs_tx_lane_map_37.0=0x2031 +xgxs_tx_lane_map_41.0=0x2031 +xgxs_tx_lane_map_45.0=0x0213 +xgxs_tx_lane_map_49.0=0x2031 +xgxs_tx_lane_map_53.0=0x2031 +xgxs_tx_lane_map_57.0=0x2031 +xgxs_tx_lane_map_61.0=0x0213 +xgxs_tx_lane_map_65.0=0x2031 +xgxs_tx_lane_map_69.0=0x2031 +xgxs_tx_lane_map_73.0=0x2031 +xgxs_tx_lane_map_77.0=0x0213 +xgxs_tx_lane_map_81.0=0x2031 +xgxs_tx_lane_map_85.0=0x2031 +xgxs_tx_lane_map_89.0=0x2031 +xgxs_tx_lane_map_93.0=0x0213 +xgxs_tx_lane_map_97.0=0x2031 +xgxs_tx_lane_map_98.0=0x2031 +xgxs_tx_lane_map_99.0=0x2031 +xgxs_tx_lane_map_100.0=0x0213 +xgxs_tx_lane_map_101.0=0x0213 +xgxs_tx_lane_map_102.0=0x2031 +xgxs_tx_lane_map_103.0=0x3120 +xgxs_tx_lane_map_104.0=0x1302 + +# tuning parameters +serdes_preemphasis_lane0_1.0=0x81f7 +serdes_preemphasis_lane1_1.0=0x81f7 +serdes_preemphasis_lane2_1.0=0x81f7 +serdes_preemphasis_lane3_1.0=0x81f7 +serdes_pre_driver_current_lane0_5.0=0x7 +serdes_driver_current_lane0_5.0=0x7 +serdes_preemphasis_lane0_5.0=0xc2f0 +serdes_pre_driver_current_lane1_5.0=0x7 +serdes_driver_current_lane1_5.0=0x7 +serdes_preemphasis_lane1_5.0=0xc2f0 +serdes_pre_driver_current_lane2_5.0=0x7 +serdes_driver_current_lane2_5.0=0x7 +serdes_preemphasis_lane2_5.0=0xc2f0 +serdes_pre_driver_current_lane3_5.0=0x7 +serdes_driver_current_lane3_5.0=0x7 +serdes_preemphasis_lane3_5.0=0xc2f0 +serdes_pre_driver_current_lane0_9.0=0x7 +serdes_driver_current_lane0_9.0=0x7 +serdes_preemphasis_lane0_9.0=0xbb10 +serdes_pre_driver_current_lane1_9.0=0x7 +serdes_driver_current_lane1_9.0=0x7 +serdes_preemphasis_lane1_9.0=0xbb10 +serdes_pre_driver_current_lane2_9.0=0x7 +serdes_driver_current_lane2_9.0=0x7 +serdes_preemphasis_lane2_9.0=0xbb10 +serdes_pre_driver_current_lane3_9.0=0x7 +serdes_driver_current_lane3_9.0=0x7 +serdes_preemphasis_lane3_9.0=0xbb10 +serdes_pre_driver_current_lane0_13.0=0x7 +serdes_driver_current_lane0_13.0=0x7 +serdes_preemphasis_lane0_13.0=0xbb10 +serdes_pre_driver_current_lane1_13.0=0x7 +serdes_driver_current_lane1_13.0=0x7 +serdes_preemphasis_lane1_13.0=0xbb10 +serdes_pre_driver_current_lane2_13.0=0x7 +serdes_driver_current_lane2_13.0=0x7 +serdes_preemphasis_lane2_13.0=0xbb10 +serdes_pre_driver_current_lane3_13.0=0x7 +serdes_driver_current_lane3_13.0=0x7 +serdes_preemphasis_lane3_13.0=0xbb10 +serdes_pre_driver_current_lane0_17.0=0x6 +serdes_driver_current_lane0_17.0=0x6 +serdes_preemphasis_lane0_17.0=0xb720 +serdes_pre_driver_current_lane1_17.0=0x6 +serdes_driver_current_lane1_17.0=0x6 +serdes_preemphasis_lane1_17.0=0xb720 +serdes_pre_driver_current_lane2_17.0=0x6 +serdes_driver_current_lane2_17.0=0x6 +serdes_preemphasis_lane2_17.0=0xb720 +serdes_pre_driver_current_lane3_17.0=0x6 +serdes_driver_current_lane3_17.0=0x6 +serdes_preemphasis_lane3_17.0=0xb720 +serdes_pre_driver_current_lane0_21.0=0x7 +serdes_driver_current_lane0_21.0=0x7 +serdes_preemphasis_lane0_21.0=0xbb10 +serdes_pre_driver_current_lane1_21.0=0x7 +serdes_driver_current_lane1_21.0=0x7 +serdes_preemphasis_lane1_21.0=0xbb10 +serdes_pre_driver_current_lane2_21.0=0x7 +serdes_driver_current_lane2_21.0=0x7 +serdes_preemphasis_lane2_21.0=0xbb10 +serdes_pre_driver_current_lane3_21.0=0x7 +serdes_driver_current_lane3_21.0=0x7 +serdes_preemphasis_lane3_21.0=0xbb10 +serdes_pre_driver_current_lane0_25.0=0x5 +serdes_driver_current_lane0_25.0=0x5 +serdes_preemphasis_lane0_25.0=0xb720 +serdes_pre_driver_current_lane1_25.0=0x5 +serdes_driver_current_lane1_25.0=0x5 +serdes_preemphasis_lane1_25.0=0xb720 +serdes_pre_driver_current_lane2_25.0=0x5 +serdes_driver_current_lane2_25.0=0x5 +serdes_preemphasis_lane2_25.0=0xb720 +serdes_pre_driver_current_lane3_25.0=0x5 +serdes_driver_current_lane3_25.0=0x5 +serdes_preemphasis_lane3_25.0=0xb720 +serdes_pre_driver_current_lane0_29.0=0x5 +serdes_driver_current_lane0_29.0=0x5 +serdes_preemphasis_lane0_29.0=0xb720 +serdes_pre_driver_current_lane1_29.0=0x5 +serdes_driver_current_lane1_29.0=0x5 +serdes_preemphasis_lane1_29.0=0xb720 +serdes_pre_driver_current_lane2_29.0=0x5 +serdes_driver_current_lane2_29.0=0x5 +serdes_preemphasis_lane2_29.0=0xb720 +serdes_pre_driver_current_lane3_29.0=0x5 +serdes_driver_current_lane3_29.0=0x5 +serdes_preemphasis_lane3_29.0=0xb720 +serdes_pre_driver_current_lane0_33.0=0x4 +serdes_driver_current_lane0_33.0=0x4 +serdes_preemphasis_lane0_33.0=0xb720 +serdes_pre_driver_current_lane1_33.0=0x4 +serdes_driver_current_lane1_33.0=0x4 +serdes_preemphasis_lane1_33.0=0xb720 +serdes_pre_driver_current_lane2_33.0=0x4 +serdes_driver_current_lane2_33.0=0x4 +serdes_preemphasis_lane2_33.0=0xb720 +serdes_pre_driver_current_lane3_33.0=0x4 +serdes_driver_current_lane3_33.0=0x4 +serdes_preemphasis_lane3_33.0=0xb720 +serdes_pre_driver_current_lane0_37.0=0x5 +serdes_driver_current_lane0_37.0=0x5 +serdes_preemphasis_lane0_37.0=0xb720 +serdes_pre_driver_current_lane1_37.0=0x5 +serdes_driver_current_lane1_37.0=0x5 +serdes_preemphasis_lane1_37.0=0xb720 +serdes_pre_driver_current_lane2_37.0=0x5 +serdes_driver_current_lane2_37.0=0x5 +serdes_preemphasis_lane2_37.0=0xb720 +serdes_pre_driver_current_lane3_37.0=0x5 +serdes_driver_current_lane3_37.0=0x5 +serdes_preemphasis_lane3_37.0=0xb720 +serdes_pre_driver_current_lane0_41.0=0x3 +serdes_driver_current_lane0_41.0=0x3 +serdes_preemphasis_lane0_41.0=0xb330 +serdes_pre_driver_current_lane1_41.0=0x3 +serdes_driver_current_lane1_41.0=0x3 +serdes_preemphasis_lane1_41.0=0xb330 +serdes_pre_driver_current_lane2_41.0=0x3 +serdes_driver_current_lane2_41.0=0x3 +serdes_preemphasis_lane2_41.0=0xb330 +serdes_pre_driver_current_lane3_41.0=0x3 +serdes_driver_current_lane3_41.0=0x3 +serdes_preemphasis_lane3_41.0=0xb330 +serdes_pre_driver_current_lane0_45.0=0x4 +serdes_driver_current_lane0_45.0=0x4 +serdes_preemphasis_lane0_45.0=0xb720 +serdes_pre_driver_current_lane1_45.0=0x4 +serdes_driver_current_lane1_45.0=0x4 +serdes_preemphasis_lane1_45.0=0xb720 +serdes_pre_driver_current_lane2_45.0=0x4 +serdes_driver_current_lane2_45.0=0x4 +serdes_preemphasis_lane2_45.0=0xb720 +serdes_pre_driver_current_lane3_45.0=0x4 +serdes_driver_current_lane3_45.0=0x4 +serdes_preemphasis_lane3_45.0=0xb720 +serdes_pre_driver_current_lane0_49.0=0x3 +serdes_driver_current_lane0_49.0=0x3 +serdes_preemphasis_lane0_49.0=0xb330 +serdes_pre_driver_current_lane1_49.0=0x3 +serdes_driver_current_lane1_49.0=0x3 +serdes_preemphasis_lane1_49.0=0xb330 +serdes_pre_driver_current_lane2_49.0=0x3 +serdes_driver_current_lane2_49.0=0x3 +serdes_preemphasis_lane2_49.0=0xb330 +serdes_pre_driver_current_lane3_49.0=0x3 +serdes_driver_current_lane3_49.0=0x3 +serdes_preemphasis_lane3_49.0=0xb330 +serdes_pre_driver_current_lane0_53.0=0x4 +serdes_driver_current_lane0_53.0=0x4 +serdes_preemphasis_lane0_53.0=0xb720 +serdes_pre_driver_current_lane1_53.0=0x4 +serdes_driver_current_lane1_53.0=0x4 +serdes_preemphasis_lane1_53.0=0xb720 +serdes_pre_driver_current_lane2_53.0=0x4 +serdes_driver_current_lane2_53.0=0x4 +serdes_preemphasis_lane2_53.0=0xb720 +serdes_pre_driver_current_lane3_53.0=0x4 +serdes_driver_current_lane3_53.0=0x4 +serdes_preemphasis_lane3_53.0=0xb720 +serdes_pre_driver_current_lane0_57.0=0x3 +serdes_driver_current_lane0_57.0=0x3 +serdes_preemphasis_lane0_57.0=0xb330 +serdes_pre_driver_current_lane1_57.0=0x3 +serdes_driver_current_lane1_57.0=0x3 +serdes_preemphasis_lane1_57.0=0xb330 +serdes_pre_driver_current_lane2_57.0=0x3 +serdes_driver_current_lane2_57.0=0x3 +serdes_preemphasis_lane2_57.0=0xb330 +serdes_pre_driver_current_lane3_57.0=0x3 +serdes_driver_current_lane3_57.0=0x3 +serdes_preemphasis_lane3_57.0=0xb330 +serdes_pre_driver_current_lane0_61.0=0x4 +serdes_driver_current_lane0_61.0=0x4 +serdes_preemphasis_lane0_61.0=0xb720 +serdes_pre_driver_current_lane1_61.0=0x4 +serdes_driver_current_lane1_61.0=0x4 +serdes_preemphasis_lane1_61.0=0xb720 +serdes_pre_driver_current_lane2_61.0=0x4 +serdes_driver_current_lane2_61.0=0x4 +serdes_preemphasis_lane2_61.0=0xb720 +serdes_pre_driver_current_lane3_61.0=0x4 +serdes_driver_current_lane3_61.0=0x4 +serdes_preemphasis_lane3_61.0=0xb720 +serdes_pre_driver_current_lane0_65.0=0x4 +serdes_driver_current_lane0_65.0=0x4 +serdes_preemphasis_lane0_65.0=0xb720 +serdes_pre_driver_current_lane1_65.0=0x4 +serdes_driver_current_lane1_65.0=0x4 +serdes_preemphasis_lane1_65.0=0xb720 +serdes_pre_driver_current_lane2_65.0=0x4 +serdes_driver_current_lane2_65.0=0x4 +serdes_preemphasis_lane2_65.0=0xb720 +serdes_pre_driver_current_lane3_65.0=0x4 +serdes_driver_current_lane3_65.0=0x4 +serdes_preemphasis_lane3_65.0=0xb720 +serdes_pre_driver_current_lane0_69.0=0x4 +serdes_driver_current_lane0_69.0=0x4 +serdes_preemphasis_lane0_69.0=0xb720 +serdes_pre_driver_current_lane1_69.0=0x4 +serdes_driver_current_lane1_69.0=0x4 +serdes_preemphasis_lane1_69.0=0xb720 +serdes_pre_driver_current_lane2_69.0=0x4 +serdes_driver_current_lane2_69.0=0x4 +serdes_preemphasis_lane2_69.0=0xb720 +serdes_pre_driver_current_lane3_69.0=0x4 +serdes_driver_current_lane3_69.0=0x4 +serdes_preemphasis_lane3_69.0=0xb720 +serdes_pre_driver_current_lane0_73.0=0x4 +serdes_driver_current_lane0_73.0=0x4 +serdes_preemphasis_lane0_73.0=0xb720 +serdes_pre_driver_current_lane1_73.0=0x4 +serdes_driver_current_lane1_73.0=0x4 +serdes_preemphasis_lane1_73.0=0xb720 +serdes_pre_driver_current_lane2_73.0=0x4 +serdes_driver_current_lane2_73.0=0x4 +serdes_preemphasis_lane2_73.0=0xb720 +serdes_pre_driver_current_lane3_73.0=0x4 +serdes_driver_current_lane3_73.0=0x4 +serdes_preemphasis_lane3_73.0=0xb720 +serdes_pre_driver_current_lane0_77.0=0x5 +serdes_driver_current_lane0_77.0=0x5 +serdes_preemphasis_lane0_77.0=0xb720 +serdes_pre_driver_current_lane1_77.0=0x5 +serdes_driver_current_lane1_77.0=0x5 +serdes_preemphasis_lane1_77.0=0xb720 +serdes_pre_driver_current_lane2_77.0=0x5 +serdes_driver_current_lane2_77.0=0x5 +serdes_preemphasis_lane2_77.0=0xb720 +serdes_pre_driver_current_lane3_77.0=0x5 +serdes_driver_current_lane3_77.0=0x5 +serdes_preemphasis_lane3_77.0=0xb720 +serdes_pre_driver_current_lane0_81.0=0x5 +serdes_driver_current_lane0_81.0=0x5 +serdes_preemphasis_lane0_81.0=0xb720 +serdes_pre_driver_current_lane1_81.0=0x5 +serdes_driver_current_lane1_81.0=0x5 +serdes_preemphasis_lane1_81.0=0xb720 +serdes_pre_driver_current_lane2_81.0=0x5 +serdes_driver_current_lane2_81.0=0x5 +serdes_preemphasis_lane2_81.0=0xb720 +serdes_pre_driver_current_lane3_81.0=0x5 +serdes_driver_current_lane3_81.0=0x5 +serdes_preemphasis_lane3_81.0=0xb720 +serdes_pre_driver_current_lane0_85.0=0x5 +serdes_driver_current_lane0_85.0=0x5 +serdes_preemphasis_lane0_85.0=0xb720 +serdes_pre_driver_current_lane1_85.0=0x5 +serdes_driver_current_lane1_85.0=0x5 +serdes_preemphasis_lane1_85.0=0xb720 +serdes_pre_driver_current_lane2_85.0=0x5 +serdes_driver_current_lane2_85.0=0x5 +serdes_preemphasis_lane2_85.0=0xb720 +serdes_pre_driver_current_lane3_85.0=0x5 +serdes_driver_current_lane3_85.0=0x5 +serdes_preemphasis_lane3_85.0=0xb720 +serdes_pre_driver_current_lane0_89.0=0x6 +serdes_driver_current_lane0_89.0=0x6 +serdes_preemphasis_lane0_89.0=0xb720 +serdes_pre_driver_current_lane1_89.0=0x6 +serdes_driver_current_lane1_89.0=0x6 +serdes_preemphasis_lane1_89.0=0xb720 +serdes_pre_driver_current_lane2_89.0=0x6 +serdes_driver_current_lane2_89.0=0x6 +serdes_preemphasis_lane2_89.0=0xb720 +serdes_pre_driver_current_lane3_89.0=0x6 +serdes_driver_current_lane3_89.0=0x6 +serdes_preemphasis_lane3_89.0=0xb720 +serdes_pre_driver_current_lane0_93.0=0x7 +serdes_driver_current_lane0_93.0=0x7 +serdes_preemphasis_lane0_93.0=0xbb10 +serdes_pre_driver_current_lane1_93.0=0x7 +serdes_driver_current_lane1_93.0=0x7 +serdes_preemphasis_lane1_93.0=0xbb10 +serdes_pre_driver_current_lane2_93.0=0x7 +serdes_driver_current_lane2_93.0=0x7 +serdes_preemphasis_lane2_93.0=0xbb10 +serdes_pre_driver_current_lane3_93.0=0x7 +serdes_driver_current_lane3_93.0=0x7 +serdes_preemphasis_lane3_93.0=0xbb10 +serdes_pre_driver_current_lane0_97.0=0x5 +serdes_driver_current_lane0_97.0=0x5 +serdes_preemphasis_lane0_97.0=0xb720 +serdes_pre_driver_current_lane1_97.0=0x5 +serdes_driver_current_lane1_97.0=0x5 +serdes_preemphasis_lane1_97.0=0xb720 +serdes_pre_driver_current_lane2_97.0=0x5 +serdes_driver_current_lane2_97.0=0x5 +serdes_preemphasis_lane2_97.0=0xb720 +serdes_pre_driver_current_lane3_97.0=0x5 +serdes_driver_current_lane3_97.0=0x5 +serdes_preemphasis_lane3_97.0=0xb720 +serdes_pre_driver_current_lane0_98.0=0x6 +serdes_driver_current_lane0_98.0=0x6 +serdes_preemphasis_lane0_98.0=0xb720 +serdes_pre_driver_current_lane1_98.0=0x6 +serdes_driver_current_lane1_98.0=0x6 +serdes_preemphasis_lane1_98.0=0xb720 +serdes_pre_driver_current_lane2_98.0=0x6 +serdes_driver_current_lane2_98.0=0x6 +serdes_preemphasis_lane2_98.0=0xb720 +serdes_pre_driver_current_lane3_98.0=0x6 +serdes_driver_current_lane3_98.0=0x6 +serdes_preemphasis_lane3_98.0=0xb720 +serdes_pre_driver_current_lane0_99.0=0x5 +serdes_driver_current_lane0_99.0=0x5 +serdes_preemphasis_lane0_99.0=0xb720 +serdes_pre_driver_current_lane1_99.0=0x5 +serdes_driver_current_lane1_99.0=0x5 +serdes_preemphasis_lane1_99.0=0xb720 +serdes_pre_driver_current_lane2_99.0=0x5 +serdes_driver_current_lane2_99.0=0x5 +serdes_preemphasis_lane2_99.0=0xb720 +serdes_pre_driver_current_lane3_99.0=0x5 +serdes_driver_current_lane3_99.0=0x5 +serdes_preemphasis_lane3_99.0=0xb720 +serdes_pre_driver_current_lane0_100.0=0x7 +serdes_driver_current_lane0_100.0=0x7 +serdes_preemphasis_lane0_100.0=0xbb10 +serdes_pre_driver_current_lane1_100.0=0x7 +serdes_driver_current_lane1_100.0=0x7 +serdes_preemphasis_lane1_100.0=0xbb10 +serdes_pre_driver_current_lane2_100.0=0x7 +serdes_driver_current_lane2_100.0=0x7 +serdes_preemphasis_lane2_100.0=0xbb10 +serdes_pre_driver_current_lane3_100.0=0x7 +serdes_driver_current_lane3_100.0=0x7 +serdes_preemphasis_lane3_100.0=0xbb10 +serdes_pre_driver_current_lane0_101.0=0x7 +serdes_driver_current_lane0_101.0=0x7 +serdes_preemphasis_lane0_101.0=0xbb10 +serdes_pre_driver_current_lane1_101.0=0x7 +serdes_driver_current_lane1_101.0=0x7 +serdes_preemphasis_lane1_101.0=0xbb10 +serdes_pre_driver_current_lane2_101.0=0x7 +serdes_driver_current_lane2_101.0=0x7 +serdes_preemphasis_lane2_101.0=0xbb10 +serdes_pre_driver_current_lane3_101.0=0x7 +serdes_driver_current_lane3_101.0=0x7 +serdes_preemphasis_lane3_101.0=0xbb10 +serdes_pre_driver_current_lane0_102.0=0x7 +serdes_driver_current_lane0_102.0=0x7 +serdes_preemphasis_lane0_102.0=0xbb10 +serdes_pre_driver_current_lane1_102.0=0x7 +serdes_driver_current_lane1_102.0=0x7 +serdes_preemphasis_lane1_102.0=0xbb10 +serdes_pre_driver_current_lane2_102.0=0x7 +serdes_driver_current_lane2_102.0=0x7 +serdes_preemphasis_lane2_102.0=0xbb10 +serdes_pre_driver_current_lane3_102.0=0x7 +serdes_driver_current_lane3_102.0=0x7 +serdes_preemphasis_lane3_102.0=0xbb10 +serdes_preemphasis_lane0_103.0=0x81f4 +serdes_preemphasis_lane1_103.0=0x81f4 +serdes_preemphasis_lane2_103.0=0x81f4 +serdes_preemphasis_lane3_103.0=0x81f4 +serdes_preemphasis_lane0_104.0=0x81f5 +serdes_preemphasis_lane1_104.0=0x81f5 +serdes_preemphasis_lane2_104.0=0x81f5 +serdes_preemphasis_lane3_104.0=0x81f5 diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/hwsku-init b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/hwsku-init new file mode 100644 index 000000000000..49639a743436 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/hwsku-init @@ -0,0 +1 @@ +echo 0 > /sys/devices/pci0000:00/0000:00:02.2/0000:02:00.0/mux From 81e5178788844de6a400b685618a5c2e670fabf9 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Tue, 25 Sep 2018 16:29:34 +0000 Subject: [PATCH 143/219] [build]: fix file permission to have a clean build debian/rules should be 755 and will be modified to 755 if not, which can cause the image to be marked as dirty Signed-off-by: Guohan Lu --- platform/broadcom/sonic-platform-modules-cel/debian/rules | 0 platform/broadcom/sonic-platform-modules-ingrasys/debian/rules | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 platform/broadcom/sonic-platform-modules-cel/debian/rules mode change 100644 => 100755 platform/broadcom/sonic-platform-modules-ingrasys/debian/rules diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/rules b/platform/broadcom/sonic-platform-modules-cel/debian/rules old mode 100644 new mode 100755 diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/debian/rules b/platform/broadcom/sonic-platform-modules-ingrasys/debian/rules old mode 100644 new mode 100755 From f9bca94d72cff9107c7e62120e7008eba2304e0b Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Tue, 21 Aug 2018 00:58:16 -0700 Subject: [PATCH 144/219] [arista]: Fix mount point discovery in boot0 for overlayfs (#1959) On overlay filesystem the name of the mountpoint will also match in the mount command for overlayfs as upperdir= To prevent detecting the wrong partition we now look for space before. This ensure that we match mountpoint and not devices in df and mount outputs. --- files/Aboot/boot0.j2 | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/files/Aboot/boot0.j2 b/files/Aboot/boot0.j2 index 435781a77485..7eebfeeee9d2 100644 --- a/files/Aboot/boot0.j2 +++ b/files/Aboot/boot0.j2 @@ -63,6 +63,7 @@ cmdline_base="$target_path/kernel-params-base" cmdline_image="$image_path/kernel-cmdline" bootconfigvars="KERNEL INITRD CONSOLESPEED PASSWORD NETDEV NETAUTO NETIP NETMASK NETGW NETDOMAIN NETDNS NETHW memtest" +flash_re=" /mnt/flash| /host" parse_environment_config() { for n in ${bootconfigvars}; do @@ -148,7 +149,8 @@ platform_specific() { # set varlog size to 100MB local varlog_size=100 - local flash_size=$(($(df | grep -E '/mnt/flash|/host' | tr -s ' ' | cut -f2 -d' ') / 1000)) + # detect the size of the flash partition from name in Aboot/EOS/SONiC + local flash_size=$(($(df | grep -E "$flash_re" | tr -s ' ' | cut -f2 -d' ') / 1000)) if [ "$platform" = "raven" ]; then aboot_machine=arista_7050_qx32 @@ -223,8 +225,8 @@ write_boot_configs() { # setting root partition if not overridden by kernel-params if ! grep -q "root=" /tmp/append; then - rootdev="$(mount | grep -E '/mnt/flash|/host' | cut -f1 -d' ')" - rootfstype="$(mount | grep -E '/mnt/flash|/host' | cut -f5 -d' ')" + rootdev="$(mount | grep -E "$flash_re" | cut -f1 -d' ')" + rootfstype="$(mount | grep -E "$flash_re" | cut -f5 -d' ')" rootuuid="$(get_uuid_for $rootdev)" if [ -z "$rootuuid" ] || [ "$rootfstype" = "vfat" ] ; then echo "root=$rootdev" >> /tmp/append From 2eee201e277f9e7a4dbf57529d6a6757aa0a75e2 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Wed, 26 Sep 2018 23:07:46 -0700 Subject: [PATCH 145/219] [7050] Rename HWSKU Arista-7050-Q31S4 to Arista-7050QX-32S-S4Q31 (#2089) Signed-off-by: Ying Xie --- .../buffers.json.j2 | 0 .../{Arista-7050-Q31S4 => Arista-7050QX-32S-S4Q31}/hwsku-init | 0 .../port_config.ini | 0 .../{Arista-7050-Q31S4 => Arista-7050QX-32S-S4Q31}/qos.json | 0 .../{Arista-7050-Q31S4 => Arista-7050QX-32S-S4Q31}/sai.profile | 0 .../td2-a7050-q31s4-31x40G-4x10G.config.bcm | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename device/arista/x86_64-arista_7050_qx32s/{Arista-7050-Q31S4 => Arista-7050QX-32S-S4Q31}/buffers.json.j2 (100%) rename device/arista/x86_64-arista_7050_qx32s/{Arista-7050-Q31S4 => Arista-7050QX-32S-S4Q31}/hwsku-init (100%) rename device/arista/x86_64-arista_7050_qx32s/{Arista-7050-Q31S4 => Arista-7050QX-32S-S4Q31}/port_config.ini (100%) rename device/arista/x86_64-arista_7050_qx32s/{Arista-7050-Q31S4 => Arista-7050QX-32S-S4Q31}/qos.json (100%) rename device/arista/x86_64-arista_7050_qx32s/{Arista-7050-Q31S4 => Arista-7050QX-32S-S4Q31}/sai.profile (100%) rename device/arista/x86_64-arista_7050_qx32s/{Arista-7050-Q31S4 => Arista-7050QX-32S-S4Q31}/td2-a7050-q31s4-31x40G-4x10G.config.bcm (100%) diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/buffers.json.j2 b/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/buffers.json.j2 similarity index 100% rename from device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/buffers.json.j2 rename to device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/buffers.json.j2 diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/hwsku-init b/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/hwsku-init similarity index 100% rename from device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/hwsku-init rename to device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/hwsku-init diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/port_config.ini b/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/port_config.ini similarity index 100% rename from device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/port_config.ini rename to device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/port_config.ini diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/qos.json b/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/qos.json similarity index 100% rename from device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/qos.json rename to device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/qos.json diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/sai.profile b/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/sai.profile similarity index 100% rename from device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/sai.profile rename to device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/sai.profile diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/td2-a7050-q31s4-31x40G-4x10G.config.bcm b/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/td2-a7050-q31s4-31x40G-4x10G.config.bcm similarity index 100% rename from device/arista/x86_64-arista_7050_qx32s/Arista-7050-Q31S4/td2-a7050-q31s4-31x40G-4x10G.config.bcm rename to device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/td2-a7050-q31s4-31x40G-4x10G.config.bcm From de0add87d05e92a84c564a17daaf16e3a9d81cc9 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Fri, 28 Sep 2018 01:59:24 -0700 Subject: [PATCH 146/219] Update submodule: sonic-snmpagent for Fix PFC counters TX/RX (#2095) Signed-off-by: Qi Luo --- src/sonic-snmpagent | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-snmpagent b/src/sonic-snmpagent index bf1b165458e4..ab91a0593fa8 160000 --- a/src/sonic-snmpagent +++ b/src/sonic-snmpagent @@ -1 +1 @@ -Subproject commit bf1b165458e4e19286d245a3398921057f4df21c +Subproject commit ab91a0593fa83677081fdff7d322f469f7471906 From 19147a4dfcdcd9dfeefd6d8a1dddf3b7775a25c0 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Fri, 28 Sep 2018 14:16:57 -0700 Subject: [PATCH 147/219] [7050] device specific hwsku-init file needs execution privilege (#2100) Signed-off-by: Ying Xie --- .../arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/hwsku-init | 0 .../x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/hwsku-init | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/hwsku-init mode change 100644 => 100755 device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/hwsku-init diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/hwsku-init b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/hwsku-init old mode 100644 new mode 100755 diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/hwsku-init b/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/hwsku-init old mode 100644 new mode 100755 From 974b066872d56e8cf4d16c8a004b08e06682116b Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 29 Sep 2018 05:43:38 +0000 Subject: [PATCH 148/219] Added platform module start/stop service for Dell S6100/Z9100 platforms - Introduced systemd .service files to start and stop platform drivers. - Moved depmod in *.postinst files. So, during first-time boot depmod is triggered post package installation and drivers will be loaded without any issues. Signed-off-by: Guohan Lu --- .../debian/platform-modules-s6100.install | 2 +- .../debian/platform-modules-s6100.postinst | 4 ++++ .../debian/platform-modules-z9100.install | 1 + .../debian/platform-modules-z9100.postinst | 5 +++++ .../s6100/systemd/platform-modules-s6100.service | 14 ++++++++++++++ .../z9100/systemd/platform-modules-z9100.service | 13 +++++++++++++ 6 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 platform/broadcom/sonic-platform-modules-dell/s6100/systemd/platform-modules-s6100.service create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9100/systemd/platform-modules-z9100.service diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install index f456acb9d812..7d56aee6e2f7 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install @@ -6,4 +6,4 @@ common/fstrim.timer etc/systemd/system common/fstrim.service etc/systemd/system s6100/scripts/platform_sensors.py usr/local/bin s6100/scripts/sensors usr/bin - +s6100/systemd/platform-modules-s6100.service etc/systemd/system diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.postinst b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.postinst index aeabe1abd27c..dc7163b6c4c1 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.postinst +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.postinst @@ -4,4 +4,8 @@ systemctl enable fstrim.timer systemctl start fstrim.timer +#Enable Dell-S6100-platform-service +depmod -a +systemctl enable platform-modules-s6100.service +systemctl start platform-modules-s6100.service #DEBHELPER# diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install index 66d24e98e89c..410dcf16ea1b 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install @@ -6,3 +6,4 @@ common/fstrim.service etc/systemd/system z9100/scripts/platform_sensors.py usr/local/bin z9100/scripts/sensors usr/bin z9100/cfg/z9100-modules.conf etc/modules-load.d +z9100/systemd/platform-modules-z9100.service etc/systemd/system diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.postinst b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.postinst index b11ae1f274c4..45cce66785dd 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.postinst +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.postinst @@ -4,4 +4,9 @@ systemctl enable fstrim.timer systemctl start fstrim.timer +# Enable Dell-Z9100-platform-service +depmod -a +systemctl enable platform-modules-z9100.service +systemctl start platform-modules-z9100.service + #DEBHELPER# diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/systemd/platform-modules-s6100.service b/platform/broadcom/sonic-platform-modules-dell/s6100/systemd/platform-modules-s6100.service new file mode 100644 index 000000000000..9b5805d5cbbb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/systemd/platform-modules-s6100.service @@ -0,0 +1,14 @@ +[Unit] +Description=Dell S6100 Platform modules +Before=pmon.service +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStartPre=/usr/local/bin/iom_power_on.sh +ExecStart=/usr/local/bin/s6100_platform.sh init +ExecStop=/usr/local/bin/s6100_platform.sh deinit +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/systemd/platform-modules-z9100.service b/platform/broadcom/sonic-platform-modules-dell/z9100/systemd/platform-modules-z9100.service new file mode 100644 index 000000000000..00fbfa6803ef --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/systemd/platform-modules-z9100.service @@ -0,0 +1,13 @@ +[Unit] +Description=Dell Z9100 Platform modules +Before=pmon.service +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/z9100_platform.sh init +ExecStop=/usr/local/bin/z9100_platform.sh deinit +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target From 6009d0c4f12a0fc03754848803f75ab92fdd113b Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Mon, 1 Oct 2018 07:23:04 +0000 Subject: [PATCH 149/219] [submodule]: update sonic-utilities 69c5b03 2018-10-01 | require root privilege for all pfcwd configuration commands (#330) Signed-off-by: Guohan Lu --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index d5f2877fd5b9..69c5b034fc03 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit d5f2877fd5b98f62c0dad0d972aeb67041a6ad26 +Subproject commit 69c5b034fc03e7888bd983de27654d093a1d0260 From aef6a31d937ee106789511f308b83270dea772fa Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Mon, 1 Oct 2018 20:47:49 +0000 Subject: [PATCH 150/219] [submodule]: update linux kernel module * 652f259 2018-10-01 | [Kernel] fix kernel build errors (#65) (HEAD, origin/201803) [Ying Xie] * 55c7a19 2018-10-01 | uart: fix race between uart_put_char() and uart_shutdown() (#64) [lguohan] Signed-off-by: Guohan Lu --- src/sonic-linux-kernel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel index ed04b3690388..652f2592b90c 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit ed04b36903885ec065274174aa775e47695db2cb +Subproject commit 652f2592b90c2ae10064b9131b5217fbdde63526 From ad4e9c3fb23d4ddb2986eceb818b171c8a16df5d Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Tue, 2 Oct 2018 01:37:15 +0000 Subject: [PATCH 151/219] [submodules]: update sonic-utilities * 1e6470a 2018-10-01 | Root priviliege for ecn configuration set commands (#332) (HEAD, origin/201803) [Wenda Ni] Signed-off-by: Guohan Lu --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 69c5b034fc03..1e6470ac4013 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 69c5b034fc03e7888bd983de27654d093a1d0260 +Subproject commit 1e6470ac4013ea057f36cfaa55734d26bfaf7e33 From 3f58ca1487ba494d03072258d5169f0da84955cd Mon Sep 17 00:00:00 2001 From: Wenda Ni Date: Tue, 2 Oct 2018 05:30:48 -0700 Subject: [PATCH 152/219] [qos]: Resolve ecn runtime config save conflict with default config (#2109) * Avoid ecn default config conflict with saving runtime ecn on/off on queues Signed-off-by: Wenda * S6000 qos & buffer config change: 1) DSCP 46 to 5 2) ecn config 3) ecn on by default 4) DWRR equal weight 5) ingress lossless alpha 1/8 Signed-off-by: Wenda --- .../Arista-7050-QX32/qos.json | 6 ++- .../Arista-7050-QX-32S/qos.json | 6 ++- .../Force10-S6000/buffers.json.j2 | 8 +++- .../Force10-S6000/qos.json | 46 +++++++++---------- .../Force10-S6100/qos.json | 6 ++- 5 files changed, 45 insertions(+), 27 deletions(-) diff --git a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/qos.json b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/qos.json index 88d872d5dc70..0eb02957299f 100644 --- a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/qos.json +++ b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/qos.json @@ -127,7 +127,11 @@ } }, "QUEUE": { - "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3-4" : { + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3" : { + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|4" : { "scheduler" : "[SCHEDULER|scheduler.0]", "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/qos.json b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/qos.json index 88d872d5dc70..0eb02957299f 100644 --- a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/qos.json +++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/qos.json @@ -127,7 +127,11 @@ } }, "QUEUE": { - "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3-4" : { + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3" : { + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|4" : { "scheduler" : "[SCHEDULER|scheduler.0]", "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers.json.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers.json.j2 index 551f73ca0477..782dc528f71e 100644 --- a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers.json.j2 +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers.json.j2 @@ -90,7 +90,7 @@ "xon":"18432", "xoff":"40560", "size":"41808", - "dynamic_th":"-4", + "dynamic_th":"-3", "xon_offset":"2496" }, "ingress_lossy_profile": { @@ -115,6 +115,9 @@ }, "{{ port_names }}|0-1": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + }, + "{{ port_names }}|5": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" } }, "BUFFER_QUEUE": { @@ -123,6 +126,9 @@ }, "{{ port_names }}|0-1": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + }, + "{{ port_names }}|5": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" } } } diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/qos.json b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/qos.json index 698811c610ff..0eb02957299f 100644 --- a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/qos.json +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/qos.json @@ -4,7 +4,8 @@ "0": "0", "1": "1", "3": "3", - "4": "4" + "4": "4", + "5": "5" } }, "MAP_PFC_PRIORITY_TO_QUEUE": { @@ -12,7 +13,8 @@ "0": "0", "1": "1", "3": "3", - "4": "4" + "4": "4", + "5": "5" } }, "TC_TO_QUEUE_MAP": { @@ -20,7 +22,8 @@ "0": "0", "1": "1", "3": "3", - "4": "4" + "4": "4", + "5": "5" } }, "DSCP_TO_TC_MAP": { @@ -71,7 +74,7 @@ "43":"0", "44":"0", "45":"0", - "46":"0", + "46":"5", "47":"0", "48":"0", "49":"0", @@ -93,14 +96,6 @@ }, "SCHEDULER": { "scheduler.0" : { - "type":"DWRR", - "weight": "25" - }, - "scheduler.1" : { - "type":"DWRR", - "weight": "30" - }, - "scheduler.2" : { "type":"DWRR", "weight": "20" } @@ -120,29 +115,34 @@ "wred_yellow_enable":"true", "wred_red_enable":"true", "ecn":"ecn_all", - "red_max_threshold":"312000", - "red_min_threshold":"104000", - "yellow_max_threshold":"312000", - "yellow_min_threshold":"104000", - "green_max_threshold":"312000", - "green_min_threshold":"104000" + "red_max_threshold":"2097152", + "red_min_threshold":"1048576", + "yellow_max_threshold":"2097152", + "yellow_min_threshold":"1048576", + "green_max_threshold":"2097152", + "green_min_threshold":"1048576", + "green_drop_probability":"5", + "yellow_drop_probability":"5", + "red_drop_probability":"5" } }, "QUEUE": { - "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3-4" : { - "scheduler" : "[SCHEDULER|scheduler.0]" - }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3" : { + "scheduler" : "[SCHEDULER|scheduler.0]", "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|4" : { + "scheduler" : "[SCHEDULER|scheduler.0]", "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0" : { - "scheduler" : "[SCHEDULER|scheduler.1]" + "scheduler" : "[SCHEDULER|scheduler.0]" }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|1" : { - "scheduler" : "[SCHEDULER|scheduler.2]" + "scheduler" : "[SCHEDULER|scheduler.0]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|5" : { + "scheduler" : "[SCHEDULER|scheduler.0]" } } } diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json index cf6992853f2b..aacc94e559ff 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json +++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json @@ -136,7 +136,11 @@ } }, "QUEUE": { - "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63|3-4" : { + "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63|3" : { + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63|4" : { "scheduler" : "[SCHEDULER|scheduler.0]", "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, From f333342dd628534ea77d72629988329d7161195b Mon Sep 17 00:00:00 2001 From: Taoyu Li Date: Fri, 28 Sep 2018 22:56:40 -0700 Subject: [PATCH 153/219] [minigraph parser] add basic support for MGMT_PORT (#2103) * [minigraph parser] add basic support for MGMT_PORT * Change method to determine local interface name --- src/sonic-config-engine/minigraph.py | 15 ++++++++++++++- src/sonic-config-engine/tests/test_cfggen.py | 5 +++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 2b6b3d9d57e7..d13c92f847b3 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -430,7 +430,20 @@ def parse_xml(filename, platform=None, port_config_file=None): if mgmt_routes: # TODO: differentiate v4 and v6 mgmt_intf.itervalues().next()['forced_mgmt_routes'] = mgmt_routes - results['MGMT_INTERFACE'] = mgmt_intf + results['MGMT_PORT'] = {} + results['MGMT_INTERFACE'] = {} + mgmt_intf_count = 0 + mgmt_alias_reverse_mapping = {} + for key in mgmt_intf: + alias = key[0] + if mgmt_alias_reverse_mapping.has_key(alias): + name = mgmt_alias_reverse_mapping[alias] + else: + name = 'eth' + str(mgmt_intf_count) + mgmt_intf_count += 1 + mgmt_alias_reverse_mapping[alias] = name + results['MGMT_PORT'][name] = {'alias': alias, 'admin_status': 'up'} + results['MGMT_INTERFACE'][(name, key[1])] = mgmt_intf[key] results['LOOPBACK_INTERFACE'] = lo_intfs phyport_intfs = {} diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 37b66a27b4c4..3d62bd77e4dd 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -92,6 +92,11 @@ def test_minigraph_everflow(self): output = self.run_script(argument) self.assertEqual(output.strip(), "{'everflow0': {'src_ip': '10.1.0.32', 'dst_ip': '2.2.2.2'}}") + def test_minigraph_mgmt_ports(self): + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v MGMT_PORT' + output = self.run_script(argument) + self.assertEqual(output.strip(), "{'eth0': {'alias': 'Management0', 'admin_status': 'up'}}") + def test_minigraph_interfaces(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v \'INTERFACE.keys()\'' output = self.run_script(argument) From f586cfa09cfd2cd6f8898b6dbaaf9bae4059c72d Mon Sep 17 00:00:00 2001 From: zzhiyuan Date: Thu, 4 Oct 2018 14:31:12 -0700 Subject: [PATCH 154/219] [devices]: Fix configurations for 7050QX-32S-S4Q31 (#2119) - Correct lane map in broadcom configuration - Add writes to txdisable bits for SFPs in hwsku-init - Add correct hwsku-init implementation for 201803 branch --- .../Arista-7050QX-32S-S4Q31/hwsku-init | 53 ++++++++++++++++++- .../td2-a7050-q31s4-31x40G-4x10G.config.bcm | 4 +- 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/hwsku-init b/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/hwsku-init index c005241e4b6a..e9bfe2e908ab 100755 --- a/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/hwsku-init +++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/hwsku-init @@ -1 +1,52 @@ -echo 1 > /sys/devices/pci0000:00/0000:00:02.2/0000:02:00.0/mux +#!/usr/bin/python +from __future__ import print_function + +import mmap +import os +import sys +from struct import pack, unpack + +class MmapResource( object ): + """Resource implementation for a directly-mapped memory region.""" + def __init__( self, path ): + try: + fd = os.open( path, os.O_RDWR ) + except EnvironmentError: + print( "FAIL can not open scd memory-map resource file" ) + print( "FAIL are you running on the proper platform?" ) + sys.exit( 1 ) + try: + size = os.fstat( fd ).st_size + except EnvironmentError: + print( "FAIL can not fstat scd memory-map resource file" ) + print( "FAIL are you running on the proper platform?" ) + sys.exit( 1 ) + try: + self.mmap_ = mmap.mmap( fd, size, mmap.MAP_SHARED, + mmap.PROT_READ | mmap.PROT_WRITE ) + except EnvironmentError: + print( "FAIL can not map scd memory-map file" ) + print( "FAIL are you running on the proper platform?" ) + sys.exit( 1 ) + finally: + try: + # Note that closing the file descriptor has no effect on the memory map + os.close( fd ) + except EnvironmentError: + print( "FAIL failed to close scd memory-map file" ) + sys.exit( 1 ) + def read32( self, addr ): + return unpack( ' Date: Thu, 4 Oct 2018 16:43:44 -0700 Subject: [PATCH 155/219] [devices]: a7060, a7260 qos & buffer config change: 1) DSCP 46 to 5; 2) ecn config; 3) ecn (#2121) on by default; 4) DWRR equal weight; 5) ingress lossless alpha 1/8 Signed-off-by: Wenda Ni --- .../pg_profile_lookup.ini | 30 +++++------ .../Arista-7060CX-32S-C32/qos.json | 54 ++++++++----------- .../pg_profile_lookup.ini | 30 +++++------ .../Arista-7060CX-32S-D48C8/qos.json | 54 ++++++++----------- .../pg_profile_lookup.ini | 30 +++++------ .../Arista-7060CX-32S-Q32/qos.json | 54 ++++++++----------- .../Arista-7260CX3-D108C8/qos.json | 54 ++++++++----------- 7 files changed, 133 insertions(+), 173 deletions(-) diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/pg_profile_lookup.ini b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/pg_profile_lookup.ini index 3b2a417cebcd..aedda37a8878 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/pg_profile_lookup.ini +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/pg_profile_lookup.ini @@ -1,17 +1,17 @@ # PG lossless profiles. # speed cable size xon xoff threshold xon_offset - 10000 5m 1248 2288 35776 -4 2288 - 25000 5m 1248 2288 53248 -4 2288 - 40000 5m 1248 2288 66560 -4 2288 - 50000 5m 1248 2288 90272 -4 2288 - 100000 5m 1248 2288 165568 -4 2288 - 10000 40m 1248 2288 37024 -4 2288 - 25000 40m 1248 2288 53248 -4 2288 - 40000 40m 1248 2288 71552 -4 2288 - 50000 40m 1248 2288 96096 -4 2288 - 100000 40m 1248 2288 177632 -4 2288 - 10000 300m 1248 2288 46176 -4 2288 - 25000 300m 1248 2288 79040 -4 2288 - 40000 300m 1248 2288 108160 -4 2288 - 50000 300m 1248 2288 141856 -4 2288 - 100000 300m 1248 2288 268736 -4 2288 + 10000 5m 1248 2288 35776 -3 2288 + 25000 5m 1248 2288 53248 -3 2288 + 40000 5m 1248 2288 66560 -3 2288 + 50000 5m 1248 2288 90272 -3 2288 + 100000 5m 1248 2288 165568 -3 2288 + 10000 40m 1248 2288 37024 -3 2288 + 25000 40m 1248 2288 53248 -3 2288 + 40000 40m 1248 2288 71552 -3 2288 + 50000 40m 1248 2288 96096 -3 2288 + 100000 40m 1248 2288 177632 -3 2288 + 10000 300m 1248 2288 46176 -3 2288 + 25000 300m 1248 2288 79040 -3 2288 + 40000 300m 1248 2288 108160 -3 2288 + 50000 300m 1248 2288 141856 -3 2288 + 100000 300m 1248 2288 268736 -3 2288 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/qos.json b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/qos.json index b724b48c2c23..deb9f40fc0f4 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/qos.json +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/qos.json @@ -83,7 +83,7 @@ "43":"0", "44":"0", "45":"0", - "46":"0", + "46":"5", "47":"0", "48":"0", "49":"0", @@ -105,14 +105,6 @@ }, "SCHEDULER": { "scheduler.0" : { - "type":"DWRR", - "weight": "25" - }, - "scheduler.1" : { - "type":"DWRR", - "weight": "30" - }, - "scheduler.2" : { "type":"DWRR", "weight": "20" } @@ -127,41 +119,39 @@ } }, "WRED_PROFILE": { - "AZURE_LOSSY" : { - "wred_green_enable":"true", - "wred_yellow_enable":"true", - "ecn":"ecn_all", - "red_max_threshold":"512000", - "red_min_threshold":"512000", - "yellow_max_threshold":"512000", - "yellow_min_threshold":"512000", - "green_max_threshold": "184320", - "green_min_threshold": "184320" - }, "AZURE_LOSSLESS" : { "wred_green_enable":"true", "wred_yellow_enable":"true", + "wred_red_enable":"true", "ecn":"ecn_all", - "red_max_threshold":"512000", - "red_min_threshold":"512000", - "yellow_max_threshold":"512000", - "yellow_min_threshold":"512000", - "green_max_threshold": "184320", - "green_min_threshold": "184320" + "red_max_threshold":"2097152", + "red_min_threshold":"1048576", + "yellow_max_threshold":"2097152", + "yellow_min_threshold":"1048576", + "green_max_threshold":"2097152", + "green_min_threshold":"1048576", + "green_drop_probability":"5", + "yellow_drop_probability":"5", + "red_drop_probability":"5" } }, "QUEUE": { - "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0-1" : { - "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]" + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3" : { + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, - "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3-4" : { - "scheduler" : "[SCHEDULER|scheduler.0]" + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|4" : { + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0" : { - "scheduler" : "[SCHEDULER|scheduler.1]" + "scheduler" : "[SCHEDULER|scheduler.0]" }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|1" : { - "scheduler" : "[SCHEDULER|scheduler.2]" + "scheduler" : "[SCHEDULER|scheduler.0]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|5" : { + "scheduler" : "[SCHEDULER|scheduler.0]" } } } diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/pg_profile_lookup.ini b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/pg_profile_lookup.ini index 7222f8014925..570454c8d5b2 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/pg_profile_lookup.ini +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/pg_profile_lookup.ini @@ -1,17 +1,17 @@ # PG lossless profiles. # speed cable size xon xoff threshold xon_offset - 10000 5m 1248 2288 35776 -4 2288 - 25000 5m 1248 2288 53248 -4 2288 - 40000 5m 1248 2288 66560 -4 2288 - 50000 5m 1248 2288 79872 -4 2288 - 100000 5m 1248 2288 165568 -4 2288 - 10000 40m 1248 2288 37024 -4 2288 - 25000 40m 1248 2288 56160 -4 2288 - 40000 40m 1248 2288 71552 -4 2288 - 50000 40m 1248 2288 85696 -4 2288 - 100000 40m 1248 2288 177632 -4 2288 - 10000 300m 1248 2288 46176 -4 2288 - 25000 300m 1248 2288 79040 -4 2288 - 40000 300m 1248 2288 108160 -4 2288 - 50000 300m 1248 2288 131456 -4 2288 - 100000 300m 1248 2288 268736 -4 2288 + 10000 5m 1248 2288 35776 -3 2288 + 25000 5m 1248 2288 53248 -3 2288 + 40000 5m 1248 2288 66560 -3 2288 + 50000 5m 1248 2288 79872 -3 2288 + 100000 5m 1248 2288 165568 -3 2288 + 10000 40m 1248 2288 37024 -3 2288 + 25000 40m 1248 2288 56160 -3 2288 + 40000 40m 1248 2288 71552 -3 2288 + 50000 40m 1248 2288 85696 -3 2288 + 100000 40m 1248 2288 177632 -3 2288 + 10000 300m 1248 2288 46176 -3 2288 + 25000 300m 1248 2288 79040 -3 2288 + 40000 300m 1248 2288 108160 -3 2288 + 50000 300m 1248 2288 131456 -3 2288 + 100000 300m 1248 2288 268736 -3 2288 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/qos.json b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/qos.json index 8149f1f111ce..8fbee4a60dd7 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/qos.json +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/qos.json @@ -83,7 +83,7 @@ "43":"0", "44":"0", "45":"0", - "46":"0", + "46":"5", "47":"0", "48":"0", "49":"0", @@ -105,14 +105,6 @@ }, "SCHEDULER": { "scheduler.0" : { - "type":"DWRR", - "weight": "25" - }, - "scheduler.1" : { - "type":"DWRR", - "weight": "30" - }, - "scheduler.2" : { "type":"DWRR", "weight": "20" } @@ -127,41 +119,39 @@ } }, "WRED_PROFILE": { - "AZURE_LOSSY" : { - "wred_green_enable":"true", - "wred_yellow_enable":"true", - "ecn":"ecn_all", - "red_max_threshold":"512000", - "red_min_threshold":"512000", - "yellow_max_threshold":"512000", - "yellow_min_threshold":"512000", - "green_max_threshold": "184320", - "green_min_threshold": "184320" - }, "AZURE_LOSSLESS" : { "wred_green_enable":"true", "wred_yellow_enable":"true", + "wred_red_enable":"true", "ecn":"ecn_all", - "red_max_threshold":"512000", - "red_min_threshold":"512000", - "yellow_max_threshold":"512000", - "yellow_min_threshold":"512000", - "green_max_threshold": "184320", - "green_min_threshold": "184320" + "red_max_threshold":"2097152", + "red_min_threshold":"1048576", + "yellow_max_threshold":"2097152", + "yellow_min_threshold":"1048576", + "green_max_threshold":"2097152", + "green_min_threshold":"1048576", + "green_drop_probability":"5", + "yellow_drop_probability":"5", + "red_drop_probability":"5" } }, "QUEUE": { - "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126|0-1": { - "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]" + "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126|3": { + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, - "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126|3-4": { - "scheduler" : "[SCHEDULER|scheduler.0]" + "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126|4": { + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126|0": { - "scheduler" : "[SCHEDULER|scheduler.1]" + "scheduler" : "[SCHEDULER|scheduler.0]" }, "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126|1": { - "scheduler" : "[SCHEDULER|scheduler.2]" + "scheduler" : "[SCHEDULER|scheduler.0]" + }, + "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126|5": { + "scheduler" : "[SCHEDULER|scheduler.0]" } } } diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/pg_profile_lookup.ini b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/pg_profile_lookup.ini index 3b2a417cebcd..aedda37a8878 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/pg_profile_lookup.ini +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/pg_profile_lookup.ini @@ -1,17 +1,17 @@ # PG lossless profiles. # speed cable size xon xoff threshold xon_offset - 10000 5m 1248 2288 35776 -4 2288 - 25000 5m 1248 2288 53248 -4 2288 - 40000 5m 1248 2288 66560 -4 2288 - 50000 5m 1248 2288 90272 -4 2288 - 100000 5m 1248 2288 165568 -4 2288 - 10000 40m 1248 2288 37024 -4 2288 - 25000 40m 1248 2288 53248 -4 2288 - 40000 40m 1248 2288 71552 -4 2288 - 50000 40m 1248 2288 96096 -4 2288 - 100000 40m 1248 2288 177632 -4 2288 - 10000 300m 1248 2288 46176 -4 2288 - 25000 300m 1248 2288 79040 -4 2288 - 40000 300m 1248 2288 108160 -4 2288 - 50000 300m 1248 2288 141856 -4 2288 - 100000 300m 1248 2288 268736 -4 2288 + 10000 5m 1248 2288 35776 -3 2288 + 25000 5m 1248 2288 53248 -3 2288 + 40000 5m 1248 2288 66560 -3 2288 + 50000 5m 1248 2288 90272 -3 2288 + 100000 5m 1248 2288 165568 -3 2288 + 10000 40m 1248 2288 37024 -3 2288 + 25000 40m 1248 2288 53248 -3 2288 + 40000 40m 1248 2288 71552 -3 2288 + 50000 40m 1248 2288 96096 -3 2288 + 100000 40m 1248 2288 177632 -3 2288 + 10000 300m 1248 2288 46176 -3 2288 + 25000 300m 1248 2288 79040 -3 2288 + 40000 300m 1248 2288 108160 -3 2288 + 50000 300m 1248 2288 141856 -3 2288 + 100000 300m 1248 2288 268736 -3 2288 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/qos.json b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/qos.json index b724b48c2c23..deb9f40fc0f4 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/qos.json +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/qos.json @@ -83,7 +83,7 @@ "43":"0", "44":"0", "45":"0", - "46":"0", + "46":"5", "47":"0", "48":"0", "49":"0", @@ -105,14 +105,6 @@ }, "SCHEDULER": { "scheduler.0" : { - "type":"DWRR", - "weight": "25" - }, - "scheduler.1" : { - "type":"DWRR", - "weight": "30" - }, - "scheduler.2" : { "type":"DWRR", "weight": "20" } @@ -127,41 +119,39 @@ } }, "WRED_PROFILE": { - "AZURE_LOSSY" : { - "wred_green_enable":"true", - "wred_yellow_enable":"true", - "ecn":"ecn_all", - "red_max_threshold":"512000", - "red_min_threshold":"512000", - "yellow_max_threshold":"512000", - "yellow_min_threshold":"512000", - "green_max_threshold": "184320", - "green_min_threshold": "184320" - }, "AZURE_LOSSLESS" : { "wred_green_enable":"true", "wred_yellow_enable":"true", + "wred_red_enable":"true", "ecn":"ecn_all", - "red_max_threshold":"512000", - "red_min_threshold":"512000", - "yellow_max_threshold":"512000", - "yellow_min_threshold":"512000", - "green_max_threshold": "184320", - "green_min_threshold": "184320" + "red_max_threshold":"2097152", + "red_min_threshold":"1048576", + "yellow_max_threshold":"2097152", + "yellow_min_threshold":"1048576", + "green_max_threshold":"2097152", + "green_min_threshold":"1048576", + "green_drop_probability":"5", + "yellow_drop_probability":"5", + "red_drop_probability":"5" } }, "QUEUE": { - "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0-1" : { - "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]" + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3" : { + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, - "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3-4" : { - "scheduler" : "[SCHEDULER|scheduler.0]" + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|4" : { + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0" : { - "scheduler" : "[SCHEDULER|scheduler.1]" + "scheduler" : "[SCHEDULER|scheduler.0]" }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|1" : { - "scheduler" : "[SCHEDULER|scheduler.2]" + "scheduler" : "[SCHEDULER|scheduler.0]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|5" : { + "scheduler" : "[SCHEDULER|scheduler.0]" } } } diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/qos.json b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/qos.json index 2aa5a902448b..051003ffb565 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/qos.json +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/qos.json @@ -83,7 +83,7 @@ "43":"0", "44":"0", "45":"0", - "46":"0", + "46":"5", "47":"0", "48":"0", "49":"0", @@ -105,14 +105,6 @@ }, "SCHEDULER": { "scheduler.0" : { - "type":"DWRR", - "weight": "25" - }, - "scheduler.1" : { - "type":"DWRR", - "weight": "30" - }, - "scheduler.2" : { "type":"DWRR", "weight": "20" } @@ -127,41 +119,39 @@ } }, "WRED_PROFILE": { - "AZURE_LOSSY" : { - "wred_green_enable":"true", - "wred_yellow_enable":"true", - "ecn":"ecn_all", - "red_max_threshold":"512000", - "red_min_threshold":"512000", - "yellow_max_threshold":"512000", - "yellow_min_threshold":"512000", - "green_max_threshold": "184320", - "green_min_threshold": "184320" - }, "AZURE_LOSSLESS" : { "wred_green_enable":"true", "wred_yellow_enable":"true", + "wred_red_enable":"true", "ecn":"ecn_all", - "red_max_threshold":"512000", - "red_min_threshold":"512000", - "yellow_max_threshold":"512000", - "yellow_min_threshold":"512000", - "green_max_threshold": "184320", - "green_min_threshold": "184320" + "red_max_threshold":"2097152", + "red_min_threshold":"1048576", + "yellow_max_threshold":"2097152", + "yellow_min_threshold":"1048576", + "green_max_threshold":"2097152", + "green_min_threshold":"1048576", + "green_drop_probability":"5", + "yellow_drop_probability":"5", + "red_drop_probability":"5" } }, "QUEUE": { - "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet26,Ethernet28,Ethernet30,Ethernet32,Ethernet34,Ethernet36,Ethernet38,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126,Ethernet128,Ethernet130,Ethernet132,Ethernet134,Ethernet136,Ethernet138,Ethernet140,Ethernet142,Ethernet144,Ethernet146,Ethernet148,Ethernet150,Ethernet152,Ethernet154,Ethernet156,Ethernet158,Ethernet160,Ethernet162,Ethernet164,Ethernet166,Ethernet168,Ethernet170,Ethernet172,Ethernet174,Ethernet176,Ethernet178,Ethernet180,Ethernet182,Ethernet184,Ethernet186,Ethernet188,Ethernet190,Ethernet192,Ethernet194,Ethernet196,Ethernet198,Ethernet200,Ethernet202,Ethernet204,Ethernet206,Ethernet208,Ethernet210,Ethernet212,Ethernet214,Ethernet216,Ethernet218,Ethernet220,Ethernet222,Ethernet224,Ethernet226,Ethernet228,Ethernet230,Ethernet232,Ethernet234,Ethernet236,Ethernet238,Ethernet240,Ethernet242,Ethernet244,Ethernet246,Ethernet248,Ethernet250,Ethernet252,Ethernet254|0-1" : { - "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]" + "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet26,Ethernet28,Ethernet30,Ethernet32,Ethernet34,Ethernet36,Ethernet38,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126,Ethernet128,Ethernet130,Ethernet132,Ethernet134,Ethernet136,Ethernet138,Ethernet140,Ethernet142,Ethernet144,Ethernet146,Ethernet148,Ethernet150,Ethernet152,Ethernet154,Ethernet156,Ethernet158,Ethernet160,Ethernet162,Ethernet164,Ethernet166,Ethernet168,Ethernet170,Ethernet172,Ethernet174,Ethernet176,Ethernet178,Ethernet180,Ethernet182,Ethernet184,Ethernet186,Ethernet188,Ethernet190,Ethernet192,Ethernet194,Ethernet196,Ethernet198,Ethernet200,Ethernet202,Ethernet204,Ethernet206,Ethernet208,Ethernet210,Ethernet212,Ethernet214,Ethernet216,Ethernet218,Ethernet220,Ethernet222,Ethernet224,Ethernet226,Ethernet228,Ethernet230,Ethernet232,Ethernet234,Ethernet236,Ethernet238,Ethernet240,Ethernet242,Ethernet244,Ethernet246,Ethernet248,Ethernet250,Ethernet252,Ethernet254|3" : { + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, - "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet26,Ethernet28,Ethernet30,Ethernet32,Ethernet34,Ethernet36,Ethernet38,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126,Ethernet128,Ethernet130,Ethernet132,Ethernet134,Ethernet136,Ethernet138,Ethernet140,Ethernet142,Ethernet144,Ethernet146,Ethernet148,Ethernet150,Ethernet152,Ethernet154,Ethernet156,Ethernet158,Ethernet160,Ethernet162,Ethernet164,Ethernet166,Ethernet168,Ethernet170,Ethernet172,Ethernet174,Ethernet176,Ethernet178,Ethernet180,Ethernet182,Ethernet184,Ethernet186,Ethernet188,Ethernet190,Ethernet192,Ethernet194,Ethernet196,Ethernet198,Ethernet200,Ethernet202,Ethernet204,Ethernet206,Ethernet208,Ethernet210,Ethernet212,Ethernet214,Ethernet216,Ethernet218,Ethernet220,Ethernet222,Ethernet224,Ethernet226,Ethernet228,Ethernet230,Ethernet232,Ethernet234,Ethernet236,Ethernet238,Ethernet240,Ethernet242,Ethernet244,Ethernet246,Ethernet248,Ethernet250,Ethernet252,Ethernet254|3-4" : { - "scheduler" : "[SCHEDULER|scheduler.0]" + "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet26,Ethernet28,Ethernet30,Ethernet32,Ethernet34,Ethernet36,Ethernet38,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126,Ethernet128,Ethernet130,Ethernet132,Ethernet134,Ethernet136,Ethernet138,Ethernet140,Ethernet142,Ethernet144,Ethernet146,Ethernet148,Ethernet150,Ethernet152,Ethernet154,Ethernet156,Ethernet158,Ethernet160,Ethernet162,Ethernet164,Ethernet166,Ethernet168,Ethernet170,Ethernet172,Ethernet174,Ethernet176,Ethernet178,Ethernet180,Ethernet182,Ethernet184,Ethernet186,Ethernet188,Ethernet190,Ethernet192,Ethernet194,Ethernet196,Ethernet198,Ethernet200,Ethernet202,Ethernet204,Ethernet206,Ethernet208,Ethernet210,Ethernet212,Ethernet214,Ethernet216,Ethernet218,Ethernet220,Ethernet222,Ethernet224,Ethernet226,Ethernet228,Ethernet230,Ethernet232,Ethernet234,Ethernet236,Ethernet238,Ethernet240,Ethernet242,Ethernet244,Ethernet246,Ethernet248,Ethernet250,Ethernet252,Ethernet254|4" : { + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet26,Ethernet28,Ethernet30,Ethernet32,Ethernet34,Ethernet36,Ethernet38,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126,Ethernet128,Ethernet130,Ethernet132,Ethernet134,Ethernet136,Ethernet138,Ethernet140,Ethernet142,Ethernet144,Ethernet146,Ethernet148,Ethernet150,Ethernet152,Ethernet154,Ethernet156,Ethernet158,Ethernet160,Ethernet162,Ethernet164,Ethernet166,Ethernet168,Ethernet170,Ethernet172,Ethernet174,Ethernet176,Ethernet178,Ethernet180,Ethernet182,Ethernet184,Ethernet186,Ethernet188,Ethernet190,Ethernet192,Ethernet194,Ethernet196,Ethernet198,Ethernet200,Ethernet202,Ethernet204,Ethernet206,Ethernet208,Ethernet210,Ethernet212,Ethernet214,Ethernet216,Ethernet218,Ethernet220,Ethernet222,Ethernet224,Ethernet226,Ethernet228,Ethernet230,Ethernet232,Ethernet234,Ethernet236,Ethernet238,Ethernet240,Ethernet242,Ethernet244,Ethernet246,Ethernet248,Ethernet250,Ethernet252,Ethernet254|0" : { - "scheduler" : "[SCHEDULER|scheduler.1]" + "scheduler" : "[SCHEDULER|scheduler.0]" }, "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet26,Ethernet28,Ethernet30,Ethernet32,Ethernet34,Ethernet36,Ethernet38,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126,Ethernet128,Ethernet130,Ethernet132,Ethernet134,Ethernet136,Ethernet138,Ethernet140,Ethernet142,Ethernet144,Ethernet146,Ethernet148,Ethernet150,Ethernet152,Ethernet154,Ethernet156,Ethernet158,Ethernet160,Ethernet162,Ethernet164,Ethernet166,Ethernet168,Ethernet170,Ethernet172,Ethernet174,Ethernet176,Ethernet178,Ethernet180,Ethernet182,Ethernet184,Ethernet186,Ethernet188,Ethernet190,Ethernet192,Ethernet194,Ethernet196,Ethernet198,Ethernet200,Ethernet202,Ethernet204,Ethernet206,Ethernet208,Ethernet210,Ethernet212,Ethernet214,Ethernet216,Ethernet218,Ethernet220,Ethernet222,Ethernet224,Ethernet226,Ethernet228,Ethernet230,Ethernet232,Ethernet234,Ethernet236,Ethernet238,Ethernet240,Ethernet242,Ethernet244,Ethernet246,Ethernet248,Ethernet250,Ethernet252,Ethernet254|1" : { - "scheduler" : "[SCHEDULER|scheduler.2]" + "scheduler" : "[SCHEDULER|scheduler.0]" + }, + "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet26,Ethernet28,Ethernet30,Ethernet32,Ethernet34,Ethernet36,Ethernet38,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126,Ethernet128,Ethernet130,Ethernet132,Ethernet134,Ethernet136,Ethernet138,Ethernet140,Ethernet142,Ethernet144,Ethernet146,Ethernet148,Ethernet150,Ethernet152,Ethernet154,Ethernet156,Ethernet158,Ethernet160,Ethernet162,Ethernet164,Ethernet166,Ethernet168,Ethernet170,Ethernet172,Ethernet174,Ethernet176,Ethernet178,Ethernet180,Ethernet182,Ethernet184,Ethernet186,Ethernet188,Ethernet190,Ethernet192,Ethernet194,Ethernet196,Ethernet198,Ethernet200,Ethernet202,Ethernet204,Ethernet206,Ethernet208,Ethernet210,Ethernet212,Ethernet214,Ethernet216,Ethernet218,Ethernet220,Ethernet222,Ethernet224,Ethernet226,Ethernet228,Ethernet230,Ethernet232,Ethernet234,Ethernet236,Ethernet238,Ethernet240,Ethernet242,Ethernet244,Ethernet246,Ethernet248,Ethernet250,Ethernet252,Ethernet254|5" : { + "scheduler" : "[SCHEDULER|scheduler.0]" } } } From 431a9f67d516253c1b667af670891ec4d1cd8710 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Fri, 5 Oct 2018 19:58:13 +0000 Subject: [PATCH 156/219] [broadcom]: update SAI to 3.1.3.4-18 Merged PR 1138465: Disable port global pause frame rx processing logic [Wenda Ni] Signed-off-by: Guohan Lu --- platform/broadcom/sai.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 4000aec1a778..69e389238720 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,9 +1,9 @@ -BRCM_SAI = libsaibcm_3.1.3.4-17_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/libsaibcm_3.1.3.4-17_amd64.deb?sv=2015-04-05&sr=b&sig=wDTUZwUF05gxdoB%2BHVZeB8uQQWq3qFmvM5VLliLHA8E%3D&se=2155-08-17T07%3A45%3A56Z&sp=r" +BRCM_SAI = libsaibcm_3.1.3.4-18_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/libsaibcm_3.1.3.4-18_amd64.deb?sv=2015-04-05&sr=b&sig=FqiCA8J4cvVyaKG9VrA9HAh2TedtJHHQUmjXQOoxiJY%3D&se=2155-08-28T19%3A38%3A44Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.1.3.4-17_amd64.deb +BRCM_SAI_DEV = libsaibcm-dev_3.1.3.4-18_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/libsaibcm-dev_3.1.3.4-17_amd64.deb?sv=2015-04-05&sr=b&sig=l%2Bvb%2F4%2FCB8IEz70msUGMYsWCpeDPp7slxwZeiKqnNAo%3D&se=2155-08-17T07%3A43%3A58Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/libsaibcm-dev_3.1.3.4-18_amd64.deb?sv=2015-04-05&sr=b&sig=kI7rK1xQ%2BkNePGDlagQgDCYmoBN%2By9Dn2UFnDAT34oA%3D&se=2155-08-28T19%3A42%3A49Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) From eba171b22281a823cb75e5248f19bc1edf9f2cf8 Mon Sep 17 00:00:00 2001 From: stepanblyschak <38952541+stepanblyschak@users.noreply.github.com> Date: Mon, 8 Oct 2018 20:58:13 +0300 Subject: [PATCH 157/219] [submodules]: update submodules for MGMT PORT over SNMP support (#2113) * [submodules]: update sonic-snmpagent, sonic-py-swsssdk Signed-off-by: Stepan Blyschak * [submodules]: update sonic-swss, sonic-swss-common Signed-off-by: Stepan Blyschak --- src/sonic-py-swsssdk | 2 +- src/sonic-snmpagent | 2 +- src/sonic-swss | 2 +- src/sonic-swss-common | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index ca540c9c51e2..7ce52d861019 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit ca540c9c51e2bb704802a89ecd2b485578bd8211 +Subproject commit 7ce52d86101906e404af96fe76e04079f4afd863 diff --git a/src/sonic-snmpagent b/src/sonic-snmpagent index ab91a0593fa8..6e32095cae44 160000 --- a/src/sonic-snmpagent +++ b/src/sonic-snmpagent @@ -1 +1 @@ -Subproject commit ab91a0593fa83677081fdff7d322f469f7471906 +Subproject commit 6e32095cae4412b566309fe3865fa90423a02d24 diff --git a/src/sonic-swss b/src/sonic-swss index 6ea4ea351fa7..4f5436fea75a 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 6ea4ea351fa78cea6e2390a4f2211d9ddca0187c +Subproject commit 4f5436fea75a33b560ff88b7562797b3d4a4d4ed diff --git a/src/sonic-swss-common b/src/sonic-swss-common index f907e9463bd9..d354171cb90f 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit f907e9463bd9eb81d5cfb6d632774de41a100f93 +Subproject commit d354171cb90f0eabb21ae0b1e4dfb515f63e83db From 773ed99d0a4360539e6e9d63b46cc3978e9bee39 Mon Sep 17 00:00:00 2001 From: zhenggen-xu Date: Wed, 10 Oct 2018 23:41:27 -0700 Subject: [PATCH 158/219] [security] Upgrade kernel to 3.16.57-2 on 201803 branch (#2116) * [security] Upgrade kernel to 3.16.57-2 Fix issues below: https://www.debian.org/security/2018/dsa-4120 https://www.debian.org/security/2018/dsa-4179 https://www.debian.org/security/2018/dsa-4187 https://www.debian.org/security/2018/dsa-4188 https://www.debian.org/security/2018/dsa-4196 and more. * update opennsl-modules-3.16.0-6-amd64_3.4.1.11-7_amd64.deb package Signed-off-by: Guohan Lu * [mellanox] update sdk base url (new kernel version) --- build_debian.sh | 6 +++--- files/build_templates/swss.service.j2 | 8 ++++---- installer/x86_64/install.sh | 4 ++-- platform/broadcom/sdk.mk | 6 ++++-- .../as5712-54x/utils/README | 4 ++-- .../as7312-54x/utils/README | 4 ++-- .../as7716-32x/utils/README | 4 ++-- .../sonic-platform-modules-accton/debian/control | 14 +++++++------- .../confs/arista-drivers.service | 2 +- .../confs/gardena-watchdog-stop.service | 2 +- .../sonic-platform-modules-arista/debian/control | 2 +- .../sonic-platform-modules-arista/utils/boot0 | 4 ++-- .../sonic-platform-modules-cel/debian/control | 2 +- .../sonic-platform-modules-dell/debian/control | 4 ++-- .../sonic-platform-modules-delta/debian/control | 6 +++--- .../sonic-platform-modules-inventec/debian/control | 4 ++-- .../sonic-platform-modules-mitac/debian/control | 2 +- .../sonic-platform-modules-quanta/debian/control | 2 +- .../sonic-platform-modules-s6000/debian/control | 2 +- .../sonic-platform-modules-e582/debian/control | 4 ++-- platform/mellanox/sdk.mk | 2 +- platform/nephos/sdk.mk | 4 ++-- .../sonic-platform-modules-accton/debian/control | 2 +- rules/linux-kernel.mk | 6 +++--- src/sonic-linux-kernel | 2 +- 25 files changed, 52 insertions(+), 50 deletions(-) diff --git a/build_debian.sh b/build_debian.sh index 1080a5847a20..297fc1da19d3 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -114,7 +114,7 @@ echo '[INFO] Install SONiC linux kernel image' ## Note: duplicate apt-get command to ensure every line return zero sudo dpkg --root=$FILESYSTEM_ROOT -i target/debs/initramfs-tools_*.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f -sudo dpkg --root=$FILESYSTEM_ROOT -i target/debs/linux-image-3.16.0-5-amd64_*.deb || \ +sudo dpkg --root=$FILESYSTEM_ROOT -i target/debs/linux-image-3.16.0-6-amd64_*.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f ## Update initramfs for booting with squashfs+aufs @@ -152,10 +152,10 @@ sudo chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/hooks/union-fsck sudo chroot $FILESYSTEM_ROOT update-initramfs -u ## Install latest intel igb driver -sudo cp target/debs/igb.ko $FILESYSTEM_ROOT/lib/modules/3.16.0-5-amd64/kernel/drivers/net/ethernet/intel/igb/igb.ko +sudo cp target/debs/igb.ko $FILESYSTEM_ROOT/lib/modules/3.16.0-6-amd64/kernel/drivers/net/ethernet/intel/igb/igb.ko ## Install latest intel ixgbe driver -sudo cp target/debs/ixgbe.ko $FILESYSTEM_ROOT/lib/modules/3.16.0-5-amd64/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe.ko +sudo cp target/debs/ixgbe.ko $FILESYSTEM_ROOT/lib/modules/3.16.0-6-amd64/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe.ko ## Install docker echo '[INFO] Install docker' diff --git a/files/build_templates/swss.service.j2 b/files/build_templates/swss.service.j2 index e16ca6636121..bb347e66ae07 100644 --- a/files/build_templates/swss.service.j2 +++ b/files/build_templates/swss.service.j2 @@ -2,16 +2,16 @@ Description=switch state service Requires=database.service updategraph.service {% if sonic_asic_platform == 'broadcom' %} -Requires=opennsl-modules-3.16.0-5-amd64.service +Requires=opennsl-modules-3.16.0-6-amd64.service {% elif sonic_asic_platform == 'nephos' %} -Requires=nps-modules-3.16.0-5-amd64.service +Requires=nps-modules-3.16.0-6-amd64.service {% endif %} After=database.service updategraph.service After=interfaces-config.service {% if sonic_asic_platform == 'broadcom' %} -After=opennsl-modules-3.16.0-5-amd64.service +After=opennsl-modules-3.16.0-6-amd64.service {% elif sonic_asic_platform == 'nephos' %} -After=nps-modules-3.16.0-5-amd64.service +After=nps-modules-3.16.0-6-amd64.service {% endif %} [Service] diff --git a/installer/x86_64/install.sh b/installer/x86_64/install.sh index 91dd57a74ba1..f136186985a6 100755 --- a/installer/x86_64/install.sh +++ b/installer/x86_64/install.sh @@ -570,11 +570,11 @@ menuentry '$demo_grub_entry' { if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi insmod part_msdos insmod ext2 - linux /$image_dir/boot/vmlinuz-3.16.0-5-amd64 root=$grub_cfg_root rw $GRUB_CMDLINE_LINUX \ + linux /$image_dir/boot/vmlinuz-3.16.0-6-amd64 root=$grub_cfg_root rw $GRUB_CMDLINE_LINUX \ loop=$image_dir/$FILESYSTEM_SQUASHFS loopfstype=squashfs \ apparmor=1 security=apparmor varlog_size=$VAR_LOG_SIZE usbcore.autosuspend=-1 $ONIE_PLATFORM_EXTRA_CMDLINE_LINUX echo 'Loading $demo_volume_label $demo_type initial ramdisk ...' - initrd /$image_dir/boot/initrd.img-3.16.0-5-amd64 + initrd /$image_dir/boot/initrd.img-3.16.0-6-amd64 } EOF diff --git a/platform/broadcom/sdk.mk b/platform/broadcom/sdk.mk index 05d51fc28d07..0e7eea0db59f 100644 --- a/platform/broadcom/sdk.mk +++ b/platform/broadcom/sdk.mk @@ -1,4 +1,6 @@ -BRCM_OPENNSL_KERNEL = opennsl-modules-3.16.0-5-amd64_3.4.1.11-2_amd64.deb -$(BRCM_OPENNSL_KERNEL)_URL = "https://sonicstorage.blob.core.windows.net/packages/opennsl-modules-3.16.0-5-amd64_3.4.1.11-2_amd64.deb?sv=2015-04-05&sr=b&sig=xtf8nafmS1pcqx5hhBsfmLNSx2BeqmwN4Dwq5uwM1bo%3D&se=2031-11-16T21%3A54%3A27Z&sp=r" +# mock link here, need to be replaced by real link from MSFT + +BRCM_OPENNSL_KERNEL = opennsl-modules-3.16.0-6-amd64_3.4.1.11-7_amd64.deb +$(BRCM_OPENNSL_KERNEL)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/opennsl-modules-3.16.0-6-amd64_3.4.1.11-7_amd64.deb?sv=2015-04-05&sr=b&sig=HGePoJSCcURIMW3bPRh5iXlx6z5SWiElmqD44mqUchI%3D&se=2155-08-28T16%3A31%3A48Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_OPENNSL_KERNEL) diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/README b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/README index 44e03cab5f52..9cd5dbdd9de5 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/README +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/README @@ -39,7 +39,7 @@ User is not necessary to handle docker environment creation. - Copy patches and series from patch/kernel of this release to sonic-linux-kernel/patch. - Build kernel by "make". - - The built kernel package, linux-image-3.16.0-5-amd64_3.16.51-3+deb8u1_amd64.deb + - The built kernel package, linux-image-3.16.0-6-amd64_3.16.51-3+deb8u1_amd64.deb , is generated. 3. Build installer - Change directory back to sonic-buildimage/. @@ -52,7 +52,7 @@ User is not necessary to handle docker environment creation. The default user and password are "admin" & "YourPaSsWoRd" respectively. - Run "make configure PLATFORM=broadcom" - Copy the built kernel debian package to target/debs/. - The file is linux-image-3.16.0-5-amd64_*_amd64.deb under directory + The file is linux-image-3.16.0-6-amd64_*_amd64.deb under directory src/sonic-linux-kernel/. - Run "make target/sonic-generic.bin" - Get the installer, target/sonic-generic.bin, to target machine and install. diff --git a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/README b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/README index 66f31a030423..97ad4e6bcbce 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/README +++ b/platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/README @@ -39,7 +39,7 @@ User is not necessary to handle docker environment creation. - Copy patches and series from patch/kernel of this release to sonic-linux-kernel/patch. - Build kernel by "make". - - The built kernel package, linux-image-3.16.0-5-amd64_3.16.51-3+deb8u1_amd64.deb + - The built kernel package, linux-image-3.16.0-6-amd64_3.16.51-3+deb8u1_amd64.deb , is generated. 3. Build installer - Change directory back to sonic-buildimage/. @@ -52,7 +52,7 @@ User is not necessary to handle docker environment creation. The default user and password are "admin" & "YourPaSsWoRd" respectively. - Run "make configure PLATFORM=broadcom" - Copy the built kernel debian package to target/debs/. - The file is linux-image-3.16.0-5-amd64_*_amd64.deb under directory + The file is linux-image-3.16.0-6-amd64_*_amd64.deb under directory src/sonic-linux-kernel/. - Run "make target/sonic-generic.bin" - Get the installer, target/sonic-generic.bin, to target machine and install. diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/README b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/README index 44e03cab5f52..9cd5dbdd9de5 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/README +++ b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/README @@ -39,7 +39,7 @@ User is not necessary to handle docker environment creation. - Copy patches and series from patch/kernel of this release to sonic-linux-kernel/patch. - Build kernel by "make". - - The built kernel package, linux-image-3.16.0-5-amd64_3.16.51-3+deb8u1_amd64.deb + - The built kernel package, linux-image-3.16.0-6-amd64_3.16.51-3+deb8u1_amd64.deb , is generated. 3. Build installer - Change directory back to sonic-buildimage/. @@ -52,7 +52,7 @@ User is not necessary to handle docker environment creation. The default user and password are "admin" & "YourPaSsWoRd" respectively. - Run "make configure PLATFORM=broadcom" - Copy the built kernel debian package to target/debs/. - The file is linux-image-3.16.0-5-amd64_*_amd64.deb under directory + The file is linux-image-3.16.0-6-amd64_*_amd64.deb under directory src/sonic-linux-kernel/. - Run "make target/sonic-generic.bin" - Get the installer, target/sonic-generic.bin, to target machine and install. diff --git a/platform/broadcom/sonic-platform-modules-accton/debian/control b/platform/broadcom/sonic-platform-modules-accton/debian/control index 22faf6d202b8..b05f00d7147f 100755 --- a/platform/broadcom/sonic-platform-modules-accton/debian/control +++ b/platform/broadcom/sonic-platform-modules-accton/debian/control @@ -7,35 +7,35 @@ Standards-Version: 3.9.3 Package: sonic-platform-accton-as7712-32x Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 +Depends: linux-image-3.16.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-accton-as5712-54x Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 +Depends: linux-image-3.16.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-accton-as7816-64x Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 +Depends: linux-image-3.16.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-accton-as7716-32x Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 +Depends: linux-image-3.16.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-accton-as7716-32xb Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 +Depends: linux-image-3.16.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-accton-as7312-54x Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 +Depends: linux-image-3.16.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-accton-as7326-56x Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 +Depends: linux-image-3.16.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-arista/confs/arista-drivers.service b/platform/broadcom/sonic-platform-modules-arista/confs/arista-drivers.service index 7c6551df9086..aee9a0dabf97 100644 --- a/platform/broadcom/sonic-platform-modules-arista/confs/arista-drivers.service +++ b/platform/broadcom/sonic-platform-modules-arista/confs/arista-drivers.service @@ -1,7 +1,7 @@ [Unit] Description=Arista kernel modules init After=local-fs.target -Before=opennsl-modules-3.16.0-5-amd64.service +Before=opennsl-modules-3.16.0-6-amd64.service ConditionKernelCommandLine=Aboot [Service] diff --git a/platform/broadcom/sonic-platform-modules-arista/confs/gardena-watchdog-stop.service b/platform/broadcom/sonic-platform-modules-arista/confs/gardena-watchdog-stop.service index af912ce7cee9..5d4905b8aa86 100644 --- a/platform/broadcom/sonic-platform-modules-arista/confs/gardena-watchdog-stop.service +++ b/platform/broadcom/sonic-platform-modules-arista/confs/gardena-watchdog-stop.service @@ -1,7 +1,7 @@ [Unit] Description=Disable the watchdog after boot After=swss.service -After=opennsl-modules-3.16.0-5-amd64.service +After=opennsl-modules-3.16.0-6-amd64.service ConditionKernelCommandLine=sid=Gardena [Service] diff --git a/platform/broadcom/sonic-platform-modules-arista/debian/control b/platform/broadcom/sonic-platform-modules-arista/debian/control index ae53eea5bc81..24c2d9ab28d4 100755 --- a/platform/broadcom/sonic-platform-modules-arista/debian/control +++ b/platform/broadcom/sonic-platform-modules-arista/debian/control @@ -21,7 +21,7 @@ Package: drivers-sonic-platform-arista Architecture: amd64 Depends: ${misc:Depends}, - linux-image-3.16.0-5-amd64 + linux-image-3.16.0-6-amd64 Description: Arista kernel modules for arista platform devices such as fan, led, sfp, psu Package: python-sonic-platform-arista diff --git a/platform/broadcom/sonic-platform-modules-arista/utils/boot0 b/platform/broadcom/sonic-platform-modules-arista/utils/boot0 index e9053f74698a..3a9e04703a2c 100755 --- a/platform/broadcom/sonic-platform-modules-arista/utils/boot0 +++ b/platform/broadcom/sonic-platform-modules-arista/utils/boot0 @@ -18,8 +18,8 @@ set -x -kernel=boot/vmlinuz-3.16.0-5-amd64 -initrd=boot/initrd.img-3.16.0-5-amd64 +kernel=boot/vmlinuz-3.16.0-6-amd64 +initrd=boot/initrd.img-3.16.0-6-amd64 kernel_params=kernel-params aboot_machine="arista_unknown" diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/control b/platform/broadcom/sonic-platform-modules-cel/debian/control index 72bcd54ee62c..d02e950f7ec5 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/control +++ b/platform/broadcom/sonic-platform-modules-cel/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: platform-modules-dx010 Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 +Depends: linux-image-3.16.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/control b/platform/broadcom/sonic-platform-modules-dell/debian/control index 45f94e04b9eb..b723e0c80993 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/control +++ b/platform/broadcom/sonic-platform-modules-dell/debian/control @@ -7,11 +7,11 @@ Standards-Version: 3.9.3 Package: platform-modules-z9100 Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 +Depends: linux-image-3.16.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-s6100 Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 +Depends: linux-image-3.16.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/control b/platform/broadcom/sonic-platform-modules-delta/debian/control index 455a5f296ac0..8f66ef525aa9 100644 --- a/platform/broadcom/sonic-platform-modules-delta/debian/control +++ b/platform/broadcom/sonic-platform-modules-delta/debian/control @@ -7,15 +7,15 @@ Standards-Version: 3.9.3 Package: platform-modules-ag9032v1 Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 +Depends: linux-image-3.16.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag9064 Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 +Depends: linux-image-3.16.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag5648 Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 +Depends: linux-image-3.16.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/control b/platform/broadcom/sonic-platform-modules-inventec/debian/control index 27258c9226c3..8a642927ce62 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/debian/control +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/control @@ -7,11 +7,11 @@ Standards-Version: 3.9.3 Package: platform-modules-d7032q28b Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 +Depends: linux-image-3.16.0-6-amd64 Description: kernel modules for platform devices such as fan, led Package: platform-modules-d7054q28b Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 +Depends: linux-image-3.16.0-6-amd64 Description: kernel modules for platform devices such as fan, led diff --git a/platform/broadcom/sonic-platform-modules-mitac/debian/control b/platform/broadcom/sonic-platform-modules-mitac/debian/control index 8e20f8524d74..a1e099c899ee 100644 --- a/platform/broadcom/sonic-platform-modules-mitac/debian/control +++ b/platform/broadcom/sonic-platform-modules-mitac/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-mitac-ly1200-32x Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 +Depends: linux-image-3.16.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-quanta/debian/control b/platform/broadcom/sonic-platform-modules-quanta/debian/control index af058ee98f2d..565e28ba3104 100755 --- a/platform/broadcom/sonic-platform-modules-quanta/debian/control +++ b/platform/broadcom/sonic-platform-modules-quanta/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-quanta-ix1b-32x Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 +Depends: linux-image-3.16.0-6-amd64 Description: kernel modules for platform devices such as psu, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-s6000/debian/control b/platform/broadcom/sonic-platform-modules-s6000/debian/control index 394a1f4aa4af..32f4fb201e41 100644 --- a/platform/broadcom/sonic-platform-modules-s6000/debian/control +++ b/platform/broadcom/sonic-platform-modules-s6000/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: platform-modules-s6000 Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 +Depends: linux-image-3.16.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/centec/sonic-platform-modules-e582/debian/control b/platform/centec/sonic-platform-modules-e582/debian/control index 103b6eca242d..c2fbdbc83102 100644 --- a/platform/centec/sonic-platform-modules-e582/debian/control +++ b/platform/centec/sonic-platform-modules-e582/debian/control @@ -7,11 +7,11 @@ Standards-Version: 3.9.3 Package: platform-modules-e582-48x2q4z Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 +Depends: linux-image-3.16.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-e582-48x6q Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 +Depends: linux-image-3.16.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index 83d5dad7af8a..b85fc0bcb033 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,4 +1,4 @@ -MLNX_SDK_BASE_URL = https://github.com/Mellanox/SAI-Implementation/raw/5675ef1037813992cd234d3afcee43959e1ca4f6/sdk +MLNX_SDK_BASE_URL = https://github.com/Mellanox/SAI-Implementation/raw/dc2bafed31d0a84d9282d65bd94b5e20574d1a4d/sdk MLNX_SDK_VERSION = 4.2.7303 MLNX_SDK_RDEBS += $(APPLIBS) $(IPROUTE2_MLNX) $(SX_ACL_RM) $(SX_COMPLIB) \ $(SX_EXAMPLES) $(SX_GEN_UTILS) $(SX_SCEW) $(SX_SDN_HAL) \ diff --git a/platform/nephos/sdk.mk b/platform/nephos/sdk.mk index ce5748745242..55720f6ab828 100644 --- a/platform/nephos/sdk.mk +++ b/platform/nephos/sdk.mk @@ -1,4 +1,4 @@ -NEPHOS_NPS_KERNEL = nps-modules-3.16.0-5_2.0.3_3147dc_amd64.deb -$(NEPHOS_NPS_KERNEL)_URL = "https://github.com/NephosInc/SONiC/raw/master/sdk/nps-modules-3.16.0-5_2.0.3_3147dc_amd64.deb" +NEPHOS_NPS_KERNEL = nps-modules-3.16.0-6_2.0.3_3147dc_amd64.deb +$(NEPHOS_NPS_KERNEL)_URL = "https://github.com/NephosInc/SONiC/raw/master/sdk/nps-modules-3.16.0-6_2.0.3_3147dc_amd64.deb" SONIC_ONLINE_DEBS += $(NEPHOS_NPS_KERNEL) diff --git a/platform/nephos/sonic-platform-modules-accton/debian/control b/platform/nephos/sonic-platform-modules-accton/debian/control index e1a403b3a719..69d6c47033ed 100755 --- a/platform/nephos/sonic-platform-modules-accton/debian/control +++ b/platform/nephos/sonic-platform-modules-accton/debian/control @@ -7,5 +7,5 @@ Standards-Version: 3.9.3 Package: sonic-platform-accton-as7116-54x Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 +Depends: linux-image-3.16.0-6-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/rules/linux-kernel.mk b/rules/linux-kernel.mk index b7c1263990f5..1fb0d1e7de1c 100644 --- a/rules/linux-kernel.mk +++ b/rules/linux-kernel.mk @@ -1,9 +1,9 @@ # linux kernel package -KVERSION_SHORT = 3.16.0-5 +KVERSION_SHORT = 3.16.0-6 KVERSION ?= $(KVERSION_SHORT)-amd64 -KERNEL_VERSION = 3.16.51 -KERNEL_SUBVERSION = 3+deb8u1 +KERNEL_VERSION = 3.16.57 +KERNEL_SUBVERSION = 2 export KVERSION_SHORT KVERSION KERNEL_VERSION KERNEL_SUBVERSION diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel index 652f2592b90c..dff16eb00bf3 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit 652f2592b90c2ae10064b9131b5217fbdde63526 +Subproject commit dff16eb00bf3fc45c4b3cb4d557732ce7a64be17 From de7f5ac907e21e6f8c7d68360ef5380e9ffcce5e Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Fri, 12 Oct 2018 19:41:22 -0700 Subject: [PATCH 159/219] [devices]: Add index column to Mellanox-SN2700-D48C8/port_config.ini (#2146) Signed-off-by: Qi Luo --- .../Mellanox-SN2700-D48C8/port_config.ini | 114 +++++++++--------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini index ffe3fe0ce6d9..9e01da79f449 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini @@ -1,57 +1,57 @@ -# name lanes speed alias -Ethernet0 0,1 50000 etp1a -Ethernet2 2,3 50000 etp1b -Ethernet4 4,5 50000 etp2a -Ethernet6 6,7 50000 etp2b -Ethernet8 8,9 50000 etp3a -Ethernet10 10,11 50000 etp3b -Ethernet12 12,13 50000 etp4a -Ethernet14 14,15 50000 etp4b -Ethernet16 16,17 50000 etp5a -Ethernet18 18,19 50000 etp5b -Ethernet20 20,21 50000 etp6a -Ethernet22 22,23 50000 etp6b -Ethernet24 24,25,26,27 100000 etp7 -Ethernet28 28,29,30,31 100000 etp8 -Ethernet32 32,33,34,35 100000 etp9 -Ethernet36 36,37,38,39 100000 etp10 -Ethernet40 40,41 50000 etp11a -Ethernet42 42,43 50000 etp11b -Ethernet44 44,45 50000 etp12a -Ethernet46 46,47 50000 etp12b -Ethernet48 48,49 50000 etp13a -Ethernet50 50,51 50000 etp13b -Ethernet52 52,53 50000 etp14a -Ethernet54 54,55 50000 etp14b -Ethernet56 56,57 50000 etp15a -Ethernet58 58,59 50000 etp15b -Ethernet60 60,61 50000 etp16a -Ethernet62 62,63 50000 etp16b -Ethernet64 64,65 50000 etp17a -Ethernet66 66,67 50000 etp17b -Ethernet68 68,69 50000 etp18a -Ethernet70 70,71 50000 etp18b -Ethernet72 72,73 50000 etp19a -Ethernet74 74,75 50000 etp19b -Ethernet76 76,77 50000 etp20a -Ethernet78 78,79 50000 etp20b -Ethernet80 80,81 50000 etp21a -Ethernet82 82,83 50000 etp21b -Ethernet84 84,85 50000 etp22a -Ethernet86 86,87 50000 etp22b -Ethernet88 88,89,90,91 100000 etp23 -Ethernet92 92,93,94,95 100000 etp24 -Ethernet96 96,97,98,99 100000 etp25 -Ethernet100 100,101,102,103 100000 etp26 -Ethernet104 104,105 50000 etp27a -Ethernet106 106,107 50000 etp27b -Ethernet108 108,109 50000 etp28a -Ethernet110 110,111 50000 etp28b -Ethernet112 112,113 50000 etp29a -Ethernet114 114,115 50000 etp29b -Ethernet116 116,117 50000 etp30a -Ethernet118 118,119 50000 etp30b -Ethernet120 120,121 50000 etp31a -Ethernet122 122,123 50000 etp31b -Ethernet124 124,125 50000 etp32a -Ethernet126 126,127 50000 etp32b +# name lanes speed alias index +Ethernet0 0,1 50000 etp1a 1 +Ethernet2 2,3 50000 etp1b 1 +Ethernet4 4,5 50000 etp2a 2 +Ethernet6 6,7 50000 etp2b 2 +Ethernet8 8,9 50000 etp3a 3 +Ethernet10 10,11 50000 etp3b 3 +Ethernet12 12,13 50000 etp4a 4 +Ethernet14 14,15 50000 etp4b 4 +Ethernet16 16,17 50000 etp5a 5 +Ethernet18 18,19 50000 etp5b 5 +Ethernet20 20,21 50000 etp6a 6 +Ethernet22 22,23 50000 etp6b 6 +Ethernet24 24,25,26,27 100000 etp7 7 +Ethernet28 28,29,30,31 100000 etp8 8 +Ethernet32 32,33,34,35 100000 etp9 9 +Ethernet36 36,37,38,39 100000 etp10 10 +Ethernet40 40,41 50000 etp11a 11 +Ethernet42 42,43 50000 etp11b 11 +Ethernet44 44,45 50000 etp12a 12 +Ethernet46 46,47 50000 etp12b 12 +Ethernet48 48,49 50000 etp13a 13 +Ethernet50 50,51 50000 etp13b 13 +Ethernet52 52,53 50000 etp14a 14 +Ethernet54 54,55 50000 etp14b 14 +Ethernet56 56,57 50000 etp15a 15 +Ethernet58 58,59 50000 etp15b 15 +Ethernet60 60,61 50000 etp16a 16 +Ethernet62 62,63 50000 etp16b 16 +Ethernet64 64,65 50000 etp17a 17 +Ethernet66 66,67 50000 etp17b 17 +Ethernet68 68,69 50000 etp18a 18 +Ethernet70 70,71 50000 etp18b 18 +Ethernet72 72,73 50000 etp19a 19 +Ethernet74 74,75 50000 etp19b 19 +Ethernet76 76,77 50000 etp20a 20 +Ethernet78 78,79 50000 etp20b 20 +Ethernet80 80,81 50000 etp21a 21 +Ethernet82 82,83 50000 etp21b 21 +Ethernet84 84,85 50000 etp22a 22 +Ethernet86 86,87 50000 etp22b 22 +Ethernet88 88,89,90,91 100000 etp23 23 +Ethernet92 92,93,94,95 100000 etp24 24 +Ethernet96 96,97,98,99 100000 etp25 25 +Ethernet100 100,101,102,103 100000 etp26 26 +Ethernet104 104,105 50000 etp27a 27 +Ethernet106 106,107 50000 etp27b 27 +Ethernet108 108,109 50000 etp28a 28 +Ethernet110 110,111 50000 etp28b 28 +Ethernet112 112,113 50000 etp29a 29 +Ethernet114 114,115 50000 etp29b 29 +Ethernet116 116,117 50000 etp30a 30 +Ethernet118 118,119 50000 etp30b 30 +Ethernet120 120,121 50000 etp31a 31 +Ethernet122 122,123 50000 etp31b 31 +Ethernet124 124,125 50000 etp32a 32 +Ethernet126 126,127 50000 etp32b 32 From 5d0748df03b6adfaa70fa68d09fb14cb350cf823 Mon Sep 17 00:00:00 2001 From: Andriy Moroz Date: Tue, 24 Jul 2018 01:51:03 +0300 Subject: [PATCH 160/219] [Mellanox] Use MAC from EEPROM for PortChannels and VLAN Interfaces (#1793) * Use MAC from EEPROM for PortChannels Signed-off-by: Andriy Moroz * Use MAC from EEPROM in DEVICE_METADATA Will affect MAC for VLAN interfaces Signed-off-by: Andriy Moroz * Get MAC via decode-syseeprom Signed-off-by: Andriy Moroz * hw-management is now a service Signed-off-by: Andriy Moroz * Add error handling for MAC fetch process Signed-off-by: Andriy Moroz --- dockers/docker-teamd/start.sh | 7 ++- .../build_templates/sonic_debian_extension.j2 | 2 +- .../updategraph.service.j2} | 4 ++ platform/mellanox/.gitignore | 1 + .../Add-systemd-service-config.patch | 58 +++++++++++++++++++ slave.mk | 2 + src/sonic-config-engine/sonic_platform.py | 13 ++++- 7 files changed, 83 insertions(+), 4 deletions(-) rename files/{image_config/updategraph/updategraph.service => build_templates/updategraph.service.j2} (74%) create mode 100644 platform/mellanox/hw-management/Add-systemd-service-config.patch diff --git a/dockers/docker-teamd/start.sh b/dockers/docker-teamd/start.sh index 6e80f6eb9a83..fb3b7c3dadf8 100755 --- a/dockers/docker-teamd/start.sh +++ b/dockers/docker-teamd/start.sh @@ -6,7 +6,12 @@ rm -rf $TEAMD_CONF_PATH mkdir -p $TEAMD_CONF_PATH SONIC_ASIC_TYPE=$(sonic-cfggen -y /etc/sonic/sonic_version.yml -v asic_type) -MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') + +if [ "$SONIC_ASIC_TYPE" == "mellanox" ]; then + MAC_ADDRESS=$(sonic-cfggen -d -v DEVICE_METADATA.localhost.mac) +else + MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') +fi # Align last byte if [ "$SONIC_ASIC_TYPE" == "mellanox" -o "$SONIC_ASIC_TYPE" == "centec" ]; then diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 7e22aad82fb4..29bfdfcd374a 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -160,7 +160,7 @@ sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable hostname-config.service sudo cp $IMAGE_CONFIGS/hostname/hostname-config.sh $FILESYSTEM_ROOT/usr/bin/ # Copy updategraph script and service file -sudo cp $IMAGE_CONFIGS/updategraph/updategraph.service $FILESYSTEM_ROOT/etc/systemd/system/ +j2 files/build_templates/updategraph.service.j2 | sudo tee $FILESYSTEM_ROOT/etc/systemd/system/updategraph.service sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable updategraph.service sudo cp $IMAGE_CONFIGS/updategraph/updategraph $FILESYSTEM_ROOT/usr/bin/ {% if enable_dhcp_graph_service == "y" %} diff --git a/files/image_config/updategraph/updategraph.service b/files/build_templates/updategraph.service.j2 similarity index 74% rename from files/image_config/updategraph/updategraph.service rename to files/build_templates/updategraph.service.j2 index ec478d93a132..8039f42531cd 100644 --- a/files/image_config/updategraph/updategraph.service +++ b/files/build_templates/updategraph.service.j2 @@ -3,6 +3,10 @@ Description=Update minigraph and set configuration based on minigraph After=rc-local.service After=database.service Requires=database.service +{% if sonic_asic_platform == 'mellanox' -%} +Requires=hw-management.service +{% endif -%} + [Service] Type=oneshot diff --git a/platform/mellanox/.gitignore b/platform/mellanox/.gitignore index 3c0769067437..ac1ce990d56d 100644 --- a/platform/mellanox/.gitignore +++ b/platform/mellanox/.gitignore @@ -3,6 +3,7 @@ mlnx-sai/* !mlnx-sai/Makefile hw-management/* !hw-management/Makefile +!hw-management/*.patch mft/* !mft/Makefile diff --git a/platform/mellanox/hw-management/Add-systemd-service-config.patch b/platform/mellanox/hw-management/Add-systemd-service-config.patch new file mode 100644 index 000000000000..4903f508bce6 --- /dev/null +++ b/platform/mellanox/hw-management/Add-systemd-service-config.patch @@ -0,0 +1,58 @@ +From 22fef644b1150677353ab0559828ea45a982d901 Mon Sep 17 00:00:00 2001 +From: Andriy Moroz +Date: Wed, 11 Jul 2018 16:51:07 +0300 +Subject: [PATCH] Add systemd service config + +Signed-off-by: Andriy Moroz +--- + debian/control | 2 +- + debian/hw-management.service | 10 ++++++++++ + debian/rules | 2 +- + 3 files changed, 12 insertions(+), 2 deletions(-) + create mode 100644 debian/hw-management.service + +diff --git a/debian/control b/debian/control +index 048cd61..7e3a545 100644 +--- a/debian/control ++++ b/debian/control +@@ -1,7 +1,7 @@ + Source: hw-management + Priority: extra + Maintainer: Adir Atias +-Build-Depends: ++Build-Depends: dh-systemd + Standards-Version: + Section: libs + Homepage: http://www.mellanox.com +diff --git a/debian/hw-management.service b/debian/hw-management.service +new file mode 100644 +index 0000000..d18916d +--- /dev/null ++++ b/debian/hw-management.service +@@ -0,0 +1,10 @@ ++[Unit] ++Description=Mellanox Hardware Management ++ ++[Service] ++Type=oneshot ++EnvironmentFile=/host/machine.conf ++ExecStart=/bin/bash -c "/usr/share/sonic/device/$onie_platform/hw-management start" ++ ++[Install] ++WantedBy=multi-user.target +diff --git a/debian/rules b/debian/rules +index fc38817..fba4150 100755 +--- a/debian/rules ++++ b/debian/rules +@@ -8,7 +8,7 @@ K_SRC ?= "/lib/modules/$(KVERSION)/build" + pwd=$(shell pwd) + + %: +- dh $@ ++ dh $@ --with systemd + + override_dh_auto_configure: + +-- +1.9.1 + diff --git a/slave.mk b/slave.mk index 2beb127b0c6f..6490dcb5dbda 100644 --- a/slave.mk +++ b/slave.mk @@ -474,6 +474,8 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ j2 -f env files/initramfs-tools/union-mount.j2 onie-image.conf > files/initramfs-tools/union-mount j2 -f env files/initramfs-tools/arista-convertfs.j2 onie-image.conf > files/initramfs-tools/arista-convertfs + j2 files/build_templates/updategraph.service.j2 > updategraph.service + $(if $($*_DOCKERS), j2 files/build_templates/sonic_debian_extension.j2 > sonic_debian_extension.sh chmod +x sonic_debian_extension.sh, diff --git a/src/sonic-config-engine/sonic_platform.py b/src/sonic-config-engine/sonic_platform.py index 9715b4b3e0e3..9ce9a7cec55b 100644 --- a/src/sonic-config-engine/sonic_platform.py +++ b/src/sonic-config-engine/sonic_platform.py @@ -41,12 +41,21 @@ def get_sonic_version_info(): return data def get_system_mac(): - proc = subprocess.Popen("ip link show eth0 | grep ether | awk '{print $2}'", shell=True, stdout=subprocess.PIPE) + version_info = get_sonic_version_info() + + if (version_info['asic_type'] == 'mellanox'): + get_mac_cmd = "sudo decode-syseeprom -m" + else: + get_mac_cmd = "ip link show eth0 | grep ether | awk '{print $2}'" + + proc = subprocess.Popen(get_mac_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) (mac, err) = proc.communicate() + if err: + return None + mac = mac.strip() # Align last byte of MAC if necessary - version_info = get_sonic_version_info() if version_info and (version_info['asic_type'] == 'mellanox' or version_info['asic_type'] == 'centec'): last_byte = mac[-2:] aligned_last_byte = format(int(int(last_byte, 16) & 0b11000000), '02x') From 4d12746491a00f32742e0642462917294d41de8b Mon Sep 17 00:00:00 2001 From: Andriy Moroz Date: Sat, 11 Aug 2018 01:37:16 +0300 Subject: [PATCH 161/219] [Mellanox] Update hw-management service config (#1914) Signed-off-by: Andriy Moroz --- .../mellanox/hw-management/Add-systemd-service-config.patch | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/mellanox/hw-management/Add-systemd-service-config.patch b/platform/mellanox/hw-management/Add-systemd-service-config.patch index 4903f508bce6..bbaed885dcb3 100644 --- a/platform/mellanox/hw-management/Add-systemd-service-config.patch +++ b/platform/mellanox/hw-management/Add-systemd-service-config.patch @@ -29,7 +29,7 @@ new file mode 100644 index 0000000..d18916d --- /dev/null +++ b/debian/hw-management.service -@@ -0,0 +1,10 @@ +@@ -0,0 +1,11 @@ +[Unit] +Description=Mellanox Hardware Management + @@ -37,6 +37,7 @@ index 0000000..d18916d +Type=oneshot +EnvironmentFile=/host/machine.conf +ExecStart=/bin/bash -c "/usr/share/sonic/device/$onie_platform/hw-management start" ++ExecStop=/bin/bash -c "/usr/share/sonic/device/$onie_platform/hw-management stop" + +[Install] +WantedBy=multi-user.target From 97fe497b846bf39d6b6c571e401788dc72350fd3 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 13 Oct 2018 20:34:16 +0000 Subject: [PATCH 162/219] [submodules]: update sonic-sairedis and sonic-utilities to use mac from syseeprom sonic-sairedis * 82fcc31 2018-07-04 | Use MAC from EEPROM for Interfaces (#329) (origin/201803) [Andriy Moroz] sonic-utilities * c0c9762 2018-06-26 | Optimize platform info fetch (#276) (HEAD, origin/201803) [Andriy Moroz] Signed-off-by: Guohan Lu --- src/sonic-sairedis | 2 +- src/sonic-utilities | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 17fd36e2e115..82fcc31e626b 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 17fd36e2e115af90dea491f71689147fc06f7d30 +Subproject commit 82fcc31e626b4c7a883d0ed4fd568f8b730c0f11 diff --git a/src/sonic-utilities b/src/sonic-utilities index 1e6470ac4013..c0c97623e5b9 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 1e6470ac4013ea057f36cfaa55734d26bfaf7e33 +Subproject commit c0c97623e5b957bb3c162b2c0eec4bf73776d72b From 15ae2a799c97a59e49f402f8838c9ebcb39c4a88 Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Tue, 2 Oct 2018 06:10:12 -0700 Subject: [PATCH 163/219] [devices]: Align flash partition at 1M (#2104) Flashes used for the 7050QX-32 and 7050QX-32S have a fw issue. The best option to solve the problem is to upgrade to a newer firmware. However this can only be done while in memory and take 10 seconds. Adding an upgrade mechanism is possible but would need more consideration as flashing the firmware and reformating the flash will exceed the fast-reboot requirements. A quick mitigation is to align the ext4 partition that we create on these vfat based system on a 4k boundary. Here we chose 1M instead but it's the same. Newer version of sfdisk do this automatically but the one in SONiC today doesn't have this behavior. This workaround will only reduce the pace of the flash health degradation. The only long term fix is to flash the firmware. --- files/initramfs-tools/arista-convertfs.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/initramfs-tools/arista-convertfs.j2 b/files/initramfs-tools/arista-convertfs.j2 index dfd2fc1d7407..85b1bc41331d 100644 --- a/files/initramfs-tools/arista-convertfs.j2 +++ b/files/initramfs-tools/arista-convertfs.j2 @@ -170,7 +170,7 @@ umount "$root_mnt" # Create a new partition table (content in flash_dev will be deleted) err_msg="Error: repartitioning $flash_dev failed" -cmd="echo ';' | sfdisk $flash_dev || (sleep 3; blockdev --rereadpt $flash_dev && fdisk -l $flash_dev | grep -q ${root_dev}.*Linux)" +cmd="echo '2048' | sfdisk $flash_dev || (sleep 3; blockdev --rereadpt $flash_dev && fdisk -l $flash_dev | grep -q ${root_dev}.*Linux)" run_cmd "$cmd" "$err_msg" sleep 5 From aa08555299fa231900939a99ecb639b8ad0609e0 Mon Sep 17 00:00:00 2001 From: paavaanan Date: Tue, 16 Oct 2018 06:44:26 +0530 Subject: [PATCH 164/219] [devices]: Dell Z9100 T0 T1 MMU/QoS fixes (#2126) * Dell Z9100 T0 PFC fixes * Addressed review comments. Fixed QoS, Changed SKU's, and sorted bcm.config * Adressed review comments and modified T0 and T1 profiles --- .../Force10-Z9100-C32/buffers.json.j2 | 2 + .../Force10-Z9100-C32/buffers_defaults_t1.j2 | 47 +++ .../Force10-Z9100-C32/pg_profile_lookup.ini | 17 + .../port_config.ini | 0 .../Force10-Z9100-C32/qos.json | 157 ++++++++ .../Force10-Z9100-C32/sai.profile | 1 + .../th-z9100-32x100G.config.bcm | 232 +++++++++++ .../Force10-Z9100-C8D48/buffers.json.j2 | 2 + .../buffers_defaults_t0.j2 | 61 +++ .../Force10-Z9100-C8D48/pg_profile_lookup.ini | 17 + .../Force10-Z9100-C8D48/port_config.ini | 57 +++ .../Force10-Z9100-C8D48/qos.json | 157 ++++++++ .../Force10-Z9100-C8D48/sai.profile | 1 + .../th-z9100-8x100G-48x50G.config.bcm | 380 ++++++++++++++++++ .../Force10-Z9100/sai.profile | 1 - .../x86_64-dell_z9100_c2538-r0/minigraph.xml | 4 +- .../z9100/scripts/z9100_platform.sh | 5 + 17 files changed, 1138 insertions(+), 3 deletions(-) create mode 100644 device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/buffers.json.j2 create mode 100644 device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/buffers_defaults_t1.j2 create mode 100644 device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/pg_profile_lookup.ini rename device/dell/x86_64-dell_z9100_c2538-r0/{Force10-Z9100 => Force10-Z9100-C32}/port_config.ini (100%) create mode 100644 device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/qos.json create mode 100644 device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/sai.profile create mode 100644 device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/th-z9100-32x100G.config.bcm create mode 100644 device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/buffers.json.j2 create mode 100644 device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/buffers_defaults_t0.j2 create mode 100644 device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/pg_profile_lookup.ini create mode 100644 device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/port_config.ini create mode 100644 device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/qos.json create mode 100644 device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/sai.profile create mode 100644 device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/th-z9100-8x100G-48x50G.config.bcm delete mode 100644 device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100/sai.profile diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/buffers.json.j2 b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/buffers.json.j2 new file mode 100644 index 000000000000..0b1cb2c541b6 --- /dev/null +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/buffers_defaults_t1.j2 b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..5c654ab9e8a1 --- /dev/null +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/buffers_defaults_t1.j2 @@ -0,0 +1,47 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0,32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx*4)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "10443264", + "type": "ingress", + "mode": "dynamic", + "xoff": "4625920" + }, + "egress_lossy_pool": { + "size": "8877440", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "15982720", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "static_th":"3995680" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/pg_profile_lookup.ini b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/pg_profile_lookup.ini new file mode 100644 index 000000000000..aedda37a8878 --- /dev/null +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 1248 2288 35776 -3 2288 + 25000 5m 1248 2288 53248 -3 2288 + 40000 5m 1248 2288 66560 -3 2288 + 50000 5m 1248 2288 90272 -3 2288 + 100000 5m 1248 2288 165568 -3 2288 + 10000 40m 1248 2288 37024 -3 2288 + 25000 40m 1248 2288 53248 -3 2288 + 40000 40m 1248 2288 71552 -3 2288 + 50000 40m 1248 2288 96096 -3 2288 + 100000 40m 1248 2288 177632 -3 2288 + 10000 300m 1248 2288 46176 -3 2288 + 25000 300m 1248 2288 79040 -3 2288 + 40000 300m 1248 2288 108160 -3 2288 + 50000 300m 1248 2288 141856 -3 2288 + 100000 300m 1248 2288 268736 -3 2288 diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100/port_config.ini b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/port_config.ini similarity index 100% rename from device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100/port_config.ini rename to device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/port_config.ini diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/qos.json b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/qos.json new file mode 100644 index 000000000000..deb9f40fc0f4 --- /dev/null +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/qos.json @@ -0,0 +1,157 @@ +{ + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "MAP_PFC_PRIORITY_TO_QUEUE": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"3", + "4":"4", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"5", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "SCHEDULER": { + "scheduler.0" : { + "type":"DWRR", + "weight": "20" + } + }, + "PORT_QOS_MAP": { + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable": "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "wred_red_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"2097152", + "red_min_threshold":"1048576", + "yellow_max_threshold":"2097152", + "yellow_min_threshold":"1048576", + "green_max_threshold":"2097152", + "green_min_threshold":"1048576", + "green_drop_probability":"5", + "yellow_drop_probability":"5", + "red_drop_probability":"5" + } + }, + "QUEUE": { + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3" : { + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|4" : { + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0" : { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|1" : { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|5" : { + "scheduler" : "[SCHEDULER|scheduler.0]" + } + } +} diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/sai.profile b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/sai.profile new file mode 100644 index 000000000000..a690c3ff8b94 --- /dev/null +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-z9100-32x100G.config.bcm diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/th-z9100-32x100G.config.bcm b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/th-z9100-32x100G.config.bcm new file mode 100644 index 000000000000..25aefca2dafa --- /dev/null +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/th-z9100-32x100G.config.bcm @@ -0,0 +1,232 @@ +#TH Z9100 32x100 + +l3_alpm_enable=2 +pfc_deadlock_seq_control=1 +bcm_stat_interval=2000000 +bcm_num_cos=8 +switch_bypass_mode=0 +mmu_lossless=0 +lpm_scaling_enable=0 +lpm_scaling_enable=0 +lpm_ipv6_128b_reserved=0 +ipv6_lpm_128b_enable=1 +l2xmsg_mode=1 +oversubscribe_mode=1 +os=unix + +pbmp_oversubscribe=0x3fd000000ff4000003fc000001fe +pbmp_xport_xe=0x3fd000000ff4000003fc000001fe + +serdes_if_type_xe=14 +serdes_if_type_ce=14 + +#Parity +parity_correction=1 +parity_enable=1 + +#Port configuration +portmap_38=49:100 +portmap_39=53:100 +portmap_40=57:100 +portmap_41=61:100 +portmap_68=65:100 +portmap_69=69:100 +portmap_70=73:100 +portmap_71=77:100 +portmap_35=37:100 +portmap_34=33:100 +portmap_37=45:100 +portmap_36=41:100 +portmap_72=81:100 +portmap_73=85:100 +portmap_74=89:100 +portmap_75=93:100 +portmap_102=97:100 +portmap_103=101:100 +portmap_104=105:100 +portmap_105=109:100 +portmap_6=21:100 +portmap_5=17:100 +portmap_8=29:100 +portmap_7=25:100 +portmap_107=117:100 +portmap_106=113:100 +portmap_109=125:100 +portmap_108=121:100 +portmap_2=5:100 +portmap_1=1:100 +portmap_4=13:100 +portmap_3=9:100 +portmap_66=129:10 +portmap_100=131:10 +portmap_33=132:10 +portmap_67=133:10 +portmap_101=134:10 +portmap_135=135:10 + +xgxs_tx_lane_map_ce0=0x0132 +xgxs_tx_lane_map_ce1=0x2301 +xgxs_tx_lane_map_ce2=0x0123 +xgxs_tx_lane_map_ce3=0x3201 +xgxs_tx_lane_map_ce4=0x3210 +xgxs_tx_lane_map_ce5=0x2301 +xgxs_tx_lane_map_ce6=0x0123 +xgxs_tx_lane_map_ce7=0x1320 +xgxs_tx_lane_map_ce8=0x1032 +xgxs_tx_lane_map_ce9=0x2031 +xgxs_tx_lane_map_ce10=0x1023 +xgxs_tx_lane_map_ce11=0x0132 +xgxs_tx_lane_map_ce12=0x0213 +xgxs_tx_lane_map_ce13=0x1032 +xgxs_tx_lane_map_ce14=0x0132 +xgxs_tx_lane_map_ce15=0x0123 +xgxs_tx_lane_map_ce16=0x0123 +xgxs_tx_lane_map_ce17=0x0123 +xgxs_tx_lane_map_ce18=0x1032 +xgxs_tx_lane_map_ce19=0x0123 +xgxs_tx_lane_map_ce20=0x2301 +xgxs_tx_lane_map_ce21=0x3102 +xgxs_tx_lane_map_ce22=0x1023 +xgxs_tx_lane_map_ce23=0x2130 +xgxs_tx_lane_map_ce24=0x2310 +xgxs_tx_lane_map_ce25=0x2013 +xgxs_tx_lane_map_ce26=0x0132 +xgxs_tx_lane_map_ce27=0x0123 +xgxs_tx_lane_map_ce28=0x0213 +xgxs_tx_lane_map_ce29=0x0123 +xgxs_tx_lane_map_ce30=0x2301 +xgxs_tx_lane_map_ce31=0x0123 + +xgxs_rx_lane_map_ce0=0x1023 +xgxs_rx_lane_map_ce1=0x1302 +xgxs_rx_lane_map_ce2=0x1203 +xgxs_rx_lane_map_ce3=0x1302 +xgxs_rx_lane_map_ce4=0x3201 +xgxs_rx_lane_map_ce5=0x1302 +xgxs_rx_lane_map_ce6=0x1203 +xgxs_rx_lane_map_ce7=0x2301 +xgxs_rx_lane_map_ce8=0x0312 +xgxs_rx_lane_map_ce9=0x1302 +xgxs_rx_lane_map_ce10=0x2103 +xgxs_rx_lane_map_ce11=0x3210 +xgxs_rx_lane_map_ce12=0x2301 +xgxs_rx_lane_map_ce13=0x0213 +xgxs_rx_lane_map_ce14=0x3210 +xgxs_rx_lane_map_ce15=0x3210 +xgxs_rx_lane_map_ce16=0x3201 +xgxs_rx_lane_map_ce17=0x0213 +xgxs_rx_lane_map_ce18=0x3210 +xgxs_rx_lane_map_ce19=0x3210 +xgxs_rx_lane_map_ce20=0x3102 +xgxs_rx_lane_map_ce21=0x2103 +xgxs_rx_lane_map_ce22=0x2301 +xgxs_rx_lane_map_ce23=0x2310 +xgxs_rx_lane_map_ce24=0x3201 +xgxs_rx_lane_map_ce25=0x0123 +xgxs_rx_lane_map_ce26=0x1023 +xgxs_rx_lane_map_ce27=0x0213 +xgxs_rx_lane_map_ce28=0x1203 +xgxs_rx_lane_map_ce29=0x0213 +xgxs_rx_lane_map_ce30=0x3201 +xgxs_rx_lane_map_ce31=0x0213 + +phy_xaui_tx_polarity_flip_ce0=0xe +phy_xaui_tx_polarity_flip_ce1=0x2 +phy_xaui_tx_polarity_flip_ce2=0xa +phy_xaui_tx_polarity_flip_ce3=0xb +phy_xaui_tx_polarity_flip_ce4=0x2 +phy_xaui_tx_polarity_flip_ce5=0x0 +phy_xaui_tx_polarity_flip_ce6=0x0 +phy_xaui_tx_polarity_flip_ce7=0xa +phy_xaui_tx_polarity_flip_ce8=0x0 +phy_xaui_tx_polarity_flip_ce9=0xb +phy_xaui_tx_polarity_flip_ce10=0xe +phy_xaui_tx_polarity_flip_ce11=0x6 +phy_xaui_tx_polarity_flip_ce12=0x6 +phy_xaui_tx_polarity_flip_ce13=0xf +phy_xaui_tx_polarity_flip_ce14=0x5 +phy_xaui_tx_polarity_flip_ce15=0x8 +phy_xaui_tx_polarity_flip_ce16=0xf +phy_xaui_tx_polarity_flip_ce17=0xf +phy_xaui_tx_polarity_flip_ce18=0xf +phy_xaui_tx_polarity_flip_ce19=0xf +phy_xaui_tx_polarity_flip_ce20=0xf +phy_xaui_tx_polarity_flip_ce21=0xf +phy_xaui_tx_polarity_flip_ce22=0xb +phy_xaui_tx_polarity_flip_ce23=0xa +phy_xaui_tx_polarity_flip_ce24=0xf +phy_xaui_tx_polarity_flip_ce25=0x0 +phy_xaui_tx_polarity_flip_ce26=0xb +phy_xaui_tx_polarity_flip_ce27=0x7 +phy_xaui_tx_polarity_flip_ce28=0x8 +phy_xaui_tx_polarity_flip_ce29=0x3 +phy_xaui_tx_polarity_flip_ce30=0xc +phy_xaui_tx_polarity_flip_ce31=0x3 + +phy_xaui_rx_polarity_flip_ce0=0xc +phy_xaui_rx_polarity_flip_ce1=0xd +phy_xaui_rx_polarity_flip_ce2=0x2 +phy_xaui_rx_polarity_flip_ce3=0xf +phy_xaui_rx_polarity_flip_ce4=0xc +phy_xaui_rx_polarity_flip_ce5=0x2 +phy_xaui_rx_polarity_flip_ce6=0x2 +phy_xaui_rx_polarity_flip_ce7=0xd +phy_xaui_rx_polarity_flip_ce8=0xd +phy_xaui_rx_polarity_flip_ce9=0xa +phy_xaui_rx_polarity_flip_ce10=0x7 +phy_xaui_rx_polarity_flip_ce11=0xf +phy_xaui_rx_polarity_flip_ce12=0xf +phy_xaui_rx_polarity_flip_ce13=0xd +phy_xaui_rx_polarity_flip_ce14=0x4 +phy_xaui_rx_polarity_flip_ce15=0xb +phy_xaui_rx_polarity_flip_ce16=0x2 +phy_xaui_rx_polarity_flip_ce17=0xd +phy_xaui_rx_polarity_flip_ce18=0xf +phy_xaui_rx_polarity_flip_ce19=0x0 +phy_xaui_rx_polarity_flip_ce20=0x0 +phy_xaui_rx_polarity_flip_ce21=0x5 +phy_xaui_rx_polarity_flip_ce22=0x0 +phy_xaui_rx_polarity_flip_ce23=0x2 +phy_xaui_rx_polarity_flip_ce24=0xc +phy_xaui_rx_polarity_flip_ce25=0x8 +phy_xaui_rx_polarity_flip_ce26=0x4 +phy_xaui_rx_polarity_flip_ce27=0x7 +phy_xaui_rx_polarity_flip_ce28=0x7 +phy_xaui_rx_polarity_flip_ce29=0x9 +phy_xaui_rx_polarity_flip_ce30=0xc +phy_xaui_rx_polarity_flip_ce31=0x8 + +dport_map_port_38=1 +dport_map_port_39=2 +dport_map_port_40=3 +dport_map_port_41=4 +dport_map_port_68=5 +dport_map_port_69=6 +dport_map_port_70=7 +dport_map_port_71=8 +dport_map_port_35=9 +dport_map_port_34=10 +dport_map_port_37=11 +dport_map_port_36=12 +dport_map_port_72=13 +dport_map_port_73=14 +dport_map_port_74=15 +dport_map_port_75=16 +dport_map_port_102=17 +dport_map_port_103=18 +dport_map_port_104=19 +dport_map_port_105=20 +dport_map_port_6=21 +dport_map_port_5=22 +dport_map_port_8=23 +dport_map_port_7=24 +dport_map_port_107=25 +dport_map_port_106=26 +dport_map_port_109=27 +dport_map_port_108=28 +dport_map_port_2=29 +dport_map_port_1=30 +dport_map_port_4=31 +dport_map_port_3=32 + +mmu_init_config="MSFT-TH-Tier1" diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/buffers.json.j2 b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/buffers.json.j2 new file mode 100644 index 000000000000..1083a6210fc9 --- /dev/null +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't0' %} +{%- include 'buffers_config.j2' %} diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/buffers_defaults_t0.j2 b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..4bd35b354c8a --- /dev/null +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/buffers_defaults_t0.j2 @@ -0,0 +1,61 @@ +{%- set default_cable = '5m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0,6) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(10,26) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(30,32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4 + 2)) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(6,10) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} + {%- for port_idx in range(26,30) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "11213696", + "type": "ingress", + "mode": "dynamic", + "xoff": "3855488" + }, + "egress_lossy_pool": { + "size": "9532224", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "15982720", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "static_th":"3995680" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/pg_profile_lookup.ini b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/pg_profile_lookup.ini new file mode 100644 index 000000000000..aedda37a8878 --- /dev/null +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 1248 2288 35776 -3 2288 + 25000 5m 1248 2288 53248 -3 2288 + 40000 5m 1248 2288 66560 -3 2288 + 50000 5m 1248 2288 90272 -3 2288 + 100000 5m 1248 2288 165568 -3 2288 + 10000 40m 1248 2288 37024 -3 2288 + 25000 40m 1248 2288 53248 -3 2288 + 40000 40m 1248 2288 71552 -3 2288 + 50000 40m 1248 2288 96096 -3 2288 + 100000 40m 1248 2288 177632 -3 2288 + 10000 300m 1248 2288 46176 -3 2288 + 25000 300m 1248 2288 79040 -3 2288 + 40000 300m 1248 2288 108160 -3 2288 + 50000 300m 1248 2288 141856 -3 2288 + 100000 300m 1248 2288 268736 -3 2288 diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/port_config.ini b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/port_config.ini new file mode 100644 index 000000000000..c1a086764854 --- /dev/null +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/port_config.ini @@ -0,0 +1,57 @@ +# name lanes alias index speed +Ethernet0 49,50 fiftyGigE1/1/1 1 50000 +Ethernet2 51,52 fiftyGigE1/1/2 1 50000 +Ethernet4 53,54 fiftyGigE1/2/1 2 50000 +Ethernet6 55,56 fiftyGigE1/2/2 2 50000 +Ethernet8 57,58 fiftyGigE1/3/1 3 50000 +Ethernet10 59,60 fiftyGigE1/3/2 3 50000 +Ethernet12 61,62 fiftyGigE1/4/1 4 50000 +Ethernet14 63,64 fiftyGigE1/4/2 4 50000 +Ethernet16 65,66 fiftyGigE1/5/1 5 50000 +Ethernet18 67,68 fiftyGigE1/5/2 5 50000 +Ethernet20 69,70 fiftyGigE1/6/1 6 50000 +Ethernet22 71,72 fiftyGigE1/6/2 6 50000 +Ethernet24 73,74,75,76 hundredGigE1/7 7 100000 +Ethernet28 77,78,79,80 hundredGigE1/8 8 100000 +Ethernet32 37,38,39,40 hundredGigE1/9 9 100000 +Ethernet36 33,34,35,36 hundredGigE1/10 10 100000 +Ethernet40 45,46 fiftyGigE1/11/1 11 50000 +Ethernet42 47,48 fiftyGigE1/11/2 11 50000 +Ethernet44 41,42 fiftyGigE1/12/1 12 50000 +Ethernet46 43,44 fiftyGigE1/12/2 12 50000 +Ethernet48 81,82 fiftyGigE1/13/1 13 50000 +Ethernet50 83,84 fiftyGigE1/13/2 13 50000 +Ethernet52 85,86 fiftyGigE1/14/1 14 50000 +Ethernet54 87,88 fiftyGigE1/14/2 14 50000 +Ethernet56 89,90 fiftyGigE1/15/1 15 50000 +Ethernet58 91,92 fiftyGigE1/15/2 15 50000 +Ethernet60 93,94 fiftyGigE1/16/1 16 50000 +Ethernet62 95,96 fiftyGigE1/16/2 16 50000 +Ethernet64 97,98 fiftyGigE1/17/1 17 50000 +Ethernet66 99,100 fiftyGigE1/17/2 17 50000 +Ethernet68 101,102 fiftyGigE1/18/1 18 50000 +Ethernet70 103,104 fiftyGigE1/18/2 18 50000 +Ethernet72 105,106 fiftyGigE1/19/1 19 50000 +Ethernet74 107,108 fiftyGigE1/19/2 19 50000 +Ethernet76 109,110 fiftyGigE1/20/1 20 50000 +Ethernet78 111,112 fiftyGigE1/20/2 20 50000 +Ethernet80 21,22 fiftyGigE1/21/1 21 50000 +Ethernet82 23,24 fiftyGigE1/21/2 21 50000 +Ethernet84 17,18 fiftyGigE1/22/1 22 50000 +Ethernet86 19,20 fiftyGigE1/22/2 22 50000 +Ethernet88 29,30 fiftyGigE1/23/1 23 50000 +Ethernet90 31,32 fiftyGigE1/23/2 23 50000 +Ethernet92 25,26 fiftyGigE1/24/1 24 50000 +Ethernet94 27,28 fiftyGigE1/24/2 24 50000 +Ethernet96 117,118 fiftyGigE1/25/1 25 50000 +Ethernet98 119,120 fiftyGigE1/25/2 25 50000 +Ethernet100 113,114 fiftyGigE1/26/1 26 50000 +Ethernet102 115,116 fiftyGigE1/26/2 26 50000 +Ethernet104 125,126,127,128 hundredGigE1/27 27 100000 +Ethernet108 121,122,123,124 hundredGigE1/28 28 100000 +Ethernet112 5,6,7,8 hundredGigE1/29 29 100000 +Ethernet116 1,2,3,4 hundredGigE1/30 30 100000 +Ethernet120 13,14 fiftyGigE1/31/1 31 50000 +Ethernet122 15,16 fiftyGigE1/31/2 31 50000 +Ethernet124 9,10 fiftyGigE1/32/1 32 50000 +Ethernet126 11,12 fiftyGigE1/32/2 32 50000 diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/qos.json b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/qos.json new file mode 100644 index 000000000000..aa4b6606af28 --- /dev/null +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/qos.json @@ -0,0 +1,157 @@ +{ + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "MAP_PFC_PRIORITY_TO_QUEUE": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"3", + "4":"4", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"5", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "SCHEDULER": { + "scheduler.0" : { + "type":"DWRR", + "weight": "20" + } + }, + "PORT_QOS_MAP": { + "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet122,Ethernet124,Ethernet126": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_enable": "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSLESS" : { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "wred_red_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"2097152", + "red_min_threshold":"1048576", + "yellow_max_threshold":"2097152", + "yellow_min_threshold":"1048576", + "green_max_threshold":"2097152", + "green_min_threshold":"1048576", + "green_drop_probability":"5", + "yellow_drop_probability":"5", + "red_drop_probability":"5" + } + }, + "QUEUE": { + "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet122,Ethernet124,Ethernet126|3": { + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet122,Ethernet124,Ethernet126|4": { + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" + }, + "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet122,Ethernet124,Ethernet126|0": { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, + "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet122,Ethernet124,Ethernet126|1": { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, + "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet122,Ethernet124,Ethernet126|5": { + "scheduler" : "[SCHEDULER|scheduler.0]" + } + } +} diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/sai.profile b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/sai.profile new file mode 100644 index 000000000000..182624c19bd4 --- /dev/null +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th-z9100-8x100G-48x50G.config.bcm diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/th-z9100-8x100G-48x50G.config.bcm b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/th-z9100-8x100G-48x50G.config.bcm new file mode 100644 index 000000000000..5dddf7d2a2d4 --- /dev/null +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/th-z9100-8x100G-48x50G.config.bcm @@ -0,0 +1,380 @@ +#TH Z9100 T0 + +l3_alpm_enable=2 +pfc_deadlock_seq_control=1 +bcm_stat_interval=2000000 +bcm_num_cos=8 +switch_bypass_mode=0 +mmu_lossless=0 +lpm_scaling_enable=0 +lpm_scaling_enable=0 +lpm_ipv6_128b_reserved=0 +ipv6_lpm_128b_enable=1 +l2xmsg_mode=1 +oversubscribe_mode=1 +os=unix + +pbmp_oversubscribe=0x3fffffffdffffffff7fffffffdfffffffe +pbmp_xport_xe=0x3fffffffdffffffff7fffffffdfffffffe + +serdes_if_type_xe=14 +serdes_if_type_ce=14 + +#Parity +parity_correction=1 +parity_enable=1 + +#Port configuration +dport_map_port_100.0=130 +dport_map_port_10.0=126 +dport_map_port_1.0=117 +dport_map_port_102.0=65 +dport_map_port_103.0=66 +dport_map_port_106.0=69 +dport_map_port_107.0=70 +dport_map_port_110.0=73 +dport_map_port_111.0=74 +dport_map_port_114.0=77 +dport_map_port_115.0=78 +dport_map_port_118.0=101 +dport_map_port_119.0=102 +dport_map_port_122.0=97 +dport_map_port_123.0=98 +dport_map_port_126.0=109 +dport_map_port_130.0=105 +dport_map_port_13.0=121 +dport_map_port_14.0=122 +dport_map_port_17.0=85 +dport_map_port_18.0=86 +dport_map_port_21.0=81 +dport_map_port_22.0=82 +dport_map_port_25.0=93 +dport_map_port_26.0=94 +dport_map_port_29.0=89 +dport_map_port_30.0=90 +dport_map_port_34.0=37 +dport_map_port_38.0=33 +dport_map_port_42.0=45 +dport_map_port_43.0=46 +dport_map_port_46.0=41 +dport_map_port_47.0=42 +dport_map_port_50.0=1 +dport_map_port_5.0=113 +dport_map_port_51.0=2 +dport_map_port_54.0=5 +dport_map_port_55.0=6 +dport_map_port_58.0=9 +dport_map_port_59.0=10 +dport_map_port_62.0=13 +dport_map_port_63.0=14 +dport_map_port_66.0=129 +dport_map_port_68.0=17 +dport_map_port_69.0=18 +dport_map_port_72.0=21 +dport_map_port_73.0=22 +dport_map_port_76.0=25 +dport_map_port_80.0=29 +dport_map_port_84.0=49 +dport_map_port_85.0=50 +dport_map_port_88.0=53 +dport_map_port_89.0=54 +dport_map_port_9.0=125 +dport_map_port_92.0=57 +dport_map_port_93.0=58 +dport_map_port_96.0=61 +dport_map_port_97.0=62 + +phy_xaui_rx_polarity_flip_100.0=0xf +phy_xaui_rx_polarity_flip_10.0=0x2 +phy_xaui_rx_polarity_flip_1.0=0x9 +phy_xaui_rx_polarity_flip_102.0=0x2 +phy_xaui_rx_polarity_flip_103.0=0x0 +phy_xaui_rx_polarity_flip_106.0=0x1 +phy_xaui_rx_polarity_flip_107.0=0x3 +phy_xaui_rx_polarity_flip_110.0=0x3 +phy_xaui_rx_polarity_flip_111.0=0x3 +phy_xaui_rx_polarity_flip_114.0=0x0 +phy_xaui_rx_polarity_flip_115.0=0x0 +phy_xaui_rx_polarity_flip_118.0=0x0 +phy_xaui_rx_polarity_flip_119.0=0x2 +phy_xaui_rx_polarity_flip_122.0=0x0 +phy_xaui_rx_polarity_flip_123.0=0x3 +phy_xaui_rx_polarity_flip_126.0=0x7 +phy_xaui_rx_polarity_flip_130.0=0x4 +phy_xaui_rx_polarity_flip_13.0=0x0 +phy_xaui_rx_polarity_flip_14.0=0x3 +phy_xaui_rx_polarity_flip_17.0=0x1 +phy_xaui_rx_polarity_flip_18.0=0x1 +phy_xaui_rx_polarity_flip_21.0=0x0 +phy_xaui_rx_polarity_flip_22.0=0x0 +phy_xaui_rx_polarity_flip_25.0=0x2 +phy_xaui_rx_polarity_flip_26.0=0x0 +phy_xaui_rx_polarity_flip_29.0=0x0 +phy_xaui_rx_polarity_flip_30.0=0x0 +phy_xaui_rx_polarity_flip_34.0=0xa +phy_xaui_rx_polarity_flip_38.0=0xd +phy_xaui_rx_polarity_flip_42.0=0x3 +phy_xaui_rx_polarity_flip_43.0=0x3 +phy_xaui_rx_polarity_flip_46.0=0x3 +phy_xaui_rx_polarity_flip_47.0=0x1 +phy_xaui_rx_polarity_flip_50.0=0x0 +phy_xaui_rx_polarity_flip_5.0=0x7 +phy_xaui_rx_polarity_flip_51.0=0x3 +phy_xaui_rx_polarity_flip_54.0=0x1 +phy_xaui_rx_polarity_flip_55.0=0x3 +phy_xaui_rx_polarity_flip_58.0=0x2 +phy_xaui_rx_polarity_flip_59.0=0x0 +phy_xaui_rx_polarity_flip_62.0=0x3 +phy_xaui_rx_polarity_flip_63.0=0x3 +phy_xaui_rx_polarity_flip_66.0=0xf +phy_xaui_rx_polarity_flip_68.0=0x0 +phy_xaui_rx_polarity_flip_69.0=0x3 +phy_xaui_rx_polarity_flip_72.0=0x2 +phy_xaui_rx_polarity_flip_73.0=0x0 +phy_xaui_rx_polarity_flip_76.0=0x2 +phy_xaui_rx_polarity_flip_80.0=0xd +phy_xaui_rx_polarity_flip_84.0=0x3 +phy_xaui_rx_polarity_flip_85.0=0x3 +phy_xaui_rx_polarity_flip_88.0=0x1 +phy_xaui_rx_polarity_flip_89.0=0x3 +phy_xaui_rx_polarity_flip_9.0=0x0 +phy_xaui_rx_polarity_flip_92.0=0x0 +phy_xaui_rx_polarity_flip_93.0=0x1 +phy_xaui_rx_polarity_flip_96.0=0x3 +phy_xaui_rx_polarity_flip_97.0=0x2 + +phy_xaui_tx_polarity_flip_100.0=0x6 +phy_xaui_tx_polarity_flip_10.0=0x0 +phy_xaui_tx_polarity_flip_1.0=0x3 +phy_xaui_tx_polarity_flip_102.0=0x3 +phy_xaui_tx_polarity_flip_103.0=0x3 +phy_xaui_tx_polarity_flip_106.0=0x3 +phy_xaui_tx_polarity_flip_107.0=0x3 +phy_xaui_tx_polarity_flip_110.0=0x3 +phy_xaui_tx_polarity_flip_111.0=0x3 +phy_xaui_tx_polarity_flip_114.0=0x3 +phy_xaui_tx_polarity_flip_115.0=0x3 +phy_xaui_tx_polarity_flip_118.0=0x0 +phy_xaui_tx_polarity_flip_119.0=0x0 +phy_xaui_tx_polarity_flip_122.0=0x3 +phy_xaui_tx_polarity_flip_123.0=0x3 +phy_xaui_tx_polarity_flip_126.0=0x7 +phy_xaui_tx_polarity_flip_130.0=0xb +phy_xaui_tx_polarity_flip_13.0=0x0 +phy_xaui_tx_polarity_flip_14.0=0x3 +phy_xaui_tx_polarity_flip_17.0=0x3 +phy_xaui_tx_polarity_flip_18.0=0x3 +phy_xaui_tx_polarity_flip_21.0=0x3 +phy_xaui_tx_polarity_flip_22.0=0x3 +phy_xaui_tx_polarity_flip_25.0=0x2 +phy_xaui_tx_polarity_flip_26.0=0x2 +phy_xaui_tx_polarity_flip_29.0=0x3 +phy_xaui_tx_polarity_flip_30.0=0x2 +phy_xaui_tx_polarity_flip_34.0=0xb +phy_xaui_tx_polarity_flip_38.0=0x0 +phy_xaui_tx_polarity_flip_42.0=0x2 +phy_xaui_tx_polarity_flip_43.0=0x1 +phy_xaui_tx_polarity_flip_46.0=0x2 +phy_xaui_tx_polarity_flip_47.0=0x3 +phy_xaui_tx_polarity_flip_50.0=0x2 +phy_xaui_tx_polarity_flip_5.0=0x8 +phy_xaui_tx_polarity_flip_51.0=0x3 +phy_xaui_tx_polarity_flip_54.0=0x2 +phy_xaui_tx_polarity_flip_55.0=0x0 +phy_xaui_tx_polarity_flip_58.0=0x2 +phy_xaui_tx_polarity_flip_59.0=0x2 +phy_xaui_tx_polarity_flip_62.0=0x3 +phy_xaui_tx_polarity_flip_63.0=0x2 +phy_xaui_tx_polarity_flip_66.0=0x6 +phy_xaui_tx_polarity_flip_68.0=0x2 +phy_xaui_tx_polarity_flip_69.0=0x0 +phy_xaui_tx_polarity_flip_72.0=0x0 +phy_xaui_tx_polarity_flip_73.0=0x0 +phy_xaui_tx_polarity_flip_76.0=0x0 +phy_xaui_tx_polarity_flip_80.0=0xa +phy_xaui_tx_polarity_flip_84.0=0x2 +phy_xaui_tx_polarity_flip_85.0=0x1 +phy_xaui_tx_polarity_flip_88.0=0x3 +phy_xaui_tx_polarity_flip_89.0=0x3 +phy_xaui_tx_polarity_flip_9.0=0x3 +phy_xaui_tx_polarity_flip_92.0=0x1 +phy_xaui_tx_polarity_flip_93.0=0x1 +phy_xaui_tx_polarity_flip_96.0=0x0 +phy_xaui_tx_polarity_flip_97.0=0x2 + +portmap_100.0=131:10 +portmap_10.0=11:50:2 +portmap_1.0=1:100 +portmap_102.0=97:50:2 +portmap_103.0=99:50:2 +portmap_106.0=101:50:2 +portmap_107.0=103:50:2 +portmap_110.0=105:50:2 +portmap_111.0=107:50:2 +portmap_114.0=109:50:2 +portmap_115.0=111:50:2 +portmap_118.0=113:50:2 +portmap_119.0=115:50:2 +portmap_122.0=117:50:2 +portmap_123.0=119:50:2 +portmap_126.0=121:100 +portmap_130.0=125:100 +portmap_13.0=13:50:2 +portmap_14.0=15:50:2 +portmap_17.0=17:50:2 +portmap_18.0=19:50:2 +portmap_21.0=21:50:2 +portmap_22.0=23:50:2 +portmap_25.0=25:50:2 +portmap_26.0=27:50:2 +portmap_29.0=29:50:2 +portmap_30.0=31:50:2 +portmap_34.0=33:100 +portmap_38.0=37:100 +portmap_42.0=41:50:2 +portmap_43.0=43:50:2 +portmap_46.0=45:50:2 +portmap_47.0=47:50:2 +portmap_50.0=49:50:2 +portmap_5.0=5:100 +portmap_51.0=51:50:2 +portmap_54.0=53:50:2 +portmap_55.0=55:50:2 +portmap_58.0=57:50:2 +portmap_59.0=59:50:2 +portmap_62.0=61:50:2 +portmap_63.0=63:50:2 +portmap_66.0=129:10 +portmap_68.0=65:50:2 +portmap_69.0=67:50:2 +portmap_72.0=69:50:2 +portmap_73.0=71:50:2 +portmap_76.0=73:100 +portmap_80.0=77:100 +portmap_84.0=81:50:2 +portmap_85.0=83:50:2 +portmap_88.0=85:50:2 +portmap_89.0=87:50:2 +portmap_9.0=9:50:2 +portmap_92.0=89:50:2 +portmap_93.0=91:50:2 +portmap_96.0=93:50:2 +portmap_97.0=95:50:2 + +xgxs_rx_lane_map_100.0=0x3210 +xgxs_rx_lane_map_10.0=0x213 +xgxs_rx_lane_map_1.0=0x213 +xgxs_rx_lane_map_102.0=0x3201 +xgxs_rx_lane_map_103.0=0x3201 +xgxs_rx_lane_map_106.0=0x213 +xgxs_rx_lane_map_107.0=0x213 +xgxs_rx_lane_map_110.0=0x3210 +xgxs_rx_lane_map_111.0=0x3210 +xgxs_rx_lane_map_114.0=0x3210 +xgxs_rx_lane_map_115.0=0x3210 +xgxs_rx_lane_map_118.0=0x123 +xgxs_rx_lane_map_119.0=0x123 +xgxs_rx_lane_map_122.0=0x3201 +xgxs_rx_lane_map_123.0=0x3201 +xgxs_rx_lane_map_126.0=0x213 +xgxs_rx_lane_map_130.0=0x1023 +xgxs_rx_lane_map_13.0=0x3201 +xgxs_rx_lane_map_14.0=0x3201 +xgxs_rx_lane_map_17.0=0x2103 +xgxs_rx_lane_map_18.0=0x2103 +xgxs_rx_lane_map_21.0=0x3102 +xgxs_rx_lane_map_22.0=0x3102 +xgxs_rx_lane_map_25.0=0x2310 +xgxs_rx_lane_map_26.0=0x2310 +xgxs_rx_lane_map_29.0=0x2301 +xgxs_rx_lane_map_30.0=0x2301 +xgxs_rx_lane_map_34.0=0x1302 +xgxs_rx_lane_map_38.0=0x312 +xgxs_rx_lane_map_42.0=0x3210 +xgxs_rx_lane_map_43.0=0x3210 +xgxs_rx_lane_map_46.0=0x2103 +xgxs_rx_lane_map_47.0=0x2103 +xgxs_rx_lane_map_50.0=0x1023 +xgxs_rx_lane_map_5.0=0x1203 +xgxs_rx_lane_map_51.0=0x1023 +xgxs_rx_lane_map_54.0=0x1302 +xgxs_rx_lane_map_55.0=0x1302 +xgxs_rx_lane_map_58.0=0x1203 +xgxs_rx_lane_map_59.0=0x1203 +xgxs_rx_lane_map_62.0=0x1302 +xgxs_rx_lane_map_63.0=0x1302 +xgxs_rx_lane_map_66.0=0x3210 +xgxs_rx_lane_map_68.0=0x3201 +xgxs_rx_lane_map_69.0=0x3201 +xgxs_rx_lane_map_72.0=0x1302 +xgxs_rx_lane_map_73.0=0x1302 +xgxs_rx_lane_map_76.0=0x1203 +xgxs_rx_lane_map_80.0=0x2301 +xgxs_rx_lane_map_84.0=0x2301 +xgxs_rx_lane_map_85.0=0x2301 +xgxs_rx_lane_map_88.0=0x213 +xgxs_rx_lane_map_89.0=0x213 +xgxs_rx_lane_map_9.0=0x213 +xgxs_rx_lane_map_92.0=0x3210 +xgxs_rx_lane_map_93.0=0x3210 +xgxs_rx_lane_map_96.0=0x3210 +xgxs_rx_lane_map_97.0=0x3210 +xgxs_tx_lane_map_100.0=0x132 +xgxs_tx_lane_map_10.0=0x123 +xgxs_tx_lane_map_1.0=0x123 +xgxs_tx_lane_map_102.0=0x123 +xgxs_tx_lane_map_103.0=0x123 +xgxs_tx_lane_map_106.0=0x123 +xgxs_tx_lane_map_107.0=0x123 +xgxs_tx_lane_map_110.0=0x132 +xgxs_tx_lane_map_111.0=0x132 +xgxs_tx_lane_map_114.0=0x123 +xgxs_tx_lane_map_115.0=0x123 +xgxs_tx_lane_map_118.0=0x2013 +xgxs_tx_lane_map_119.0=0x2013 +xgxs_tx_lane_map_122.0=0x2310 +xgxs_tx_lane_map_123.0=0x2310 +xgxs_tx_lane_map_126.0=0x123 +xgxs_tx_lane_map_130.0=0x132 +xgxs_tx_lane_map_13.0=0x2301 +xgxs_tx_lane_map_14.0=0x2301 +xgxs_tx_lane_map_17.0=0x3102 +xgxs_tx_lane_map_18.0=0x3102 +xgxs_tx_lane_map_21.0=0x132 +xgxs_tx_lane_map_22.0=0x132 +xgxs_tx_lane_map_25.0=0x2130 +xgxs_tx_lane_map_26.0=0x2130 +xgxs_tx_lane_map_29.0=0x1023 +xgxs_tx_lane_map_30.0=0x1023 +xgxs_tx_lane_map_34.0=0x2031 +xgxs_tx_lane_map_38.0=0x1032 +xgxs_tx_lane_map_42.0=0x132 +xgxs_tx_lane_map_43.0=0x132 +xgxs_tx_lane_map_46.0=0x1023 +xgxs_tx_lane_map_47.0=0x1023 +xgxs_tx_lane_map_50.0=0x132 +xgxs_tx_lane_map_5.0=0x213 +xgxs_tx_lane_map_51.0=0x132 +xgxs_tx_lane_map_54.0=0x2301 +xgxs_tx_lane_map_55.0=0x2301 +xgxs_tx_lane_map_58.0=0x123 +xgxs_tx_lane_map_59.0=0x123 +xgxs_tx_lane_map_62.0=0x3201 +xgxs_tx_lane_map_63.0=0x3201 +xgxs_tx_lane_map_66.0=0x132 +xgxs_tx_lane_map_68.0=0x3210 +xgxs_tx_lane_map_69.0=0x3210 +xgxs_tx_lane_map_72.0=0x2301 +xgxs_tx_lane_map_73.0=0x2301 +xgxs_tx_lane_map_76.0=0x123 +xgxs_tx_lane_map_80.0=0x1320 +xgxs_tx_lane_map_84.0=0x213 +xgxs_tx_lane_map_85.0=0x213 +xgxs_tx_lane_map_88.0=0x1032 +xgxs_tx_lane_map_89.0=0x1032 +xgxs_tx_lane_map_9.0=0x123 +xgxs_tx_lane_map_92.0=0x132 +xgxs_tx_lane_map_93.0=0x132 +xgxs_tx_lane_map_96.0=0x123 +xgxs_tx_lane_map_97.0=0x123 +mmu_init_config="MSFT-TH-Tier0" diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100/sai.profile b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100/sai.profile deleted file mode 100644 index 2c9a6e54c1ac..000000000000 --- a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100/sai.profile +++ /dev/null @@ -1 +0,0 @@ -SAI_INIT_CONFIG_FILE=/etc/bcm/th-z9100-32x100G.config.bcm diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/minigraph.xml b/device/dell/x86_64-dell_z9100_c2538-r0/minigraph.xml index e1d42d180fe0..3632224e48f8 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/minigraph.xml +++ b/device/dell/x86_64-dell_z9100_c2538-r0/minigraph.xml @@ -1040,7 +1040,7 @@ sonic - Force10-Z9100 + Force10-Z9100-C32
@@ -1075,5 +1075,5 @@ sonic - Force10-Z9100 + Force10-Z9100-C32
diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh index 6b62144eedac..0fa2afc2bc92 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh @@ -151,6 +151,11 @@ if [[ "$1" == "init" ]]; then switch_board_qsfp_mux "new_device" switch_board_sfp "new_device" switch_board_qsfp "new_device" + value=0x0 + echo $value > /sys/class/i2c-adapter/i2c-14/14-003e/qsfp_lpmode + echo $value > /sys/class/i2c-adapter/i2c-15/15-003e/qsfp_lpmode + echo $value > /sys/class/i2c-adapter/i2c-16/16-003e/qsfp_lpmode + elif [[ "$1" == "deinit" ]]; then switch_board_sfp "delete_device" switch_board_cpld "delete_device" From 6a9bfafb10c91e9ba1a770755ceba9c8e6c78163 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Fri, 29 Jun 2018 08:37:20 -0700 Subject: [PATCH 165/219] [syncd] Treat bcmcmd as a supervisor task so we could collect stdout/stderr (#1825) --- platform/broadcom/docker-syncd-brcm/start.sh | 3 ++- platform/broadcom/docker-syncd-brcm/supervisord.conf | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/platform/broadcom/docker-syncd-brcm/start.sh b/platform/broadcom/docker-syncd-brcm/start.sh index fe08e1bfa1ff..5f5dd0678c7c 100755 --- a/platform/broadcom/docker-syncd-brcm/start.sh +++ b/platform/broadcom/docker-syncd-brcm/start.sh @@ -18,6 +18,7 @@ else fi fi +rm -f /var/run/sswsyncd/sswsyncd.socket supervisorctl start syncd # Function: wait until syncd has created the socket for bcmcmd to connect to @@ -36,5 +37,5 @@ wait_syncd() { # If this platform has an initialization file for the Broadcom LED microprocessor, load it if [ -r ${PLATFORM_DIR}/led_proc_init.soc ]; then wait_syncd - /usr/bin/bcmcmd -t 60 "rcload ${PLATFORM_DIR}/led_proc_init.soc" + supervisorctl start ledinit fi diff --git a/platform/broadcom/docker-syncd-brcm/supervisord.conf b/platform/broadcom/docker-syncd-brcm/supervisord.conf index 1af5d70a1d0c..fe590ede18c5 100644 --- a/platform/broadcom/docker-syncd-brcm/supervisord.conf +++ b/platform/broadcom/docker-syncd-brcm/supervisord.conf @@ -26,3 +26,11 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog + +[program:ledinit] +command=/usr/bin/bcmcmd -t 60 "rcload /usr/share/sonic/platform/led_proc_init.soc" +priority=4 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog From 969ba5b2a7c9a70e2a73483e711a9ff2ee35cde6 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Wed, 17 Oct 2018 19:32:27 -0700 Subject: [PATCH 166/219] [lldpd]: Use kernel autoprobe for netlink socket .nl_pid portion of the address (#2164) --- ...el-to-find-appropriate-nl_pid-automa.patch | 25 +++++++++++++++++++ src/lldpd/patch/series | 1 + 2 files changed, 26 insertions(+) create mode 100644 src/lldpd/patch/0002-Let-linux-kernel-to-find-appropriate-nl_pid-automa.patch diff --git a/src/lldpd/patch/0002-Let-linux-kernel-to-find-appropriate-nl_pid-automa.patch b/src/lldpd/patch/0002-Let-linux-kernel-to-find-appropriate-nl_pid-automa.patch new file mode 100644 index 000000000000..801fdd8ec96e --- /dev/null +++ b/src/lldpd/patch/0002-Let-linux-kernel-to-find-appropriate-nl_pid-automa.patch @@ -0,0 +1,25 @@ +From 2ee8585e8b716719a11235ab5c291b2f6ac9ce1a Mon Sep 17 00:00:00 2001 +From: Pavel Shirshov +Date: Wed, 17 Oct 2018 21:05:58 +0000 +Subject: [PATCH] Let linux kernel to find appropriate nl_pid automatically + +--- + src/daemon/netlink.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/daemon/netlink.c b/src/daemon/netlink.c +index 1a64a23..f4227b8 100644 +--- a/src/daemon/netlink.c ++++ b/src/daemon/netlink.c +@@ -93,7 +93,7 @@ netlink_connect(struct lldpd *cfg, int protocol, unsigned groups) + int s; + struct sockaddr_nl local = { + .nl_family = AF_NETLINK, +- .nl_pid = getpid(), ++ .nl_pid = 0, + .nl_groups = groups + }; + +-- +2.7.4 + diff --git a/src/lldpd/patch/series b/src/lldpd/patch/series index 8aa5ab8d8f3f..2ca46b575396 100644 --- a/src/lldpd/patch/series +++ b/src/lldpd/patch/series @@ -1,2 +1,3 @@ # This series applies on GIT commit 396961a038a38675d46f96eaa7b430b2a1f8701b 0001-return-error-when-port-does-not-exist.patch +0002-Let-linux-kernel-to-find-appropriate-nl_pid-automa.patch From 2aac4c482248e3066d68337b101c8b5f26bc799f Mon Sep 17 00:00:00 2001 From: Taoyu Li Date: Thu, 18 Oct 2018 12:42:24 -0700 Subject: [PATCH 167/219] [tacplus nss conf] tacplus should be before compat (#2163) --- files/image_config/hostcfgd/hostcfgd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index 8c03f2234a94..f156f7e9402c 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -127,10 +127,10 @@ class AaaCfg(object): # Add tacplus in nsswitch.conf if TACACS+ enable if 'tacacs+' in auth['login']: if os.path.isfile(NSS_CONF): - os.system("sed -i -e '/tacplus/b' -e '/^passwd/s/compat/& tacplus/' /etc/nsswitch.conf") + os.system("sed -i -e '/tacplus/b' -e '/^passwd/s/compat/tacplus &/' /etc/nsswitch.conf") else: if os.path.isfile(NSS_CONF): - os.system("sed -i -e '/^passwd/s/ tacplus//' /etc/nsswitch.conf") + os.system("sed -i -e '/^passwd/s/tacplus //' /etc/nsswitch.conf") # Set tacacs+ server in nss-tacplus conf template_file = os.path.abspath(NSS_TACPLUS_CONF_TEMPLATE) From e2d565ae03ced4345fb2fe3dd2bf0ce40d746bcb Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Thu, 18 Oct 2018 15:22:26 -0700 Subject: [PATCH 168/219] [teamd] Force team device recreation in case it already exists (#2168) * Force team device recreation in case it already exists --- dockers/docker-teamd/teamd.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockers/docker-teamd/teamd.sh b/dockers/docker-teamd/teamd.sh index 2b6d9fb53970..1c080d24bb27 100755 --- a/dockers/docker-teamd/teamd.sh +++ b/dockers/docker-teamd/teamd.sh @@ -6,7 +6,7 @@ function start_app { rm -f /var/run/teamd/* if [ "$(ls -A $TEAMD_CONF_PATH)" ]; then for f in $TEAMD_CONF_PATH/*; do - teamd -f $f -d + teamd -f $f -d -r done fi teamsyncd & From ce54ef72569a6263da5f3410640d4b5c21d827c7 Mon Sep 17 00:00:00 2001 From: Andriy Moroz Date: Tue, 30 Oct 2018 10:49:36 +0200 Subject: [PATCH 169/219] [mellanox]: Update MFT tools to v4.9.0 (#2207) Signed-off-by: Andriy Moroz --- platform/mellanox/mft.mk | 4 ++-- platform/mellanox/mft/Makefile | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/platform/mellanox/mft.mk b/platform/mellanox/mft.mk index 2fb3af338d75..69b7eb79470f 100644 --- a/platform/mellanox/mft.mk +++ b/platform/mellanox/mft.mk @@ -1,9 +1,9 @@ # Mellanox SAI -MFT = mft-4.5.0-31.amd64.deb +MFT = mft-4.9.0-38.amd64.deb $(MFT)_SRC_PATH = $(PLATFORM_PATH)/mft $(MFT)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) SONIC_MAKE_DEBS += $(MFT) -KERNEL_MFT = kernel-mft-dkms_4.5.0-$(KVERSION)_all.deb +KERNEL_MFT = kernel-mft-dkms_4.9.0-$(KVERSION)_all.deb $(eval $(call add_derived_package,$(MFT),$(KERNEL_MFT))) diff --git a/platform/mellanox/mft/Makefile b/platform/mellanox/mft/Makefile index eea78cd76031..fc222d602128 100644 --- a/platform/mellanox/mft/Makefile +++ b/platform/mellanox/mft/Makefile @@ -1,12 +1,12 @@ .ONESHELL: SHELL = /bin/bash -MFT_NAME = mft-4.5.0-31-x86_64-deb +MFT_NAME = mft-4.9.0-38-x86_64-deb MFT_TGZ = $(MFT_NAME).tgz -SRC_DEB = kernel-mft-dkms_4.5.0-31_all.deb +SRC_DEB = kernel-mft-dkms_4.9.0-38_all.deb -MAIN_TARGET = mft-4.5.0-31.amd64.deb -DERIVED_TARGETS = kernel-mft-dkms_4.5.0-$(KVERSION)_all.deb +MAIN_TARGET = mft-4.9.0-38.amd64.deb +DERIVED_TARGETS = kernel-mft-dkms_4.9.0-$(KVERSION)_all.deb $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : rm -rf $(MFT_NAME) @@ -21,7 +21,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : fi done - tar xvf `sudo dkms mkdriverdisk kernel-mft-dkms/4.5.0 -a all -d ubuntu -k $(KVERSION) --media tar | grep "Disk image location" | cut -d':' -f2` + tar xvf `sudo dkms mkdriverdisk kernel-mft-dkms/4.9.0 -a all -d ubuntu -k $(KVERSION) --media tar | grep "Disk image location" | cut -d':' -f2` popd # fix timestamp because we do not actually build tools, only kernel From f089d1497013df4d5a4fda8bddc056eec1d02e4e Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Thu, 1 Nov 2018 15:11:27 -0700 Subject: [PATCH 170/219] [console speed] lock console speed to start up speed (#2222) Auto negotiating console speed could cause sonic to lock on a wrong speed under rare conditions. The only way to come out of the wrong speed is to issue line break or restart console service with forced speed, or reboot sonic. Lock down the console speed to avoid these situations. Signed-off-by: Ying Xie --- files/image_config/platform/rc.local | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/files/image_config/platform/rc.local b/files/image_config/platform/rc.local index de54d141ef7e..89ccb4bd54be 100755 --- a/files/image_config/platform/rc.local +++ b/files/image_config/platform/rc.local @@ -85,6 +85,19 @@ update_mgmt_interface_macaddr() { sed -i "/eth0/ s/ATTR{address}==\"$old_mac\"/ATTR{address}==\"$new_mac\"/g" /etc/udev/rules.d/70-persistent-net.rules } +program_console_speed() +{ + speed=$(cat /proc/cmdline | grep -Eo 'console=ttyS[0-9]+,[0-9]+' | cut -d "," -f2) + if [ -z "$speed" ]; then + CONSOLE_SPEED=9600 + else + CONSOLE_SPEED=$speed + fi + + sed -i "s|\-\-keep\-baud .* %I| $CONSOLE_SPEED %I|g" /lib/systemd/system/serial-getty@.service + systemctl daemon-reload +} + # If the machine.conf is absent, it indicates that the unit booted # into SONiC from another NOS. Extract the machine.conf from ONIE. if [ ! -e /host/machine.conf ]; then @@ -185,6 +198,8 @@ done eval sonic_version=$(cat /etc/sonic/sonic_version.yml | grep build_version | cut -f2 -d" ") +program_console_speed + if [ -f /host/image-$sonic_version/platform/firsttime ]; then if [ -n "$aboot_platform" ]; then From e7105273828ddd294c37d5e305024e7e19442874 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Fri, 13 Jul 2018 10:27:47 -0700 Subject: [PATCH 171/219] [caclmgrd] Add a rule to allow all connections from localhost (#1858) --- files/image_config/caclmgrd/caclmgrd | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index 0dc59766b3d5..6ddd6de007c8 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -121,6 +121,10 @@ class ControlPlaneAclManager(object): iptables_cmds.append("ip6tables -F") iptables_cmds.append("ip6tables -X") + # Add iptables commands to allow all IPv4 and IPv6 traffic from localhost + iptables_cmds.append("iptables -A INPUT -s 127.0.0.1 -i lo -j ACCEPT") + iptables_cmds.append("ip6tables -A INPUT -s ::1 -i lo -j ACCEPT") + # Get current ACL tables and rules from Config DB self._tables_db_info = self.config_db.get_table(self.ACL_TABLE) self._rules_db_info = self.config_db.get_table(self.ACL_RULE) From bef80b3fc3203b4dab7e8d0733ac732adc9a74b8 Mon Sep 17 00:00:00 2001 From: Pradchaya P Date: Fri, 17 Aug 2018 00:38:33 +0700 Subject: [PATCH 172/219] [device/dx010] configuration port index start from 1 (#1927) * update sfputil, port indext start from 1 * DX010 update SKUs port config index Port index in port_config.ini now start from 1. * Seastone-DX010-10-50 port config update * Seastone-DX010-50 port config update * Seastone-DX010 port config update * Update dx010 sfputil plugin * Implement lpmode set function. * Implement transceiver reset function. * Python code style format. * Remove new line at the end of port_config.ini *New line cause parsing error in sfputilbase. * Add get_transceiver_change_event method *This needed by new sfputilbase implement. * Fix unintended line breaks --- .../Seastone-DX010-10-50/port_config.ini | 226 +++++++++--------- .../Seastone-DX010-50/port_config.ini | 130 +++++----- .../Seastone-DX010/port_config.ini | 66 ++--- .../x86_64-cel_seastone-r0/plugins/sfputil.py | 120 +++++++++- 4 files changed, 322 insertions(+), 220 deletions(-) mode change 100755 => 100644 device/celestica/x86_64-cel_seastone-r0/plugins/sfputil.py diff --git a/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-10-50/port_config.ini b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-10-50/port_config.ini index 16b89088aab8..c88ae8c298f1 100644 --- a/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-10-50/port_config.ini +++ b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-10-50/port_config.ini @@ -1,113 +1,113 @@ -# name lanes alias -Ethernet0 65 Eth1/1 -Ethernet1 66 Eth1/2 -Ethernet2 67 Eth1/3 -Ethernet3 68 Eth1/4 -Ethernet4 69 Eth2/1 -Ethernet5 70 Eth2/2 -Ethernet6 71 Eth2/3 -Ethernet7 72 Eth2/4 -Ethernet8 73 Eth3/1 -Ethernet9 74 Eth3/2 -Ethernet10 75 Eth3/3 -Ethernet11 76 Eth3/4 -Ethernet12 77 Eth4/1 -Ethernet13 78 Eth4/2 -Ethernet14 79 Eth4/3 -Ethernet15 80 Eth4/4 -Ethernet16 33 Eth5/1 -Ethernet17 34 Eth5/2 -Ethernet18 35 Eth5/3 -Ethernet19 36 Eth5/4 -Ethernet20 37 Eth6/1 -Ethernet21 38 Eth6/2 -Ethernet22 39 Eth6/3 -Ethernet23 40 Eth6/4 -Ethernet24 41 Eth7/1 -Ethernet25 42 Eth7/2 -Ethernet26 43 Eth7/3 -Ethernet27 44 Eth7/4 -Ethernet28 45 Eth8/1 -Ethernet29 46 Eth8/2 -Ethernet30 47 Eth8/3 -Ethernet31 48 Eth8/4 -Ethernet32 49 Eth9/1 -Ethernet33 50 Eth9/2 -Ethernet34 51 Eth9/3 -Ethernet35 52 Eth9/4 -Ethernet36 53 Eth10/1 -Ethernet37 54 Eth10/2 -Ethernet38 55 Eth10/3 -Ethernet39 56 Eth10/4 -Ethernet40 57 Eth11/1 -Ethernet41 58 Eth11/2 -Ethernet42 59 Eth11/3 -Ethernet43 60 Eth11/4 -Ethernet44 61 Eth12/1 -Ethernet45 62 Eth12/2 -Ethernet46 63 Eth12/3 -Ethernet47 64 Eth12/4 -Ethernet48 81 Eth13/1 -Ethernet49 82 Eth13/2 -Ethernet50 83 Eth13/3 -Ethernet51 84 Eth13/4 -Ethernet52 85 Eth14/1 -Ethernet53 86 Eth14/2 -Ethernet54 87 Eth14/3 -Ethernet55 88 Eth14/4 -Ethernet56 89 Eth15/1 -Ethernet57 90 Eth15/2 -Ethernet58 91 Eth15/3 -Ethernet59 92 Eth15/4 -Ethernet60 93 Eth16/1 -Ethernet61 94 Eth16/2 -Ethernet62 95 Eth16/3 -Ethernet63 96 Eth16/4 -Ethernet64 97 Eth17/1 -Ethernet65 98 Eth17/2 -Ethernet66 99 Eth17/3 -Ethernet67 100 Eth17/4 -Ethernet68 101 Eth18/1 -Ethernet69 102 Eth18/2 -Ethernet70 103 Eth18/3 -Ethernet71 104 Eth18/4 -Ethernet72 105 Eth19/1 -Ethernet73 106 Eth19/2 -Ethernet74 107 Eth19/3 -Ethernet75 108 Eth19/4 -Ethernet76 109 Eth20/1 -Ethernet77 110 Eth20/2 -Ethernet78 111 Eth20/3 -Ethernet79 112 Eth20/4 -Ethernet80 1 Eth21/1 -Ethernet81 2 Eth21/2 -Ethernet82 3 Eth21/3 -Ethernet83 4 Eth21/4 -Ethernet84 5 Eth22/1 -Ethernet85 6 Eth22/2 -Ethernet86 7 Eth22/3 -Ethernet87 8 Eth22/4 -Ethernet88 9 Eth23/1 -Ethernet89 10 Eth23/2 -Ethernet90 11 Eth23/3 -Ethernet91 12 Eth23/4 -Ethernet92 13 Eth24/1 -Ethernet93 14 Eth24/2 -Ethernet94 15 Eth24/3 -Ethernet95 16 Eth24/4 -Ethernet96 17,18 Eth25/1 -Ethernet98 19,20 Eth25/2 -Ethernet100 21,22 Eth26/1 -Ethernet102 23,24 Eth26/2 -Ethernet104 25,26 Eth27/1 -Ethernet106 27,28 Eth27/2 -Ethernet108 29,30 Eth28/1 -Ethernet110 31,32 Eth28/2 -Ethernet112 113,114 Eth29/1 -Ethernet114 115,116 Eth29/2 -Ethernet116 117,118 Eth30/1 -Ethernet118 119,120 Eth30/2 -Ethernet120 121,122 Eth31/1 -Ethernet122 123,124 Eth31/2 -Ethernet124 125,126 Eth32/1 -Ethernet126 127,128 Eth32/2 +# name lanes alias index speed +Ethernet0 65 Eth1/1 1 10000 +Ethernet1 66 Eth1/2 1 10000 +Ethernet2 67 Eth1/3 1 10000 +Ethernet3 68 Eth1/4 1 10000 +Ethernet4 69 Eth2/1 2 10000 +Ethernet5 70 Eth2/2 2 10000 +Ethernet6 71 Eth2/3 2 10000 +Ethernet7 72 Eth2/4 2 10000 +Ethernet8 73 Eth3/1 3 10000 +Ethernet9 74 Eth3/2 3 10000 +Ethernet10 75 Eth3/3 3 10000 +Ethernet11 76 Eth3/4 3 10000 +Ethernet12 77 Eth4/1 4 10000 +Ethernet13 78 Eth4/2 4 10000 +Ethernet14 79 Eth4/3 4 10000 +Ethernet15 80 Eth4/4 4 10000 +Ethernet16 33 Eth5/1 5 10000 +Ethernet17 34 Eth5/2 5 10000 +Ethernet18 35 Eth5/3 5 10000 +Ethernet19 36 Eth5/4 5 10000 +Ethernet20 37 Eth6/1 6 10000 +Ethernet21 38 Eth6/2 6 10000 +Ethernet22 39 Eth6/3 6 10000 +Ethernet23 40 Eth6/4 6 10000 +Ethernet24 41 Eth7/1 7 10000 +Ethernet25 42 Eth7/2 7 10000 +Ethernet26 43 Eth7/3 7 10000 +Ethernet27 44 Eth7/4 7 10000 +Ethernet28 45 Eth8/1 8 10000 +Ethernet29 46 Eth8/2 8 10000 +Ethernet30 47 Eth8/3 8 10000 +Ethernet31 48 Eth8/4 8 10000 +Ethernet32 49 Eth9/1 9 10000 +Ethernet33 50 Eth9/2 9 10000 +Ethernet34 51 Eth9/3 9 10000 +Ethernet35 52 Eth9/4 9 10000 +Ethernet36 53 Eth10/1 10 10000 +Ethernet37 54 Eth10/2 10 10000 +Ethernet38 55 Eth10/3 10 10000 +Ethernet39 56 Eth10/4 10 10000 +Ethernet40 57 Eth11/1 11 10000 +Ethernet41 58 Eth11/2 11 10000 +Ethernet42 59 Eth11/3 11 10000 +Ethernet43 60 Eth11/4 11 10000 +Ethernet44 61 Eth12/1 12 10000 +Ethernet45 62 Eth12/2 12 10000 +Ethernet46 63 Eth12/3 12 10000 +Ethernet47 64 Eth12/4 12 10000 +Ethernet48 81 Eth13/1 13 10000 +Ethernet49 82 Eth13/2 13 10000 +Ethernet50 83 Eth13/3 13 10000 +Ethernet51 84 Eth13/4 13 10000 +Ethernet52 85 Eth14/1 14 10000 +Ethernet53 86 Eth14/2 14 10000 +Ethernet54 87 Eth14/3 14 10000 +Ethernet55 88 Eth14/4 14 10000 +Ethernet56 89 Eth15/1 15 10000 +Ethernet57 90 Eth15/2 15 10000 +Ethernet58 91 Eth15/3 15 10000 +Ethernet59 92 Eth15/4 15 10000 +Ethernet60 93 Eth16/1 16 10000 +Ethernet61 94 Eth16/2 16 10000 +Ethernet62 95 Eth16/3 16 10000 +Ethernet63 96 Eth16/4 16 10000 +Ethernet64 97 Eth17/1 17 10000 +Ethernet65 98 Eth17/2 17 10000 +Ethernet66 99 Eth17/3 17 10000 +Ethernet67 100 Eth17/4 17 10000 +Ethernet68 101 Eth18/1 18 10000 +Ethernet69 102 Eth18/2 18 10000 +Ethernet70 103 Eth18/3 18 10000 +Ethernet71 104 Eth18/4 18 10000 +Ethernet72 105 Eth19/1 19 10000 +Ethernet73 106 Eth19/2 19 10000 +Ethernet74 107 Eth19/3 19 10000 +Ethernet75 108 Eth19/4 19 10000 +Ethernet76 109 Eth20/1 20 10000 +Ethernet77 110 Eth20/2 20 10000 +Ethernet78 111 Eth20/3 20 10000 +Ethernet79 112 Eth20/4 20 10000 +Ethernet80 1 Eth21/1 21 10000 +Ethernet81 2 Eth21/2 21 10000 +Ethernet82 3 Eth21/3 21 10000 +Ethernet83 4 Eth21/4 21 10000 +Ethernet84 5 Eth22/1 22 10000 +Ethernet85 6 Eth22/2 22 10000 +Ethernet86 7 Eth22/3 22 10000 +Ethernet87 8 Eth22/4 22 10000 +Ethernet88 9 Eth23/1 23 10000 +Ethernet89 10 Eth23/2 23 10000 +Ethernet90 11 Eth23/3 23 10000 +Ethernet91 12 Eth23/4 23 10000 +Ethernet92 13 Eth24/1 24 10000 +Ethernet93 14 Eth24/2 24 10000 +Ethernet94 15 Eth24/3 25 10000 +Ethernet95 16 Eth24/4 25 10000 +Ethernet96 17,18 Eth25/1 26 50000 +Ethernet98 19,20 Eth25/2 26 50000 +Ethernet100 21,22 Eth26/1 27 50000 +Ethernet102 23,24 Eth26/2 27 50000 +Ethernet104 25,26 Eth27/1 28 50000 +Ethernet106 27,28 Eth27/2 28 50000 +Ethernet108 29,30 Eth28/1 29 50000 +Ethernet110 31,32 Eth28/2 29 50000 +Ethernet112 113,114 Eth29/1 30 50000 +Ethernet114 115,116 Eth29/2 30 50000 +Ethernet116 117,118 Eth30/1 31 50000 +Ethernet118 119,120 Eth30/2 31 50000 +Ethernet120 121,122 Eth31/1 32 50000 +Ethernet122 123,124 Eth31/2 32 50000 +Ethernet124 125,126 Eth32/1 32 50000 +Ethernet126 127,128 Eth32/2 32 50000 diff --git a/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50/port_config.ini b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50/port_config.ini index 70553360da28..6b10ccce35a1 100644 --- a/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50/port_config.ini +++ b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50/port_config.ini @@ -1,65 +1,65 @@ -# name lanes alias -Ethernet0 65,66 Eth1/1 -Ethernet2 67,68 Eth1/2 -Ethernet4 69,70 Eth2/1 -Ethernet6 71,72 Eth2/2 -Ethernet8 73,74 Eth3/1 -Ethernet10 75,76 Eth3/2 -Ethernet12 77,78 Eth4/1 -Ethernet14 79,80 Eth4/2 -Ethernet16 33,34 Eth5/1 -Ethernet18 35,36 Eth5/2 -Ethernet20 37,38 Eth6/1 -Ethernet22 39,40 Eth6/2 -Ethernet24 41,42 Eth7/1 -Ethernet26 43,44 Eth7/2 -Ethernet28 45,46 Eth8/1 -Ethernet30 47,48 Eth8/2 -Ethernet32 49,50 Eth9/1 -Ethernet34 51,52 Eth9/2 -Ethernet36 53,54 Eth10/1 -Ethernet38 55,56 Eth10/2 -Ethernet40 57,58 Eth11/1 -Ethernet42 59,60 Eth11/2 -Ethernet44 61,62 Eth12/1 -Ethernet46 63,64 Eth12/2 -Ethernet48 81,82 Eth13/1 -Ethernet50 83,84 Eth13/2 -Ethernet52 85,86 Eth14/1 -Ethernet54 87,88 Eth14/2 -Ethernet56 89,90 Eth15/1 -Ethernet58 91,92 Eth15/2 -Ethernet60 93,94 Eth16/1 -Ethernet62 95,96 Eth16/2 -Ethernet64 97,98 Eth17/1 -Ethernet66 99,100 Eth17/2 -Ethernet68 101,102 Eth18/1 -Ethernet70 103,104 Eth18/2 -Ethernet72 105,106 Eth19/1 -Ethernet74 107,108 Eth19/2 -Ethernet76 109,110 Eth20/1 -Ethernet78 111,112 Eth20/2 -Ethernet80 1,2 Eth21/1 -Ethernet82 3,4 Eth21/2 -Ethernet84 5,6 Eth22/1 -Ethernet86 7,8 Eth22/2 -Ethernet88 9,10 Eth23/1 -Ethernet90 11,12 Eth23/2 -Ethernet92 13,14 Eth24/1 -Ethernet94 15,16 Eth24/2 -Ethernet96 17,18 Eth25/1 -Ethernet98 19,20 Eth25/2 -Ethernet100 21,22 Eth26/1 -Ethernet102 23,24 Eth26/2 -Ethernet104 25,26 Eth27/1 -Ethernet106 27,28 Eth27/2 -Ethernet108 29,30 Eth28/1 -Ethernet110 31,32 Eth28/2 -Ethernet112 113,114 Eth29/1 -Ethernet114 115,116 Eth29/2 -Ethernet116 117,118 Eth30/1 -Ethernet118 119,120 Eth30/2 -Ethernet120 121,122 Eth31/1 -Ethernet122 123,124 Eth31/2 -Ethernet124 125,126 Eth32/1 -Ethernet126 127,128 Eth32/2 +# name lanes alias index speed +Ethernet0 65,66 Eth1/1 1 50000 +Ethernet2 67,68 Eth1/2 1 50000 +Ethernet4 69,70 Eth2/1 2 50000 +Ethernet6 71,72 Eth2/2 2 50000 +Ethernet8 73,74 Eth3/1 3 50000 +Ethernet10 75,76 Eth3/2 3 50000 +Ethernet12 77,78 Eth4/1 4 50000 +Ethernet14 79,80 Eth4/2 4 50000 +Ethernet16 33,34 Eth5/1 5 50000 +Ethernet18 35,36 Eth5/2 5 50000 +Ethernet20 37,38 Eth6/1 6 50000 +Ethernet22 39,40 Eth6/2 6 50000 +Ethernet24 41,42 Eth7/1 7 50000 +Ethernet26 43,44 Eth7/2 7 50000 +Ethernet28 45,46 Eth8/1 8 50000 +Ethernet30 47,48 Eth8/2 8 50000 +Ethernet32 49,50 Eth9/1 9 50000 +Ethernet34 51,52 Eth9/2 9 50000 +Ethernet36 53,54 Eth10/1 10 50000 +Ethernet38 55,56 Eth10/2 10 50000 +Ethernet40 57,58 Eth11/1 11 50000 +Ethernet42 59,60 Eth11/2 11 50000 +Ethernet44 61,62 Eth12/1 12 50000 +Ethernet46 63,64 Eth12/2 12 50000 +Ethernet48 81,82 Eth13/1 13 50000 +Ethernet50 83,84 Eth13/2 13 50000 +Ethernet52 85,86 Eth14/1 14 50000 +Ethernet54 87,88 Eth14/2 14 50000 +Ethernet56 89,90 Eth15/1 15 50000 +Ethernet58 91,92 Eth15/2 15 50000 +Ethernet60 93,94 Eth16/1 16 50000 +Ethernet62 95,96 Eth16/2 16 50000 +Ethernet64 97,98 Eth17/1 17 50000 +Ethernet66 99,100 Eth17/2 17 50000 +Ethernet68 101,102 Eth18/1 18 50000 +Ethernet70 103,104 Eth18/2 18 50000 +Ethernet72 105,106 Eth19/1 19 50000 +Ethernet74 107,108 Eth19/2 19 50000 +Ethernet76 109,110 Eth20/1 20 50000 +Ethernet78 111,112 Eth20/2 20 50000 +Ethernet80 1,2 Eth21/1 21 50000 +Ethernet82 3,4 Eth21/2 21 50000 +Ethernet84 5,6 Eth22/1 22 50000 +Ethernet86 7,8 Eth22/2 22 50000 +Ethernet88 9,10 Eth23/1 23 50000 +Ethernet90 11,12 Eth23/2 23 50000 +Ethernet92 13,14 Eth24/1 24 50000 +Ethernet94 15,16 Eth24/2 24 50000 +Ethernet96 17,18 Eth25/1 25 50000 +Ethernet98 19,20 Eth25/2 25 50000 +Ethernet100 21,22 Eth26/1 26 50000 +Ethernet102 23,24 Eth26/2 26 50000 +Ethernet104 25,26 Eth27/1 27 50000 +Ethernet106 27,28 Eth27/2 27 50000 +Ethernet108 29,30 Eth28/1 28 50000 +Ethernet110 31,32 Eth28/2 28 50000 +Ethernet112 113,114 Eth29/1 29 50000 +Ethernet114 115,116 Eth29/2 29 50000 +Ethernet116 117,118 Eth30/1 30 50000 +Ethernet118 119,120 Eth30/2 30 50000 +Ethernet120 121,122 Eth31/1 31 50000 +Ethernet122 123,124 Eth31/2 31 50000 +Ethernet124 125,126 Eth32/1 32 50000 +Ethernet126 127,128 Eth32/2 32 50000 diff --git a/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010/port_config.ini b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010/port_config.ini index 9f039e003488..e097f3b66cee 100644 --- a/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010/port_config.ini +++ b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010/port_config.ini @@ -1,33 +1,33 @@ -# name lanes alias -Ethernet0 65,66,67,68 Eth1 -Ethernet4 69,70,71,72 Eth2 -Ethernet8 73,74,75,76 Eth3 -Ethernet12 77,78,79,80 Eth4 -Ethernet16 33,34,35,36 Eth5 -Ethernet20 37,38,39,40 Eth6 -Ethernet24 41,42,43,44 Eth7 -Ethernet28 45,46,47,48 Eth8 -Ethernet32 49,50,51,52 Eth9 -Ethernet36 53,54,55,56 Eth10 -Ethernet40 57,58,59,60 Eth11 -Ethernet44 61,62,63,64 Eth12 -Ethernet48 81,82,83,84 Eth13 -Ethernet52 85,86,87,88 Eth14 -Ethernet56 89,90,91,92 Eth15 -Ethernet60 93,94,95,96 Eth16 -Ethernet64 97,98,99,100 Eth17 -Ethernet68 101,102,103,104 Eth18 -Ethernet72 105,106,107,108 Eth19 -Ethernet76 109,110,111,112 Eth20 -Ethernet80 1,2,3,4 Eth21 -Ethernet84 5,6,7,8 Eth22 -Ethernet88 9,10,11,12 Eth23 -Ethernet92 13,14,15,16 Eth24 -Ethernet96 17,18,19,20 Eth25 -Ethernet100 21,22,23,24 Eth26 -Ethernet104 25,26,27,28 Eth27 -Ethernet108 29,30,31,32 Eth28 -Ethernet112 113,114,115,116 Eth29 -Ethernet116 117,118,119,120 Eth30 -Ethernet120 121,122,123,124 Eth31 -Ethernet124 125,126,127,128 Eth32 +# name lanes alias index speed +Ethernet0 65,66,67,68 Eth1 1 100000 +Ethernet4 69,70,71,72 Eth2 2 100000 +Ethernet8 73,74,75,76 Eth3 3 100000 +Ethernet12 77,78,79,80 Eth4 4 100000 +Ethernet16 33,34,35,36 Eth5 5 100000 +Ethernet20 37,38,39,40 Eth6 6 100000 +Ethernet24 41,42,43,44 Eth7 7 100000 +Ethernet28 45,46,47,48 Eth8 8 100000 +Ethernet32 49,50,51,52 Eth9 9 100000 +Ethernet36 53,54,55,56 Eth10 10 100000 +Ethernet40 57,58,59,60 Eth11 11 100000 +Ethernet44 61,62,63,64 Eth12 12 100000 +Ethernet48 81,82,83,84 Eth13 13 100000 +Ethernet52 85,86,87,88 Eth14 14 100000 +Ethernet56 89,90,91,92 Eth15 15 100000 +Ethernet60 93,94,95,96 Eth16 16 100000 +Ethernet64 97,98,99,100 Eth17 17 100000 +Ethernet68 101,102,103,104 Eth18 18 100000 +Ethernet72 105,106,107,108 Eth19 19 100000 +Ethernet76 109,110,111,112 Eth20 20 100000 +Ethernet80 1,2,3,4 Eth21 21 100000 +Ethernet84 5,6,7,8 Eth22 22 100000 +Ethernet88 9,10,11,12 Eth23 23 100000 +Ethernet92 13,14,15,16 Eth24 24 100000 +Ethernet96 17,18,19,20 Eth25 25 100000 +Ethernet100 21,22,23,24 Eth26 26 100000 +Ethernet104 25,26,27,28 Eth27 27 100000 +Ethernet108 29,30,31,32 Eth28 28 100000 +Ethernet112 113,114,115,116 Eth29 29 100000 +Ethernet116 117,118,119,120 Eth30 30 100000 +Ethernet120 121,122,123,124 Eth31 31 100000 +Ethernet124 125,126,127,128 Eth32 32 100000 diff --git a/device/celestica/x86_64-cel_seastone-r0/plugins/sfputil.py b/device/celestica/x86_64-cel_seastone-r0/plugins/sfputil.py old mode 100755 new mode 100644 index f1e6b1daa3e1..c361659b0f17 --- a/device/celestica/x86_64-cel_seastone-r0/plugins/sfputil.py +++ b/device/celestica/x86_64-cel_seastone-r0/plugins/sfputil.py @@ -13,12 +13,11 @@ class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" - PORT_START = 0 - PORT_END = 31 + PORT_START = 1 + PORT_END = 32 PORTS_IN_BLOCK = 32 _port_to_eeprom_mapping = {} - qsfp_ports = range(0, PORTS_IN_BLOCK + 1) @property def port_start(self): @@ -30,7 +29,7 @@ def port_end(self): @property def qsfp_ports(self): - return range(0, self.PORTS_IN_BLOCK + 1) + return range(self.PORT_START, self.PORTS_IN_BLOCK + 1) @property def port_to_eeprom_mapping(self): @@ -41,7 +40,10 @@ def __init__(self): eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom' for x in range(self.PORT_START, self.PORT_END + 1): - self.port_to_eeprom_mapping[x] = eeprom_path.format( x + 26 ) + if self.port_start == 1: + self.port_to_eeprom_mapping[x] = eeprom_path.format((x - 1) + 26) + else: + self.port_to_eeprom_mapping[x] = eeprom_path.format(x + 26) SfpUtilBase.__init__(self) def get_presence(self, port_num): @@ -60,8 +62,14 @@ def get_presence(self, port_num): # content is a string containing the hex representation of the register reg_value = int(content, 16) + # Determind if port_num start from 1 or 0 + if self.port_start == 1: + bit_index = port_num - 1 + else: + bit_index = port_num + # Mask off the bit corresponding to our port - mask = (1 << port_num) + mask = (1 << bit_index) # ModPrsL is active low if reg_value & mask == 0: @@ -85,8 +93,14 @@ def get_low_power_mode(self, port_num): # content is a string containing the hex representation of the register reg_value = int(content, 16) + # Determind if port_num start from 1 or 0 + if self.port_start == 1: + bit_index = port_num - 1 + else: + bit_index = port_num + # Mask off the bit corresponding to our port - mask = (1 << port_num) + mask = (1 << bit_index) # LPMode is active high if reg_value & mask == 0: @@ -95,8 +109,96 @@ def get_low_power_mode(self, port_num): return True def set_low_power_mode(self, port_num, lpmode): - raise NotImplementedError + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + try: + reg_file = open("/sys/devices/platform/dx010_cpld/qsfp_lpmode", "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = reg_file.readline().rstrip() + + # content is a string containing the hex representation of the register + reg_value = int(content, 16) + + # Determind if port_num start from 1 or 0 + if self.port_start == 1: + bit_index = port_num - 1 + else: + bit_index = port_num + + # Mask off the bit corresponding to our port + mask = (1 << bit_index) + + # LPMode is active high; set or clear the bit accordingly + if lpmode is True: + reg_value = reg_value | mask + else: + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + content = hex(reg_value).strip('L') + + reg_file.seek(0) + reg_file.write(content) + reg_file.close() + + return True def reset(self, port_num): - raise NotImplementedError + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + try: + reg_file = open("/sys/devices/platform/dx010_cpld/qsfp_reset", "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = reg_file.readline().rstrip() + + # File content is a string containing the hex representation of the + # register + reg_value = int(content, 16) + + # Determind if port_num start from 1 or 0 + if self.port_start == 1: + bit_index = port_num - 1 + else: + bit_index = port_num + + # Mask off the bit corresponding to our port + mask = (1 << bit_index) + + # ResetL is active low + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + reg_file.seek(0) + reg_file.write(hex(reg_value).rstrip('L')) + reg_file.close() + + # Sleep 1 second to allow it to settle + time.sleep(1) + # Flip the bit back high and write back to the register to take port + # out of reset + try: + reg_file = open("/sys/devices/platform/dx010_cpld/qsfp_reset", "w") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = reg_value | mask + reg_file.seek(0) + reg_file.write(hex(reg_value).rstrip('L')) + reg_file.close() + + return True + + def get_transceiver_change_event(self, timeout=0): + raise NotImplementedError From 28790056c3f88e8d2e81b1f2941e2bd6e5cda41a Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Wed, 14 Nov 2018 01:13:10 -0800 Subject: [PATCH 173/219] Store thrift source packages in blob (#2255) Signed-off-by: Qi Luo --- src/thrift/Makefile | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/thrift/Makefile b/src/thrift/Makefile index 786a10641e60..dad28571b922 100644 --- a/src/thrift/Makefile +++ b/src/thrift/Makefile @@ -10,12 +10,15 @@ DERIVED_TARGETS = libthrift-dev_$(THRIFT_VERSION_FULL)_amd64.deb \ python-thrift_$(THRIFT_VERSION_FULL)_amd64.deb \ thrift-compiler_$(THRIFT_VERSION_FULL)_amd64.deb +#THRIFT_LINK_PRE = http://http.debian.net/debian/pool/main/t/thrift +THRIFT_LINK_PRE = https://sonicstorage.blob.core.windows.net/packages/debian + $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : rm -rf thrift-$(THRIFT_VERSION) - wget -nc http://http.debian.net/debian/pool/main/t/thrift/thrift_$(THRIFT_VERSION).orig.tar.gz - wget -nc http://http.debian.net/debian/pool/main/t/thrift/thrift_$(THRIFT_VERSION_FULL).debian.tar.xz - wget -nc http://http.debian.net/debian/pool/main/t/thrift/thrift_$(THRIFT_VERSION_FULL).dsc + wget -nc "$(THRIFT_LINK_PRE)/thrift_$(THRIFT_VERSION).orig.tar.gz?sv=2015-04-05&sr=b&sig=wM3B01UnZQYYr7ZGXmCvRn6MMeS5hn5Oa5G5%2Btub53g%3D&se=2028-11-11T02%3A20%3A36Z&sp=r" + wget -nc "$(THRIFT_LINK_PRE)/thrift_$(THRIFT_VERSION_FULL).debian.tar.xz?sv=2015-04-05&sr=b&sig=76bx%2BN8uxYbuI%2BEq8uK%2B8cTKTzVmjtjsQ9weejWNINk%3D&se=2028-11-11T02%3A19%3A30Z&sp=r" + wget -nc "$(THRIFT_LINK_PRE)/thrift_$(THRIFT_VERSION_FULL).dsc?sv=2015-04-05&sr=b&sig=Vpk1eJ97I5aWrtjAYS8w8AKyLXcJKFGIVFOOBGR3a5I%3D&se=2028-11-11T02%3A20%3A20Z&sp=r" dpkg-source -x thrift_$(THRIFT_VERSION_FULL).dsc pushd thrift-$(THRIFT_VERSION) From f7b17608b33507b1d979b191b886d9a8992db023 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Wed, 14 Nov 2018 19:32:29 -0800 Subject: [PATCH 174/219] Fix bug: wget rename saved file (#2259) Signed-off-by: Qi Luo --- src/thrift/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/thrift/Makefile b/src/thrift/Makefile index dad28571b922..03b56ff34390 100644 --- a/src/thrift/Makefile +++ b/src/thrift/Makefile @@ -16,9 +16,9 @@ THRIFT_LINK_PRE = https://sonicstorage.blob.core.windows.net/packages/debian $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : rm -rf thrift-$(THRIFT_VERSION) - wget -nc "$(THRIFT_LINK_PRE)/thrift_$(THRIFT_VERSION).orig.tar.gz?sv=2015-04-05&sr=b&sig=wM3B01UnZQYYr7ZGXmCvRn6MMeS5hn5Oa5G5%2Btub53g%3D&se=2028-11-11T02%3A20%3A36Z&sp=r" - wget -nc "$(THRIFT_LINK_PRE)/thrift_$(THRIFT_VERSION_FULL).debian.tar.xz?sv=2015-04-05&sr=b&sig=76bx%2BN8uxYbuI%2BEq8uK%2B8cTKTzVmjtjsQ9weejWNINk%3D&se=2028-11-11T02%3A19%3A30Z&sp=r" - wget -nc "$(THRIFT_LINK_PRE)/thrift_$(THRIFT_VERSION_FULL).dsc?sv=2015-04-05&sr=b&sig=Vpk1eJ97I5aWrtjAYS8w8AKyLXcJKFGIVFOOBGR3a5I%3D&se=2028-11-11T02%3A20%3A20Z&sp=r" + wget -nc -O "thrift_$(THRIFT_VERSION).orig.tar.gz" "$(THRIFT_LINK_PRE)/thrift_$(THRIFT_VERSION).orig.tar.gz?sv=2015-04-05&sr=b&sig=wM3B01UnZQYYr7ZGXmCvRn6MMeS5hn5Oa5G5%2Btub53g%3D&se=2028-11-11T02%3A20%3A36Z&sp=r" + wget -nc -O "thrift_$(THRIFT_VERSION_FULL).debian.tar.xz" "$(THRIFT_LINK_PRE)/thrift_$(THRIFT_VERSION_FULL).debian.tar.xz?sv=2015-04-05&sr=b&sig=76bx%2BN8uxYbuI%2BEq8uK%2B8cTKTzVmjtjsQ9weejWNINk%3D&se=2028-11-11T02%3A19%3A30Z&sp=r" + wget -nc -O "thrift_$(THRIFT_VERSION_FULL).dsc" "$(THRIFT_LINK_PRE)/thrift_$(THRIFT_VERSION_FULL).dsc?sv=2015-04-05&sr=b&sig=Vpk1eJ97I5aWrtjAYS8w8AKyLXcJKFGIVFOOBGR3a5I%3D&se=2028-11-11T02%3A20%3A20Z&sp=r" dpkg-source -x thrift_$(THRIFT_VERSION_FULL).dsc pushd thrift-$(THRIFT_VERSION) From 6da462e7c1515e921f0e57d084742c9ac6f557ee Mon Sep 17 00:00:00 2001 From: Wenda Ni Date: Fri, 16 Nov 2018 00:52:32 -0800 Subject: [PATCH 175/219] [buffer]: Update pg headroom egress service pool for a7050 and s6000 (#2261) Signed-off-by: Wenda --- .../Arista-7050-QX32/buffers.json.j2 | 6 +++--- .../Arista-7050-QX-32S/buffers.json.j2 | 6 +++--- .../Force10-S6000/buffers.json.j2 | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers.json.j2 b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers.json.j2 index 782dc528f71e..424ad6bf353e 100644 --- a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers.json.j2 +++ b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers.json.j2 @@ -79,7 +79,7 @@ "mode": "static" }, "egress_lossy_pool": { - "size": "8072396", + "size": "7582515", "type": "egress", "mode": "dynamic" } @@ -88,8 +88,8 @@ "ingress_lossless_profile": { "pool":"[BUFFER_POOL|ingress_lossless_pool]", "xon":"18432", - "xoff":"40560", - "size":"41808", + "xoff":"50128", + "size":"51376", "dynamic_th":"-3", "xon_offset":"2496" }, diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/buffers.json.j2 b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/buffers.json.j2 index 782dc528f71e..424ad6bf353e 100644 --- a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/buffers.json.j2 +++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/buffers.json.j2 @@ -79,7 +79,7 @@ "mode": "static" }, "egress_lossy_pool": { - "size": "8072396", + "size": "7582515", "type": "egress", "mode": "dynamic" } @@ -88,8 +88,8 @@ "ingress_lossless_profile": { "pool":"[BUFFER_POOL|ingress_lossless_pool]", "xon":"18432", - "xoff":"40560", - "size":"41808", + "xoff":"50128", + "size":"51376", "dynamic_th":"-3", "xon_offset":"2496" }, diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers.json.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers.json.j2 index 782dc528f71e..424ad6bf353e 100644 --- a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers.json.j2 +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers.json.j2 @@ -79,7 +79,7 @@ "mode": "static" }, "egress_lossy_pool": { - "size": "8072396", + "size": "7582515", "type": "egress", "mode": "dynamic" } @@ -88,8 +88,8 @@ "ingress_lossless_profile": { "pool":"[BUFFER_POOL|ingress_lossless_pool]", "xon":"18432", - "xoff":"40560", - "size":"41808", + "xoff":"50128", + "size":"51376", "dynamic_th":"-3", "xon_offset":"2496" }, From 92341b8e06f5c063fca412fa89b65b1d202fffc1 Mon Sep 17 00:00:00 2001 From: lguohan Date: Sun, 18 Nov 2018 19:21:21 -0800 Subject: [PATCH 176/219] [submodule]: update sonic-py-swsssdk (#2271) * 8113744 2018-11-18 | Force key/value convertion to str before send to redis lib (#39) (HEAD, origin/master, origin/HEAD) [Taoyu Li] Signed-off-by: Guohan Lu --- src/sonic-py-swsssdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index 7ce52d861019..81137443d337 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit 7ce52d86101906e404af96fe76e04079f4afd863 +Subproject commit 81137443d3374268a336788796872369d2e16390 From 6a24eb4151ebe4e1c3ebcc63f47193fee26eb54d Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Mon, 19 Nov 2018 12:03:15 -0800 Subject: [PATCH 177/219] Fix redis-py version to 2.10.6 (#2273) * Fix redis-py version Signed-off-by: Qi Luo * Update submodule sonic-py-swsssdk: Fix redis-py version to 2.10.6 Signed-off-by: Qi Luo --- files/build_templates/sonic_debian_extension.j2 | 2 +- src/sonic-py-swsssdk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 29bfdfcd374a..c15cd4f9e805 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -74,7 +74,7 @@ sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $CONFIG sudo rm -rf $FILESYSTEM_ROOT/$CONFIG_ENGINE_WHEEL_NAME # Install Python client for Redis -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install redis +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install "redis==2.10.6" sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install redis-dump-load # Install SwSS SDK Python 2 package diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index 81137443d337..cb4fec9d078f 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit 81137443d3374268a336788796872369d2e16390 +Subproject commit cb4fec9d078f72ca378ecba5e6a112e3028c2221 From f5edde91859f6261df64ddb818bd757e241c7c9a Mon Sep 17 00:00:00 2001 From: Shuotian Cheng Date: Tue, 27 Nov 2018 15:53:14 -0800 Subject: [PATCH 178/219] [utilities]: Update sonic-utilities submodule (#2307) Update sonic-utilities submodule: ecnconfig check against invalid argument value (#343) pfcwd start commd pre-check fix (#339) [acl_loader]: Add support for parsing input interface (#386) Signed-off-by: Shu0T1an ChenG --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index c0c97623e5b9..cd59964cee8d 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit c0c97623e5b957bb3c162b2c0eec4bf73776d72b +Subproject commit cd59964cee8d2abae29e25218d0af66da709f72c From ecb8e53da13516d4d8fabf879018c9ad31816009 Mon Sep 17 00:00:00 2001 From: simonJi2018 <37395146+simonJi2018@users.noreply.github.com> Date: Sun, 2 Dec 2018 23:14:01 -0800 Subject: [PATCH 179/219] update sdk and sai for 201803 (#2331) * uodate sai and sdk for fix some bug and add some filt to device/accton and ingrasys for support different sfp module and hw version * update device config for support s9230 R0B and update port_config.nps and ini * update device file * fix some code error * fix init chip config data error --- .../Accton-AS7116-54X/port_config.nps | 56 + .../Accton-AS7116-54X/port_config.nps.AOC.R0B | 358 ---- .../Accton-AS7116-54X/port_config.nps.DAC.R0B | 357 ---- .../INGRASYS-S9130-32X/port_config.nps | 34 + .../INGRASYS-S9230-64X/port_config.ini | 8 +- .../INGRASYS-S9230-64X/port_config.nps | 1545 ++++++++--------- .../led_proc_init.nps | 2 +- platform/nephos/one-image.mk | 2 +- platform/nephos/sai.mk | 11 +- platform/nephos/sdk.mk | 7 +- 10 files changed, 789 insertions(+), 1591 deletions(-) delete mode 100644 device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps.AOC.R0B delete mode 100644 device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps.DAC.R0B diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps index 34e5a2daab80..e639b4572feb 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps +++ b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps @@ -346,6 +346,62 @@ phy set pre-emphasis portlist=53 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis portlist=53 lane-cnt=4 property=cn1 data=0x1.1.1.1 phy set pre-emphasis portlist=53 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a phy set pre-emphasis portlist=53 lane-cnt=4 property=c1 data=0x7.7.7.7 +phy set mdio portlist=0 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=1 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=2 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=3 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=4 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=5 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=6 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=7 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=8 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=9 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=10 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=11 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=12 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=13 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=14 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=15 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=16 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=17 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=18 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=19 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=20 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=21 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=22 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=23 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=24 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=25 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=26 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=27 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=28 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=29 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=30 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=31 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=32 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=33 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=34 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=35 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=36 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=37 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=38 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=39 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=40 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=41 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=42 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=43 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=44 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=45 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=46 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=47 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=48 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=49 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=50 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=51 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=52 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=53 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=129 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=130 devad=0x1E addr=0x2 data=0x0000 port set property portlist=0-47 speed=25g port set property portlist=48-53 speed=100g port set property portlist=129-130 speed=10g diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps.AOC.R0B b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps.AOC.R0B deleted file mode 100644 index 34e5a2daab80..000000000000 --- a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps.AOC.R0B +++ /dev/null @@ -1,358 +0,0 @@ -init start stage unit=0 low-level -init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=25g active=true -init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=25g active=true -init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=25g active=true -init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=25g active=true -init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=25g active=true -init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=25g active=true -init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=25g active=true -init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=25g active=true -init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=25g active=true -init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=25g active=true -init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=25g active=true -init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=25g active=true -init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=25g active=true -init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=25g active=true -init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=25g active=true -init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=25g active=true -init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=25g active=true -init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=25g active=true -init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=25g active=true -init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=25g active=true -init set port-map unit=0 port=20 eth-macro=10 lane=0 max-speed=25g active=true -init set port-map unit=0 port=21 eth-macro=10 lane=1 max-speed=25g active=true -init set port-map unit=0 port=22 eth-macro=10 lane=2 max-speed=25g active=true -init set port-map unit=0 port=23 eth-macro=10 lane=3 max-speed=25g active=true -init set port-map unit=0 port=24 eth-macro=12 lane=0 max-speed=25g active=true -init set port-map unit=0 port=25 eth-macro=12 lane=1 max-speed=25g active=true -init set port-map unit=0 port=26 eth-macro=12 lane=2 max-speed=25g active=true -init set port-map unit=0 port=27 eth-macro=12 lane=3 max-speed=25g active=true -init set port-map unit=0 port=28 eth-macro=14 lane=0 max-speed=25g active=true -init set port-map unit=0 port=29 eth-macro=14 lane=1 max-speed=25g active=true -init set port-map unit=0 port=30 eth-macro=14 lane=2 max-speed=25g active=true -init set port-map unit=0 port=31 eth-macro=14 lane=3 max-speed=25g active=true -init set port-map unit=0 port=32 eth-macro=16 lane=0 max-speed=25g active=true -init set port-map unit=0 port=33 eth-macro=16 lane=1 max-speed=25g active=true -init set port-map unit=0 port=34 eth-macro=16 lane=2 max-speed=25g active=true -init set port-map unit=0 port=35 eth-macro=16 lane=3 max-speed=25g active=true -init set port-map unit=0 port=36 eth-macro=17 lane=0 max-speed=25g active=true -init set port-map unit=0 port=37 eth-macro=17 lane=1 max-speed=25g active=true -init set port-map unit=0 port=38 eth-macro=17 lane=2 max-speed=25g active=true -init set port-map unit=0 port=39 eth-macro=17 lane=3 max-speed=25g active=true -init set port-map unit=0 port=40 eth-macro=18 lane=0 max-speed=25g active=true -init set port-map unit=0 port=41 eth-macro=18 lane=1 max-speed=25g active=true -init set port-map unit=0 port=42 eth-macro=18 lane=2 max-speed=25g active=true -init set port-map unit=0 port=43 eth-macro=18 lane=3 max-speed=25g active=true -init set port-map unit=0 port=44 eth-macro=19 lane=0 max-speed=25g active=true -init set port-map unit=0 port=45 eth-macro=19 lane=1 max-speed=25g active=true -init set port-map unit=0 port=46 eth-macro=19 lane=2 max-speed=25g active=true -init set port-map unit=0 port=47 eth-macro=19 lane=3 max-speed=25g active=true -init set port-map unit=0 port=48 eth-macro=21 lane=0 max-speed=100g active=true -init set port-map unit=0 port=49 eth-macro=20 lane=0 max-speed=100g active=true -init set port-map unit=0 port=50 eth-macro=26 lane=0 max-speed=100g active=true -init set port-map unit=0 port=51 eth-macro=27 lane=0 max-speed=100g active=true -init set port-map unit=0 port=52 eth-macro=28 lane=0 max-speed=100g active=true -init set port-map unit=0 port=53 eth-macro=29 lane=0 max-speed=100g active=true -init set port-map unit=0 port=129 eth-macro=0 lane=1 max-speed=10g active=true guarantee=true cpi=true -init set port-map unit=0 port=130 eth-macro=0 lane=0 max-speed=10g active=true guarantee=true cpi=true init-done=true -init start stage unit=0 task-rsrc -init start stage unit=0 module -init start stage unit=0 task -phy set lane-swap portlist=0 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=1 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=2 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=3 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=4 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=5 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=6 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=7 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=8 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=9 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=10 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=11 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=12 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=13 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=14 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=15 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=16 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=17 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=18 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=19 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=20 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=21 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=22 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=23 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=24 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=25 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=26 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=27 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=28 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=29 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=30 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=31 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=32 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=33 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=34 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=35 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=36 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=37 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=38 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=39 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=40 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=41 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=42 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=43 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=44 lane-cnt=1 property=tx data=0x0 -phy set lane-swap portlist=45 lane-cnt=1 property=tx data=0x1 -phy set lane-swap portlist=46 lane-cnt=1 property=tx data=0x2 -phy set lane-swap portlist=47 lane-cnt=1 property=tx data=0x3 -phy set lane-swap portlist=48 lane-cnt=4 property=tx data=0x1.3.0.2 -phy set lane-swap portlist=49 lane-cnt=4 property=tx data=0x0.3.1.2 -phy set lane-swap portlist=50 lane-cnt=4 property=tx data=0x1.3.0.2 -phy set lane-swap portlist=51 lane-cnt=4 property=tx data=0x2.0.3.1 -phy set lane-swap portlist=52 lane-cnt=4 property=tx data=0x3.2.1.0 -phy set lane-swap portlist=53 lane-cnt=4 property=tx data=0x3.2.1.0 -phy set lane-swap portlist=0 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=1 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=2 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=3 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=4 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=5 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=6 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=7 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=8 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=9 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=10 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=11 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=12 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=13 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=14 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=15 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=16 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=17 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=18 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=19 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=20 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=21 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=22 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=23 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=24 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=25 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=26 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=27 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=28 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=29 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=30 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=31 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=32 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=33 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=34 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=35 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=36 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=37 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=38 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=39 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=40 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=41 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=42 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=43 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=44 lane-cnt=1 property=rx data=0x1 -phy set lane-swap portlist=45 lane-cnt=1 property=rx data=0x2 -phy set lane-swap portlist=46 lane-cnt=1 property=rx data=0x3 -phy set lane-swap portlist=47 lane-cnt=1 property=rx data=0x0 -phy set lane-swap portlist=48 lane-cnt=4 property=rx data=0x2.1.0.3 -phy set lane-swap portlist=49 lane-cnt=4 property=rx data=0x0.1.3.2 -phy set lane-swap portlist=50 lane-cnt=4 property=rx data=0x3.1.0.2 -phy set lane-swap portlist=51 lane-cnt=4 property=rx data=0x1.3.0.2 -phy set lane-swap portlist=52 lane-cnt=4 property=rx data=0x3.2.1.0 -phy set lane-swap portlist=53 lane-cnt=4 property=rx data=0x3.2.1.0 -phy set polarity-rev portlist=0 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=1 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=2 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=3 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=4 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=5 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=6 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=7 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=8 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=9 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=10 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=11 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=12 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=13 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=14 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=15 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=16 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=17 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=18 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=19 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=20 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=21 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=22 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=23 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=24 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=25 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=26 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=27 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=28 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=29 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=30 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=31 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=32 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=33 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=34 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=35 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=36 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=37 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=38 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=39 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=40 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=41 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=42 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=43 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=44 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=45 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=46 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=47 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev portlist=48 lane-cnt=4 property=tx data=0x0.0.0.1 -phy set polarity-rev portlist=49 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev portlist=50 lane-cnt=4 property=tx data=0x1.1.0.0 -phy set polarity-rev portlist=51 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev portlist=52 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev portlist=53 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev portlist=0 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=1 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=2 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=3 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=4 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=5 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=6 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=7 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=8 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=9 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=10 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=11 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=12 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=13 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=14 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=15 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=16 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=17 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=18 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=19 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=20 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=21 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=22 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=23 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=24 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=25 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=26 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=27 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=28 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=29 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=30 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=31 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=32 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=33 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=34 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=35 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=36 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=37 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=38 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=39 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=40 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=41 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=42 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=43 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=44 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=45 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=46 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=47 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev portlist=48 lane-cnt=4 property=rx data=0x0.1.0.1 -phy set polarity-rev portlist=49 lane-cnt=4 property=rx data=0x1.0.1.0 -phy set polarity-rev portlist=50 lane-cnt=4 property=rx data=0x0.0.1.0 -phy set polarity-rev portlist=51 lane-cnt=4 property=rx data=0x0.0.0.1 -phy set polarity-rev portlist=52 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev portlist=53 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set pre-emphasis portlist=0 lane-cnt=4 property=c2 data=0x2.2.2.2 -phy set pre-emphasis portlist=0 lane-cnt=4 property=cn1 data=0x1.1.1.1 -phy set pre-emphasis portlist=0 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a -phy set pre-emphasis portlist=0 lane-cnt=4 property=c1 data=0x7.7.7.7 -phy set pre-emphasis portlist=4 lane-cnt=4 property=c2 data=0x2.2.2.2 -phy set pre-emphasis portlist=4 lane-cnt=4 property=cn1 data=0x1.1.1.1 -phy set pre-emphasis portlist=4 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a -phy set pre-emphasis portlist=4 lane-cnt=4 property=c1 data=0x7.7.7.7 -phy set pre-emphasis portlist=8 lane-cnt=4 property=c2 data=0x2.2.2.2 -phy set pre-emphasis portlist=8 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=8 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c -phy set pre-emphasis portlist=8 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis portlist=12 lane-cnt=4 property=c2 data=0x2.2.2.2 -phy set pre-emphasis portlist=12 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=12 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis portlist=12 lane-cnt=4 property=c1 data=0x7.7.7.7 -phy set pre-emphasis portlist=16 lane-cnt=4 property=c2 data=0x2.2.2.2 -phy set pre-emphasis portlist=16 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=16 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c -phy set pre-emphasis portlist=16 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis portlist=20 lane-cnt=4 property=c2 data=0x2.2.2.2 -phy set pre-emphasis portlist=20 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=20 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c -phy set pre-emphasis portlist=20 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis portlist=24 lane-cnt=4 property=c2 data=0x2.2.2.2 -phy set pre-emphasis portlist=24 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=24 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c -phy set pre-emphasis portlist=24 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis portlist=28 lane-cnt=4 property=c2 data=0x2.2.2.2 -phy set pre-emphasis portlist=28 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=28 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c -phy set pre-emphasis portlist=28 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis portlist=32 lane-cnt=4 property=c2 data=0x2.2.2.2 -phy set pre-emphasis portlist=32 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=32 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c -phy set pre-emphasis portlist=32 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis portlist=36 lane-cnt=4 property=c2 data=0x2.2.2.2 -phy set pre-emphasis portlist=36 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=36 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c -phy set pre-emphasis portlist=36 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis portlist=40 lane-cnt=4 property=c2 data=0x2.2.2.2 -phy set pre-emphasis portlist=40 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=40 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c -phy set pre-emphasis portlist=40 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis portlist=44 lane-cnt=4 property=c2 data=0x2.2.2.2 -phy set pre-emphasis portlist=44 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=44 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c -phy set pre-emphasis portlist=44 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis portlist=48 lane-cnt=4 property=c2 data=0x2.2.2.2 -phy set pre-emphasis portlist=48 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=48 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis portlist=48 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis portlist=49 lane-cnt=4 property=c2 data=0x2.2.2.2 -phy set pre-emphasis portlist=49 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=49 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis portlist=49 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis portlist=50 lane-cnt=4 property=c2 data=0x2.2.2.2 -phy set pre-emphasis portlist=50 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=50 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis portlist=50 lane-cnt=4 property=c1 data=0x7.7.7.7 -phy set pre-emphasis portlist=51 lane-cnt=4 property=c2 data=0x2.2.2.2 -phy set pre-emphasis portlist=51 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=51 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis portlist=51 lane-cnt=4 property=c1 data=0x7.7.7.7 -phy set pre-emphasis portlist=52 lane-cnt=4 property=c2 data=0x2.2.2.2 -phy set pre-emphasis portlist=52 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis portlist=52 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a -phy set pre-emphasis portlist=52 lane-cnt=4 property=c1 data=0x8.8.8.8 -phy set pre-emphasis portlist=53 lane-cnt=4 property=c2 data=0x2.2.2.2 -phy set pre-emphasis portlist=53 lane-cnt=4 property=cn1 data=0x1.1.1.1 -phy set pre-emphasis portlist=53 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a -phy set pre-emphasis portlist=53 lane-cnt=4 property=c1 data=0x7.7.7.7 -port set property portlist=0-47 speed=25g -port set property portlist=48-53 speed=100g -port set property portlist=129-130 speed=10g -port set property portlist=0-47 medium-type=sr -port set property portlist=48-53 medium-type=sr4 -port set property portlist=129-130 medium-type=kr -port set adver portlist=129-130 speed-10g-kr -port set property portlist=129-130 an=enable -port set property portlist=0-53,129-130 admin=enable - diff --git a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps.DAC.R0B b/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps.DAC.R0B deleted file mode 100644 index af9927ae2884..000000000000 --- a/device/accton/x86_64-accton_as7116_54x-r0/Accton-AS7116-54X/port_config.nps.DAC.R0B +++ /dev/null @@ -1,357 +0,0 @@ -init start stage unit=0 low-level -init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=25g active=true -init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=25g active=true -init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=25g active=true -init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=25g active=true -init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=25g active=true -init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=25g active=true -init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=25g active=true -init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=25g active=true -init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=25g active=true -init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=25g active=true -init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=25g active=true -init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=25g active=true -init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=25g active=true -init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=25g active=true -init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=25g active=true -init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=25g active=true -init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=25g active=true -init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=25g active=true -init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=25g active=true -init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=25g active=true -init set port-map unit=0 port=20 eth-macro=10 lane=0 max-speed=25g active=true -init set port-map unit=0 port=21 eth-macro=10 lane=1 max-speed=25g active=true -init set port-map unit=0 port=22 eth-macro=10 lane=2 max-speed=25g active=true -init set port-map unit=0 port=23 eth-macro=10 lane=3 max-speed=25g active=true -init set port-map unit=0 port=24 eth-macro=12 lane=0 max-speed=25g active=true -init set port-map unit=0 port=25 eth-macro=12 lane=1 max-speed=25g active=true -init set port-map unit=0 port=26 eth-macro=12 lane=2 max-speed=25g active=true -init set port-map unit=0 port=27 eth-macro=12 lane=3 max-speed=25g active=true -init set port-map unit=0 port=28 eth-macro=14 lane=0 max-speed=25g active=true -init set port-map unit=0 port=29 eth-macro=14 lane=1 max-speed=25g active=true -init set port-map unit=0 port=30 eth-macro=14 lane=2 max-speed=25g active=true -init set port-map unit=0 port=31 eth-macro=14 lane=3 max-speed=25g active=true -init set port-map unit=0 port=32 eth-macro=16 lane=0 max-speed=25g active=true -init set port-map unit=0 port=33 eth-macro=16 lane=1 max-speed=25g active=true -init set port-map unit=0 port=34 eth-macro=16 lane=2 max-speed=25g active=true -init set port-map unit=0 port=35 eth-macro=16 lane=3 max-speed=25g active=true -init set port-map unit=0 port=36 eth-macro=17 lane=0 max-speed=25g active=true -init set port-map unit=0 port=37 eth-macro=17 lane=1 max-speed=25g active=true -init set port-map unit=0 port=38 eth-macro=17 lane=2 max-speed=25g active=true -init set port-map unit=0 port=39 eth-macro=17 lane=3 max-speed=25g active=true -init set port-map unit=0 port=40 eth-macro=18 lane=0 max-speed=25g active=true -init set port-map unit=0 port=41 eth-macro=18 lane=1 max-speed=25g active=true -init set port-map unit=0 port=42 eth-macro=18 lane=2 max-speed=25g active=true -init set port-map unit=0 port=43 eth-macro=18 lane=3 max-speed=25g active=true -init set port-map unit=0 port=44 eth-macro=19 lane=0 max-speed=25g active=true -init set port-map unit=0 port=45 eth-macro=19 lane=1 max-speed=25g active=true -init set port-map unit=0 port=46 eth-macro=19 lane=2 max-speed=25g active=true -init set port-map unit=0 port=47 eth-macro=19 lane=3 max-speed=25g active=true -init set port-map unit=0 port=48 eth-macro=21 lane=0 max-speed=100g active=true -init set port-map unit=0 port=49 eth-macro=20 lane=0 max-speed=100g active=true -init set port-map unit=0 port=50 eth-macro=26 lane=0 max-speed=100g active=true -init set port-map unit=0 port=51 eth-macro=27 lane=0 max-speed=100g active=true -init set port-map unit=0 port=52 eth-macro=28 lane=0 max-speed=100g active=true -init set port-map unit=0 port=53 eth-macro=29 lane=0 max-speed=100g active=true -init set port-map unit=0 port=129 eth-macro=0 lane=1 max-speed=10g active=true guarantee=true cpi=true -init set port-map unit=0 port=130 eth-macro=0 lane=0 max-speed=10g active=true guarantee=true cpi=true init-done=true -init start stage unit=0 task-rsrc -init start stage unit=0 module -init start stage unit=0 task -phy set lane-swap unit=0 portlist=0 lane-cnt=1 property=tx data=0x0 -phy set lane-swap unit=0 portlist=1 lane-cnt=1 property=tx data=0x1 -phy set lane-swap unit=0 portlist=2 lane-cnt=1 property=tx data=0x2 -phy set lane-swap unit=0 portlist=3 lane-cnt=1 property=tx data=0x3 -phy set lane-swap unit=0 portlist=4 lane-cnt=1 property=tx data=0x3 -phy set lane-swap unit=0 portlist=5 lane-cnt=1 property=tx data=0x2 -phy set lane-swap unit=0 portlist=6 lane-cnt=1 property=tx data=0x1 -phy set lane-swap unit=0 portlist=7 lane-cnt=1 property=tx data=0x0 -phy set lane-swap unit=0 portlist=8 lane-cnt=1 property=tx data=0x0 -phy set lane-swap unit=0 portlist=9 lane-cnt=1 property=tx data=0x1 -phy set lane-swap unit=0 portlist=10 lane-cnt=1 property=tx data=0x2 -phy set lane-swap unit=0 portlist=11 lane-cnt=1 property=tx data=0x3 -phy set lane-swap unit=0 portlist=12 lane-cnt=1 property=tx data=0x3 -phy set lane-swap unit=0 portlist=13 lane-cnt=1 property=tx data=0x2 -phy set lane-swap unit=0 portlist=14 lane-cnt=1 property=tx data=0x1 -phy set lane-swap unit=0 portlist=15 lane-cnt=1 property=tx data=0x0 -phy set lane-swap unit=0 portlist=16 lane-cnt=1 property=tx data=0x3 -phy set lane-swap unit=0 portlist=17 lane-cnt=1 property=tx data=0x2 -phy set lane-swap unit=0 portlist=18 lane-cnt=1 property=tx data=0x0 -phy set lane-swap unit=0 portlist=19 lane-cnt=1 property=tx data=0x1 -phy set lane-swap unit=0 portlist=20 lane-cnt=1 property=tx data=0x3 -phy set lane-swap unit=0 portlist=21 lane-cnt=1 property=tx data=0x2 -phy set lane-swap unit=0 portlist=22 lane-cnt=1 property=tx data=0x1 -phy set lane-swap unit=0 portlist=23 lane-cnt=1 property=tx data=0x0 -phy set lane-swap unit=0 portlist=24 lane-cnt=1 property=tx data=0x3 -phy set lane-swap unit=0 portlist=25 lane-cnt=1 property=tx data=0x2 -phy set lane-swap unit=0 portlist=26 lane-cnt=1 property=tx data=0x1 -phy set lane-swap unit=0 portlist=27 lane-cnt=1 property=tx data=0x0 -phy set lane-swap unit=0 portlist=28 lane-cnt=1 property=tx data=0x3 -phy set lane-swap unit=0 portlist=29 lane-cnt=1 property=tx data=0x2 -phy set lane-swap unit=0 portlist=30 lane-cnt=1 property=tx data=0x1 -phy set lane-swap unit=0 portlist=31 lane-cnt=1 property=tx data=0x0 -phy set lane-swap unit=0 portlist=32 lane-cnt=1 property=tx data=0x0 -phy set lane-swap unit=0 portlist=33 lane-cnt=1 property=tx data=0x1 -phy set lane-swap unit=0 portlist=34 lane-cnt=1 property=tx data=0x2 -phy set lane-swap unit=0 portlist=35 lane-cnt=1 property=tx data=0x3 -phy set lane-swap unit=0 portlist=36 lane-cnt=1 property=tx data=0x0 -phy set lane-swap unit=0 portlist=37 lane-cnt=1 property=tx data=0x1 -phy set lane-swap unit=0 portlist=38 lane-cnt=1 property=tx data=0x2 -phy set lane-swap unit=0 portlist=39 lane-cnt=1 property=tx data=0x3 -phy set lane-swap unit=0 portlist=40 lane-cnt=1 property=tx data=0x0 -phy set lane-swap unit=0 portlist=41 lane-cnt=1 property=tx data=0x1 -phy set lane-swap unit=0 portlist=42 lane-cnt=1 property=tx data=0x2 -phy set lane-swap unit=0 portlist=43 lane-cnt=1 property=tx data=0x3 -phy set lane-swap unit=0 portlist=44 lane-cnt=1 property=tx data=0x0 -phy set lane-swap unit=0 portlist=45 lane-cnt=1 property=tx data=0x1 -phy set lane-swap unit=0 portlist=46 lane-cnt=1 property=tx data=0x2 -phy set lane-swap unit=0 portlist=47 lane-cnt=1 property=tx data=0x3 -phy set lane-swap unit=0 portlist=48 lane-cnt=4 property=tx data=0x1.3.0.2 -phy set lane-swap unit=0 portlist=49 lane-cnt=4 property=tx data=0x0.3.1.2 -phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=tx data=0x1.3.0.2 -phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=tx data=0x2.0.3.1 -phy set lane-swap unit=0 portlist=52 lane-cnt=4 property=tx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=tx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=0 lane-cnt=1 property=rx data=0x0 -phy set lane-swap unit=0 portlist=1 lane-cnt=1 property=rx data=0x1 -phy set lane-swap unit=0 portlist=2 lane-cnt=1 property=rx data=0x2 -phy set lane-swap unit=0 portlist=3 lane-cnt=1 property=rx data=0x3 -phy set lane-swap unit=0 portlist=4 lane-cnt=1 property=rx data=0x3 -phy set lane-swap unit=0 portlist=5 lane-cnt=1 property=rx data=0x2 -phy set lane-swap unit=0 portlist=6 lane-cnt=1 property=rx data=0x1 -phy set lane-swap unit=0 portlist=7 lane-cnt=1 property=rx data=0x0 -phy set lane-swap unit=0 portlist=8 lane-cnt=1 property=rx data=0x0 -phy set lane-swap unit=0 portlist=9 lane-cnt=1 property=rx data=0x1 -phy set lane-swap unit=0 portlist=10 lane-cnt=1 property=rx data=0x2 -phy set lane-swap unit=0 portlist=11 lane-cnt=1 property=rx data=0x3 -phy set lane-swap unit=0 portlist=12 lane-cnt=1 property=rx data=0x3 -phy set lane-swap unit=0 portlist=13 lane-cnt=1 property=rx data=0x2 -phy set lane-swap unit=0 portlist=14 lane-cnt=1 property=rx data=0x0 -phy set lane-swap unit=0 portlist=15 lane-cnt=1 property=rx data=0x1 -phy set lane-swap unit=0 portlist=16 lane-cnt=1 property=rx data=0x0 -phy set lane-swap unit=0 portlist=17 lane-cnt=1 property=rx data=0x3 -phy set lane-swap unit=0 portlist=18 lane-cnt=1 property=rx data=0x2 -phy set lane-swap unit=0 portlist=19 lane-cnt=1 property=rx data=0x1 -phy set lane-swap unit=0 portlist=20 lane-cnt=1 property=rx data=0x3 -phy set lane-swap unit=0 portlist=21 lane-cnt=1 property=rx data=0x0 -phy set lane-swap unit=0 portlist=22 lane-cnt=1 property=rx data=0x1 -phy set lane-swap unit=0 portlist=23 lane-cnt=1 property=rx data=0x2 -phy set lane-swap unit=0 portlist=24 lane-cnt=1 property=rx data=0x3 -phy set lane-swap unit=0 portlist=25 lane-cnt=1 property=rx data=0x0 -phy set lane-swap unit=0 portlist=26 lane-cnt=1 property=rx data=0x1 -phy set lane-swap unit=0 portlist=27 lane-cnt=1 property=rx data=0x2 -phy set lane-swap unit=0 portlist=28 lane-cnt=1 property=rx data=0x3 -phy set lane-swap unit=0 portlist=29 lane-cnt=1 property=rx data=0x0 -phy set lane-swap unit=0 portlist=30 lane-cnt=1 property=rx data=0x1 -phy set lane-swap unit=0 portlist=31 lane-cnt=1 property=rx data=0x2 -phy set lane-swap unit=0 portlist=32 lane-cnt=1 property=rx data=0x1 -phy set lane-swap unit=0 portlist=33 lane-cnt=1 property=rx data=0x2 -phy set lane-swap unit=0 portlist=34 lane-cnt=1 property=rx data=0x3 -phy set lane-swap unit=0 portlist=35 lane-cnt=1 property=rx data=0x0 -phy set lane-swap unit=0 portlist=36 lane-cnt=1 property=rx data=0x1 -phy set lane-swap unit=0 portlist=37 lane-cnt=1 property=rx data=0x2 -phy set lane-swap unit=0 portlist=38 lane-cnt=1 property=rx data=0x3 -phy set lane-swap unit=0 portlist=39 lane-cnt=1 property=rx data=0x0 -phy set lane-swap unit=0 portlist=40 lane-cnt=1 property=rx data=0x1 -phy set lane-swap unit=0 portlist=41 lane-cnt=1 property=rx data=0x2 -phy set lane-swap unit=0 portlist=42 lane-cnt=1 property=rx data=0x3 -phy set lane-swap unit=0 portlist=43 lane-cnt=1 property=rx data=0x0 -phy set lane-swap unit=0 portlist=44 lane-cnt=1 property=rx data=0x1 -phy set lane-swap unit=0 portlist=45 lane-cnt=1 property=rx data=0x2 -phy set lane-swap unit=0 portlist=46 lane-cnt=1 property=rx data=0x3 -phy set lane-swap unit=0 portlist=47 lane-cnt=1 property=rx data=0x0 -phy set lane-swap unit=0 portlist=48 lane-cnt=4 property=rx data=0x2.1.0.3 -phy set lane-swap unit=0 portlist=49 lane-cnt=4 property=rx data=0x0.1.3.2 -phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=rx data=0x3.1.0.2 -phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=rx data=0x1.3.0.2 -phy set lane-swap unit=0 portlist=52 lane-cnt=4 property=rx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=rx data=0x3.2.1.0 -phy set polarity-rev unit=0 portlist=0 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=1 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=2 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=3 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=4 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=5 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=6 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=7 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=8 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=9 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=10 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=11 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=12 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=13 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=14 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=15 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=16 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=17 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=18 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=19 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=20 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=21 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=22 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=23 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=24 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=25 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=26 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=27 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=28 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=29 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=30 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=31 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=32 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=33 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=34 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=35 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=36 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=37 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=38 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=39 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=40 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=41 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=42 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=43 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=44 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=45 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=46 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=47 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=48 lane-cnt=4 property=tx data=0x0.0.0.1 -phy set polarity-rev unit=0 portlist=49 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=tx data=0x1.1.0.0 -phy set polarity-rev unit=0 portlist=51 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=52 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=53 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=0 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=1 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=2 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=3 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=4 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=5 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=6 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=7 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=8 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=9 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=10 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=11 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=12 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=13 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=14 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=15 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=16 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=17 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=18 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=19 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=20 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=21 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=22 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=23 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=24 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=25 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=26 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=27 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=28 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=29 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=30 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=31 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=32 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=33 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=34 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=35 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=36 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=37 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=38 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=39 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=40 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=41 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=42 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=43 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=44 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=45 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=46 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=47 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=48 lane-cnt=4 property=rx data=0x0.1.0.1 -phy set polarity-rev unit=0 portlist=49 lane-cnt=4 property=rx data=0x1.0.1.0 -phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=rx data=0x0.0.1.0 -phy set polarity-rev unit=0 portlist=51 lane-cnt=4 property=rx data=0x0.0.0.1 -phy set polarity-rev unit=0 portlist=52 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=53 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=0 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=0 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=0 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e -phy set pre-emphasis unit=0 portlist=0 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis unit=0 portlist=4 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=4 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=4 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e -phy set pre-emphasis unit=0 portlist=4 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis unit=0 portlist=8 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=8 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=8 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e -phy set pre-emphasis unit=0 portlist=8 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis unit=0 portlist=12 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=12 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=12 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e -phy set pre-emphasis unit=0 portlist=12 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis unit=0 portlist=16 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=16 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=16 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e -phy set pre-emphasis unit=0 portlist=16 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis unit=0 portlist=20 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=20 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=20 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e -phy set pre-emphasis unit=0 portlist=20 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis unit=0 portlist=24 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=24 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=24 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e -phy set pre-emphasis unit=0 portlist=24 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis unit=0 portlist=28 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=28 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=28 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e -phy set pre-emphasis unit=0 portlist=28 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis unit=0 portlist=32 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=32 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=32 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e -phy set pre-emphasis unit=0 portlist=32 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis unit=0 portlist=36 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=36 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=36 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e -phy set pre-emphasis unit=0 portlist=36 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis unit=0 portlist=40 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=40 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=40 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e -phy set pre-emphasis unit=0 portlist=40 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis unit=0 portlist=44 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=44 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=44 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e -phy set pre-emphasis unit=0 portlist=44 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis unit=0 portlist=48 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=48 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=48 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e -phy set pre-emphasis unit=0 portlist=48 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis unit=0 portlist=49 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=49 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=49 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e -phy set pre-emphasis unit=0 portlist=49 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis unit=0 portlist=50 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=50 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=50 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e -phy set pre-emphasis unit=0 portlist=50 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis unit=0 portlist=51 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=51 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=51 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e -phy set pre-emphasis unit=0 portlist=51 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis unit=0 portlist=52 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=52 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=52 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e -phy set pre-emphasis unit=0 portlist=52 lane-cnt=4 property=c1 data=0x2.2.2.2 -phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c2 data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=cn1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c0 data=0x1e.1e.1e.1e -phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c1 data=0x2.2.2.2 -port set property unit=0 portlist=0-47 speed=25g -port set property unit=0 portlist=48-53 speed=100g -port set property unit=0 portlist=129-130 speed=10g -port set property unit=0 portlist=0-47 medium-type=cr -port set property unit=0 portlist=48-53 medium-type=cr4 -port set property unit=0 portlist=129-130 medium-type=kr -port set adver unit=0 portlist=129-130 speed-10g-kr -port set property unit=0 portlist=129-130 an=enable -port set property unit=0 portlist=0-53,129-130 admin=enable diff --git a/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/port_config.nps b/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/port_config.nps index f9e5396d0cfc..49068859b25c 100644 --- a/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/port_config.nps +++ b/device/ingrasys/x86_64-ingrasys_s9130_32x-r0/INGRASYS-S9130-32X/port_config.nps @@ -308,6 +308,40 @@ phy set pre-emphasis unit=0 portlist=130 lane-cnt=1 property=c2 data=0x01 phy set pre-emphasis unit=0 portlist=130 lane-cnt=1 property=cn1 data=0x01 phy set pre-emphasis unit=0 portlist=130 lane-cnt=1 property=c0 data=0x02 phy set pre-emphasis unit=0 portlist=130 lane-cnt=1 property=c1 data=0x03 +phy set mdio portlist=0 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=1 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=2 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=3 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=4 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=5 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=6 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=7 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=8 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=9 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=10 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=11 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=12 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=13 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=14 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=15 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=16 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=17 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=18 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=19 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=20 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=21 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=22 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=23 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=24 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=25 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=26 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=27 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=28 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=29 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=30 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=31 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=129 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=130 devad=0x1E addr=0x2 data=0x0000 port set property unit=0 portlist=0-31 speed=100g port set property unit=0 portlist=129-130 speed=10g port set property unit=0 portlist=0-31 medium-type=sr4 diff --git a/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/port_config.ini b/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/port_config.ini index 18b9d933a669..d57c1f350186 100644 --- a/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/port_config.ini +++ b/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/port_config.ini @@ -1,6 +1,6 @@ # name lanes alias index -Ethernet0 4,5,6,7 Ethernet1/1 0 -Ethernet4 0,1,2,3 Ethernet2/1 1 +Ethernet0 0,1,2,3 Ethernet1/1 0 +Ethernet4 4,5,6,7 Ethernet2/1 1 Ethernet8 20,21,22,23 Ethernet3/1 2 Ethernet12 16,17,18,19 Ethernet4/1 3 Ethernet16 36,37,38,39 Ethernet5/1 4 @@ -61,5 +61,5 @@ Ethernet232 220,221,222,223 Ethernet59/1 58 Ethernet236 216,217,218,219 Ethernet60/1 59 Ethernet240 236,237,238,239 Ethernet61/1 60 Ethernet244 232,233,234,235 Ethernet62/1 61 -Ethernet248 252,253,254,255 Ethernet63/1 62 -Ethernet252 248,249,250,251 Ethernet64/1 63 +Ethernet248 248,249,250,251 Ethernet63/1 62 +Ethernet252 252,253,254,255 Ethernet64/1 63 \ No newline at end of file diff --git a/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/port_config.nps b/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/port_config.nps index 4f86c1c44235..0e14b9ced3fe 100644 --- a/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/port_config.nps +++ b/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/INGRASYS-S9230-64X/port_config.nps @@ -1,864 +1,681 @@ -init start stage unit=0 low-level -init set port-map unit=0 port=0 eth-macro=1 lane=0 max-speed=100g active=true -init set port-map unit=0 port=1 eth-macro=0 lane=0 max-speed=100g active=true -init set port-map unit=0 port=2 eth-macro=5 lane=0 max-speed=100g active=true -init set port-map unit=0 port=3 eth-macro=4 lane=0 max-speed=100g active=true -init set port-map unit=0 port=4 eth-macro=9 lane=0 max-speed=100g active=true -init set port-map unit=0 port=5 eth-macro=8 lane=0 max-speed=100g active=true -init set port-map unit=0 port=6 eth-macro=13 lane=0 max-speed=100g active=true -init set port-map unit=0 port=7 eth-macro=12 lane=0 max-speed=100g active=true -init set port-map unit=0 port=8 eth-macro=17 lane=0 max-speed=100g active=true -init set port-map unit=0 port=9 eth-macro=16 lane=0 max-speed=100g active=true -init set port-map unit=0 port=10 eth-macro=21 lane=0 max-speed=100g active=true -init set port-map unit=0 port=11 eth-macro=20 lane=0 max-speed=100g active=true -init set port-map unit=0 port=12 eth-macro=25 lane=0 max-speed=100g active=true -init set port-map unit=0 port=13 eth-macro=24 lane=0 max-speed=100g active=true -init set port-map unit=0 port=14 eth-macro=29 lane=0 max-speed=100g active=true -init set port-map unit=0 port=15 eth-macro=28 lane=0 max-speed=100g active=true -init set port-map unit=0 port=16 eth-macro=33 lane=0 max-speed=100g active=true -init set port-map unit=0 port=17 eth-macro=32 lane=0 max-speed=100g active=true -init set port-map unit=0 port=18 eth-macro=37 lane=0 max-speed=100g active=true -init set port-map unit=0 port=19 eth-macro=36 lane=0 max-speed=100g active=true -init set port-map unit=0 port=20 eth-macro=41 lane=0 max-speed=100g active=true -init set port-map unit=0 port=21 eth-macro=40 lane=0 max-speed=100g active=true -init set port-map unit=0 port=22 eth-macro=45 lane=0 max-speed=100g active=true -init set port-map unit=0 port=23 eth-macro=44 lane=0 max-speed=100g active=true -init set port-map unit=0 port=24 eth-macro=49 lane=0 max-speed=100g active=true -init set port-map unit=0 port=25 eth-macro=48 lane=0 max-speed=100g active=true -init set port-map unit=0 port=26 eth-macro=53 lane=0 max-speed=100g active=true -init set port-map unit=0 port=27 eth-macro=52 lane=0 max-speed=100g active=true -init set port-map unit=0 port=28 eth-macro=57 lane=0 max-speed=100g active=true -init set port-map unit=0 port=29 eth-macro=56 lane=0 max-speed=100g active=true -init set port-map unit=0 port=30 eth-macro=61 lane=0 max-speed=100g active=true -init set port-map unit=0 port=31 eth-macro=60 lane=0 max-speed=100g active=true -init set port-map unit=0 port=32 eth-macro=3 lane=0 max-speed=100g active=true -init set port-map unit=0 port=33 eth-macro=2 lane=0 max-speed=100g active=true -init set port-map unit=0 port=34 eth-macro=7 lane=0 max-speed=100g active=true -init set port-map unit=0 port=35 eth-macro=6 lane=0 max-speed=100g active=true -init set port-map unit=0 port=36 eth-macro=11 lane=0 max-speed=100g active=true -init set port-map unit=0 port=37 eth-macro=10 lane=0 max-speed=100g active=true -init set port-map unit=0 port=38 eth-macro=15 lane=0 max-speed=100g active=true -init set port-map unit=0 port=39 eth-macro=14 lane=0 max-speed=100g active=true -init set port-map unit=0 port=40 eth-macro=19 lane=0 max-speed=100g active=true -init set port-map unit=0 port=41 eth-macro=18 lane=0 max-speed=100g active=true -init set port-map unit=0 port=42 eth-macro=23 lane=0 max-speed=100g active=true -init set port-map unit=0 port=43 eth-macro=22 lane=0 max-speed=100g active=true -init set port-map unit=0 port=44 eth-macro=27 lane=0 max-speed=100g active=true -init set port-map unit=0 port=45 eth-macro=26 lane=0 max-speed=100g active=true -init set port-map unit=0 port=46 eth-macro=31 lane=0 max-speed=100g active=true -init set port-map unit=0 port=47 eth-macro=30 lane=0 max-speed=100g active=true -init set port-map unit=0 port=48 eth-macro=35 lane=0 max-speed=100g active=true -init set port-map unit=0 port=49 eth-macro=34 lane=0 max-speed=100g active=true -init set port-map unit=0 port=50 eth-macro=39 lane=0 max-speed=100g active=true -init set port-map unit=0 port=51 eth-macro=38 lane=0 max-speed=100g active=true -init set port-map unit=0 port=52 eth-macro=43 lane=0 max-speed=100g active=true -init set port-map unit=0 port=53 eth-macro=42 lane=0 max-speed=100g active=true -init set port-map unit=0 port=54 eth-macro=47 lane=0 max-speed=100g active=true -init set port-map unit=0 port=55 eth-macro=46 lane=0 max-speed=100g active=true -init set port-map unit=0 port=56 eth-macro=51 lane=0 max-speed=100g active=true -init set port-map unit=0 port=57 eth-macro=50 lane=0 max-speed=100g active=true -init set port-map unit=0 port=58 eth-macro=55 lane=0 max-speed=100g active=true -init set port-map unit=0 port=59 eth-macro=54 lane=0 max-speed=100g active=true -init set port-map unit=0 port=60 eth-macro=59 lane=0 max-speed=100g active=true -init set port-map unit=0 port=61 eth-macro=58 lane=0 max-speed=100g active=true -init set port-map unit=0 port=62 eth-macro=63 lane=0 max-speed=100g active=true -init set port-map unit=0 port=63 eth-macro=62 lane=0 max-speed=100g active=true -init set port-map unit=0 port=129 eth-macro=0 lane=1 max-speed=10g active=true guarantee=true cpi=true -init set port-map unit=0 port=130 eth-macro=0 lane=0 max-speed=10g active=true guarantee=true cpi=true init-done=true -init start stage unit=0 task-rsrc -init start stage unit=0 module -init start stage unit=0 task -phy set lane-swap unit=0 portlist=0 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=1 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=2 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=3 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=4 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=5 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=6 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=7 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=8 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=9 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=10 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=11 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=12 lane-cnt=4 property=tx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=13 lane-cnt=4 property=tx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=14 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=15 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=16 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=17 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=18 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=19 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=20 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=21 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=22 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=23 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=24 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=25 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=26 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=27 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=28 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=29 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=30 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=31 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=32 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=33 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=34 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=35 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=36 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=37 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=38 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=39 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=40 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=41 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=42 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=43 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=44 lane-cnt=4 property=tx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=45 lane-cnt=4 property=tx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=46 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=47 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=48 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=49 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=52 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=54 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=55 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=56 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=57 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=58 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=59 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=60 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=61 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=62 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=63 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=129 lane-cnt=1 property=tx data=0x1 -phy set lane-swap unit=0 portlist=130 lane-cnt=1 property=tx data=0x0 -phy set lane-swap unit=0 portlist=0 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=1 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=2 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=3 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=4 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=5 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=6 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=7 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=8 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=9 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=10 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=11 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=12 lane-cnt=4 property=rx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=13 lane-cnt=4 property=rx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=14 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=15 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=16 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=17 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=18 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=19 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=20 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=21 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=22 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=23 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=24 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=25 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=26 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=27 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=28 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=29 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=30 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=31 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=32 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=33 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=34 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=35 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=36 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=37 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=38 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=39 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=40 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=41 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=42 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=43 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=44 lane-cnt=4 property=rx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=45 lane-cnt=4 property=rx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=46 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=47 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=48 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=49 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=52 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=54 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=55 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=56 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=57 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=58 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=59 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=60 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=61 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=62 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=63 lane-cnt=4 property=rx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=129 lane-cnt=1 property=rx data=0x1 -phy set lane-swap unit=0 portlist=130 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=0 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=1 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=2 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=3 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=4 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=5 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=6 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=7 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=8 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=9 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=10 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=11 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=12 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=13 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=14 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=15 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=16 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=17 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=18 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=19 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=20 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=21 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=22 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=23 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=24 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=25 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=26 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=27 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=28 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=29 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=30 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=31 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=32 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=33 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=34 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=35 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=36 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=37 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=38 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=39 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=40 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=41 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=42 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=43 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=44 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=45 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=46 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=47 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=48 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=49 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=51 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=52 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=53 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=54 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=55 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=56 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=57 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=58 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=59 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=60 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=61 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=62 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=63 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=129 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=130 lane-cnt=1 property=tx data=0x0 -phy set polarity-rev unit=0 portlist=0 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=1 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=2 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=3 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=4 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=5 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=6 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=7 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=8 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=9 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=10 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=11 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=12 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=13 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=14 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=15 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=16 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=17 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=18 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=19 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=20 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=21 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=22 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=23 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=24 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=25 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=26 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=27 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=28 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=29 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=30 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=31 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=32 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=33 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=34 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=35 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=36 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=37 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=38 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=39 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=40 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=41 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=42 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=43 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=44 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=45 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=46 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=47 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=48 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=49 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=51 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=52 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=53 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=54 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=55 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=56 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=57 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=58 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=59 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=60 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=61 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=62 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=63 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=129 lane-cnt=1 property=rx data=0x0 -phy set polarity-rev unit=0 portlist=130 lane-cnt=1 property=rx data=0x0 -phy set pre-emphasis unit=0 portlist=0 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=0 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=0 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a -phy set pre-emphasis unit=0 portlist=0 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis unit=0 portlist=1 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=1 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=1 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a -phy set pre-emphasis unit=0 portlist=1 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis unit=0 portlist=2 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=2 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=2 lane-cnt=4 property=c0 data=0x19.19.19.19 -phy set pre-emphasis unit=0 portlist=2 lane-cnt=4 property=c1 data=0x7.7.7.7 -phy set pre-emphasis unit=0 portlist=3 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=3 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=3 lane-cnt=4 property=c0 data=0x19.19.19.19 -phy set pre-emphasis unit=0 portlist=3 lane-cnt=4 property=c1 data=0x7.7.7.7 -phy set pre-emphasis unit=0 portlist=4 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=4 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=4 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a -phy set pre-emphasis unit=0 portlist=4 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis unit=0 portlist=5 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=5 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=5 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a -phy set pre-emphasis unit=0 portlist=5 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis unit=0 portlist=6 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=6 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=6 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=6 lane-cnt=4 property=c1 data=0x5.5.5.5 -phy set pre-emphasis unit=0 portlist=7 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=7 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=7 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=7 lane-cnt=4 property=c1 data=0x5.5.5.5 -phy set pre-emphasis unit=0 portlist=8 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=8 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=8 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=8 lane-cnt=4 property=c1 data=0x5.5.5.5 -phy set pre-emphasis unit=0 portlist=9 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=9 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=9 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=9 lane-cnt=4 property=c1 data=0x5.5.5.5 -phy set pre-emphasis unit=0 portlist=10 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=10 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=10 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=10 lane-cnt=4 property=c1 data=0x5.5.5.5 -phy set pre-emphasis unit=0 portlist=11 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=11 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=11 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=11 lane-cnt=4 property=c1 data=0x5.5.5.5 -phy set pre-emphasis unit=0 portlist=12 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=12 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=12 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=12 lane-cnt=4 property=c1 data=0x5.5.5.5 -phy set pre-emphasis unit=0 portlist=13 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=13 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=13 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=13 lane-cnt=4 property=c1 data=0x5.5.5.5 -phy set pre-emphasis unit=0 portlist=14 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=14 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=14 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c -phy set pre-emphasis unit=0 portlist=14 lane-cnt=4 property=c1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=15 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=15 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=15 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c -phy set pre-emphasis unit=0 portlist=15 lane-cnt=4 property=c1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=16 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=16 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=16 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c -phy set pre-emphasis unit=0 portlist=16 lane-cnt=4 property=c1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=17 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=17 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=17 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c -phy set pre-emphasis unit=0 portlist=17 lane-cnt=4 property=c1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=18 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=18 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=18 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c -phy set pre-emphasis unit=0 portlist=18 lane-cnt=4 property=c1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=19 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=19 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=19 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c -phy set pre-emphasis unit=0 portlist=19 lane-cnt=4 property=c1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=20 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=20 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=20 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=20 lane-cnt=4 property=c1 data=0x5.5.5.5 -phy set pre-emphasis unit=0 portlist=21 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=21 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=21 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=21 lane-cnt=4 property=c1 data=0x5.5.5.5 -phy set pre-emphasis unit=0 portlist=22 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=22 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=22 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c -phy set pre-emphasis unit=0 portlist=22 lane-cnt=4 property=c1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=23 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=23 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=23 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c -phy set pre-emphasis unit=0 portlist=23 lane-cnt=4 property=c1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=24 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=24 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=24 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=24 lane-cnt=4 property=c1 data=0x5.5.5.5 -phy set pre-emphasis unit=0 portlist=25 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=25 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=25 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=25 lane-cnt=4 property=c1 data=0x5.5.5.5 -phy set pre-emphasis unit=0 portlist=26 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=26 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=26 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a -phy set pre-emphasis unit=0 portlist=26 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis unit=0 portlist=27 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=27 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=27 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a -phy set pre-emphasis unit=0 portlist=27 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis unit=0 portlist=28 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=28 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=28 lane-cnt=4 property=c0 data=0x19.19.19.19 -phy set pre-emphasis unit=0 portlist=28 lane-cnt=4 property=c1 data=0x7.7.7.7 -phy set pre-emphasis unit=0 portlist=29 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=29 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=29 lane-cnt=4 property=c0 data=0x19.19.19.19 -phy set pre-emphasis unit=0 portlist=29 lane-cnt=4 property=c1 data=0x7.7.7.7 -phy set pre-emphasis unit=0 portlist=30 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=30 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=30 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a -phy set pre-emphasis unit=0 portlist=30 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis unit=0 portlist=31 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=31 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=31 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a -phy set pre-emphasis unit=0 portlist=31 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis unit=0 portlist=32 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=32 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=32 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a -phy set pre-emphasis unit=0 portlist=32 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis unit=0 portlist=33 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=33 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=33 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a -phy set pre-emphasis unit=0 portlist=33 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis unit=0 portlist=34 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=34 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=34 lane-cnt=4 property=c0 data=0x19.19.19.19 -phy set pre-emphasis unit=0 portlist=34 lane-cnt=4 property=c1 data=0x7.7.7.7 -phy set pre-emphasis unit=0 portlist=35 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=35 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=35 lane-cnt=4 property=c0 data=0x19.19.19.19 -phy set pre-emphasis unit=0 portlist=35 lane-cnt=4 property=c1 data=0x7.7.7.7 -phy set pre-emphasis unit=0 portlist=36 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=36 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=36 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a -phy set pre-emphasis unit=0 portlist=36 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis unit=0 portlist=37 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=37 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=37 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a -phy set pre-emphasis unit=0 portlist=37 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis unit=0 portlist=38 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=38 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=38 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=38 lane-cnt=4 property=c1 data=0x5.5.5.5 -phy set pre-emphasis unit=0 portlist=39 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=39 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=39 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=39 lane-cnt=4 property=c1 data=0x5.5.5.5 -phy set pre-emphasis unit=0 portlist=40 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=40 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=40 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=40 lane-cnt=4 property=c1 data=0x5.5.5.5 -phy set pre-emphasis unit=0 portlist=41 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=41 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=41 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=41 lane-cnt=4 property=c1 data=0x5.5.5.5 -phy set pre-emphasis unit=0 portlist=42 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=42 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=42 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=42 lane-cnt=4 property=c1 data=0x5.5.5.5 -phy set pre-emphasis unit=0 portlist=43 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=43 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=43 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=43 lane-cnt=4 property=c1 data=0x5.5.5.5 -phy set pre-emphasis unit=0 portlist=44 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=44 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=44 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=44 lane-cnt=4 property=c1 data=0x5.5.5.5 -phy set pre-emphasis unit=0 portlist=45 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=45 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=45 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=45 lane-cnt=4 property=c1 data=0x5.5.5.5 -phy set pre-emphasis unit=0 portlist=46 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=46 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=46 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c -phy set pre-emphasis unit=0 portlist=46 lane-cnt=4 property=c1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=47 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=47 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=47 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c -phy set pre-emphasis unit=0 portlist=47 lane-cnt=4 property=c1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=48 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=48 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=48 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c -phy set pre-emphasis unit=0 portlist=48 lane-cnt=4 property=c1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=49 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=49 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=49 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c -phy set pre-emphasis unit=0 portlist=49 lane-cnt=4 property=c1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=50 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=50 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=50 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c -phy set pre-emphasis unit=0 portlist=50 lane-cnt=4 property=c1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=51 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=51 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=51 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c -phy set pre-emphasis unit=0 portlist=51 lane-cnt=4 property=c1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=52 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=52 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=52 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=52 lane-cnt=4 property=c1 data=0x5.5.5.5 -phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c1 data=0x5.5.5.5 -phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c -phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=c1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=c0 data=0x1c.1c.1c.1c -phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=c1 data=0x4.4.4.4 -phy set pre-emphasis unit=0 portlist=56 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=56 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=56 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=56 lane-cnt=4 property=c1 data=0x5.5.5.5 -phy set pre-emphasis unit=0 portlist=57 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=57 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=57 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=57 lane-cnt=4 property=c1 data=0x5.5.5.5 -phy set pre-emphasis unit=0 portlist=58 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=58 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=58 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a -phy set pre-emphasis unit=0 portlist=58 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis unit=0 portlist=59 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=59 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=59 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a -phy set pre-emphasis unit=0 portlist=59 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis unit=0 portlist=60 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=60 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=60 lane-cnt=4 property=c0 data=0x19.19.19.19 -phy set pre-emphasis unit=0 portlist=60 lane-cnt=4 property=c1 data=0x7.7.7.7 -phy set pre-emphasis unit=0 portlist=61 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=61 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=61 lane-cnt=4 property=c0 data=0x19.19.19.19 -phy set pre-emphasis unit=0 portlist=61 lane-cnt=4 property=c1 data=0x7.7.7.7 -phy set pre-emphasis unit=0 portlist=62 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=62 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=62 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a -phy set pre-emphasis unit=0 portlist=62 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis unit=0 portlist=63 lane-cnt=4 property=c2 data=0x1.1.1.1 -phy set pre-emphasis unit=0 portlist=63 lane-cnt=4 property=cn1 data=0x3.3.3.3 -phy set pre-emphasis unit=0 portlist=63 lane-cnt=4 property=c0 data=0x1a.1a.1a.1a -phy set pre-emphasis unit=0 portlist=63 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis unit=0 portlist=129 lane-cnt=1 property=c2 data=0x1 -phy set pre-emphasis unit=0 portlist=129 lane-cnt=1 property=cn1 data=0x1 -phy set pre-emphasis unit=0 portlist=129 lane-cnt=1 property=c0 data=0x2 -phy set pre-emphasis unit=0 portlist=129 lane-cnt=1 property=c1 data=0x3 -phy set pre-emphasis unit=0 portlist=130 lane-cnt=1 property=c2 data=0x1 -phy set pre-emphasis unit=0 portlist=130 lane-cnt=1 property=cn1 data=0x1 -phy set pre-emphasis unit=0 portlist=130 lane-cnt=1 property=c0 data=0x2 -phy set pre-emphasis unit=0 portlist=130 lane-cnt=1 property=c1 data=0x3 -port set property unit=0 portlist=0 speed=100g -port set property unit=0 portlist=1 speed=100g -port set property unit=0 portlist=2 speed=100g -port set property unit=0 portlist=3 speed=100g -port set property unit=0 portlist=4 speed=100g -port set property unit=0 portlist=5 speed=100g -port set property unit=0 portlist=6 speed=100g -port set property unit=0 portlist=7 speed=100g -port set property unit=0 portlist=8 speed=100g -port set property unit=0 portlist=9 speed=100g -port set property unit=0 portlist=10 speed=100g -port set property unit=0 portlist=11 speed=100g -port set property unit=0 portlist=12 speed=100g -port set property unit=0 portlist=13 speed=100g -port set property unit=0 portlist=14 speed=100g -port set property unit=0 portlist=15 speed=100g -port set property unit=0 portlist=16 speed=100g -port set property unit=0 portlist=17 speed=100g -port set property unit=0 portlist=18 speed=100g -port set property unit=0 portlist=19 speed=100g -port set property unit=0 portlist=20 speed=100g -port set property unit=0 portlist=21 speed=100g -port set property unit=0 portlist=22 speed=100g -port set property unit=0 portlist=23 speed=100g -port set property unit=0 portlist=24 speed=100g -port set property unit=0 portlist=25 speed=100g -port set property unit=0 portlist=26 speed=100g -port set property unit=0 portlist=27 speed=100g -port set property unit=0 portlist=28 speed=100g -port set property unit=0 portlist=29 speed=100g -port set property unit=0 portlist=30 speed=100g -port set property unit=0 portlist=31 speed=100g -port set property unit=0 portlist=32 speed=100g -port set property unit=0 portlist=33 speed=100g -port set property unit=0 portlist=34 speed=100g -port set property unit=0 portlist=35 speed=100g -port set property unit=0 portlist=36 speed=100g -port set property unit=0 portlist=37 speed=100g -port set property unit=0 portlist=38 speed=100g -port set property unit=0 portlist=39 speed=100g -port set property unit=0 portlist=40 speed=100g -port set property unit=0 portlist=41 speed=100g -port set property unit=0 portlist=42 speed=100g -port set property unit=0 portlist=43 speed=100g -port set property unit=0 portlist=44 speed=100g -port set property unit=0 portlist=45 speed=100g -port set property unit=0 portlist=46 speed=100g -port set property unit=0 portlist=47 speed=100g -port set property unit=0 portlist=48 speed=100g -port set property unit=0 portlist=49 speed=100g -port set property unit=0 portlist=50 speed=100g -port set property unit=0 portlist=51 speed=100g -port set property unit=0 portlist=52 speed=100g -port set property unit=0 portlist=53 speed=100g -port set property unit=0 portlist=54 speed=100g -port set property unit=0 portlist=55 speed=100g -port set property unit=0 portlist=56 speed=100g -port set property unit=0 portlist=57 speed=100g -port set property unit=0 portlist=58 speed=100g -port set property unit=0 portlist=59 speed=100g -port set property unit=0 portlist=60 speed=100g -port set property unit=0 portlist=61 speed=100g -port set property unit=0 portlist=62 speed=100g -port set property unit=0 portlist=63 speed=100g -port set property unit=0 portlist=129 speed=10g -port set property unit=0 portlist=130 speed=10g -port set property unit=0 portlist=0 medium-type=sr4 -port set property unit=0 portlist=1 medium-type=sr4 -port set property unit=0 portlist=2 medium-type=sr4 -port set property unit=0 portlist=3 medium-type=sr4 -port set property unit=0 portlist=4 medium-type=sr4 -port set property unit=0 portlist=5 medium-type=sr4 -port set property unit=0 portlist=6 medium-type=sr4 -port set property unit=0 portlist=7 medium-type=sr4 -port set property unit=0 portlist=8 medium-type=sr4 -port set property unit=0 portlist=9 medium-type=sr4 -port set property unit=0 portlist=10 medium-type=sr4 -port set property unit=0 portlist=11 medium-type=sr4 -port set property unit=0 portlist=12 medium-type=sr4 -port set property unit=0 portlist=13 medium-type=sr4 -port set property unit=0 portlist=14 medium-type=sr4 -port set property unit=0 portlist=15 medium-type=sr4 -port set property unit=0 portlist=16 medium-type=sr4 -port set property unit=0 portlist=17 medium-type=sr4 -port set property unit=0 portlist=18 medium-type=sr4 -port set property unit=0 portlist=19 medium-type=sr4 -port set property unit=0 portlist=20 medium-type=sr4 -port set property unit=0 portlist=21 medium-type=sr4 -port set property unit=0 portlist=22 medium-type=sr4 -port set property unit=0 portlist=23 medium-type=sr4 -port set property unit=0 portlist=24 medium-type=sr4 -port set property unit=0 portlist=25 medium-type=sr4 -port set property unit=0 portlist=26 medium-type=sr4 -port set property unit=0 portlist=27 medium-type=sr4 -port set property unit=0 portlist=28 medium-type=sr4 -port set property unit=0 portlist=29 medium-type=sr4 -port set property unit=0 portlist=30 medium-type=sr4 -port set property unit=0 portlist=31 medium-type=sr4 -port set property unit=0 portlist=32 medium-type=sr4 -port set property unit=0 portlist=33 medium-type=sr4 -port set property unit=0 portlist=34 medium-type=sr4 -port set property unit=0 portlist=35 medium-type=sr4 -port set property unit=0 portlist=36 medium-type=sr4 -port set property unit=0 portlist=37 medium-type=sr4 -port set property unit=0 portlist=38 medium-type=sr4 -port set property unit=0 portlist=39 medium-type=sr4 -port set property unit=0 portlist=40 medium-type=sr4 -port set property unit=0 portlist=41 medium-type=sr4 -port set property unit=0 portlist=42 medium-type=sr4 -port set property unit=0 portlist=43 medium-type=sr4 -port set property unit=0 portlist=44 medium-type=sr4 -port set property unit=0 portlist=45 medium-type=sr4 -port set property unit=0 portlist=46 medium-type=sr4 -port set property unit=0 portlist=47 medium-type=sr4 -port set property unit=0 portlist=48 medium-type=sr4 -port set property unit=0 portlist=49 medium-type=sr4 -port set property unit=0 portlist=50 medium-type=sr4 -port set property unit=0 portlist=51 medium-type=sr4 -port set property unit=0 portlist=52 medium-type=sr4 -port set property unit=0 portlist=53 medium-type=sr4 -port set property unit=0 portlist=54 medium-type=sr4 -port set property unit=0 portlist=55 medium-type=sr4 -port set property unit=0 portlist=56 medium-type=sr4 -port set property unit=0 portlist=57 medium-type=sr4 -port set property unit=0 portlist=58 medium-type=sr4 -port set property unit=0 portlist=59 medium-type=sr4 -port set property unit=0 portlist=60 medium-type=sr4 -port set property unit=0 portlist=61 medium-type=sr4 -port set property unit=0 portlist=62 medium-type=sr4 -port set property unit=0 portlist=63 medium-type=sr4 -port set property unit=0 portlist=129 medium-type=kr -port set property unit=0 portlist=130 medium-type=kr -port set property unit=0 portlist=0 fec=disable -port set property unit=0 portlist=1 fec=disable -port set property unit=0 portlist=2 fec=disable -port set property unit=0 portlist=3 fec=disable -port set property unit=0 portlist=4 fec=disable -port set property unit=0 portlist=5 fec=disable -port set property unit=0 portlist=6 fec=disable -port set property unit=0 portlist=7 fec=disable -port set property unit=0 portlist=8 fec=disable -port set property unit=0 portlist=9 fec=disable -port set property unit=0 portlist=10 fec=disable -port set property unit=0 portlist=11 fec=disable -port set property unit=0 portlist=12 fec=disable -port set property unit=0 portlist=13 fec=disable -port set property unit=0 portlist=14 fec=disable -port set property unit=0 portlist=15 fec=disable -port set property unit=0 portlist=16 fec=disable -port set property unit=0 portlist=17 fec=disable -port set property unit=0 portlist=18 fec=disable -port set property unit=0 portlist=19 fec=disable -port set property unit=0 portlist=20 fec=disable -port set property unit=0 portlist=21 fec=disable -port set property unit=0 portlist=22 fec=disable -port set property unit=0 portlist=23 fec=disable -port set property unit=0 portlist=24 fec=disable -port set property unit=0 portlist=25 fec=disable -port set property unit=0 portlist=26 fec=disable -port set property unit=0 portlist=27 fec=disable -port set property unit=0 portlist=28 fec=disable -port set property unit=0 portlist=29 fec=disable -port set property unit=0 portlist=30 fec=disable -port set property unit=0 portlist=31 fec=disable -port set property unit=0 portlist=32 fec=disable -port set property unit=0 portlist=33 fec=disable -port set property unit=0 portlist=34 fec=disable -port set property unit=0 portlist=35 fec=disable -port set property unit=0 portlist=36 fec=disable -port set property unit=0 portlist=37 fec=disable -port set property unit=0 portlist=38 fec=disable -port set property unit=0 portlist=39 fec=disable -port set property unit=0 portlist=40 fec=disable -port set property unit=0 portlist=41 fec=disable -port set property unit=0 portlist=42 fec=disable -port set property unit=0 portlist=43 fec=disable -port set property unit=0 portlist=44 fec=disable -port set property unit=0 portlist=45 fec=disable -port set property unit=0 portlist=46 fec=disable -port set property unit=0 portlist=47 fec=disable -port set property unit=0 portlist=48 fec=disable -port set property unit=0 portlist=49 fec=disable -port set property unit=0 portlist=50 fec=disable -port set property unit=0 portlist=51 fec=disable -port set property unit=0 portlist=52 fec=disable -port set property unit=0 portlist=53 fec=disable -port set property unit=0 portlist=54 fec=disable -port set property unit=0 portlist=55 fec=disable -port set property unit=0 portlist=56 fec=disable -port set property unit=0 portlist=57 fec=disable -port set property unit=0 portlist=58 fec=disable -port set property unit=0 portlist=59 fec=disable -port set property unit=0 portlist=60 fec=disable -port set property unit=0 portlist=61 fec=disable -port set property unit=0 portlist=62 fec=disable -port set property unit=0 portlist=63 fec=disable -port set adver unit=0 portlist=129 speed-10g-kr -port set adver unit=0 portlist=130 speed-10g-kr -port set property unit=0 portlist=129 an=enable -port set property unit=0 portlist=130 an=enable -port set property unit=0 portlist=0 admin=enable -port set property unit=0 portlist=1 admin=enable -port set property unit=0 portlist=2 admin=enable -port set property unit=0 portlist=3 admin=enable -port set property unit=0 portlist=4 admin=enable -port set property unit=0 portlist=5 admin=enable -port set property unit=0 portlist=6 admin=enable -port set property unit=0 portlist=7 admin=enable -port set property unit=0 portlist=8 admin=enable -port set property unit=0 portlist=9 admin=enable -port set property unit=0 portlist=10 admin=enable -port set property unit=0 portlist=11 admin=enable -port set property unit=0 portlist=12 admin=enable -port set property unit=0 portlist=13 admin=enable -port set property unit=0 portlist=14 admin=enable -port set property unit=0 portlist=15 admin=enable -port set property unit=0 portlist=16 admin=enable -port set property unit=0 portlist=17 admin=enable -port set property unit=0 portlist=18 admin=enable -port set property unit=0 portlist=19 admin=enable -port set property unit=0 portlist=20 admin=enable -port set property unit=0 portlist=21 admin=enable -port set property unit=0 portlist=22 admin=enable -port set property unit=0 portlist=23 admin=enable -port set property unit=0 portlist=24 admin=enable -port set property unit=0 portlist=25 admin=enable -port set property unit=0 portlist=26 admin=enable -port set property unit=0 portlist=27 admin=enable -port set property unit=0 portlist=28 admin=enable -port set property unit=0 portlist=29 admin=enable -port set property unit=0 portlist=30 admin=enable -port set property unit=0 portlist=31 admin=enable -port set property unit=0 portlist=32 admin=enable -port set property unit=0 portlist=33 admin=enable -port set property unit=0 portlist=34 admin=enable -port set property unit=0 portlist=35 admin=enable -port set property unit=0 portlist=36 admin=enable -port set property unit=0 portlist=37 admin=enable -port set property unit=0 portlist=38 admin=enable -port set property unit=0 portlist=39 admin=enable -port set property unit=0 portlist=40 admin=enable -port set property unit=0 portlist=41 admin=enable -port set property unit=0 portlist=42 admin=enable -port set property unit=0 portlist=43 admin=enable -port set property unit=0 portlist=44 admin=enable -port set property unit=0 portlist=45 admin=enable -port set property unit=0 portlist=46 admin=enable -port set property unit=0 portlist=47 admin=enable -port set property unit=0 portlist=48 admin=enable -port set property unit=0 portlist=49 admin=enable -port set property unit=0 portlist=50 admin=enable -port set property unit=0 portlist=51 admin=enable -port set property unit=0 portlist=52 admin=enable -port set property unit=0 portlist=53 admin=enable -port set property unit=0 portlist=54 admin=enable -port set property unit=0 portlist=55 admin=enable -port set property unit=0 portlist=56 admin=enable -port set property unit=0 portlist=57 admin=enable -port set property unit=0 portlist=58 admin=enable -port set property unit=0 portlist=59 admin=enable -port set property unit=0 portlist=60 admin=enable -port set property unit=0 portlist=61 admin=enable -port set property unit=0 portlist=62 admin=enable -port set property unit=0 portlist=63 admin=enable -port set property unit=0 portlist=129 admin=enable -port set property unit=0 portlist=130 admin=enable +init start stage low-level +init set port-map port=0 eth-macro=0 lane=0 max-speed=100g active=true +init set port-map port=1 eth-macro=1 lane=0 max-speed=100g active=true +init set port-map port=2 eth-macro=5 lane=0 max-speed=100g active=true +init set port-map port=3 eth-macro=4 lane=0 max-speed=100g active=true +init set port-map port=4 eth-macro=9 lane=0 max-speed=100g active=true +init set port-map port=5 eth-macro=8 lane=0 max-speed=100g active=true +init set port-map port=6 eth-macro=13 lane=0 max-speed=100g active=true +init set port-map port=7 eth-macro=12 lane=0 max-speed=100g active=true +init set port-map port=8 eth-macro=17 lane=0 max-speed=100g active=true +init set port-map port=9 eth-macro=16 lane=0 max-speed=100g active=true +init set port-map port=10 eth-macro=21 lane=0 max-speed=100g active=true +init set port-map port=11 eth-macro=20 lane=0 max-speed=100g active=true +init set port-map port=12 eth-macro=25 lane=0 max-speed=100g active=true +init set port-map port=13 eth-macro=24 lane=0 max-speed=100g active=true +init set port-map port=14 eth-macro=29 lane=0 max-speed=100g active=true +init set port-map port=15 eth-macro=28 lane=0 max-speed=100g active=true +init set port-map port=16 eth-macro=33 lane=0 max-speed=100g active=true +init set port-map port=17 eth-macro=32 lane=0 max-speed=100g active=true +init set port-map port=18 eth-macro=37 lane=0 max-speed=100g active=true +init set port-map port=19 eth-macro=36 lane=0 max-speed=100g active=true +init set port-map port=20 eth-macro=41 lane=0 max-speed=100g active=true +init set port-map port=21 eth-macro=40 lane=0 max-speed=100g active=true +init set port-map port=22 eth-macro=45 lane=0 max-speed=100g active=true +init set port-map port=23 eth-macro=44 lane=0 max-speed=100g active=true +init set port-map port=24 eth-macro=49 lane=0 max-speed=100g active=true +init set port-map port=25 eth-macro=48 lane=0 max-speed=100g active=true +init set port-map port=26 eth-macro=53 lane=0 max-speed=100g active=true +init set port-map port=27 eth-macro=52 lane=0 max-speed=100g active=true +init set port-map port=28 eth-macro=57 lane=0 max-speed=100g active=true +init set port-map port=29 eth-macro=56 lane=0 max-speed=100g active=true +init set port-map port=30 eth-macro=61 lane=0 max-speed=100g active=true +init set port-map port=31 eth-macro=60 lane=0 max-speed=100g active=true +init set port-map port=32 eth-macro=3 lane=0 max-speed=100g active=true +init set port-map port=33 eth-macro=2 lane=0 max-speed=100g active=true +init set port-map port=34 eth-macro=7 lane=0 max-speed=100g active=true +init set port-map port=35 eth-macro=6 lane=0 max-speed=100g active=true +init set port-map port=36 eth-macro=11 lane=0 max-speed=100g active=true +init set port-map port=37 eth-macro=10 lane=0 max-speed=100g active=true +init set port-map port=38 eth-macro=15 lane=0 max-speed=100g active=true +init set port-map port=39 eth-macro=14 lane=0 max-speed=100g active=true +init set port-map port=40 eth-macro=19 lane=0 max-speed=100g active=true +init set port-map port=41 eth-macro=18 lane=0 max-speed=100g active=true +init set port-map port=42 eth-macro=23 lane=0 max-speed=100g active=true +init set port-map port=43 eth-macro=22 lane=0 max-speed=100g active=true +init set port-map port=44 eth-macro=27 lane=0 max-speed=100g active=true +init set port-map port=45 eth-macro=26 lane=0 max-speed=100g active=true +init set port-map port=46 eth-macro=31 lane=0 max-speed=100g active=true +init set port-map port=47 eth-macro=30 lane=0 max-speed=100g active=true +init set port-map port=48 eth-macro=35 lane=0 max-speed=100g active=true +init set port-map port=49 eth-macro=34 lane=0 max-speed=100g active=true +init set port-map port=50 eth-macro=39 lane=0 max-speed=100g active=true +init set port-map port=51 eth-macro=38 lane=0 max-speed=100g active=true +init set port-map port=52 eth-macro=43 lane=0 max-speed=100g active=true +init set port-map port=53 eth-macro=42 lane=0 max-speed=100g active=true +init set port-map port=54 eth-macro=47 lane=0 max-speed=100g active=true +init set port-map port=55 eth-macro=46 lane=0 max-speed=100g active=true +init set port-map port=56 eth-macro=51 lane=0 max-speed=100g active=true +init set port-map port=57 eth-macro=50 lane=0 max-speed=100g active=true +init set port-map port=58 eth-macro=55 lane=0 max-speed=100g active=true +init set port-map port=59 eth-macro=54 lane=0 max-speed=100g active=true +init set port-map port=60 eth-macro=59 lane=0 max-speed=100g active=true +init set port-map port=61 eth-macro=58 lane=0 max-speed=100g active=true +init set port-map port=62 eth-macro=62 lane=0 max-speed=100g active=true +init set port-map port=63 eth-macro=63 lane=0 max-speed=100g active=true +init set port-map port=129 eth-macro=0 lane=1 max-speed=10g active=true guarantee=true cpi=true +init set port-map port=130 eth-macro=0 lane=0 max-speed=10g active=true guarantee=true cpi=true init-done=true + +init start stage task-rsrc +init start stage module +init start stage task + +phy set lane-swap portlist=0 lane-cnt=4 property=tx data=0x3.2.0.1 +phy set lane-swap portlist=1 lane-cnt=4 property=tx data=0x2.1.3.0 +phy set lane-swap portlist=2 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=3 lane-cnt=4 property=tx data=0x2.3.0.1 +phy set lane-swap portlist=4 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=5 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=6 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=7 lane-cnt=4 property=tx data=0x1.0.2.3 +phy set lane-swap portlist=8 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=9 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=10 lane-cnt=4 property=tx data=0x0.3.2.1 +phy set lane-swap portlist=11 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=12 lane-cnt=4 property=tx data=0x3.2.0.1 +phy set lane-swap portlist=13 lane-cnt=4 property=tx data=0x3.2.1.0 +phy set lane-swap portlist=14 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=15 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=16 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=17 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=18 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=19 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=20 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=21 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=22 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=23 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=24 lane-cnt=4 property=tx data=0x0.3.2.1 +phy set lane-swap portlist=25 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=26 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=27 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=28 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=29 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=30 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=31 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=32 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=33 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=34 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=35 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=36 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=37 lane-cnt=4 property=tx data=0x3.1.0.2 +phy set lane-swap portlist=38 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=39 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=40 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=41 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=42 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=43 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=44 lane-cnt=4 property=tx data=0x3.2.1.0 +phy set lane-swap portlist=45 lane-cnt=4 property=tx data=0x3.2.1.0 +phy set lane-swap portlist=46 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=47 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=48 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=49 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=50 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=51 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=52 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=53 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=54 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=55 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=56 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=57 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=58 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=59 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=60 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=61 lane-cnt=4 property=tx data=0x0.1.2.3 +phy set lane-swap portlist=62 lane-cnt=4 property=tx data=0x1.0.2.3 +phy set lane-swap portlist=63 lane-cnt=4 property=tx data=0x3.1.0.2 +phy set lane-swap portlist=129 lane-cnt=1 property=tx data=0x1 +phy set lane-swap portlist=130 lane-cnt=1 property=tx data=0x0 +phy set lane-swap portlist=0 lane-cnt=4 property=rx data=0x2.0.3.1 +phy set lane-swap portlist=1 lane-cnt=4 property=rx data=0x1.3.0.2 +phy set lane-swap portlist=2 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=3 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=4 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=5 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=6 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=7 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=8 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=9 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=10 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=11 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=12 lane-cnt=4 property=rx data=0x3.2.1.0 +phy set lane-swap portlist=13 lane-cnt=4 property=rx data=0x3.2.1.0 +phy set lane-swap portlist=14 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=15 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=16 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=17 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=18 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=19 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=20 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=21 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=22 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=23 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=24 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=25 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=26 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=27 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=28 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=29 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=30 lane-cnt=4 property=rx data=0x0.2.1.3 +phy set lane-swap portlist=31 lane-cnt=4 property=rx data=0x0.2.1.3 +phy set lane-swap portlist=32 lane-cnt=4 property=rx data=0x0.2.1.3 +phy set lane-swap portlist=33 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=34 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=35 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=36 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=37 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=38 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=39 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=40 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=41 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=42 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=43 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=44 lane-cnt=4 property=rx data=0x3.2.1.0 +phy set lane-swap portlist=45 lane-cnt=4 property=rx data=0x3.2.1.0 +phy set lane-swap portlist=46 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=47 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=48 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=49 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=50 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=51 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=52 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=53 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=54 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=55 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=56 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=57 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=58 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=59 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=60 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=61 lane-cnt=4 property=rx data=0x0.1.2.3 +phy set lane-swap portlist=62 lane-cnt=4 property=rx data=0x1.3.0.2 +phy set lane-swap portlist=63 lane-cnt=4 property=rx data=0x3.1.2.0 +phy set lane-swap portlist=129 lane-cnt=1 property=rx data=0x1 +phy set lane-swap portlist=130 lane-cnt=1 property=rx data=0x0 + +phy set polarity-rev portlist=0 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=1 lane-cnt=4 property=tx data=0x0.1.0.0 +phy set polarity-rev portlist=2 lane-cnt=4 property=tx data=0x1.0.0.1 +phy set polarity-rev portlist=3 lane-cnt=4 property=tx data=0x1.1.1.1 +phy set polarity-rev portlist=4 lane-cnt=4 property=tx data=0x0.1.0.1 +phy set polarity-rev portlist=5 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=6 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=7 lane-cnt=4 property=tx data=0x1.0.0.0 +phy set polarity-rev portlist=8 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=9 lane-cnt=4 property=tx data=0x0.1.0.0 +phy set polarity-rev portlist=10 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=11 lane-cnt=4 property=tx data=0x0.1.0.0 +phy set polarity-rev portlist=12 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=13 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=14 lane-cnt=4 property=tx data=0x1.0.0.0 +phy set polarity-rev portlist=15 lane-cnt=4 property=tx data=0x0.1.0.0 +phy set polarity-rev portlist=16 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=17 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=18 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=19 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=20 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=21 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=22 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=23 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=24 lane-cnt=4 property=tx data=0x0.0.1.0 +phy set polarity-rev portlist=25 lane-cnt=4 property=tx data=0x1.0.0.1 +phy set polarity-rev portlist=26 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=27 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=28 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=29 lane-cnt=4 property=tx data=0x0.1.0.0 +phy set polarity-rev portlist=30 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=31 lane-cnt=4 property=tx data=0x0.0.1.0 +phy set polarity-rev portlist=32 lane-cnt=4 property=tx data=0x0.1.1.1 +phy set polarity-rev portlist=33 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=34 lane-cnt=4 property=tx data=0x0.1.1.1 +phy set polarity-rev portlist=35 lane-cnt=4 property=tx data=0x1.0.0.0 +phy set polarity-rev portlist=36 lane-cnt=4 property=tx data=0x0.0.1.1 +phy set polarity-rev portlist=37 lane-cnt=4 property=tx data=0x0.0.0.1 +phy set polarity-rev portlist=38 lane-cnt=4 property=tx data=0x0.1.1.0 +phy set polarity-rev portlist=39 lane-cnt=4 property=tx data=0x1.0.1.0 +phy set polarity-rev portlist=40 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=41 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=42 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=43 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=44 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=45 lane-cnt=4 property=tx data=0x0.0.1.0 +phy set polarity-rev portlist=46 lane-cnt=4 property=tx data=0x0.0.0.1 +phy set polarity-rev portlist=47 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=48 lane-cnt=4 property=tx data=0x0.0.1.1 +phy set polarity-rev portlist=49 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=50 lane-cnt=4 property=tx data=0x0.0.1.1 +phy set polarity-rev portlist=51 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=52 lane-cnt=4 property=tx data=0x0.0.1.1 +phy set polarity-rev portlist=53 lane-cnt=4 property=tx data=0x0.0.1.0 +phy set polarity-rev portlist=54 lane-cnt=4 property=tx data=0x0.0.1.1 +phy set polarity-rev portlist=55 lane-cnt=4 property=tx data=0x0.0.1.1 +phy set polarity-rev portlist=56 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=57 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=58 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=59 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=60 lane-cnt=4 property=tx data=0x0.1.0.1 +phy set polarity-rev portlist=61 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=62 lane-cnt=4 property=tx data=0x0.0.0.0 +phy set polarity-rev portlist=63 lane-cnt=4 property=tx data=0x0.0.1.0 +phy set polarity-rev portlist=129 lane-cnt=1 property=tx data=0x0 +phy set polarity-rev portlist=130 lane-cnt=1 property=tx data=0x0 + +phy set polarity-rev portlist=0 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=1 lane-cnt=4 property=rx data=0x1.0.0.0 +phy set polarity-rev portlist=2 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=3 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=4 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=5 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=6 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=7 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=8 lane-cnt=4 property=rx data=0x0.0.0.1 +phy set polarity-rev portlist=9 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=10 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=11 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=12 lane-cnt=4 property=rx data=0x1.0.0.0 +phy set polarity-rev portlist=13 lane-cnt=4 property=rx data=0x0.0.1.0 +phy set polarity-rev portlist=14 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=15 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=16 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=17 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=18 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=19 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=20 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=21 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=22 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=23 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=24 lane-cnt=4 property=rx data=0x0.0.0.1 +phy set polarity-rev portlist=25 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=26 lane-cnt=4 property=rx data=0x0.0.0.1 +phy set polarity-rev portlist=27 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=28 lane-cnt=4 property=rx data=0x0.0.0.1 +phy set polarity-rev portlist=29 lane-cnt=4 property=rx data=0x1.0.1.0 +phy set polarity-rev portlist=30 lane-cnt=4 property=rx data=0x0.0.1.0 +phy set polarity-rev portlist=31 lane-cnt=4 property=rx data=0x1.1.0.0 +phy set polarity-rev portlist=32 lane-cnt=4 property=rx data=0x0.1.1.1 +phy set polarity-rev portlist=33 lane-cnt=4 property=rx data=0x1.1.1.0 +phy set polarity-rev portlist=34 lane-cnt=4 property=rx data=0x0.0.1.1 +phy set polarity-rev portlist=35 lane-cnt=4 property=rx data=0x0.0.1.0 +phy set polarity-rev portlist=36 lane-cnt=4 property=rx data=0x0.0.0.1 +phy set polarity-rev portlist=37 lane-cnt=4 property=rx data=0x0.0.0.1 +phy set polarity-rev portlist=38 lane-cnt=4 property=rx data=0x0.0.0.1 +phy set polarity-rev portlist=39 lane-cnt=4 property=rx data=0x0.0.0.1 +phy set polarity-rev portlist=40 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=41 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=42 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=43 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=44 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=45 lane-cnt=4 property=rx data=0x0.1.0.1 +phy set polarity-rev portlist=46 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=47 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=48 lane-cnt=4 property=rx data=0x0.0.0.1 +phy set polarity-rev portlist=49 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=50 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=51 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=52 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=53 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=54 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=55 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=56 lane-cnt=4 property=rx data=0x0.1.0.0 +phy set polarity-rev portlist=57 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=58 lane-cnt=4 property=rx data=0x0.1.0.0 +phy set polarity-rev portlist=59 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=60 lane-cnt=4 property=rx data=0x0.0.0.1 +phy set polarity-rev portlist=61 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=62 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=63 lane-cnt=4 property=rx data=0x0.0.0.0 +phy set polarity-rev portlist=129 lane-cnt=1 property=rx data=0x0 +phy set polarity-rev portlist=130 lane-cnt=1 property=rx data=0x0 + +phy set pre-emphasis portlist=0 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=0 lane-cnt=4 property=c1 data=0x09.09.09.09 +phy set pre-emphasis portlist=0 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=0 lane-cnt=4 property=c0 data=0x19.19.18.19 +phy set pre-emphasis portlist=1 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=1 lane-cnt=4 property=c1 data=0x09.09.09.09 +phy set pre-emphasis portlist=1 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=1 lane-cnt=4 property=c0 data=0x19.18.19.19 +phy set pre-emphasis portlist=2 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=2 lane-cnt=4 property=c1 data=0x08.08.09.09 +phy set pre-emphasis portlist=2 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=2 lane-cnt=4 property=c0 data=0x19.19.19.19 +phy set pre-emphasis portlist=3 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=3 lane-cnt=4 property=c1 data=0x08.08.09.08 +phy set pre-emphasis portlist=3 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=3 lane-cnt=4 property=c0 data=0x19.19.19.19 +phy set pre-emphasis portlist=4 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=4 lane-cnt=4 property=c1 data=0x06.07.07.08 +phy set pre-emphasis portlist=4 lane-cnt=4 property=cn1 data=0x03.02.02.02 +phy set pre-emphasis portlist=4 lane-cnt=4 property=c0 data=0x19.19.18.19 +phy set pre-emphasis portlist=5 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=5 lane-cnt=4 property=c1 data=0x07.07.07.07 +phy set pre-emphasis portlist=5 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=5 lane-cnt=4 property=c0 data=0x19.19.18.18 +phy set pre-emphasis portlist=6 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=6 lane-cnt=4 property=c1 data=0x06.06.06.07 +phy set pre-emphasis portlist=6 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=6 lane-cnt=4 property=c0 data=0x18.18.18.18 +phy set pre-emphasis portlist=7 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=7 lane-cnt=4 property=c1 data=0x06.06.06.06 +phy set pre-emphasis portlist=7 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=7 lane-cnt=4 property=c0 data=0x18.18.18.18 +phy set pre-emphasis portlist=8 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=8 lane-cnt=4 property=c1 data=0x06.06.06.06 +phy set pre-emphasis portlist=8 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=8 lane-cnt=4 property=c0 data=0x18.18.18.18 +phy set pre-emphasis portlist=9 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=9 lane-cnt=4 property=c1 data=0x06.06.06.06 +phy set pre-emphasis portlist=9 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=9 lane-cnt=4 property=c0 data=0x17.17.17.17 +phy set pre-emphasis portlist=10 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=10 lane-cnt=4 property=c1 data=0x05.05.05.05 +phy set pre-emphasis portlist=10 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=10 lane-cnt=4 property=c0 data=0x16.17.17.17 +phy set pre-emphasis portlist=11 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=11 lane-cnt=4 property=c1 data=0x05.05.05.05 +phy set pre-emphasis portlist=11 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=11 lane-cnt=4 property=c0 data=0x17.17.17.17 +phy set pre-emphasis portlist=12 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=12 lane-cnt=4 property=c1 data=0x05.05.05.05 +phy set pre-emphasis portlist=12 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=12 lane-cnt=4 property=c0 data=0x17.17.17.17 +phy set pre-emphasis portlist=13 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=13 lane-cnt=4 property=c1 data=0x05.05.05.05 +phy set pre-emphasis portlist=13 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=13 lane-cnt=4 property=c0 data=0x17.17.17.17 +phy set pre-emphasis portlist=14 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=14 lane-cnt=4 property=c1 data=0x04.05.04.05 +phy set pre-emphasis portlist=14 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=14 lane-cnt=4 property=c0 data=0x18.17.18.17 +phy set pre-emphasis portlist=15 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=15 lane-cnt=4 property=c1 data=0x06.05.06.06 +phy set pre-emphasis portlist=15 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=15 lane-cnt=4 property=c0 data=0x16.17.16.16 +phy set pre-emphasis portlist=16 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=16 lane-cnt=4 property=c1 data=0x05.06.06.06 +phy set pre-emphasis portlist=16 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=16 lane-cnt=4 property=c0 data=0x17.18.18.16 +phy set pre-emphasis portlist=17 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=17 lane-cnt=4 property=c1 data=0x04.04.04.04 +phy set pre-emphasis portlist=17 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=17 lane-cnt=4 property=c0 data=0x16.16.16.16 +phy set pre-emphasis portlist=18 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=18 lane-cnt=4 property=c1 data=0x05.05.05.05 +phy set pre-emphasis portlist=18 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=18 lane-cnt=4 property=c0 data=0x16.16.16.16 +phy set pre-emphasis portlist=19 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=19 lane-cnt=4 property=c1 data=0x05.05.05.05 +phy set pre-emphasis portlist=19 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=19 lane-cnt=4 property=c0 data=0x16.16.16.16 +phy set pre-emphasis portlist=20 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=20 lane-cnt=4 property=c1 data=0x05.05.05.05 +phy set pre-emphasis portlist=20 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=20 lane-cnt=4 property=c0 data=0x16.16.16.16 +phy set pre-emphasis portlist=21 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=21 lane-cnt=4 property=c1 data=0x05.05.05.05 +phy set pre-emphasis portlist=21 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=21 lane-cnt=4 property=c0 data=0x16.16.16.16 +phy set pre-emphasis portlist=22 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=22 lane-cnt=4 property=c1 data=0x06.06.06.06 +phy set pre-emphasis portlist=22 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=22 lane-cnt=4 property=c0 data=0x17.17.18.17 +phy set pre-emphasis portlist=23 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=23 lane-cnt=4 property=c1 data=0x06.06.06.06 +phy set pre-emphasis portlist=23 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=23 lane-cnt=4 property=c0 data=0x17.17.17.17 +phy set pre-emphasis portlist=24 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=24 lane-cnt=4 property=c1 data=0x07.07.07.07 +phy set pre-emphasis portlist=24 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=24 lane-cnt=4 property=c0 data=0x18.18.18.18 +phy set pre-emphasis portlist=25 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=25 lane-cnt=4 property=c1 data=0x07.07.07.07 +phy set pre-emphasis portlist=25 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=25 lane-cnt=4 property=c0 data=0x18.18.18.18 +phy set pre-emphasis portlist=26 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=26 lane-cnt=4 property=c1 data=0x08.08.07.07 +phy set pre-emphasis portlist=26 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=26 lane-cnt=4 property=c0 data=0x19.19.19.19 +phy set pre-emphasis portlist=27 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=27 lane-cnt=4 property=c1 data=0x08.08.08.08 +phy set pre-emphasis portlist=27 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=27 lane-cnt=4 property=c0 data=0x19.19.19.19 +phy set pre-emphasis portlist=28 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=28 lane-cnt=4 property=c1 data=0x09.09.09.09 +phy set pre-emphasis portlist=28 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=28 lane-cnt=4 property=c0 data=0x19.19.19.19 +phy set pre-emphasis portlist=29 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=29 lane-cnt=4 property=c1 data=0x09.09.09.09 +phy set pre-emphasis portlist=29 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=29 lane-cnt=4 property=c0 data=0x19.19.19.19 +phy set pre-emphasis portlist=30 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=30 lane-cnt=4 property=c1 data=0x08.09.09.09 +phy set pre-emphasis portlist=30 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=30 lane-cnt=4 property=c0 data=0x18.19.19.19 +phy set pre-emphasis portlist=31 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=31 lane-cnt=4 property=c1 data=0x09.09.09.09 +phy set pre-emphasis portlist=31 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=31 lane-cnt=4 property=c0 data=0x19.19.19.19 +phy set pre-emphasis portlist=32 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=32 lane-cnt=4 property=c1 data=0x09.09.09.09 +phy set pre-emphasis portlist=32 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=32 lane-cnt=4 property=c0 data=0x19.19.19.19 +phy set pre-emphasis portlist=33 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=33 lane-cnt=4 property=c1 data=0x08.09.09.09 +phy set pre-emphasis portlist=33 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=33 lane-cnt=4 property=c0 data=0x19.19.19.19 +phy set pre-emphasis portlist=34 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=34 lane-cnt=4 property=c1 data=0x08.07.08.08 +phy set pre-emphasis portlist=34 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=34 lane-cnt=4 property=c0 data=0x19.19.19.19 +phy set pre-emphasis portlist=35 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=35 lane-cnt=4 property=c1 data=0x08.08.07.08 +phy set pre-emphasis portlist=35 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=35 lane-cnt=4 property=c0 data=0x19.19.19.19 +phy set pre-emphasis portlist=36 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=36 lane-cnt=4 property=c1 data=0x07.07.07.07 +phy set pre-emphasis portlist=36 lane-cnt=4 property=cn1 data=0x01.02.02.02 +phy set pre-emphasis portlist=36 lane-cnt=4 property=c0 data=0x19.18.18.18 +phy set pre-emphasis portlist=37 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=37 lane-cnt=4 property=c1 data=0x06.06.06.07 +phy set pre-emphasis portlist=37 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=37 lane-cnt=4 property=c0 data=0x18.18.18.18 +phy set pre-emphasis portlist=38 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=38 lane-cnt=4 property=c1 data=0x06.06.05.06 +phy set pre-emphasis portlist=38 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=38 lane-cnt=4 property=c0 data=0x18.18.18.18 +phy set pre-emphasis portlist=39 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=39 lane-cnt=4 property=c1 data=0x06.07.06.06 +phy set pre-emphasis portlist=39 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=39 lane-cnt=4 property=c0 data=0x18.18.18.18 +phy set pre-emphasis portlist=40 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=40 lane-cnt=4 property=c1 data=0x05.05.05.05 +phy set pre-emphasis portlist=40 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=40 lane-cnt=4 property=c0 data=0x18.18.18.18 +phy set pre-emphasis portlist=41 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=41 lane-cnt=4 property=c1 data=0x05.06.05.05 +phy set pre-emphasis portlist=41 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=41 lane-cnt=4 property=c0 data=0x16.17.18.18 +phy set pre-emphasis portlist=42 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=42 lane-cnt=4 property=c1 data=0x05.05.05.05 +phy set pre-emphasis portlist=42 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=42 lane-cnt=4 property=c0 data=0x17.17.17.17 +phy set pre-emphasis portlist=43 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=43 lane-cnt=4 property=c1 data=0x06.05.05.05 +phy set pre-emphasis portlist=43 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=43 lane-cnt=4 property=c0 data=0x17.17.17.17 +phy set pre-emphasis portlist=44 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=44 lane-cnt=4 property=c1 data=0x05.05.05.05 +phy set pre-emphasis portlist=44 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=44 lane-cnt=4 property=c0 data=0x17.17.17.17 +phy set pre-emphasis portlist=45 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=45 lane-cnt=4 property=c1 data=0x05.05.04.05 +phy set pre-emphasis portlist=45 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=45 lane-cnt=4 property=c0 data=0x17.17.18.17 +phy set pre-emphasis portlist=46 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=46 lane-cnt=4 property=c1 data=0x05.05.06.06 +phy set pre-emphasis portlist=46 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=46 lane-cnt=4 property=c0 data=0x17.17.16.16 +phy set pre-emphasis portlist=47 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=47 lane-cnt=4 property=c1 data=0x05.05.06.06 +phy set pre-emphasis portlist=47 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=47 lane-cnt=4 property=c0 data=0x17.17.16.16 +phy set pre-emphasis portlist=48 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=48 lane-cnt=4 property=c1 data=0x05.05.05.05 +phy set pre-emphasis portlist=48 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=48 lane-cnt=4 property=c0 data=0x16.16.16.16 +phy set pre-emphasis portlist=49 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=49 lane-cnt=4 property=c1 data=0x05.05.05.05 +phy set pre-emphasis portlist=49 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=49 lane-cnt=4 property=c0 data=0x16.16.16.16 +phy set pre-emphasis portlist=50 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=50 lane-cnt=4 property=c1 data=0x05.05.05.05 +phy set pre-emphasis portlist=50 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=50 lane-cnt=4 property=c0 data=0x16.16.16.16 +phy set pre-emphasis portlist=51 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=51 lane-cnt=4 property=c1 data=0x05.05.05.05 +phy set pre-emphasis portlist=51 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=51 lane-cnt=4 property=c0 data=0x16.16.16.16 +phy set pre-emphasis portlist=52 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=52 lane-cnt=4 property=c1 data=0x06.06.05.05 +phy set pre-emphasis portlist=52 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=52 lane-cnt=4 property=c0 data=0x16.17.17.17 +phy set pre-emphasis portlist=53 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=53 lane-cnt=4 property=c1 data=0x06.06.06.06 +phy set pre-emphasis portlist=53 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=53 lane-cnt=4 property=c0 data=0x16.17.17.17 +phy set pre-emphasis portlist=54 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=54 lane-cnt=4 property=c1 data=0x06.06.06.06 +phy set pre-emphasis portlist=54 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=54 lane-cnt=4 property=c0 data=0x18.18.18.18 +phy set pre-emphasis portlist=55 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=55 lane-cnt=4 property=c1 data=0x06.06.06.06 +phy set pre-emphasis portlist=55 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=55 lane-cnt=4 property=c0 data=0x18.18.18.18 +phy set pre-emphasis portlist=56 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=56 lane-cnt=4 property=c1 data=0x07.07.07.07 +phy set pre-emphasis portlist=56 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=56 lane-cnt=4 property=c0 data=0x18.18.18.18 +phy set pre-emphasis portlist=57 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=57 lane-cnt=4 property=c1 data=0x07.07.07.07 +phy set pre-emphasis portlist=57 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=57 lane-cnt=4 property=c0 data=0x18.18.18.18 +phy set pre-emphasis portlist=58 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=58 lane-cnt=4 property=c1 data=0x08.08.08.08 +phy set pre-emphasis portlist=58 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=58 lane-cnt=4 property=c0 data=0x19.19.19.19 +phy set pre-emphasis portlist=59 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=59 lane-cnt=4 property=c1 data=0x08.08.08.08 +phy set pre-emphasis portlist=59 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=59 lane-cnt=4 property=c0 data=0x19.19.19.19 +phy set pre-emphasis portlist=60 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=60 lane-cnt=4 property=c1 data=0x09.09.09.09 +phy set pre-emphasis portlist=60 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=60 lane-cnt=4 property=c0 data=0x19.19.19.19 +phy set pre-emphasis portlist=61 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=61 lane-cnt=4 property=c1 data=0x09.09.09.09 +phy set pre-emphasis portlist=61 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=61 lane-cnt=4 property=c0 data=0x19.19.19.19 +phy set pre-emphasis portlist=62 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=62 lane-cnt=4 property=c1 data=0x09.09.09.09 +phy set pre-emphasis portlist=62 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=62 lane-cnt=4 property=c0 data=0x19.19.19.19 +phy set pre-emphasis portlist=63 lane-cnt=4 property=c2 data=0x00.00.00.00 +phy set pre-emphasis portlist=63 lane-cnt=4 property=c1 data=0x09.09.09.09 +phy set pre-emphasis portlist=63 lane-cnt=4 property=cn1 data=0x02.02.02.02 +phy set pre-emphasis portlist=63 lane-cnt=4 property=c0 data=0x19.19.19.19 + +phy set pre-emphasis portlist=129 lane-cnt=1 property=c2 data=0x01 +phy set pre-emphasis portlist=129 lane-cnt=1 property=cn1 data=0x01 +phy set pre-emphasis portlist=129 lane-cnt=1 property=c0 data=0x02 +phy set pre-emphasis portlist=129 lane-cnt=1 property=c1 data=0x03 +phy set pre-emphasis portlist=130 lane-cnt=1 property=c2 data=0x01 +phy set pre-emphasis portlist=130 lane-cnt=1 property=cn1 data=0x01 +phy set pre-emphasis portlist=130 lane-cnt=1 property=c0 data=0x02 +phy set pre-emphasis portlist=130 lane-cnt=1 property=c1 data=0x03 + +phy set mdio portlist=0 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=1 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=2 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=3 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=4 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=5 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=6 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=7 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=8 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=9 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=10 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=11 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=12 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=13 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=14 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=15 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=16 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=17 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=18 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=19 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=20 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=21 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=22 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=23 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=24 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=25 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=26 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=27 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=28 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=29 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=30 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=31 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=32 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=33 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=34 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=35 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=36 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=37 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=38 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=39 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=40 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=41 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=42 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=43 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=44 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=45 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=46 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=47 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=48 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=49 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=50 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=51 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=52 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=53 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=54 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=55 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=56 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=57 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=58 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=59 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=60 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=61 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=62 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=63 devad=0x1E addr=0x2 data=0x8000 +phy set mdio portlist=129 devad=0x1E addr=0x2 data=0x0000 +phy set mdio portlist=130 devad=0x1E addr=0x2 data=0x0000 + +port set property portlist=0-63 speed=100g +port set property portlist=129-130 speed=10g +port set property portlist=0-63 medium-type=sr4 +port set property portlist=129-130 medium-type=kr +port set property portlist=0-63 fec=disable +port set adver portlist=129-130 speed-10g-kr +port set property portlist=129-130 an=enable + +port set property portlist=0-63,129-130 admin=enable diff --git a/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/led_proc_init.nps b/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/led_proc_init.nps index fc640e0d78f8..717d3303f172 100644 --- a/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/led_proc_init.nps +++ b/device/ingrasys/x86_64-ingrasys_s9230_64x-r0/led_proc_init.nps @@ -1,7 +1,7 @@ #unit NPS_CFG_TYPE_XXX param0 param1 value #---- ---------------- ------ ------ ----- 0 NPS_CFG_TYPE_USE_UNIT_PORT 0 0 1 -0 NPS_CFG_TYPE_LED_CFG 0 0 2 +0 NPS_CFG_TYPE_LED_CFG 0 0 6 0 NPS_CFG_TYPE_CPI_PORT_MODE 129 0 1 0 NPS_CFG_TYPE_CPI_PORT_MODE 130 0 1 0 NPS_CFG_TYPE_USER_BUF_CTRL 0 0 1 diff --git a/platform/nephos/one-image.mk b/platform/nephos/one-image.mk index 61dcd6e30468..aa5cc1ff4324 100644 --- a/platform/nephos/one-image.mk +++ b/platform/nephos/one-image.mk @@ -6,6 +6,6 @@ $(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie $(SONIC_ONE_IMAGE)_INSTALLS += $(NEPHOS_NPS_KERNEL) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(INGRASYS_S9130_32X_PLATFORM_MODULE) \ $(INGRASYS_S9230_64X_PLATFORM_MODULE) \ - $(ACCTON_AS7116_54X_PLATFORM_MODULE) + $(ACCTON_AS7116_54X_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_IMAGES) SONIC_INSTALLERS += $(SONIC_ONE_IMAGE) diff --git a/platform/nephos/sai.mk b/platform/nephos/sai.mk index 79f7569f1c16..89f1c4711dbc 100644 --- a/platform/nephos/sai.mk +++ b/platform/nephos/sai.mk @@ -1,9 +1,12 @@ -NEPHOS_SAI = libsainps_2.0.3_sai_1.2.4_3147dc_amd64.deb -$(NEPHOS_SAI)_URL = "https://github.com/NephosInc/SONiC/raw/master/sai/libsainps_2.0.3_sai_1.2.4_3147dc_amd64.deb" +SDK_VERSION = 2.0.5 +SAI_VERSION = 1.2.4 +SAI_COMMIT_ID = ce1d52 +NEPHOS_SAI = libsainps_$(SDK_VERSION)_sai_$(SAI_VERSION)_$(SAI_COMMIT_ID)_amd64.deb +$(NEPHOS_SAI)_URL = "https://github.com/NephosInc/SONiC/raw/master/sai/libsainps_$(SDK_VERSION)_sai_$(SAI_VERSION)_$(SAI_COMMIT_ID)_amd64.deb" -NEPHOS_SAI_DEV = libsainps-dev_2.0.3_sai_1.2.4_3147dc_amd64.deb +NEPHOS_SAI_DEV = libsainps-dev_$(SDK_VERSION)_sai_$(SAI_VERSION)_$(SAI_COMMIT_ID)_amd64.deb $(eval $(call add_derived_package,$(NEPHOS_SAI),$(NEPHOS_SAI_DEV))) -$(NEPHOS_SAI_DEV)_URL = "https://github.com/NephosInc/SONiC/raw/master/sai/libsainps-dev_2.0.3_sai_1.2.4_3147dc_amd64.deb" +$(NEPHOS_SAI_DEV)_URL = "https://github.com/NephosInc/SONiC/raw/master/sai/libsainps-dev_$(SDK_VERSION)_sai_$(SAI_VERSION)_$(SAI_COMMIT_ID)_amd64.deb" SONIC_ONLINE_DEBS += $(NEPHOS_SAI) $(NEPHOS_SAI_DEV) $(NEPHOS_SAI_DEV)_DEPENDS += $(NEPHOS_SAI) diff --git a/platform/nephos/sdk.mk b/platform/nephos/sdk.mk index 55720f6ab828..101d90e9e77e 100644 --- a/platform/nephos/sdk.mk +++ b/platform/nephos/sdk.mk @@ -1,4 +1,7 @@ -NEPHOS_NPS_KERNEL = nps-modules-3.16.0-6_2.0.3_3147dc_amd64.deb -$(NEPHOS_NPS_KERNEL)_URL = "https://github.com/NephosInc/SONiC/raw/master/sdk/nps-modules-3.16.0-6_2.0.3_3147dc_amd64.deb" +SDK_VERSION = 2.0.5 +LINUX_VER = 3.16.0-6 +SDK_COMMIT_ID = f2e56f +NEPHOS_NPS_KERNEL = nps-modules-$(LINUX_VER)_$(SDK_VERSION)_$(SDK_COMMIT_ID)_amd64.deb +$(NEPHOS_NPS_KERNEL)_URL = "https://github.com/NephosInc/SONiC/raw/master/sdk/nps-modules-$(LINUX_VER)_$(SDK_VERSION)_$(SDK_COMMIT_ID)_amd64.deb" SONIC_ONLINE_DEBS += $(NEPHOS_NPS_KERNEL) From 3f16fb0255b79dea5a8777bb3a4a5109c5cf3e3d Mon Sep 17 00:00:00 2001 From: paavaanan Date: Tue, 4 Dec 2018 23:56:46 +0530 Subject: [PATCH 180/219] [Dell] sensors.conf files for S6100/Z9100 (#2282) * [Dell] sensors.conf files for S6100/Z9100 Addded sensors.conf file for S6100/Z9100 switches. sensorsd daemon can able to write syslogs when alarms are raised for any specific attribute. Added alarm supprot for onboard sensors. Tuned return values of attributes to avoid "Bad Adddress" proc errors. Exported SMF version. * Converted TAB to Spaces --- .../x86_64-dell_s6100_c2538-r0/sensors.conf | 9 ++ .../x86_64-dell_z9100_c2538-r0/sensors.conf | 12 ++ .../common/dell_pmc.c | 144 +++++++++++++++--- 3 files changed, 144 insertions(+), 21 deletions(-) create mode 100644 device/dell/x86_64-dell_s6100_c2538-r0/sensors.conf create mode 100644 device/dell/x86_64-dell_z9100_c2538-r0/sensors.conf diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/sensors.conf b/device/dell/x86_64-dell_s6100_c2538-r0/sensors.conf new file mode 100644 index 000000000000..43fa7357c177 --- /dev/null +++ b/device/dell/x86_64-dell_s6100_c2538-r0/sensors.conf @@ -0,0 +1,9 @@ +chip "SMF_S6100_ON-isa-0000" +label power1 "PSU1 Input Power" +label power2 "PSU1 Output Power" +label power3 "PSU2 Input Power" +label power4 "PSU2 Output Power" +label temp14 "PSU1 Temp" +label temp15 "PSU1 Temp" +ignore temp12 +ignore temp13 diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/sensors.conf b/device/dell/x86_64-dell_z9100_c2538-r0/sensors.conf new file mode 100644 index 000000000000..31a656fcf0b3 --- /dev/null +++ b/device/dell/x86_64-dell_z9100_c2538-r0/sensors.conf @@ -0,0 +1,12 @@ +chip "SMF_Z9100_ON-isa-0000" +label power1 "PSU1 Input Power" +label power2 "PSU1 Output Power" +label power3 "PSU2 Input Power" +label power4 "PSU2 Output Power" +label temp14 "PSU1 Temp" +label temp15 "PSU1 Temp" +ignore temp12 +ignore temp13 +ignore temp5 +ignore temp7 +ignore temp8 diff --git a/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c b/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c index 557976457503..e599fdf464e2 100644 --- a/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c +++ b/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c @@ -28,6 +28,7 @@ #define SIO_DRVNAME "SMF" #define DEBUG 1 #define LABELS 1 +#define SMF_VERSION_ADDR 0x0000 #define FANIN_MAX 12 /* Counted from 1 */ #define VSEN_MAX 48 /* VSEN1.. */ @@ -471,6 +472,32 @@ static int smf_read_reg16(struct smf_data *data, u16 reg) return res; } +/* SMF Version */ +static ssize_t show_smf_version(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + unsigned int ret = 0; + unsigned int smf_version = 0; + unsigned int smf_firmware_major_ver = 0; + unsigned int smf_firmware_minor_ver = 0; + struct smf_data *data = dev_get_drvdata(dev); + + ret = smf_read_reg(data, (SMF_VERSION_ADDR + index*2)); + + if (index > 0) { + smf_firmware_major_ver = ((ret & (0xC0)) >> 6); + smf_firmware_minor_ver = (ret & (0x3F)); + ret = sprintf(buf, "%u.%u\n", smf_firmware_major_ver, + smf_firmware_minor_ver); + } else { + smf_version = ret; + ret = sprintf(buf, "%u\n", smf_version); + } + + return ret; +} + /* FANIN ATTR */ static ssize_t @@ -514,6 +541,9 @@ static ssize_t show_fan(struct device *dev, if (ret < 0) return ret; + if (ret & 0x8000) + ret = - (ret & 0x7fff); + rpm = ret; if(export_hex) @@ -1327,23 +1357,28 @@ static ssize_t show_temp_crit(struct device *dev, } -/*static ssize_t show_temp_alarm(struct device *dev, +static ssize_t show_temp_alarm(struct device *dev, struct device_attribute *devattr, char *buf) { int index = to_sensor_dev_attr(devattr)->index; struct smf_data *data = dev_get_drvdata(dev); - int ret; - int temp; + int ret = 0; + int temp = 0; - ret = smf_read_reg16(data, TEMP_SENSOR_1_STATUS + index * 2); + ret = smf_read_reg(data, TEMP_SENSOR_1_STATUS + index); - if (ret < 0) - return ret; + if (ret < 0) { + return ret; + } + + if (ret == 0xff) { + ret = 0; + } temp = ret; return sprintf(buf, "%d\n", temp); -}*/ +} static umode_t smf_tcpu_is_visible(struct kobject *kobj, @@ -1432,6 +1467,25 @@ static SENSOR_DEVICE_ATTR(temp13_max, S_IRUGO, show_temp_crit, NULL, 50); static SENSOR_DEVICE_ATTR(temp14_max, S_IRUGO, show_temp_crit, NULL, 46); static SENSOR_DEVICE_ATTR(temp15_max, S_IRUGO, show_temp_crit, NULL, 50); +static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0); +static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 1); +static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 2); +static SENSOR_DEVICE_ATTR(temp4_alarm, S_IRUGO, show_temp_alarm, NULL, 3); +static SENSOR_DEVICE_ATTR(temp5_alarm, S_IRUGO, show_temp_alarm, NULL, 4); +static SENSOR_DEVICE_ATTR(temp6_alarm, S_IRUGO, show_temp_alarm, NULL, 5); +static SENSOR_DEVICE_ATTR(temp7_alarm, S_IRUGO, show_temp_alarm, NULL, 6); +static SENSOR_DEVICE_ATTR(temp8_alarm, S_IRUGO, show_temp_alarm, NULL, 7); +static SENSOR_DEVICE_ATTR(temp9_alarm, S_IRUGO, show_temp_alarm, NULL, 8); +static SENSOR_DEVICE_ATTR(temp10_alarm, S_IRUGO, show_temp_alarm, NULL, 9); +static SENSOR_DEVICE_ATTR(temp11_alarm, S_IRUGO, show_temp_alarm, NULL, 10); +static SENSOR_DEVICE_ATTR(temp12_alarm, S_IRUGO, show_temp_alarm, NULL, 11); +static SENSOR_DEVICE_ATTR(temp13_alarm, S_IRUGO, show_temp_alarm, NULL, 12); + +static SENSOR_DEVICE_ATTR(temp14_alarm, S_IRUGO, show_temp_alarm, NULL, 13); +static SENSOR_DEVICE_ATTR(temp15_alarm, S_IRUGO, show_temp_alarm, NULL, 14); + + + static struct attribute *smf_tcpu_attrs[] = { &sensor_dev_attr_temp1_input.dev_attr.attr, @@ -1498,6 +1552,23 @@ static struct attribute *smf_tcpu_attrs[] = { &sensor_dev_attr_temp14_max.dev_attr.attr, &sensor_dev_attr_temp15_max.dev_attr.attr, + &sensor_dev_attr_temp1_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_alarm.dev_attr.attr, + &sensor_dev_attr_temp4_alarm.dev_attr.attr, + &sensor_dev_attr_temp5_alarm.dev_attr.attr, + &sensor_dev_attr_temp6_alarm.dev_attr.attr, + &sensor_dev_attr_temp7_alarm.dev_attr.attr, + &sensor_dev_attr_temp8_alarm.dev_attr.attr, + &sensor_dev_attr_temp9_alarm.dev_attr.attr, + &sensor_dev_attr_temp10_alarm.dev_attr.attr, + &sensor_dev_attr_temp11_alarm.dev_attr.attr, + &sensor_dev_attr_temp12_alarm.dev_attr.attr, + &sensor_dev_attr_temp13_alarm.dev_attr.attr, + &sensor_dev_attr_temp14_alarm.dev_attr.attr, + &sensor_dev_attr_temp15_alarm.dev_attr.attr, + + NULL }; @@ -1525,26 +1596,37 @@ static ssize_t show_psu(struct device *dev, struct smf_data *data = dev_get_drvdata(dev); int ret=0, export_hex=0; int psu_status=0, pow; + int pow_val = 0; switch (index) { case 0: pow = smf_read_reg16(data, PSU_1_MAX_POWER); - /* TODO Fix */ - if (data->kind == s6100smf) - ret = 1000000 * 1100; - else - ret = 1000000 * 750; + /* TODO Fix */ + if (data->kind == s6100smf) + ret = 1000000 * 1100; + else + ret = 1000000 * 750; break; case 1: ret = smf_read_reg(data, PSU_1_STATUS); export_hex=1; break; case 2: - ret = 100000 * smf_read_reg16(data, PSU_1_INPUT_POWER); + pow_val = smf_read_reg16(data, PSU_1_INPUT_POWER); + /* In case of absent psu, pow_val will be 0xffff */ + if (pow_val == 0xffff) { + pow_val = 0; + } + ret = 100000 * pow_val; break; case 3: - ret = 100000 * smf_read_reg16(data, PSU_1_OUTPUT_POWER); + pow_val = smf_read_reg16(data, PSU_1_OUTPUT_POWER); + /* In case of absent psu, pow_val will be 0xffff */ + if (pow_val == 0xffff) { + pow_val = 0; + } + ret = 100000 * pow_val; break; case 4: psu_status = smf_read_reg(data, PSU_1_STATUS); @@ -1554,21 +1636,31 @@ static ssize_t show_psu(struct device *dev, case 5: pow = smf_read_reg16(data, PSU_2_MAX_POWER); ret = 1000000 * pow; - /* TODO Fix */ - if (data->kind == s6100smf) - ret = 1000000 * 1100; - else - ret = 1000000 * 750; + /* TODO Fix */ + if (data->kind == s6100smf) + ret = 1000000 * 1100; + else + ret = 1000000 * 750; break; case 6: ret = smf_read_reg(data, PSU_2_STATUS); export_hex=1; break; case 7: - ret = 100000 * smf_read_reg16(data, PSU_2_INPUT_POWER); + pow_val = smf_read_reg16(data, PSU_2_INPUT_POWER); + /* In case of absent psu, pow_val will be 0xffff */ + if (pow_val == 0xffff) { + pow_val = 0; + } + ret = 100000 * pow_val; break; case 8: - ret = 100000 * smf_read_reg16(data, PSU_2_OUTPUT_POWER); + pow_val = smf_read_reg16(data, PSU_2_OUTPUT_POWER); + /* In case of absent psu, pow_val will be 0xffff */ + if (pow_val == 0xffff) { + pow_val = 0; + } + ret = 100000 * pow_val; break; case 9: psu_status = smf_read_reg(data, PSU_2_STATUS); @@ -1577,6 +1669,10 @@ static ssize_t show_psu(struct device *dev, break; case 10: pow = smf_read_reg16(data, CURRENT_TOTAL_POWER); + /* In case of both psu absent, pow will be 0xffff */ + if (pow == 0xffff) { + pow = 0; + } ret = pow/10; break; default: @@ -1678,7 +1774,13 @@ static SENSOR_DEVICE_ATTR(psu1_presence, S_IRUGO, show_psu, NULL, 1); static SENSOR_DEVICE_ATTR(psu2_presence, S_IRUGO, show_psu, NULL, 6); static SENSOR_DEVICE_ATTR(current_total_power, S_IRUGO, show_psu, NULL, 10); +/* SMF Version */ +static SENSOR_DEVICE_ATTR(smf_version, S_IRUGO, show_smf_version, NULL, 0); +static SENSOR_DEVICE_ATTR(smf_firmware_ver, S_IRUGO, show_smf_version, NULL, 1); + static struct attribute *smf_dell_attrs[] = { + &sensor_dev_attr_smf_version.dev_attr.attr, + &sensor_dev_attr_smf_firmware_ver.dev_attr.attr, &sensor_dev_attr_fan_tray_presence.dev_attr.attr, &sensor_dev_attr_fan1_airflow.dev_attr.attr, &sensor_dev_attr_fan3_airflow.dev_attr.attr, From ad2812ae8de53aef4564f29d06a001376227c0e1 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Tue, 11 Dec 2018 14:18:09 +0000 Subject: [PATCH 181/219] [submodules]: update sonic-quagga cde2966 2018-06-26 | * Reduce severity of log 'vty connect from' from INFO to DEBUG (#21) (HEAD) [pavel-shirshov] Signed-off-by: Guohan Lu --- src/sonic-quagga | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-quagga b/src/sonic-quagga index 0bc6bd6b208e..cde29666c363 160000 --- a/src/sonic-quagga +++ b/src/sonic-quagga @@ -1 +1 @@ -Subproject commit 0bc6bd6b208e3701df89c3e231c48f3bdb3d046f +Subproject commit cde29666c363e34ea7f230bb827644457acedcbc From 5479286502e916924ae6ee30a6db9ea73106b1e7 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 28 Nov 2018 00:12:03 -0800 Subject: [PATCH 182/219] [boot] Start ntp-config service after all Docker containers are started (#2303) --- files/build_templates/bgp.service.j2 | 1 + files/build_templates/dhcp_relay.service.j2 | 1 + files/build_templates/lldp.service.j2 | 1 + files/build_templates/pmon.service.j2 | 1 + files/build_templates/radv.service.j2 | 1 + files/build_templates/snmp.service.j2 | 1 + files/build_templates/swss.service.j2 | 1 + files/build_templates/teamd.service.j2 | 1 + files/build_templates/telemetry.service.j2 | 1 + 9 files changed, 9 insertions(+) diff --git a/files/build_templates/bgp.service.j2 b/files/build_templates/bgp.service.j2 index 6c3e343fcf44..bc023b7d714d 100644 --- a/files/build_templates/bgp.service.j2 +++ b/files/build_templates/bgp.service.j2 @@ -2,6 +2,7 @@ Description=BGP container Requires=updategraph.service After=updategraph.service +Before=ntp-config.service [Service] User={{ sonicadmin_user }} diff --git a/files/build_templates/dhcp_relay.service.j2 b/files/build_templates/dhcp_relay.service.j2 index ea53fa2deda4..b4d9ceb38f0c 100644 --- a/files/build_templates/dhcp_relay.service.j2 +++ b/files/build_templates/dhcp_relay.service.j2 @@ -2,6 +2,7 @@ Description=DHCP relay container Requires=updategraph.service swss.service teamd.service After=updategraph.service swss.service teamd.service +Before=ntp-config.service [Service] User={{ sonicadmin_user }} diff --git a/files/build_templates/lldp.service.j2 b/files/build_templates/lldp.service.j2 index d35cdacca0f3..d294a08900f4 100644 --- a/files/build_templates/lldp.service.j2 +++ b/files/build_templates/lldp.service.j2 @@ -2,6 +2,7 @@ Description=LLDP container Requires=updategraph.service After=updategraph.service +Before=ntp-config.service [Service] User={{ sonicadmin_user }} diff --git a/files/build_templates/pmon.service.j2 b/files/build_templates/pmon.service.j2 index 83dd8e4b648d..de4e62df5e10 100644 --- a/files/build_templates/pmon.service.j2 +++ b/files/build_templates/pmon.service.j2 @@ -2,6 +2,7 @@ Description=Platform monitor container Requires=updategraph.service After=updategraph.service +Before=ntp-config.service [Service] User={{ sonicadmin_user }} diff --git a/files/build_templates/radv.service.j2 b/files/build_templates/radv.service.j2 index 7d6da31e135f..065f01906076 100644 --- a/files/build_templates/radv.service.j2 +++ b/files/build_templates/radv.service.j2 @@ -2,6 +2,7 @@ Description=Router advertiser container Requires=updategraph.service swss.service After=updategraph.service swss.service +Before=ntp-config.service [Service] User={{ sonicadmin_user }} diff --git a/files/build_templates/snmp.service.j2 b/files/build_templates/snmp.service.j2 index 6398477ab6a1..f344f2e805ea 100644 --- a/files/build_templates/snmp.service.j2 +++ b/files/build_templates/snmp.service.j2 @@ -2,6 +2,7 @@ Description=SNMP container Requires=updategraph.service swss.service After=updategraph.service swss.service +Before=ntp-config.service [Service] ExecStartPre=/usr/bin/{{docker_container_name}}.sh start diff --git a/files/build_templates/swss.service.j2 b/files/build_templates/swss.service.j2 index bb347e66ae07..afd442e8c44a 100644 --- a/files/build_templates/swss.service.j2 +++ b/files/build_templates/swss.service.j2 @@ -13,6 +13,7 @@ After=opennsl-modules-3.16.0-6-amd64.service {% elif sonic_asic_platform == 'nephos' %} After=nps-modules-3.16.0-6-amd64.service {% endif %} +Before=ntp-config.service [Service] User=root diff --git a/files/build_templates/teamd.service.j2 b/files/build_templates/teamd.service.j2 index bbd04a81b05b..5cd36c6748b9 100644 --- a/files/build_templates/teamd.service.j2 +++ b/files/build_templates/teamd.service.j2 @@ -2,6 +2,7 @@ Description=TEAMD container Requires=updategraph.service After=updategraph.service +Before=ntp-config.service [Service] User={{ sonicadmin_user }} diff --git a/files/build_templates/telemetry.service.j2 b/files/build_templates/telemetry.service.j2 index 5f2e81ed95ea..132924b04193 100644 --- a/files/build_templates/telemetry.service.j2 +++ b/files/build_templates/telemetry.service.j2 @@ -2,6 +2,7 @@ Description=Telemetry container Requires=swss.service After=swss.service +Before=ntp-config.service [Service] User={{ sonicadmin_user }} From 92a80702d54e3d52108d4b91cef60caa85a7bfa1 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Fri, 14 Dec 2018 09:29:20 +0000 Subject: [PATCH 183/219] [submodule]: update sonic-linux-kernel 3893844 2018-12-14 | uart: fix race in uart_write() (#74) (HEAD, azure/201803) [lguohan] Signed-off-by: Guohan Lu --- src/sonic-linux-kernel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel index dff16eb00bf3..3893844286d7 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit dff16eb00bf3fc45c4b3cb4d557732ce7a64be17 +Subproject commit 3893844286d77be4d3dc185e51d511494d359c1b From 2933665c16dff76bf2a348a33cf9ac6eca7d00f5 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Fri, 14 Dec 2018 09:30:27 +0000 Subject: [PATCH 184/219] [baseimage]: force create symlink in union-fsck fix error in update-initramfs when install kernel package in sonic Signed-off-by: Guohan Lu --- files/initramfs-tools/union-fsck | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/initramfs-tools/union-fsck b/files/initramfs-tools/union-fsck index b1c116700be0..e21c03f19404 100644 --- a/files/initramfs-tools/union-fsck +++ b/files/initramfs-tools/union-fsck @@ -27,7 +27,7 @@ for type in $(get_fstypes_boot | sort | uniq); do if [ -h "$prog" ]; then link=$(readlink -f "$prog") copy_exec "$link" - ln -s "$link" "${DESTDIR}/$prog" + ln -sf "$link" "${DESTDIR}/$prog" elif [ -x "$prog" ] ; then copy_exec "$prog" else From 524cfebc23e1825717dfea65559616854355aea7 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Fri, 7 Dec 2018 20:04:22 -0800 Subject: [PATCH 185/219] [docker-syncd-brcm] Add 'startsecs=0' to ledinit process (#2366) --- platform/broadcom/docker-syncd-brcm/supervisord.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/broadcom/docker-syncd-brcm/supervisord.conf b/platform/broadcom/docker-syncd-brcm/supervisord.conf index fe590ede18c5..a2e0743b1cf5 100644 --- a/platform/broadcom/docker-syncd-brcm/supervisord.conf +++ b/platform/broadcom/docker-syncd-brcm/supervisord.conf @@ -32,5 +32,6 @@ command=/usr/bin/bcmcmd -t 60 "rcload /usr/share/sonic/platform/led_proc_init.so priority=4 autostart=false autorestart=false +startsecs=0 stdout_logfile=syslog stderr_logfile=syslog From 1a84813f0dc0da3334c0df7231c103be286e879f Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Wed, 26 Dec 2018 19:36:00 +0000 Subject: [PATCH 186/219] [submodule]: update sonic-utilities HEAD is now at 2aa8ced [sonic-utilities/scripts] Fixing FP ports issue (#268) Signed-off-by: Guohan Lu --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index cd59964cee8d..2aa8ced4f9cd 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit cd59964cee8d2abae29e25218d0af66da709f72c +Subproject commit 2aa8ced4f9cdc56f0f1e1e004f781e6e0d63c35e From 69d5d61eb872aedf734c6d32aaaa4366d1ca8e1e Mon Sep 17 00:00:00 2001 From: shawnli-van <43871303+shawnli-van@users.noreply.github.com> Date: Mon, 31 Dec 2018 09:40:11 -0800 Subject: [PATCH 187/219] [devices]: Fix arista-convertfs for aligning flash via sfdisk in Jessie (#2402) (#2406) The sfdisk in Jessie use unit Cylinder by default. To perform 1M aligning partition, 2048 sector unit is desirable instead. --- files/initramfs-tools/arista-convertfs.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/initramfs-tools/arista-convertfs.j2 b/files/initramfs-tools/arista-convertfs.j2 index 85b1bc41331d..896175bebc99 100644 --- a/files/initramfs-tools/arista-convertfs.j2 +++ b/files/initramfs-tools/arista-convertfs.j2 @@ -170,7 +170,7 @@ umount "$root_mnt" # Create a new partition table (content in flash_dev will be deleted) err_msg="Error: repartitioning $flash_dev failed" -cmd="echo '2048' | sfdisk $flash_dev || (sleep 3; blockdev --rereadpt $flash_dev && fdisk -l $flash_dev | grep -q ${root_dev}.*Linux)" +cmd="echo '2048' | sfdisk -u S --force $flash_dev || (sleep 3; blockdev --rereadpt $flash_dev && fdisk -l $flash_dev | grep -q ${root_dev}.*Linux)" run_cmd "$cmd" "$err_msg" sleep 5 From a46903b3f54f95e3ea6fefc9453b43fe338c7a9e Mon Sep 17 00:00:00 2001 From: Wenda Ni Date: Wed, 2 Jan 2019 09:50:07 -0800 Subject: [PATCH 188/219] [buffer]: Update pg headroom (10% safe margin) & egress service pool for a7050 and s6000 (#2407) Signed-off-by: Wenda --- .../Arista-7050-QX32/buffers.json.j2 | 6 +++--- .../Arista-7050-QX-32S/buffers.json.j2 | 6 +++--- .../Force10-S6000/buffers.json.j2 | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers.json.j2 b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers.json.j2 index 424ad6bf353e..db37b6cd36a6 100644 --- a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers.json.j2 +++ b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers.json.j2 @@ -79,7 +79,7 @@ "mode": "static" }, "egress_lossy_pool": { - "size": "7582515", + "size": "7326924", "type": "egress", "mode": "dynamic" } @@ -88,8 +88,8 @@ "ingress_lossless_profile": { "pool":"[BUFFER_POOL|ingress_lossless_pool]", "xon":"18432", - "xoff":"50128", - "size":"51376", + "xoff":"55120", + "size":"56368", "dynamic_th":"-3", "xon_offset":"2496" }, diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/buffers.json.j2 b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/buffers.json.j2 index 424ad6bf353e..db37b6cd36a6 100644 --- a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/buffers.json.j2 +++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/buffers.json.j2 @@ -79,7 +79,7 @@ "mode": "static" }, "egress_lossy_pool": { - "size": "7582515", + "size": "7326924", "type": "egress", "mode": "dynamic" } @@ -88,8 +88,8 @@ "ingress_lossless_profile": { "pool":"[BUFFER_POOL|ingress_lossless_pool]", "xon":"18432", - "xoff":"50128", - "size":"51376", + "xoff":"55120", + "size":"56368", "dynamic_th":"-3", "xon_offset":"2496" }, diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers.json.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers.json.j2 index 424ad6bf353e..db37b6cd36a6 100644 --- a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers.json.j2 +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers.json.j2 @@ -79,7 +79,7 @@ "mode": "static" }, "egress_lossy_pool": { - "size": "7582515", + "size": "7326924", "type": "egress", "mode": "dynamic" } @@ -88,8 +88,8 @@ "ingress_lossless_profile": { "pool":"[BUFFER_POOL|ingress_lossless_pool]", "xon":"18432", - "xoff":"50128", - "size":"51376", + "xoff":"55120", + "size":"56368", "dynamic_th":"-3", "xon_offset":"2496" }, From e45f51961944d77110871257f954f37ebba4022b Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Fri, 4 Jan 2019 19:29:36 +0000 Subject: [PATCH 189/219] [submodule]: * 06c73ca 2019-01-04 | [sonic_instaler]: use triple sync to flush fs changes to disk (#425) (HEAD, origin/201803) [lguohan] --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 2aa8ced4f9cd..06c73ca4a612 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 2aa8ced4f9cdc56f0f1e1e004f781e6e0d63c35e +Subproject commit 06c73ca4a6129782f004e69331250841a527de52 From 95a0a673c18a476c81f7d142fc7bdaee92de6b19 Mon Sep 17 00:00:00 2001 From: Shuotian Cheng Date: Tue, 8 Jan 2019 19:33:54 -0800 Subject: [PATCH 190/219] [libteam]: Add patch to update orig_hwaddr unconditionally (#2425) --- ...5-update-hwaddr-orig-unconditionally.patch | 22 +++++++++++++++++++ src/libteam/Makefile | 1 + 2 files changed, 23 insertions(+) create mode 100644 src/libteam/0005-update-hwaddr-orig-unconditionally.patch diff --git a/src/libteam/0005-update-hwaddr-orig-unconditionally.patch b/src/libteam/0005-update-hwaddr-orig-unconditionally.patch new file mode 100644 index 000000000000..82ef75c33e33 --- /dev/null +++ b/src/libteam/0005-update-hwaddr-orig-unconditionally.patch @@ -0,0 +1,22 @@ +diff --git a/libteam/ifinfo.c b/libteam/ifinfo.c +index 72155ae..44de4ca 100644 +--- a/libteam/ifinfo.c ++++ b/libteam/ifinfo.c +@@ -105,15 +105,13 @@ static void update_hwaddr(struct team_ifinfo *ifinfo, struct rtnl_link *link) + hwaddr_len = nl_addr_get_len(nl_addr); + if (ifinfo->hwaddr_len != hwaddr_len) { + ifinfo->hwaddr_len = hwaddr_len; +- if (!ifinfo->master_ifindex) +- ifinfo->orig_hwaddr_len = hwaddr_len; ++ ifinfo->orig_hwaddr_len = hwaddr_len; + set_changed(ifinfo, CHANGED_HWADDR_LEN); + } + hwaddr = nl_addr_get_binary_addr(nl_addr); + if (memcmp(ifinfo->hwaddr, hwaddr, hwaddr_len)) { + memcpy(ifinfo->hwaddr, hwaddr, hwaddr_len); +- if (!ifinfo->master_ifindex) +- memcpy(ifinfo->orig_hwaddr, hwaddr, hwaddr_len); ++ memcpy(ifinfo->orig_hwaddr, hwaddr, hwaddr_len); + set_changed(ifinfo, CHANGED_HWADDR); + } + } diff --git a/src/libteam/Makefile b/src/libteam/Makefile index a20f8dbd35b0..bb4e00822b24 100644 --- a/src/libteam/Makefile +++ b/src/libteam/Makefile @@ -19,6 +19,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : git apply ../0002-libteam-Temporarily-remove-redundant-debug-mes.patch git apply ../0003-teamd-lacp-runner-will-send-lacp-update-right-after-.patch git apply ../0004-libteam-Add-lacp-fallback-support-for-single-member-.patch + git apply ../0005-update-hwaddr-orig-unconditionally.patch popd # Obtain debian packaging From 39f0c251fa554094e122e79a6c2af8953f8fffcb Mon Sep 17 00:00:00 2001 From: sridhar-ravindran <45350577+sridhar-ravindran@users.noreply.github.com> Date: Mon, 14 Jan 2019 23:26:17 +0530 Subject: [PATCH 191/219] [devices]: Porting MUX reset logic to fix probe fails (#2441) --- .../common/dell_i2c_utils.sh | 71 +++++++++++++- .../debian/platform-modules-s6100.install | 2 +- .../debian/platform-modules-z9100.install | 1 + .../s6100/modules/dell_s6100_iom_cpld.c | 32 +++++++ .../s6100/scripts/io_rd_wr.py | 93 ------------------- .../s6100/scripts/s6100_platform.sh | 42 +++++++-- .../z9100/scripts/z9100_platform.sh | 27 ++++-- 7 files changed, 157 insertions(+), 111 deletions(-) delete mode 100755 platform/broadcom/sonic-platform-modules-dell/s6100/scripts/io_rd_wr.py diff --git a/platform/broadcom/sonic-platform-modules-dell/common/dell_i2c_utils.sh b/platform/broadcom/sonic-platform-modules-dell/common/dell_i2c_utils.sh index 896e0166dc59..7ebf1e544497 100755 --- a/platform/broadcom/sonic-platform-modules-dell/common/dell_i2c_utils.sh +++ b/platform/broadcom/sonic-platform-modules-dell/common/dell_i2c_utils.sh @@ -18,7 +18,7 @@ i2c_config() { done if [[ "$count" -eq "$MAX_BUS_RETRY" ]]; then - echo "ERROR: $@ : i2c bus not created" + echo "dell_i2c_utils : ERROR: $@ : i2c bus not created" return fi @@ -31,7 +31,7 @@ i2c_config() { done if [[ "$count" -eq "$MAX_I2C_OP_RETRY" ]]; then - echo "ERROR: $@ : i2c operation failed" + echo "dell_i2c_utils : ERROR: $@ : i2c operation failed" return fi } @@ -53,10 +53,75 @@ i2c_poll_bus_exists() { done if [[ "$count" -eq "$MAX_BUS_RETRY" ]]; then - echo "ERROR: $@ : i2c bus not created" + echo "dell_i2c_utils : ERROR: $@ : i2c bus not created" return 1 else return 0 fi } +# Perform an i2c mux device create +# Input is of the form: +# i2c_mux_create mux_driver i2c_addr i2c_bus_num i2c_child_bus_num_start +# where i2c_bus_num is the bus number in which the mux is to be created and +# i2c_child_bus_num_start is the first of the 8 bus channels that this mux should create +i2c_mux_create() { + local MAX_MUX_CHANNEL_RETRY=3 + local MAX_MUX_CHANNELS=8 + local count=0 + local i + local mux_driver=$1 + local i2c_addr=$2 + local i2c_bus_num=$3 + local i2c_child_bus_num_start=$4 + + # Construct the i2c bus, the first and last bus channels that will be created under the MUX + i2c_bus=/sys/bus/i2c/devices/i2c-$i2c_bus_num + i2c_mux_channel_first=$i2c_bus/i2c-$i2c_child_bus_num_start + i2c_mux_channel_last=$i2c_bus/i2c-$(expr $i2c_child_bus_num_start + $MAX_MUX_CHANNELS - 1) + + if i2c_poll_bus_exists $i2c_bus; then + while [[ "$count" -lt "$MAX_MUX_CHANNEL_RETRY" ]]; do + eval "echo $mux_driver $i2c_addr > /sys/bus/i2c/devices/i2c-$i2c_bus_num/new_device" > /dev/null 2>&1 + ret=$? + + # Give more time for the mux channels to get created based on retries + i=0 + while [[ "$i" -lt "$count" ]]; do + sleep 1 + i=$((i+1)) + done + + # Check if the (first and last) mux channels got created + if [[ $ret -eq "0" && -e $i2c_mux_channel_first && -e $i2c_mux_channel_last ]]; then + break; + else + # If the channel did not get created, remove the mux, reset the mux tree and retry + echo "dell_i2c_utils : ERROR: i2c mux channel not created for $mux_driver,$i2c_addr,$i2c_bus_num" + i2c_mux_delete $i2c_addr $i2c_bus_num + reset_muxes + fi + + count=$((count+1)) + done + fi + + if [[ "$count" -eq "$MAX_MUX_CHANNEL_RETRY" ]]; then + echo "dell_i2c_utils : ERROR: $1,$2 : i2c mux channel not created" + return + fi + + return +} + +# Perform an i2c mux device delete +# Input is of the form: +# i2c_mux_delete i2c_addr i2c_bus_num +i2c_mux_delete() { + local i2c_addr + local i2c_bus_num + + i2c_addr=$1 + i2c_bus_num=$2 + i2c_config "echo $i2c_addr > /sys/bus/i2c/devices/i2c-$i2c_bus_num/delete_device" +} diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install index 7d56aee6e2f7..89550dd84668 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install @@ -1,7 +1,7 @@ -s6100/scripts/io_rd_wr.py usr/local/bin s6100/scripts/iom_power_*.sh usr/local/bin s6100/scripts/s6100_platform.sh usr/local/bin common/dell_i2c_utils.sh usr/local/bin +common/io_rd_wr.py usr/local/bin common/fstrim.timer etc/systemd/system common/fstrim.service etc/systemd/system s6100/scripts/platform_sensors.py usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install index 410dcf16ea1b..8d14a562cdd1 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-z9100.install @@ -1,6 +1,7 @@ z9100/scripts/check_qsfp.sh usr/local/bin z9100/scripts/z9100_platform.sh usr/local/bin common/dell_i2c_utils.sh usr/local/bin +common/io_rd_wr.py usr/local/bin common/fstrim.timer etc/systemd/system common/fstrim.service etc/systemd/system z9100/scripts/platform_sensors.py usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/modules/dell_s6100_iom_cpld.c b/platform/broadcom/sonic-platform-modules-dell/s6100/modules/dell_s6100_iom_cpld.c index 6cc28f707a1f..9c519d35a8a2 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/modules/dell_s6100_iom_cpld.c +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/modules/dell_s6100_iom_cpld.c @@ -11,6 +11,8 @@ //iom cpld slave address #define IOM_CPLD_SLAVE_ADD 0x3e +#define CPLD_SEP_RST0 0x5 + //iom cpld ver register #define IOM_CPLD_SLAVE_VER 0x00 @@ -182,16 +184,46 @@ static ssize_t set_reset(struct device *dev, struct device_attribute *devattr, c return count; } +static ssize_t get_sep_reset(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + u8 devdata=0; + struct cpld_data *data = dev_get_drvdata(dev); + + ret = dell_s6100_iom_cpld_read(data,IOM_CPLD_SLAVE_ADD,CPLD_SEP_RST0); + if(ret < 0) + return sprintf(buf, "read error"); + devdata = (u8)ret & 0xff; + return sprintf(buf,"0x%02x\n",devdata); +} + +static ssize_t set_sep_reset(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + unsigned long devdata; + int err; + struct cpld_data *data = dev_get_drvdata(dev); + + err = kstrtoul(buf, 16, &devdata); + if (err) + return err; + + dell_s6100_iom_cpld_write(data,IOM_CPLD_SLAVE_ADD,CPLD_SEP_RST0,(u8)(devdata & 0xff)); + + return count; +} + static DEVICE_ATTR(iom_cpld_vers,S_IRUGO,get_cpldver, NULL); static DEVICE_ATTR(qsfp_modprs, S_IRUGO,get_modprs, NULL); static DEVICE_ATTR(qsfp_lpmode, S_IRUGO | S_IWUSR,get_lpmode,set_lpmode); static DEVICE_ATTR(qsfp_reset, S_IRUGO | S_IWUSR,get_reset, set_reset); +static DEVICE_ATTR(sep_reset, S_IRUGO | S_IWUSR, get_sep_reset, set_sep_reset); static struct attribute *i2c_cpld_attrs[] = { &dev_attr_qsfp_lpmode.attr, &dev_attr_qsfp_reset.attr, &dev_attr_qsfp_modprs.attr, &dev_attr_iom_cpld_vers.attr, + &dev_attr_sep_reset.attr, NULL, }; diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/io_rd_wr.py b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/io_rd_wr.py deleted file mode 100755 index dc9dd09807c2..000000000000 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/io_rd_wr.py +++ /dev/null @@ -1,93 +0,0 @@ -#!/usr/bin/python -#Script to read/write the io based registers - -import sys -import os -import getopt -import struct - -io_resource='/dev/port' - -def usage(): - ''' This is the Usage Method ''' - - print 'Utility for IO read/write' - print '\t\t io_rd_wr.py --get --offset ' - print '\t\t io_rd_wr.py --set --val --offset ' - sys.exit(1) - -def io_reg_read(io_resource,offset): - fd=os.open(io_resource, os.O_RDONLY) - if(fd<0): - print 'file open failed %s"%io_resource' - return - if(os.lseek(fd, offset, os.SEEK_SET) != offset): - print 'lseek failed on %s'%io_resource - return - buf=os.read(fd,1) - reg_val1=ord(buf) - print 'reg value %x'%reg_val1 - os.close(fd) - -def io_reg_write(io_resource,offset,val): - fd=os.open(io_resource,os.O_RDWR) - if(fd<0): - print 'file open failed %s"%io_resource' - return - if(os.lseek(fd, offset, os.SEEK_SET) != offset): - print 'lseek failed on %s'%io_resource - return - ret=os.write(fd,struct.pack('B',val)) - if(ret != 1): - print 'write failed %d'%ret - return - os.close(fd) - -def main(argv): - - ''' The main function will read the user input from the - command line argument and process the request ''' - - opts = '' - val = '' - choice = '' - resouce = '' - offset = '' - - try: - opts, args = getopt.getopt(argv, "hgs:" , \ - ["val=","offset=","help", "get", "set"]) - - except getopt.GetoptError: - usage() - - for opt,arg in opts: - - if opt in ('-h','--help'): - choice = 'help' - - elif opt in ('-g', '--get'): - choice = 'get' - - elif opt in ('-s', '--set'): - choice = 'set' - - elif opt == '--offset': - offset = int(arg,16) - - elif opt == '--val': - val = int(arg,16) - - if choice == 'get' and offset != '': - io_reg_read(io_resource,offset) - - elif choice == 'set' and offset != '' and val != '': - io_reg_write(io_resource,offset,val) - - else: - usage() - -#Calling the main method -if __name__ == "__main__": - main(sys.argv[1:]) - diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh index be143cb9efe7..6b5e2a074539 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh @@ -21,9 +21,9 @@ init_devnum() { # Attach/Detach CPU board mux @ 0x70 cpu_board_mux() { case $1 in - "new_device") i2c_config "echo pca9547 0x70 > /sys/bus/i2c/devices/i2c-${devnum}/$1" + "new_device") i2c_mux_create pca9547 0x70 $devnum 2 ;; - "delete_device") i2c_config "echo 0x70 > /sys/bus/i2c/devices/i2c-${devnum}/$1" + "delete_device") i2c_mux_delete 0x70 $devnum ;; *) echo "s6100_platform: cpu_board_mux: invalid command !" ;; @@ -33,9 +33,9 @@ cpu_board_mux() { # Attach/Detach Switchboard MUX @ 0x71 switch_board_mux() { case $1 in - "new_device") i2c_config "echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-4/$1" + "new_device") i2c_mux_create pca9548 0x71 4 10 ;; - "delete_device") i2c_config "echo 0x71 > /sys/bus/i2c/devices/i2c-4/$1" + "delete_device") i2c_mux_delete 0x71 4 ;; *) echo "s6100_platform: switch_board_mux : invalid command !" ;; @@ -78,13 +78,17 @@ switch_board_cpld() { switch_board_qsfp_mux() { case $1 in "new_device") + # The mux for the QSFPs spawn {18..25}, {26..33}... {74..81} + # starting at chennel 18 and 16 channels per IOM. + channel_first=18 for ((i=9;i>=6;i--)); do # 0x71 mux on the IOM 1 mux_index=$(expr $i - 5) echo "Attaching PCA9548 $mux_index" - i2c_config "echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-$i/$1" - i2c_config "echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-$i/$1" + i2c_mux_create pca9548 0x71 $i $channel_first + i2c_mux_create pca9548 0x72 $i $(expr $channel_first + 8) + channel_first=$(expr $channel_first + 16) done ;; "delete_device") @@ -93,8 +97,8 @@ switch_board_qsfp_mux() { # 0x71 mux on the IOM 1 mux_index=$(expr $i - 5) echo "Detaching PCA9548 $mux_index" - i2c_config "echo 0x71 > /sys/bus/i2c/devices/i2c-$devnum/i2c-$i/$1" - i2c_config "echo 0x72 > /sys/bus/i2c/devices/i2c-$devnum/i2c-$i/$1" + i2c_mux_delete 0x71 $i + i2c_mux_delete 0x72 $i done ;; *) echo "s6100_platform: switch_board_qsfp_mux: invalid command !" @@ -171,6 +175,28 @@ switch_board_qsfp_lpmode() { echo $value > /sys/class/i2c-adapter/i2c-17/17-003e/qsfp_lpmode } +# Reset the mux tree +reset_muxes() { + local i + + # Reset the IOM muxes (if they have been already instantiated) + for ((i=14;i<=17;i++)); + do + if [[ -e /sys/class/i2c-adapter/i2c-$i/$i-003e ]]; then + echo 0xfc > /sys/class/i2c-adapter/i2c-$i/$i-003e/sep_reset + echo 0xff > /sys/class/i2c-adapter/i2c-$i/$i-003e/sep_reset + fi + done + + # Reset the switch card PCA9548A + io_rd_wr.py --set --val 0xef --offset 0x110 + io_rd_wr.py --set --val 0xff --offset 0x110 + + # Reset the CPU Card PCA9547 + io_rd_wr.py --set --val 0xfd --offset 0x20b + io_rd_wr.py --set --val 0xff --offset 0x20b +} + init_devnum if [[ "$1" == "init" ]]; then diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh index 0fa2afc2bc92..6aaa7339235c 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/z9100_platform.sh @@ -21,9 +21,9 @@ init_devnum() { # Attach/Detach CPU board mux @ 0x70 cpu_board_mux() { case $1 in - "new_device") i2c_config "echo pca9547 0x70 > /sys/bus/i2c/devices/i2c-${devnum}/$1" + "new_device") i2c_mux_create pca9547 0x70 $devnum 2 ;; - "delete_device") i2c_config "echo 0x70 > /sys/bus/i2c/devices/i2c-${devnum}/$1" + "delete_device") i2c_mux_delete 0x70 $devnum ;; *) echo "z9100_platform: cpu_board_mux: invalid command !" ;; @@ -33,9 +33,9 @@ cpu_board_mux() { # Attach/Detach switch board MUX to IOM CPLDs @ 0x71 switch_board_mux() { case $1 in - "new_device") i2c_config "echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-4/$1" + "new_device") i2c_mux_create pca9548 0x71 4 10 ;; - "delete_device") i2c_config "echo 0x71 > /sys/bus/i2c/devices/i2c-4/$1" + "delete_device") i2c_mux_delete 0x71 4 ;; *) echo "z9100_platform: switch_board_mux : invalid command !" ;; @@ -78,12 +78,16 @@ switch_board_cpld() { switch_board_qsfp_mux() { case $1 in "new_device") + # The mux for the QSFPs spawn {18..25}, {26..33}, {34..41} and {42..49} + # starting at chennel 18 and 8 channels per mux. + channel_first=18 for ((i=9;i>=6;i--)); do # 0x71 mux on the IOM 1 mux_index=$(expr $i - 5) echo "Attaching PCA9548 $mux_index" - i2c_config "echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-$i/$1" + i2c_mux_create pca9548 0x71 $i $channel_first + channel_first=$(expr $channel_first + 8) done ;; "delete_device") @@ -92,7 +96,7 @@ switch_board_qsfp_mux() { # 0x71 mux on the IOM 1 mux_index=$(expr $i - 5) echo "Detaching PCA9548 $mux_index" - i2c_config "echo 0x71 > /sys/bus/i2c/devices/i2c-$devnum/i2c-$i/$1" + i2c_mux_delete 0x71 $i done ;; *) echo "z9100_platform: switch_board_qsfp_mux: invalid command !" @@ -136,6 +140,17 @@ switch_board_qsfp() { esac } +# Reset the mux tree +reset_muxes() { + # Reset the IOM muxes and the switch card mux + io_rd_wr.py --set --val 0xe0 --offset 0x110 + io_rd_wr.py --set --val 0xff --offset 0x110 + + # Reset the CPU Card PCA9547 + io_rd_wr.py --set --val 0xfd --offset 0x20b + io_rd_wr.py --set --val 0xff --offset 0x20b +} + init_devnum if [[ "$1" == "init" ]]; then From aa338254411645a30d6c5fba523337ece79a2863 Mon Sep 17 00:00:00 2001 From: Wenda Ni Date: Wed, 16 Jan 2019 18:45:47 -0800 Subject: [PATCH 192/219] [Qos]: Remove WRED on lossy queues on msn2700 (#2456) Signed-off-by: Wenda --- device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/qos.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/qos.json b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/qos.json index df3d29c636e3..9ac8fd3af813 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/qos.json +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/qos.json @@ -156,9 +156,6 @@ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|1": { "scheduler" : "[SCHEDULER|scheduler.2]" }, - "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0-1": { - "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]" - }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3-4": { "scheduler" : "[SCHEDULER|scheduler.0]", "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" From a18ec656d1c4121d27d4e9345b7089479d18b30b Mon Sep 17 00:00:00 2001 From: sridhar-ravindran <45350577+sridhar-ravindran@users.noreply.github.com> Date: Wed, 23 Jan 2019 22:53:39 +0530 Subject: [PATCH 193/219] [devices]: Fix for build break for device s6100/z9100 from #2441 checkin (#2477) --- .../common/io_rd_wr.py | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100755 platform/broadcom/sonic-platform-modules-dell/common/io_rd_wr.py diff --git a/platform/broadcom/sonic-platform-modules-dell/common/io_rd_wr.py b/platform/broadcom/sonic-platform-modules-dell/common/io_rd_wr.py new file mode 100755 index 000000000000..2b6413970a75 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/common/io_rd_wr.py @@ -0,0 +1,93 @@ +#!/usr/bin/python +#Script to read/write the io based registers + +import sys +import os +import getopt +import struct + +io_resource='/dev/port' + +def usage(): + ''' This is the Usage Method ''' + + print 'Utility for IO read/write' + print '\t\t io_rd_wr.py --get --offset ' + print '\t\t io_rd_wr.py --set --val --offset ' + sys.exit(1) + +def io_reg_read(io_resource,offset): + fd=os.open(io_resource, os.O_RDONLY) + if(fd<0): + print 'file open failed %s"%io_resource' + return + if(os.lseek(fd, offset, os.SEEK_SET) != offset): + print 'lseek failed on %s'%io_resource + return + buf=os.read(fd,1) + reg_val1=ord(buf) + print 'reg value %x'%reg_val1 + os.close(fd) + +def io_reg_write(io_resource,offset,val): + fd=os.open(io_resource,os.O_RDWR) + if(fd<0): + print 'file open failed %s"%io_resource' + return + if(os.lseek(fd, offset, os.SEEK_SET) != offset): + print 'lseek failed on %s'%io_resource + return + ret=os.write(fd,struct.pack('B',val)) + if(ret != 1): + print 'write failed %d'%ret + return + os.close(fd) + +def main(argv): + + ''' The main function will read the user input from the + command line argument and process the request ''' + + opts = '' + val = '' + choice = '' + resouce = '' + offset = '' + + try: + opts, args = getopt.getopt(argv, "hgs:" , \ + ["val=","offset=","help", "get", "set"]) + + except getopt.GetoptError: + usage() + + for opt,arg in opts: + + if opt in ('-h','--help'): + choice = 'help' + + elif opt in ('-g', '--get'): + choice = 'get' + + elif opt in ('-s', '--set'): + choice = 'set' + + elif opt == '--offset': + offset = int(arg,16) + + elif opt == '--val': + val = int(arg,16) + + if choice == 'get' and offset != '': + io_reg_read(io_resource,offset) + + elif choice == 'set' and offset != '' and val != '': + io_reg_write(io_resource,offset,val) + + else: + usage() + +#Calling the main method +if __name__ == "__main__": + main(sys.argv[1:]) + From a18464b334415b5478ec2cfaed32f8dd5978737b Mon Sep 17 00:00:00 2001 From: paavaanan Date: Sat, 26 Jan 2019 01:48:25 +0530 Subject: [PATCH 194/219] [devices]: platform_reboot support for Dell S6100/Z9100 platforms (#2480) * platform_reboot support for Dell S6100/Z9100 platforms --- .../platform_reboot | 25 +++++++++++++++++++ .../platform_reboot | 25 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100755 device/dell/x86_64-dell_s6100_c2538-r0/platform_reboot create mode 100755 device/dell/x86_64-dell_z9100_c2538-r0/platform_reboot diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/platform_reboot b/device/dell/x86_64-dell_s6100_c2538-r0/platform_reboot new file mode 100755 index 000000000000..3e165630658b --- /dev/null +++ b/device/dell/x86_64-dell_s6100_c2538-r0/platform_reboot @@ -0,0 +1,25 @@ +#!/usr/bin/python +import sys +import os +import struct + +PORT_RES = '/dev/port' + + +def portio_reg_write(resource, offset, val): + fd = os.open(resource, os.O_RDWR) + if(fd < 0): + print 'file open failed %s" % resource' + return + if(os.lseek(fd, offset, os.SEEK_SET) != offset): + print 'lseek failed on %s' % resource + return + ret = os.write(fd, struct.pack('B', val)) + if(ret != 1): + print 'write failed %d' % ret + return + os.close(fd) + +if __name__ == "__main__": + portio_reg_write(PORT_RES, 0xcf9, 0xe) + diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/platform_reboot b/device/dell/x86_64-dell_z9100_c2538-r0/platform_reboot new file mode 100755 index 000000000000..3e165630658b --- /dev/null +++ b/device/dell/x86_64-dell_z9100_c2538-r0/platform_reboot @@ -0,0 +1,25 @@ +#!/usr/bin/python +import sys +import os +import struct + +PORT_RES = '/dev/port' + + +def portio_reg_write(resource, offset, val): + fd = os.open(resource, os.O_RDWR) + if(fd < 0): + print 'file open failed %s" % resource' + return + if(os.lseek(fd, offset, os.SEEK_SET) != offset): + print 'lseek failed on %s' % resource + return + ret = os.write(fd, struct.pack('B', val)) + if(ret != 1): + print 'write failed %d' % ret + return + os.close(fd) + +if __name__ == "__main__": + portio_reg_write(PORT_RES, 0xcf9, 0xe) + From c82be495b9c2338c7835b9991e5f713281657138 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 23 Jan 2019 18:47:05 -0800 Subject: [PATCH 195/219] [caclmgrd] Don't crash if we find empty/null rule_props (#2475) * [caclmgrd] Don't crash if we find empty/null rule_props --- files/image_config/caclmgrd/caclmgrd | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index 6ddd6de007c8..450aedaedcbb 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -157,7 +157,15 @@ class ControlPlaneAclManager(object): for ((rule_table_name, rule_id), rule_props) in self._rules_db_info.iteritems(): if rule_table_name == table_name: - acl_rules[rule_props["PRIORITY"]] = rule_props + if not rule_props: + log_warning("rule_props for rule_id {} empty or null!".format(rule_id)) + continue + + try: + acl_rules[rule_props["PRIORITY"]] = rule_props + except KeyError: + log_error("rule_props for rule_id {} does not have key 'PRIORITY'!".format(rule_id)) + continue # If we haven't determined the IP version for this ACL table yet, # try to do it now. We determine heuristically based on whether the From a67a93747570c589552c489cbc7c6c98faeb400a Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 15 Jan 2019 11:27:46 -0800 Subject: [PATCH 196/219] [lldp] For MGMT port, if port alias is available, use it for Port ID subtype; otherwise use port name (#2445) --- dockers/docker-lldp-sv2/lldpd.conf.j2 | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dockers/docker-lldp-sv2/lldpd.conf.j2 b/dockers/docker-lldp-sv2/lldpd.conf.j2 index 94a04596699f..fd8a4d4c5458 100644 --- a/dockers/docker-lldp-sv2/lldpd.conf.j2 +++ b/dockers/docker-lldp-sv2/lldpd.conf.j2 @@ -1,3 +1,9 @@ {% if MGMT_INTERFACE %} -configure ports eth0 lldp portidsubtype local {{ MGMT_INTERFACE.keys()[0][0] }} +{# If MGMT port alias is available, use it for port ID subtype, otherwise use port name #} +{% set mgmt_port_name = MGMT_INTERFACE.keys()[0][0] %} +{% if MGMT_PORT and MGMT_PORT[mgmt_port_name] and MGMT_PORT[mgmt_port_name].alias %} +configure ports eth0 lldp portidsubtype local {{ MGMT_PORT[mgmt_port_name].alias }} +{% else %} +configure ports eth0 lldp portidsubtype local {{ mgmt_port_name }} +{% endif %} {% endif %} From 4b70ae9467065bbfda5d8eb5bbad512fc3bddf86 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Mon, 28 Jan 2019 17:13:40 +0000 Subject: [PATCH 197/219] [submodule]: update sonic-utilities 518ff41 2019-01-28 | Revert "Fix the ipv6 address lost issue with current config CLI (#331)" (HEAD, origin/201803) [Guohan Lu] Signed-off-by: Guohan Lu --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 06c73ca4a612..518ff41415c0 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 06c73ca4a6129782f004e69331250841a527de52 +Subproject commit 518ff41415c02c6d32b2db3ef1057bd5f87713fc From 8fda69389e5d7a729850000956c3b1711c8185e8 Mon Sep 17 00:00:00 2001 From: Wenda Ni Date: Fri, 1 Feb 2019 17:25:10 -0800 Subject: [PATCH 198/219] [QoS]: Qos config change (#2504) * a7050-QX-32S, a7050-QX32, s6000: 1) dscp mapping; 2) DWRR a7060-Q32, a7060-C32, a7060-D48C8, s6100, z9100-C32, z9100-D48C8, a7260-D108C8 mmu setting change: 1) Update headroom pool size; Update ingress service pool and egress lossy pool sizes accordingly; 2) Add DSCP 48 to TC 6 mapping; 3) scheduler weight redistribute Signed-off-by: Wenda Ni * Correct format Signed-off-by: Wenda * Link queue 2 to lossy buffer Add scheduling weight to queue 2 Signed-off-by: Wenda * Link pg 2 to lossy buffer Signed-off-by: Wenda * Add tc to pg, tc to queue, pfc to queue mapping for 2, 6 (and 7) Signed-off-by: Wenda --- .../Arista-7050-QX32/buffers.json.j2 | 8 +- .../Arista-7050-QX32/qos.json | 153 ++++++++++-------- .../Arista-7050-QX-32S/buffers.json.j2 | 8 +- .../Arista-7050-QX-32S/qos.json | 153 ++++++++++-------- .../buffers_defaults_t0.j2 | 6 +- .../buffers_defaults_t1.j2 | 6 +- .../Arista-7060CX-32S-C32/qos.json | 138 ++++++++-------- .../buffers_defaults_t0.j2 | 6 +- .../pg_profile_lookup.ini | 2 +- .../Arista-7060CX-32S-D48C8/qos.json | 138 ++++++++-------- .../buffers_defaults_t0.j2 | 6 +- .../buffers_defaults_t1.j2 | 6 +- .../Arista-7060CX-32S-Q32/qos.json | 138 ++++++++-------- .../buffers_defaults_t0.j2 | 6 +- .../Arista-7260CX3-D108C8/qos.json | 138 ++++++++-------- .../Force10-S6000/buffers.json.j2 | 8 +- .../Force10-S6000/qos.json | 153 ++++++++++-------- .../Force10-S6100/buffers_defaults_t0.j2 | 6 +- .../Force10-S6100/buffers_defaults_t1.j2 | 6 +- .../Force10-S6100/qos.json | 138 ++++++++-------- .../Force10-Z9100-C32/buffers_defaults_t1.j2 | 6 +- .../Force10-Z9100-C32/qos.json | 138 ++++++++-------- .../buffers_defaults_t0.j2 | 6 +- .../Force10-Z9100-C8D48/qos.json | 138 ++++++++-------- files/build_templates/buffers_config.j2 | 8 +- 25 files changed, 823 insertions(+), 696 deletions(-) diff --git a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers.json.j2 b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers.json.j2 index db37b6cd36a6..e080492a40a7 100644 --- a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers.json.j2 +++ b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers.json.j2 @@ -113,10 +113,10 @@ "{{ port_names }}|3-4": { "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" }, - "{{ port_names }}|0-1": { + "{{ port_names }}|0-2": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "{{ port_names }}|5": { + "{{ port_names }}|5-6": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" } }, @@ -124,10 +124,10 @@ "{{ port_names }}|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "{{ port_names }}|0-1": { + "{{ port_names }}|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "{{ port_names }}|5": { + "{{ port_names }}|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" } } diff --git a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/qos.json b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/qos.json index 0eb02957299f..524d53b4f4dd 100644 --- a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/qos.json +++ b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/qos.json @@ -3,101 +3,114 @@ "AZURE": { "0": "0", "1": "1", + "2": "2", "3": "3", "4": "4", - "5": "5" + "5": "5", + "6": "6", + "7": "7" } }, "MAP_PFC_PRIORITY_TO_QUEUE": { "AZURE": { "0": "0", "1": "1", + "2": "2", "3": "3", "4": "4", - "5": "5" + "5": "5", + "6": "6", + "7": "7" } }, "TC_TO_QUEUE_MAP": { "AZURE": { "0": "0", "1": "1", + "2": "2", "3": "3", "4": "4", - "5": "5" + "5": "5", + "6": "6", + "7": "7" } }, "DSCP_TO_TC_MAP": { "AZURE": { - "0":"0", - "1":"0", - "2":"0", + "0":"1", + "1":"1", + "2":"1", "3":"3", "4":"4", - "5":"0", - "6":"0", - "7":"0", - "8":"1", - "9":"0", - "10":"0", - "11":"0", - "12":"0", - "13":"0", - "14":"0", - "15":"0", - "16":"0", - "17":"0", - "18":"0", - "19":"0", - "20":"0", - "21":"0", - "22":"0", - "23":"0", - "24":"0", - "25":"0", - "26":"0", - "27":"0", - "28":"0", - "29":"0", - "30":"0", - "31":"0", - "32":"0", - "33":"0", - "34":"0", - "35":"0", - "36":"0", - "37":"0", - "38":"0", - "39":"0", - "40":"0", - "41":"0", - "42":"0", - "43":"0", - "44":"0", - "45":"0", + "5":"2", + "6":"1", + "7":"1", + "8":"0", + "9":"1", + "10":"1", + "11":"1", + "12":"1", + "13":"1", + "14":"1", + "15":"1", + "16":"1", + "17":"1", + "18":"1", + "19":"1", + "20":"1", + "21":"1", + "22":"1", + "23":"1", + "24":"1", + "25":"1", + "26":"1", + "27":"1", + "28":"1", + "29":"1", + "30":"1", + "31":"1", + "32":"1", + "33":"1", + "34":"1", + "35":"1", + "36":"1", + "37":"1", + "38":"1", + "39":"1", + "40":"1", + "41":"1", + "42":"1", + "43":"1", + "44":"1", + "45":"1", "46":"5", - "47":"0", - "48":"0", - "49":"0", - "50":"0", - "51":"0", - "52":"0", - "53":"0", - "54":"0", - "55":"0", - "56":"0", - "57":"0", - "58":"0", - "59":"0", - "60":"0", - "61":"0", - "62":"0", - "63":"0" + "47":"1", + "48":"6", + "49":"1", + "50":"1", + "51":"1", + "52":"1", + "53":"1", + "54":"1", + "55":"1", + "56":"1", + "57":"1", + "58":"1", + "59":"1", + "60":"1", + "61":"1", + "62":"1", + "63":"1" } }, "SCHEDULER": { "scheduler.0" : { "type":"DWRR", - "weight": "20" + "weight": "14" + }, + "scheduler.1" : { + "type":"DWRR", + "weight": "15" } }, "PORT_QOS_MAP": { @@ -128,11 +141,11 @@ }, "QUEUE": { "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3" : { - "scheduler" : "[SCHEDULER|scheduler.0]", + "scheduler" : "[SCHEDULER|scheduler.1]", "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|4" : { - "scheduler" : "[SCHEDULER|scheduler.0]", + "scheduler" : "[SCHEDULER|scheduler.1]", "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0" : { @@ -141,8 +154,14 @@ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|1" : { "scheduler" : "[SCHEDULER|scheduler.0]" }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|2" : { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|5" : { "scheduler" : "[SCHEDULER|scheduler.0]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|6" : { + "scheduler" : "[SCHEDULER|scheduler.0]" } } } diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/buffers.json.j2 b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/buffers.json.j2 index db37b6cd36a6..e080492a40a7 100644 --- a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/buffers.json.j2 +++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/buffers.json.j2 @@ -113,10 +113,10 @@ "{{ port_names }}|3-4": { "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" }, - "{{ port_names }}|0-1": { + "{{ port_names }}|0-2": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "{{ port_names }}|5": { + "{{ port_names }}|5-6": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" } }, @@ -124,10 +124,10 @@ "{{ port_names }}|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "{{ port_names }}|0-1": { + "{{ port_names }}|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "{{ port_names }}|5": { + "{{ port_names }}|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" } } diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/qos.json b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/qos.json index 0eb02957299f..524d53b4f4dd 100644 --- a/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/qos.json +++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/qos.json @@ -3,101 +3,114 @@ "AZURE": { "0": "0", "1": "1", + "2": "2", "3": "3", "4": "4", - "5": "5" + "5": "5", + "6": "6", + "7": "7" } }, "MAP_PFC_PRIORITY_TO_QUEUE": { "AZURE": { "0": "0", "1": "1", + "2": "2", "3": "3", "4": "4", - "5": "5" + "5": "5", + "6": "6", + "7": "7" } }, "TC_TO_QUEUE_MAP": { "AZURE": { "0": "0", "1": "1", + "2": "2", "3": "3", "4": "4", - "5": "5" + "5": "5", + "6": "6", + "7": "7" } }, "DSCP_TO_TC_MAP": { "AZURE": { - "0":"0", - "1":"0", - "2":"0", + "0":"1", + "1":"1", + "2":"1", "3":"3", "4":"4", - "5":"0", - "6":"0", - "7":"0", - "8":"1", - "9":"0", - "10":"0", - "11":"0", - "12":"0", - "13":"0", - "14":"0", - "15":"0", - "16":"0", - "17":"0", - "18":"0", - "19":"0", - "20":"0", - "21":"0", - "22":"0", - "23":"0", - "24":"0", - "25":"0", - "26":"0", - "27":"0", - "28":"0", - "29":"0", - "30":"0", - "31":"0", - "32":"0", - "33":"0", - "34":"0", - "35":"0", - "36":"0", - "37":"0", - "38":"0", - "39":"0", - "40":"0", - "41":"0", - "42":"0", - "43":"0", - "44":"0", - "45":"0", + "5":"2", + "6":"1", + "7":"1", + "8":"0", + "9":"1", + "10":"1", + "11":"1", + "12":"1", + "13":"1", + "14":"1", + "15":"1", + "16":"1", + "17":"1", + "18":"1", + "19":"1", + "20":"1", + "21":"1", + "22":"1", + "23":"1", + "24":"1", + "25":"1", + "26":"1", + "27":"1", + "28":"1", + "29":"1", + "30":"1", + "31":"1", + "32":"1", + "33":"1", + "34":"1", + "35":"1", + "36":"1", + "37":"1", + "38":"1", + "39":"1", + "40":"1", + "41":"1", + "42":"1", + "43":"1", + "44":"1", + "45":"1", "46":"5", - "47":"0", - "48":"0", - "49":"0", - "50":"0", - "51":"0", - "52":"0", - "53":"0", - "54":"0", - "55":"0", - "56":"0", - "57":"0", - "58":"0", - "59":"0", - "60":"0", - "61":"0", - "62":"0", - "63":"0" + "47":"1", + "48":"6", + "49":"1", + "50":"1", + "51":"1", + "52":"1", + "53":"1", + "54":"1", + "55":"1", + "56":"1", + "57":"1", + "58":"1", + "59":"1", + "60":"1", + "61":"1", + "62":"1", + "63":"1" } }, "SCHEDULER": { "scheduler.0" : { "type":"DWRR", - "weight": "20" + "weight": "14" + }, + "scheduler.1" : { + "type":"DWRR", + "weight": "15" } }, "PORT_QOS_MAP": { @@ -128,11 +141,11 @@ }, "QUEUE": { "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3" : { - "scheduler" : "[SCHEDULER|scheduler.0]", + "scheduler" : "[SCHEDULER|scheduler.1]", "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|4" : { - "scheduler" : "[SCHEDULER|scheduler.0]", + "scheduler" : "[SCHEDULER|scheduler.1]", "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0" : { @@ -141,8 +154,14 @@ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|1" : { "scheduler" : "[SCHEDULER|scheduler.0]" }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|2" : { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|5" : { "scheduler" : "[SCHEDULER|scheduler.0]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|6" : { + "scheduler" : "[SCHEDULER|scheduler.0]" } } } diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/buffers_defaults_t0.j2 index 3e39d411e8bf..cb74cb75281b 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/buffers_defaults_t0.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/buffers_defaults_t0.j2 @@ -11,13 +11,13 @@ {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "11213696", + "size": "10875072", "type": "ingress", "mode": "dynamic", - "xoff": "3855488" + "xoff": "4194112" }, "egress_lossy_pool": { - "size": "9532224", + "size": "9243812", "type": "egress", "mode": "dynamic" }, diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/buffers_defaults_t1.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/buffers_defaults_t1.j2 index d9f562f95624..0699433bffb4 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/buffers_defaults_t1.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/buffers_defaults_t1.j2 @@ -11,13 +11,13 @@ {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "10443264", + "size": "10875072", "type": "ingress", "mode": "dynamic", - "xoff": "4625920" + "xoff": "4194112" }, "egress_lossy_pool": { - "size": "8877440", + "size": "9243812", "type": "egress", "mode": "dynamic" }, diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/qos.json b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/qos.json index deb9f40fc0f4..524d53b4f4dd 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/qos.json +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32/qos.json @@ -37,76 +37,80 @@ }, "DSCP_TO_TC_MAP": { "AZURE": { - "0":"0", - "1":"0", - "2":"0", + "0":"1", + "1":"1", + "2":"1", "3":"3", "4":"4", - "5":"0", - "6":"0", - "7":"0", - "8":"1", - "9":"0", - "10":"0", - "11":"0", - "12":"0", - "13":"0", - "14":"0", - "15":"0", - "16":"0", - "17":"0", - "18":"0", - "19":"0", - "20":"0", - "21":"0", - "22":"0", - "23":"0", - "24":"0", - "25":"0", - "26":"0", - "27":"0", - "28":"0", - "29":"0", - "30":"0", - "31":"0", - "32":"0", - "33":"0", - "34":"0", - "35":"0", - "36":"0", - "37":"0", - "38":"0", - "39":"0", - "40":"0", - "41":"0", - "42":"0", - "43":"0", - "44":"0", - "45":"0", + "5":"2", + "6":"1", + "7":"1", + "8":"0", + "9":"1", + "10":"1", + "11":"1", + "12":"1", + "13":"1", + "14":"1", + "15":"1", + "16":"1", + "17":"1", + "18":"1", + "19":"1", + "20":"1", + "21":"1", + "22":"1", + "23":"1", + "24":"1", + "25":"1", + "26":"1", + "27":"1", + "28":"1", + "29":"1", + "30":"1", + "31":"1", + "32":"1", + "33":"1", + "34":"1", + "35":"1", + "36":"1", + "37":"1", + "38":"1", + "39":"1", + "40":"1", + "41":"1", + "42":"1", + "43":"1", + "44":"1", + "45":"1", "46":"5", - "47":"0", - "48":"0", - "49":"0", - "50":"0", - "51":"0", - "52":"0", - "53":"0", - "54":"0", - "55":"0", - "56":"0", - "57":"0", - "58":"0", - "59":"0", - "60":"0", - "61":"0", - "62":"0", - "63":"0" + "47":"1", + "48":"6", + "49":"1", + "50":"1", + "51":"1", + "52":"1", + "53":"1", + "54":"1", + "55":"1", + "56":"1", + "57":"1", + "58":"1", + "59":"1", + "60":"1", + "61":"1", + "62":"1", + "63":"1" } }, "SCHEDULER": { "scheduler.0" : { "type":"DWRR", - "weight": "20" + "weight": "14" + }, + "scheduler.1" : { + "type":"DWRR", + "weight": "15" } }, "PORT_QOS_MAP": { @@ -137,11 +141,11 @@ }, "QUEUE": { "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3" : { - "scheduler" : "[SCHEDULER|scheduler.0]", + "scheduler" : "[SCHEDULER|scheduler.1]", "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|4" : { - "scheduler" : "[SCHEDULER|scheduler.0]", + "scheduler" : "[SCHEDULER|scheduler.1]", "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0" : { @@ -150,8 +154,14 @@ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|1" : { "scheduler" : "[SCHEDULER|scheduler.0]" }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|2" : { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|5" : { "scheduler" : "[SCHEDULER|scheduler.0]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|6" : { + "scheduler" : "[SCHEDULER|scheduler.0]" } } } diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers_defaults_t0.j2 index 7463e20afabe..5d6e0cd61a7e 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers_defaults_t0.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/buffers_defaults_t0.j2 @@ -25,13 +25,13 @@ {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "11213696", + "size": "10875072", "type": "ingress", "mode": "dynamic", - "xoff": "3855488" + "xoff": "4194112" }, "egress_lossy_pool": { - "size": "9532224", + "size": "9243812", "type": "egress", "mode": "dynamic" }, diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/pg_profile_lookup.ini b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/pg_profile_lookup.ini index 570454c8d5b2..dc05d0a100a3 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/pg_profile_lookup.ini +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/pg_profile_lookup.ini @@ -13,5 +13,5 @@ 10000 300m 1248 2288 46176 -3 2288 25000 300m 1248 2288 79040 -3 2288 40000 300m 1248 2288 108160 -3 2288 - 50000 300m 1248 2288 131456 -3 2288 + 50000 300m 1248 2288 141856 -3 2288 100000 300m 1248 2288 268736 -3 2288 diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/qos.json b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/qos.json index 8fbee4a60dd7..0f8c5cb88d42 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/qos.json +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-D48C8/qos.json @@ -37,76 +37,80 @@ }, "DSCP_TO_TC_MAP": { "AZURE": { - "0":"0", - "1":"0", - "2":"0", + "0":"1", + "1":"1", + "2":"1", "3":"3", "4":"4", - "5":"0", - "6":"0", - "7":"0", - "8":"1", - "9":"0", - "10":"0", - "11":"0", - "12":"0", - "13":"0", - "14":"0", - "15":"0", - "16":"0", - "17":"0", - "18":"0", - "19":"0", - "20":"0", - "21":"0", - "22":"0", - "23":"0", - "24":"0", - "25":"0", - "26":"0", - "27":"0", - "28":"0", - "29":"0", - "30":"0", - "31":"0", - "32":"0", - "33":"0", - "34":"0", - "35":"0", - "36":"0", - "37":"0", - "38":"0", - "39":"0", - "40":"0", - "41":"0", - "42":"0", - "43":"0", - "44":"0", - "45":"0", + "5":"2", + "6":"1", + "7":"1", + "8":"0", + "9":"1", + "10":"1", + "11":"1", + "12":"1", + "13":"1", + "14":"1", + "15":"1", + "16":"1", + "17":"1", + "18":"1", + "19":"1", + "20":"1", + "21":"1", + "22":"1", + "23":"1", + "24":"1", + "25":"1", + "26":"1", + "27":"1", + "28":"1", + "29":"1", + "30":"1", + "31":"1", + "32":"1", + "33":"1", + "34":"1", + "35":"1", + "36":"1", + "37":"1", + "38":"1", + "39":"1", + "40":"1", + "41":"1", + "42":"1", + "43":"1", + "44":"1", + "45":"1", "46":"5", - "47":"0", - "48":"0", - "49":"0", - "50":"0", - "51":"0", - "52":"0", - "53":"0", - "54":"0", - "55":"0", - "56":"0", - "57":"0", - "58":"0", - "59":"0", - "60":"0", - "61":"0", - "62":"0", - "63":"0" + "47":"1", + "48":"6", + "49":"1", + "50":"1", + "51":"1", + "52":"1", + "53":"1", + "54":"1", + "55":"1", + "56":"1", + "57":"1", + "58":"1", + "59":"1", + "60":"1", + "61":"1", + "62":"1", + "63":"1" } }, "SCHEDULER": { "scheduler.0" : { "type":"DWRR", - "weight": "20" + "weight": "14" + }, + "scheduler.1" : { + "type":"DWRR", + "weight": "15" } }, "PORT_QOS_MAP": { @@ -137,11 +141,11 @@ }, "QUEUE": { "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126|3": { - "scheduler" : "[SCHEDULER|scheduler.0]", + "scheduler" : "[SCHEDULER|scheduler.1]", "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126|4": { - "scheduler" : "[SCHEDULER|scheduler.0]", + "scheduler" : "[SCHEDULER|scheduler.1]", "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126|0": { @@ -150,8 +154,14 @@ "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126|1": { "scheduler" : "[SCHEDULER|scheduler.0]" }, + "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126|2": { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126|5": { "scheduler" : "[SCHEDULER|scheduler.0]" + }, + "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126|6": { + "scheduler" : "[SCHEDULER|scheduler.0]" } } } diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t0.j2 index 3e39d411e8bf..cb74cb75281b 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t0.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t0.j2 @@ -11,13 +11,13 @@ {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "11213696", + "size": "10875072", "type": "ingress", "mode": "dynamic", - "xoff": "3855488" + "xoff": "4194112" }, "egress_lossy_pool": { - "size": "9532224", + "size": "9243812", "type": "egress", "mode": "dynamic" }, diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t1.j2 b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t1.j2 index d9f562f95624..0699433bffb4 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t1.j2 +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/buffers_defaults_t1.j2 @@ -11,13 +11,13 @@ {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "10443264", + "size": "10875072", "type": "ingress", "mode": "dynamic", - "xoff": "4625920" + "xoff": "4194112" }, "egress_lossy_pool": { - "size": "8877440", + "size": "9243812", "type": "egress", "mode": "dynamic" }, diff --git a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/qos.json b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/qos.json index deb9f40fc0f4..524d53b4f4dd 100644 --- a/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/qos.json +++ b/device/arista/x86_64-arista_7060_cx32s/Arista-7060CX-32S-Q32/qos.json @@ -37,76 +37,80 @@ }, "DSCP_TO_TC_MAP": { "AZURE": { - "0":"0", - "1":"0", - "2":"0", + "0":"1", + "1":"1", + "2":"1", "3":"3", "4":"4", - "5":"0", - "6":"0", - "7":"0", - "8":"1", - "9":"0", - "10":"0", - "11":"0", - "12":"0", - "13":"0", - "14":"0", - "15":"0", - "16":"0", - "17":"0", - "18":"0", - "19":"0", - "20":"0", - "21":"0", - "22":"0", - "23":"0", - "24":"0", - "25":"0", - "26":"0", - "27":"0", - "28":"0", - "29":"0", - "30":"0", - "31":"0", - "32":"0", - "33":"0", - "34":"0", - "35":"0", - "36":"0", - "37":"0", - "38":"0", - "39":"0", - "40":"0", - "41":"0", - "42":"0", - "43":"0", - "44":"0", - "45":"0", + "5":"2", + "6":"1", + "7":"1", + "8":"0", + "9":"1", + "10":"1", + "11":"1", + "12":"1", + "13":"1", + "14":"1", + "15":"1", + "16":"1", + "17":"1", + "18":"1", + "19":"1", + "20":"1", + "21":"1", + "22":"1", + "23":"1", + "24":"1", + "25":"1", + "26":"1", + "27":"1", + "28":"1", + "29":"1", + "30":"1", + "31":"1", + "32":"1", + "33":"1", + "34":"1", + "35":"1", + "36":"1", + "37":"1", + "38":"1", + "39":"1", + "40":"1", + "41":"1", + "42":"1", + "43":"1", + "44":"1", + "45":"1", "46":"5", - "47":"0", - "48":"0", - "49":"0", - "50":"0", - "51":"0", - "52":"0", - "53":"0", - "54":"0", - "55":"0", - "56":"0", - "57":"0", - "58":"0", - "59":"0", - "60":"0", - "61":"0", - "62":"0", - "63":"0" + "47":"1", + "48":"6", + "49":"1", + "50":"1", + "51":"1", + "52":"1", + "53":"1", + "54":"1", + "55":"1", + "56":"1", + "57":"1", + "58":"1", + "59":"1", + "60":"1", + "61":"1", + "62":"1", + "63":"1" } }, "SCHEDULER": { "scheduler.0" : { "type":"DWRR", - "weight": "20" + "weight": "14" + }, + "scheduler.1" : { + "type":"DWRR", + "weight": "15" } }, "PORT_QOS_MAP": { @@ -137,11 +141,11 @@ }, "QUEUE": { "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3" : { - "scheduler" : "[SCHEDULER|scheduler.0]", + "scheduler" : "[SCHEDULER|scheduler.1]", "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|4" : { - "scheduler" : "[SCHEDULER|scheduler.0]", + "scheduler" : "[SCHEDULER|scheduler.1]", "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0" : { @@ -150,8 +154,14 @@ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|1" : { "scheduler" : "[SCHEDULER|scheduler.0]" }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|2" : { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|5" : { "scheduler" : "[SCHEDULER|scheduler.0]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|6" : { + "scheduler" : "[SCHEDULER|scheduler.0]" } } } diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/buffers_defaults_t0.j2 index b3b8e6b13c45..a5951e156b26 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/buffers_defaults_t0.j2 +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/buffers_defaults_t0.j2 @@ -18,13 +18,13 @@ {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "32799936", + "size": "33329088", "type": "ingress", "mode": "dynamic", - "xoff": "8356608" + "xoff": "7827456" }, "egress_lossy_pool": { - "size": "26240448", + "size": "26663272", "type": "egress", "mode": "dynamic" }, diff --git a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/qos.json b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/qos.json index 051003ffb565..681aa583d845 100644 --- a/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/qos.json +++ b/device/arista/x86_64-arista_7260cx3_64/Arista-7260CX3-D108C8/qos.json @@ -37,76 +37,80 @@ }, "DSCP_TO_TC_MAP": { "AZURE": { - "0":"0", - "1":"0", - "2":"0", + "0":"1", + "1":"1", + "2":"1", "3":"3", "4":"4", - "5":"0", - "6":"0", - "7":"0", - "8":"1", - "9":"0", - "10":"0", - "11":"0", - "12":"0", - "13":"0", - "14":"0", - "15":"0", - "16":"0", - "17":"0", - "18":"0", - "19":"0", - "20":"0", - "21":"0", - "22":"0", - "23":"0", - "24":"0", - "25":"0", - "26":"0", - "27":"0", - "28":"0", - "29":"0", - "30":"0", - "31":"0", - "32":"0", - "33":"0", - "34":"0", - "35":"0", - "36":"0", - "37":"0", - "38":"0", - "39":"0", - "40":"0", - "41":"0", - "42":"0", - "43":"0", - "44":"0", - "45":"0", + "5":"2", + "6":"1", + "7":"1", + "8":"0", + "9":"1", + "10":"1", + "11":"1", + "12":"1", + "13":"1", + "14":"1", + "15":"1", + "16":"1", + "17":"1", + "18":"1", + "19":"1", + "20":"1", + "21":"1", + "22":"1", + "23":"1", + "24":"1", + "25":"1", + "26":"1", + "27":"1", + "28":"1", + "29":"1", + "30":"1", + "31":"1", + "32":"1", + "33":"1", + "34":"1", + "35":"1", + "36":"1", + "37":"1", + "38":"1", + "39":"1", + "40":"1", + "41":"1", + "42":"1", + "43":"1", + "44":"1", + "45":"1", "46":"5", - "47":"0", - "48":"0", - "49":"0", - "50":"0", - "51":"0", - "52":"0", - "53":"0", - "54":"0", - "55":"0", - "56":"0", - "57":"0", - "58":"0", - "59":"0", - "60":"0", - "61":"0", - "62":"0", - "63":"0" + "47":"1", + "48":"6", + "49":"1", + "50":"1", + "51":"1", + "52":"1", + "53":"1", + "54":"1", + "55":"1", + "56":"1", + "57":"1", + "58":"1", + "59":"1", + "60":"1", + "61":"1", + "62":"1", + "63":"1" } }, "SCHEDULER": { "scheduler.0" : { "type":"DWRR", - "weight": "20" + "weight": "14" + }, + "scheduler.1" : { + "type":"DWRR", + "weight": "15" } }, "PORT_QOS_MAP": { @@ -137,11 +141,11 @@ }, "QUEUE": { "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet26,Ethernet28,Ethernet30,Ethernet32,Ethernet34,Ethernet36,Ethernet38,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126,Ethernet128,Ethernet130,Ethernet132,Ethernet134,Ethernet136,Ethernet138,Ethernet140,Ethernet142,Ethernet144,Ethernet146,Ethernet148,Ethernet150,Ethernet152,Ethernet154,Ethernet156,Ethernet158,Ethernet160,Ethernet162,Ethernet164,Ethernet166,Ethernet168,Ethernet170,Ethernet172,Ethernet174,Ethernet176,Ethernet178,Ethernet180,Ethernet182,Ethernet184,Ethernet186,Ethernet188,Ethernet190,Ethernet192,Ethernet194,Ethernet196,Ethernet198,Ethernet200,Ethernet202,Ethernet204,Ethernet206,Ethernet208,Ethernet210,Ethernet212,Ethernet214,Ethernet216,Ethernet218,Ethernet220,Ethernet222,Ethernet224,Ethernet226,Ethernet228,Ethernet230,Ethernet232,Ethernet234,Ethernet236,Ethernet238,Ethernet240,Ethernet242,Ethernet244,Ethernet246,Ethernet248,Ethernet250,Ethernet252,Ethernet254|3" : { - "scheduler" : "[SCHEDULER|scheduler.0]", + "scheduler" : "[SCHEDULER|scheduler.1]", "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet26,Ethernet28,Ethernet30,Ethernet32,Ethernet34,Ethernet36,Ethernet38,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126,Ethernet128,Ethernet130,Ethernet132,Ethernet134,Ethernet136,Ethernet138,Ethernet140,Ethernet142,Ethernet144,Ethernet146,Ethernet148,Ethernet150,Ethernet152,Ethernet154,Ethernet156,Ethernet158,Ethernet160,Ethernet162,Ethernet164,Ethernet166,Ethernet168,Ethernet170,Ethernet172,Ethernet174,Ethernet176,Ethernet178,Ethernet180,Ethernet182,Ethernet184,Ethernet186,Ethernet188,Ethernet190,Ethernet192,Ethernet194,Ethernet196,Ethernet198,Ethernet200,Ethernet202,Ethernet204,Ethernet206,Ethernet208,Ethernet210,Ethernet212,Ethernet214,Ethernet216,Ethernet218,Ethernet220,Ethernet222,Ethernet224,Ethernet226,Ethernet228,Ethernet230,Ethernet232,Ethernet234,Ethernet236,Ethernet238,Ethernet240,Ethernet242,Ethernet244,Ethernet246,Ethernet248,Ethernet250,Ethernet252,Ethernet254|4" : { - "scheduler" : "[SCHEDULER|scheduler.0]", + "scheduler" : "[SCHEDULER|scheduler.1]", "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet26,Ethernet28,Ethernet30,Ethernet32,Ethernet34,Ethernet36,Ethernet38,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126,Ethernet128,Ethernet130,Ethernet132,Ethernet134,Ethernet136,Ethernet138,Ethernet140,Ethernet142,Ethernet144,Ethernet146,Ethernet148,Ethernet150,Ethernet152,Ethernet154,Ethernet156,Ethernet158,Ethernet160,Ethernet162,Ethernet164,Ethernet166,Ethernet168,Ethernet170,Ethernet172,Ethernet174,Ethernet176,Ethernet178,Ethernet180,Ethernet182,Ethernet184,Ethernet186,Ethernet188,Ethernet190,Ethernet192,Ethernet194,Ethernet196,Ethernet198,Ethernet200,Ethernet202,Ethernet204,Ethernet206,Ethernet208,Ethernet210,Ethernet212,Ethernet214,Ethernet216,Ethernet218,Ethernet220,Ethernet222,Ethernet224,Ethernet226,Ethernet228,Ethernet230,Ethernet232,Ethernet234,Ethernet236,Ethernet238,Ethernet240,Ethernet242,Ethernet244,Ethernet246,Ethernet248,Ethernet250,Ethernet252,Ethernet254|0" : { @@ -150,8 +154,14 @@ "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet26,Ethernet28,Ethernet30,Ethernet32,Ethernet34,Ethernet36,Ethernet38,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126,Ethernet128,Ethernet130,Ethernet132,Ethernet134,Ethernet136,Ethernet138,Ethernet140,Ethernet142,Ethernet144,Ethernet146,Ethernet148,Ethernet150,Ethernet152,Ethernet154,Ethernet156,Ethernet158,Ethernet160,Ethernet162,Ethernet164,Ethernet166,Ethernet168,Ethernet170,Ethernet172,Ethernet174,Ethernet176,Ethernet178,Ethernet180,Ethernet182,Ethernet184,Ethernet186,Ethernet188,Ethernet190,Ethernet192,Ethernet194,Ethernet196,Ethernet198,Ethernet200,Ethernet202,Ethernet204,Ethernet206,Ethernet208,Ethernet210,Ethernet212,Ethernet214,Ethernet216,Ethernet218,Ethernet220,Ethernet222,Ethernet224,Ethernet226,Ethernet228,Ethernet230,Ethernet232,Ethernet234,Ethernet236,Ethernet238,Ethernet240,Ethernet242,Ethernet244,Ethernet246,Ethernet248,Ethernet250,Ethernet252,Ethernet254|1" : { "scheduler" : "[SCHEDULER|scheduler.0]" }, + "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet26,Ethernet28,Ethernet30,Ethernet32,Ethernet34,Ethernet36,Ethernet38,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126,Ethernet128,Ethernet130,Ethernet132,Ethernet134,Ethernet136,Ethernet138,Ethernet140,Ethernet142,Ethernet144,Ethernet146,Ethernet148,Ethernet150,Ethernet152,Ethernet154,Ethernet156,Ethernet158,Ethernet160,Ethernet162,Ethernet164,Ethernet166,Ethernet168,Ethernet170,Ethernet172,Ethernet174,Ethernet176,Ethernet178,Ethernet180,Ethernet182,Ethernet184,Ethernet186,Ethernet188,Ethernet190,Ethernet192,Ethernet194,Ethernet196,Ethernet198,Ethernet200,Ethernet202,Ethernet204,Ethernet206,Ethernet208,Ethernet210,Ethernet212,Ethernet214,Ethernet216,Ethernet218,Ethernet220,Ethernet222,Ethernet224,Ethernet226,Ethernet228,Ethernet230,Ethernet232,Ethernet234,Ethernet236,Ethernet238,Ethernet240,Ethernet242,Ethernet244,Ethernet246,Ethernet248,Ethernet250,Ethernet252,Ethernet254|2" : { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet26,Ethernet28,Ethernet30,Ethernet32,Ethernet34,Ethernet36,Ethernet38,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126,Ethernet128,Ethernet130,Ethernet132,Ethernet134,Ethernet136,Ethernet138,Ethernet140,Ethernet142,Ethernet144,Ethernet146,Ethernet148,Ethernet150,Ethernet152,Ethernet154,Ethernet156,Ethernet158,Ethernet160,Ethernet162,Ethernet164,Ethernet166,Ethernet168,Ethernet170,Ethernet172,Ethernet174,Ethernet176,Ethernet178,Ethernet180,Ethernet182,Ethernet184,Ethernet186,Ethernet188,Ethernet190,Ethernet192,Ethernet194,Ethernet196,Ethernet198,Ethernet200,Ethernet202,Ethernet204,Ethernet206,Ethernet208,Ethernet210,Ethernet212,Ethernet214,Ethernet216,Ethernet218,Ethernet220,Ethernet222,Ethernet224,Ethernet226,Ethernet228,Ethernet230,Ethernet232,Ethernet234,Ethernet236,Ethernet238,Ethernet240,Ethernet242,Ethernet244,Ethernet246,Ethernet248,Ethernet250,Ethernet252,Ethernet254|5" : { "scheduler" : "[SCHEDULER|scheduler.0]" + }, + "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet26,Ethernet28,Ethernet30,Ethernet32,Ethernet34,Ethernet36,Ethernet38,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet106,Ethernet108,Ethernet110,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126,Ethernet128,Ethernet130,Ethernet132,Ethernet134,Ethernet136,Ethernet138,Ethernet140,Ethernet142,Ethernet144,Ethernet146,Ethernet148,Ethernet150,Ethernet152,Ethernet154,Ethernet156,Ethernet158,Ethernet160,Ethernet162,Ethernet164,Ethernet166,Ethernet168,Ethernet170,Ethernet172,Ethernet174,Ethernet176,Ethernet178,Ethernet180,Ethernet182,Ethernet184,Ethernet186,Ethernet188,Ethernet190,Ethernet192,Ethernet194,Ethernet196,Ethernet198,Ethernet200,Ethernet202,Ethernet204,Ethernet206,Ethernet208,Ethernet210,Ethernet212,Ethernet214,Ethernet216,Ethernet218,Ethernet220,Ethernet222,Ethernet224,Ethernet226,Ethernet228,Ethernet230,Ethernet232,Ethernet234,Ethernet236,Ethernet238,Ethernet240,Ethernet242,Ethernet244,Ethernet246,Ethernet248,Ethernet250,Ethernet252,Ethernet254|6" : { + "scheduler" : "[SCHEDULER|scheduler.0]" } } } diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers.json.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers.json.j2 index db37b6cd36a6..e080492a40a7 100644 --- a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers.json.j2 +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers.json.j2 @@ -113,10 +113,10 @@ "{{ port_names }}|3-4": { "profile" : "[BUFFER_PROFILE|ingress_lossless_profile]" }, - "{{ port_names }}|0-1": { + "{{ port_names }}|0-2": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "{{ port_names }}|5": { + "{{ port_names }}|5-6": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" } }, @@ -124,10 +124,10 @@ "{{ port_names }}|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "{{ port_names }}|0-1": { + "{{ port_names }}|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "{{ port_names }}|5": { + "{{ port_names }}|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" } } diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/qos.json b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/qos.json index 0eb02957299f..524d53b4f4dd 100644 --- a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/qos.json +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/qos.json @@ -3,101 +3,114 @@ "AZURE": { "0": "0", "1": "1", + "2": "2", "3": "3", "4": "4", - "5": "5" + "5": "5", + "6": "6", + "7": "7" } }, "MAP_PFC_PRIORITY_TO_QUEUE": { "AZURE": { "0": "0", "1": "1", + "2": "2", "3": "3", "4": "4", - "5": "5" + "5": "5", + "6": "6", + "7": "7" } }, "TC_TO_QUEUE_MAP": { "AZURE": { "0": "0", "1": "1", + "2": "2", "3": "3", "4": "4", - "5": "5" + "5": "5", + "6": "6", + "7": "7" } }, "DSCP_TO_TC_MAP": { "AZURE": { - "0":"0", - "1":"0", - "2":"0", + "0":"1", + "1":"1", + "2":"1", "3":"3", "4":"4", - "5":"0", - "6":"0", - "7":"0", - "8":"1", - "9":"0", - "10":"0", - "11":"0", - "12":"0", - "13":"0", - "14":"0", - "15":"0", - "16":"0", - "17":"0", - "18":"0", - "19":"0", - "20":"0", - "21":"0", - "22":"0", - "23":"0", - "24":"0", - "25":"0", - "26":"0", - "27":"0", - "28":"0", - "29":"0", - "30":"0", - "31":"0", - "32":"0", - "33":"0", - "34":"0", - "35":"0", - "36":"0", - "37":"0", - "38":"0", - "39":"0", - "40":"0", - "41":"0", - "42":"0", - "43":"0", - "44":"0", - "45":"0", + "5":"2", + "6":"1", + "7":"1", + "8":"0", + "9":"1", + "10":"1", + "11":"1", + "12":"1", + "13":"1", + "14":"1", + "15":"1", + "16":"1", + "17":"1", + "18":"1", + "19":"1", + "20":"1", + "21":"1", + "22":"1", + "23":"1", + "24":"1", + "25":"1", + "26":"1", + "27":"1", + "28":"1", + "29":"1", + "30":"1", + "31":"1", + "32":"1", + "33":"1", + "34":"1", + "35":"1", + "36":"1", + "37":"1", + "38":"1", + "39":"1", + "40":"1", + "41":"1", + "42":"1", + "43":"1", + "44":"1", + "45":"1", "46":"5", - "47":"0", - "48":"0", - "49":"0", - "50":"0", - "51":"0", - "52":"0", - "53":"0", - "54":"0", - "55":"0", - "56":"0", - "57":"0", - "58":"0", - "59":"0", - "60":"0", - "61":"0", - "62":"0", - "63":"0" + "47":"1", + "48":"6", + "49":"1", + "50":"1", + "51":"1", + "52":"1", + "53":"1", + "54":"1", + "55":"1", + "56":"1", + "57":"1", + "58":"1", + "59":"1", + "60":"1", + "61":"1", + "62":"1", + "63":"1" } }, "SCHEDULER": { "scheduler.0" : { "type":"DWRR", - "weight": "20" + "weight": "14" + }, + "scheduler.1" : { + "type":"DWRR", + "weight": "15" } }, "PORT_QOS_MAP": { @@ -128,11 +141,11 @@ }, "QUEUE": { "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3" : { - "scheduler" : "[SCHEDULER|scheduler.0]", + "scheduler" : "[SCHEDULER|scheduler.1]", "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|4" : { - "scheduler" : "[SCHEDULER|scheduler.0]", + "scheduler" : "[SCHEDULER|scheduler.1]", "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0" : { @@ -141,8 +154,14 @@ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|1" : { "scheduler" : "[SCHEDULER|scheduler.0]" }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|2" : { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|5" : { "scheduler" : "[SCHEDULER|scheduler.0]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|6" : { + "scheduler" : "[SCHEDULER|scheduler.0]" } } } diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/buffers_defaults_t0.j2 b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/buffers_defaults_t0.j2 index e337f676b650..f949a31eab7b 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/buffers_defaults_t0.j2 +++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/buffers_defaults_t0.j2 @@ -11,13 +11,13 @@ {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "11213696", + "size": "10875072", "type": "ingress", "mode": "dynamic", - "xoff": "3855488" + "xoff": "4194112" }, "egress_lossy_pool": { - "size": "9532224", + "size": "9243812", "type": "egress", "mode": "dynamic" }, diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/buffers_defaults_t1.j2 b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/buffers_defaults_t1.j2 index c7c98bfe4299..e56bbb65845f 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/buffers_defaults_t1.j2 +++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/buffers_defaults_t1.j2 @@ -11,13 +11,13 @@ {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "10443264", + "size": "10875072", "type": "ingress", "mode": "dynamic", - "xoff": "4625920" + "xoff": "4194112" }, "egress_lossy_pool": { - "size": "8877440", + "size": "9243812", "type": "egress", "mode": "dynamic" }, diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json index aacc94e559ff..f1458e06a70d 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json +++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json @@ -37,76 +37,80 @@ }, "DSCP_TO_TC_MAP": { "AZURE": { - "0":"0", - "1":"0", - "2":"0", + "0":"1", + "1":"1", + "2":"1", "3":"3", "4":"4", - "5":"0", - "6":"0", - "7":"0", - "8":"1", - "9":"0", - "10":"0", - "11":"0", - "12":"0", - "13":"0", - "14":"0", - "15":"0", - "16":"0", - "17":"0", - "18":"0", - "19":"0", - "20":"0", - "21":"0", - "22":"0", - "23":"0", - "24":"0", - "25":"0", - "26":"0", - "27":"0", - "28":"0", - "29":"0", - "30":"0", - "31":"0", - "32":"0", - "33":"0", - "34":"0", - "35":"0", - "36":"0", - "37":"0", - "38":"0", - "39":"0", - "40":"0", - "41":"0", - "42":"0", - "43":"0", - "44":"0", - "45":"0", + "5":"2", + "6":"1", + "7":"1", + "8":"0", + "9":"1", + "10":"1", + "11":"1", + "12":"1", + "13":"1", + "14":"1", + "15":"1", + "16":"1", + "17":"1", + "18":"1", + "19":"1", + "20":"1", + "21":"1", + "22":"1", + "23":"1", + "24":"1", + "25":"1", + "26":"1", + "27":"1", + "28":"1", + "29":"1", + "30":"1", + "31":"1", + "32":"1", + "33":"1", + "34":"1", + "35":"1", + "36":"1", + "37":"1", + "38":"1", + "39":"1", + "40":"1", + "41":"1", + "42":"1", + "43":"1", + "44":"1", + "45":"1", "46":"5", - "47":"0", - "48":"0", - "49":"0", - "50":"0", - "51":"0", - "52":"0", - "53":"0", - "54":"0", - "55":"0", - "56":"0", - "57":"0", - "58":"0", - "59":"0", - "60":"0", - "61":"0", - "62":"0", - "63":"0" + "47":"1", + "48":"6", + "49":"1", + "50":"1", + "51":"1", + "52":"1", + "53":"1", + "54":"1", + "55":"1", + "56":"1", + "57":"1", + "58":"1", + "59":"1", + "60":"1", + "61":"1", + "62":"1", + "63":"1" } }, "SCHEDULER": { "scheduler.0" : { "type":"DWRR", - "weight": "20" + "weight": "14" + }, + "scheduler.1" : { + "type":"DWRR", + "weight": "15" } }, "PORT_QOS_MAP": { @@ -137,11 +141,11 @@ }, "QUEUE": { "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63|3" : { - "scheduler" : "[SCHEDULER|scheduler.0]", + "scheduler" : "[SCHEDULER|scheduler.1]", "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63|4" : { - "scheduler" : "[SCHEDULER|scheduler.0]", + "scheduler" : "[SCHEDULER|scheduler.1]", "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63|0" : { @@ -150,8 +154,14 @@ "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63|1" : { "scheduler" : "[SCHEDULER|scheduler.0]" }, + "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63|2" : { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63|5" : { "scheduler" : "[SCHEDULER|scheduler.0]" + }, + "Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet49,Ethernet50,Ethernet51,Ethernet52,Ethernet53,Ethernet54,Ethernet55,Ethernet56,Ethernet57,Ethernet58,Ethernet59,Ethernet60,Ethernet61,Ethernet62,Ethernet63|6" : { + "scheduler" : "[SCHEDULER|scheduler.0]" } } } diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/buffers_defaults_t1.j2 b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/buffers_defaults_t1.j2 index 5c654ab9e8a1..e127362c091a 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/buffers_defaults_t1.j2 +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/buffers_defaults_t1.j2 @@ -11,13 +11,13 @@ {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "10443264", + "size": "10875072", "type": "ingress", "mode": "dynamic", - "xoff": "4625920" + "xoff": "4194112" }, "egress_lossy_pool": { - "size": "8877440", + "size": "9243812", "type": "egress", "mode": "dynamic" }, diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/qos.json b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/qos.json index deb9f40fc0f4..524d53b4f4dd 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/qos.json +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C32/qos.json @@ -37,76 +37,80 @@ }, "DSCP_TO_TC_MAP": { "AZURE": { - "0":"0", - "1":"0", - "2":"0", + "0":"1", + "1":"1", + "2":"1", "3":"3", "4":"4", - "5":"0", - "6":"0", - "7":"0", - "8":"1", - "9":"0", - "10":"0", - "11":"0", - "12":"0", - "13":"0", - "14":"0", - "15":"0", - "16":"0", - "17":"0", - "18":"0", - "19":"0", - "20":"0", - "21":"0", - "22":"0", - "23":"0", - "24":"0", - "25":"0", - "26":"0", - "27":"0", - "28":"0", - "29":"0", - "30":"0", - "31":"0", - "32":"0", - "33":"0", - "34":"0", - "35":"0", - "36":"0", - "37":"0", - "38":"0", - "39":"0", - "40":"0", - "41":"0", - "42":"0", - "43":"0", - "44":"0", - "45":"0", + "5":"2", + "6":"1", + "7":"1", + "8":"0", + "9":"1", + "10":"1", + "11":"1", + "12":"1", + "13":"1", + "14":"1", + "15":"1", + "16":"1", + "17":"1", + "18":"1", + "19":"1", + "20":"1", + "21":"1", + "22":"1", + "23":"1", + "24":"1", + "25":"1", + "26":"1", + "27":"1", + "28":"1", + "29":"1", + "30":"1", + "31":"1", + "32":"1", + "33":"1", + "34":"1", + "35":"1", + "36":"1", + "37":"1", + "38":"1", + "39":"1", + "40":"1", + "41":"1", + "42":"1", + "43":"1", + "44":"1", + "45":"1", "46":"5", - "47":"0", - "48":"0", - "49":"0", - "50":"0", - "51":"0", - "52":"0", - "53":"0", - "54":"0", - "55":"0", - "56":"0", - "57":"0", - "58":"0", - "59":"0", - "60":"0", - "61":"0", - "62":"0", - "63":"0" + "47":"1", + "48":"6", + "49":"1", + "50":"1", + "51":"1", + "52":"1", + "53":"1", + "54":"1", + "55":"1", + "56":"1", + "57":"1", + "58":"1", + "59":"1", + "60":"1", + "61":"1", + "62":"1", + "63":"1" } }, "SCHEDULER": { "scheduler.0" : { "type":"DWRR", - "weight": "20" + "weight": "14" + }, + "scheduler.1" : { + "type":"DWRR", + "weight": "15" } }, "PORT_QOS_MAP": { @@ -137,11 +141,11 @@ }, "QUEUE": { "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3" : { - "scheduler" : "[SCHEDULER|scheduler.0]", + "scheduler" : "[SCHEDULER|scheduler.1]", "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|4" : { - "scheduler" : "[SCHEDULER|scheduler.0]", + "scheduler" : "[SCHEDULER|scheduler.1]", "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0" : { @@ -150,8 +154,14 @@ "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|1" : { "scheduler" : "[SCHEDULER|scheduler.0]" }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|2" : { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|5" : { "scheduler" : "[SCHEDULER|scheduler.0]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|6" : { + "scheduler" : "[SCHEDULER|scheduler.0]" } } } diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/buffers_defaults_t0.j2 b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/buffers_defaults_t0.j2 index 4bd35b354c8a..f200b85b2027 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/buffers_defaults_t0.j2 +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/buffers_defaults_t0.j2 @@ -25,13 +25,13 @@ {%- macro generate_buffer_pool_and_profiles() %} "BUFFER_POOL": { "ingress_lossless_pool": { - "size": "11213696", + "size": "10875072", "type": "ingress", "mode": "dynamic", - "xoff": "3855488" + "xoff": "4194112" }, "egress_lossy_pool": { - "size": "9532224", + "size": "9243812", "type": "egress", "mode": "dynamic" }, diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/qos.json b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/qos.json index aa4b6606af28..355f33385bfb 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/qos.json +++ b/device/dell/x86_64-dell_z9100_c2538-r0/Force10-Z9100-C8D48/qos.json @@ -37,76 +37,80 @@ }, "DSCP_TO_TC_MAP": { "AZURE": { - "0":"0", - "1":"0", - "2":"0", + "0":"1", + "1":"1", + "2":"1", "3":"3", "4":"4", - "5":"0", - "6":"0", - "7":"0", - "8":"1", - "9":"0", - "10":"0", - "11":"0", - "12":"0", - "13":"0", - "14":"0", - "15":"0", - "16":"0", - "17":"0", - "18":"0", - "19":"0", - "20":"0", - "21":"0", - "22":"0", - "23":"0", - "24":"0", - "25":"0", - "26":"0", - "27":"0", - "28":"0", - "29":"0", - "30":"0", - "31":"0", - "32":"0", - "33":"0", - "34":"0", - "35":"0", - "36":"0", - "37":"0", - "38":"0", - "39":"0", - "40":"0", - "41":"0", - "42":"0", - "43":"0", - "44":"0", - "45":"0", + "5":"2", + "6":"1", + "7":"1", + "8":"0", + "9":"1", + "10":"1", + "11":"1", + "12":"1", + "13":"1", + "14":"1", + "15":"1", + "16":"1", + "17":"1", + "18":"1", + "19":"1", + "20":"1", + "21":"1", + "22":"1", + "23":"1", + "24":"1", + "25":"1", + "26":"1", + "27":"1", + "28":"1", + "29":"1", + "30":"1", + "31":"1", + "32":"1", + "33":"1", + "34":"1", + "35":"1", + "36":"1", + "37":"1", + "38":"1", + "39":"1", + "40":"1", + "41":"1", + "42":"1", + "43":"1", + "44":"1", + "45":"1", "46":"5", - "47":"0", - "48":"0", - "49":"0", - "50":"0", - "51":"0", - "52":"0", - "53":"0", - "54":"0", - "55":"0", - "56":"0", - "57":"0", - "58":"0", - "59":"0", - "60":"0", - "61":"0", - "62":"0", - "63":"0" + "47":"1", + "48":"6", + "49":"1", + "50":"1", + "51":"1", + "52":"1", + "53":"1", + "54":"1", + "55":"1", + "56":"1", + "57":"1", + "58":"1", + "59":"1", + "60":"1", + "61":"1", + "62":"1", + "63":"1" } }, "SCHEDULER": { "scheduler.0" : { "type":"DWRR", - "weight": "20" + "weight": "14" + }, + "scheduler.1" : { + "type":"DWRR", + "weight": "15" } }, "PORT_QOS_MAP": { @@ -137,11 +141,11 @@ }, "QUEUE": { "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet122,Ethernet124,Ethernet126|3": { - "scheduler" : "[SCHEDULER|scheduler.0]", + "scheduler" : "[SCHEDULER|scheduler.1]", "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet122,Ethernet124,Ethernet126|4": { - "scheduler" : "[SCHEDULER|scheduler.0]", + "scheduler" : "[SCHEDULER|scheduler.1]", "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" }, "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet122,Ethernet124,Ethernet126|0": { @@ -150,8 +154,14 @@ "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet122,Ethernet124,Ethernet126|1": { "scheduler" : "[SCHEDULER|scheduler.0]" }, + "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet122,Ethernet124,Ethernet126|2": { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet122,Ethernet124,Ethernet126|5": { "scheduler" : "[SCHEDULER|scheduler.0]" + }, + "Ethernet0,Ethernet2,Ethernet4,Ethernet6,Ethernet8,Ethernet10,Ethernet12,Ethernet14,Ethernet16,Ethernet18,Ethernet20,Ethernet22,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet42,Ethernet44,Ethernet46,Ethernet48,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet58,Ethernet60,Ethernet62,Ethernet64,Ethernet66,Ethernet68,Ethernet70,Ethernet72,Ethernet74,Ethernet76,Ethernet78,Ethernet80,Ethernet82,Ethernet84,Ethernet86,Ethernet88,Ethernet90,Ethernet92,Ethernet94,Ethernet96,Ethernet98,Ethernet100,Ethernet102,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet122,Ethernet124,Ethernet126|6": { + "scheduler" : "[SCHEDULER|scheduler.0]" } } } diff --git a/files/build_templates/buffers_config.j2 b/files/build_templates/buffers_config.j2 index f4d2fd3a6d2d..686d2824d4b4 100644 --- a/files/build_templates/buffers_config.j2 +++ b/files/build_templates/buffers_config.j2 @@ -119,10 +119,10 @@ def {{ defs.generate_pg_profils }}, {% else %} "BUFFER_PG": { - "{{ port_names_all }}|0-1": { + "{{ port_names_all }}|0-2": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" }, - "{{ port_names_all }}|5": { + "{{ port_names_all }}|5-6": { "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" } }, @@ -135,10 +135,10 @@ def "{{ port_names_all }}|3-4": { "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" }, - "{{ port_names_all }}|0-1": { + "{{ port_names_all }}|0-2": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" }, - "{{ port_names_all }}|5": { + "{{ port_names_all }}|5-6": { "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" } } From 9fad56fc82cd753535f2e0b247bf64e8446ef3eb Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 2 Feb 2019 01:27:31 +0000 Subject: [PATCH 199/219] [submodule]: update sonic-quagga * 9d651b9 2019-01-30 | Add debug messages for bgp route advertisement (#30) (HEAD, origin/debian/0.99.24.1, origin/HEAD) [pavel-shirshov] * 4b7825c 2018-10-12 | [security] Fix double free of unknown attribute (Quagga-2018-1114) [zhenggen-xu] * 3ede63f 2018-10-10 | [security] debug print of received NOTIFY data can over-read msg array (Quagga-2018-1550) [zhenggen-xu] * 3c64a8c 2018-10-10 | [security] Fix infinite loop on certain invalid OPEN messages (Quagga-2018-1975) [zhenggen-xu] * 3348a33 2018-09-12 | CLI for BGP-GR restart-timer (#24) [Rodny Molina] * a0630b7 2018-08-12 | Add support of custom ip dscp value for bgp sessions (#22) [pavel-shirshov] Signed-off-by: Guohan Lu --- src/sonic-quagga | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-quagga b/src/sonic-quagga index cde29666c363..9d651b93d41f 160000 --- a/src/sonic-quagga +++ b/src/sonic-quagga @@ -1 +1 @@ -Subproject commit cde29666c363e34ea7f230bb827644457acedcbc +Subproject commit 9d651b93d41f94f8de135c2754082f91505c30d7 From e117802c51557320b39d37a25b5c212f20bb44b0 Mon Sep 17 00:00:00 2001 From: Praveen Chaudhary Date: Wed, 6 Feb 2019 17:33:56 -0800 Subject: [PATCH 200/219] [ntp]: Do not disable reader for error ENOBUFS (#2529) Need to build NTP 4.2.6 locally due to a Bug in NTP 4.2.6. Changes: 1.) Remove 'apt-get ntp' step from build_debian.sh. 2.) Add NTP package as part of base image in slave.mk. 3.) NTP Makefile for Sonic Build System rules/ntp.mk. 4.) NTP Source Makefile src/ntp/Makefile. 5.) Patch to fix the issure src/ntp/patch. Signed-off-by: Praveen Chaudhary * [src/ntp/Makefile]: DSC file URL points to sonic storage. Signed-off-by: Praveen Chaudhary * [src/ntp/Makefile]: Changes to build with sonic blob. --- build_debian.sh | 1 - .../build_templates/sonic_debian_extension.j2 | 4 +++ rules/ntp.mk | 13 +++++++ slave.mk | 1 + sonic-slave/Dockerfile | 7 +++- src/ntp/Makefile | 35 +++++++++++++++++++ ...-donot-disable-reader-kernel-enobufs.patch | 31 ++++++++++++++++ src/ntp/patch/series | 1 + 8 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 rules/ntp.mk create mode 100644 src/ntp/Makefile create mode 100644 src/ntp/patch/0001-donot-disable-reader-kernel-enobufs.patch create mode 100644 src/ntp/patch/series diff --git a/build_debian.sh b/build_debian.sh index 297fc1da19d3..ab8bb81824a0 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -199,7 +199,6 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in vim \ tcpdump \ dbus \ - ntp \ ntpstat \ openssh-server \ python \ diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index c15cd4f9e805..84dbaca39854 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -102,6 +102,10 @@ sudo dpkg --root=$FILESYSTEM_ROOT -i target/debs/bash_*.deb || \ # in bash.bashrc, so we copy a version of the file with it enabled here. sudo cp -f $IMAGE_CONFIGS/bash/bash.bashrc $FILESYSTEM_ROOT/etc/ +# Install NTP version 4.2.6 this way until required fix is available for Jessie. +sudo dpkg --root=$FILESYSTEM_ROOT -i target/debs/ntp_4.2.6*.deb || \ + sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f + # Install SONiC Device Data (and its dependencies via 'apt-get -y install -f') sudo dpkg --root=$FILESYSTEM_ROOT -i target/debs/sonic-device-data_*.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f diff --git a/rules/ntp.mk b/rules/ntp.mk new file mode 100644 index 000000000000..20d35da126a2 --- /dev/null +++ b/rules/ntp.mk @@ -0,0 +1,13 @@ +# ntp_4.2.6.p5+dfsg-7+deb8u2.deb + +NTP_VERSION_MAJOR = 4.2.6 +NTP_VERSION_SUFFIX = .p5+dfsg +NTP_VERSION_SUFFIX_NUM = 7+deb8u2 +NTP_VERSION_FULL = $(NTP_VERSION_MAJOR)$(NTP_VERSION_SUFFIX)-$(NTP_VERSION_SUFFIX_NUM) +NTP_VERSION = $(NTP_VERSION_MAJOR)$(NTP_VERSION_SUFFIX) + +export NTP_VERSION NTP_VERSION_FULL + +NTP = ntp_$(NTP_VERSION_FULL)_amd64.deb +$(NTP)_SRC_PATH = $(SRC_PATH)/ntp +SONIC_MAKE_DEBS += $(NTP) diff --git a/slave.mk b/slave.mk index 6490dcb5dbda..803b87aaffdb 100644 --- a/slave.mk +++ b/slave.mk @@ -430,6 +430,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(SONIC_UTILS) \ $(BASH) \ $(LIBWRAP) \ + $(NTP) \ $(LIBPAM_TACPLUS) \ $(LIBNSS_TACPLUS)) \ $$(addprefix $(TARGET_PATH)/,$$($$*_DOCKERS)) \ diff --git a/sonic-slave/Dockerfile b/sonic-slave/Dockerfile index dd526a898e8d..803fabcfb105 100644 --- a/sonic-slave/Dockerfile +++ b/sonic-slave/Dockerfile @@ -215,7 +215,12 @@ RUN apt-get update && apt-get install -y \ texlive-latex-extra \ texlive-latex-recommended \ # For bash - texi2html + texi2html \ +# For ntp + autogen \ + libopts25-dev \ + pps-tools \ + dh-apparmor # For linux build RUN apt-get -y build-dep linux diff --git a/src/ntp/Makefile b/src/ntp/Makefile new file mode 100644 index 000000000000..ad073289993c --- /dev/null +++ b/src/ntp/Makefile @@ -0,0 +1,35 @@ +SHELL = /bin/bash +.ONESHELL: +.SHELLFLAGS += -e + +MAIN_TARGET = ntp_$(NTP_VERSION_FULL)_amd64.deb + +DSC_FILE = ntp_$(NTP_VERSION_FULL).dsc +ORIG_FILE = ntp_$(NTP_VERSION).orig.tar.gz +DEBIAN_FILE = ntp_$(NTP_VERSION_FULL).debian.tar.xz + +DSC_FILE_URL = "https://sonicstorage.blob.core.windows.net/packages/debian/$(DSC_FILE)?sv=2015-04-05&sr=b&sig=HxuXOJsIfkj3lF2TlCShil7lFFf90Zh8oBNTfaka%2FNc%3D&se=2155-12-30T06%3A25%3A21Z&sp=r" +ORIG_FILE_URL = "https://sonicstorage.blob.core.windows.net/packages/debian/$(ORIG_FILE)?sv=2015-04-05&sr=b&sig=bZcv%2B25Ke%2FBcWWd8WdBuK9sMDkcF45Yd2hAmmHBHfTk%3D&se=2155-12-30T06%3A26%3A27Z&sp=r" +DEBIAN_FILE_URL = "https://sonicstorage.blob.core.windows.net/packages/debian/$(DEBIAN_FILE)?sv=2015-04-05&sr=b&sig=WGy6DcbTXo9FDRq%2F0gaiwV7oAYY86dHSUlvGaMrINBM%3D&se=2155-12-30T06%3A21%3A57Z&sp=r" + +$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + rm -rf ntp-$(NTP_VERSION) + wget -O "$(DSC_FILE)" $(DSC_FILE_URL) + wget -O "$(ORIG_FILE)" $(ORIG_FILE_URL) + wget -O "$(DEBIAN_FILE)" $(DEBIAN_FILE_URL) + + dpkg-source -x $(DSC_FILE) + + pushd ntp-$(NTP_VERSION) + + git init + git add -f * + git commit -m "original source files" + + stg init + stg import -s ../patch/series + + dpkg-buildpackage -us -uc -b -j$(SONIC_CONFIG_MAKE_JOBS) + popd + + mv $* $(DEST)/ diff --git a/src/ntp/patch/0001-donot-disable-reader-kernel-enobufs.patch b/src/ntp/patch/0001-donot-disable-reader-kernel-enobufs.patch new file mode 100644 index 000000000000..f44701e6764f --- /dev/null +++ b/src/ntp/patch/0001-donot-disable-reader-kernel-enobufs.patch @@ -0,0 +1,31 @@ +commit 1534de6d3ef2d188d1e2697f7180786ee5a8a9dc +Author: Praveen Chaudhary +Date: Sat Feb 2 20:12:53 2019 -0800 + + [ntp_io.c]: Do not disable reader for error ENOBUFS. + + Signed-off-by: Praveen Chaudhary + +diff --git a/ntpd/ntp_io.c b/ntpd/ntp_io.c +index f2a2404..fe5c94d 100644 +--- a/ntpd/ntp_io.c ++++ b/ntpd/ntp_io.c +@@ -4430,10 +4430,14 @@ process_routing_msgs(struct asyncio_reader *reader) + cnt = read(reader->fd, buffer, sizeof(buffer)); + + if (cnt < 0) { +- msyslog(LOG_ERR, +- "i/o error on routing socket %m - disabling"); +- remove_asyncio_reader(reader); +- delete_asyncio_reader(reader); ++ if (errno == ENOBUFS) { ++ msyslog(LOG_ERR, "routing socket reports: %m"); ++ } else { ++ msyslog(LOG_ERR, ++ "i/o error on routing socket %m - disabling"); ++ remove_asyncio_reader(reader); ++ delete_asyncio_reader(reader); ++ } + return; + } + diff --git a/src/ntp/patch/series b/src/ntp/patch/series new file mode 100644 index 000000000000..c5fa8dfb7ba9 --- /dev/null +++ b/src/ntp/patch/series @@ -0,0 +1 @@ +0001-donot-disable-reader-kernel-enobufs.patch From c4b8e36dc3d15c4fb0d816028d258b2f429e42ff Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Fri, 8 Feb 2019 09:30:37 +0000 Subject: [PATCH 201/219] [submodule]: update sonic-swss * e7bb548 2018-11-28 | [aclorch]: Store control plane ACL tables in orchagent (#708) (HEAD, origin/201803) [Shuotian Cheng] Signed-off-by: Guohan Lu --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 4f5436fea75a..e7bb5483b1f6 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 4f5436fea75a33b560ff88b7562797b3d4a4d4ed +Subproject commit e7bb5483b1f6109760b5738551368184aa0ab711 From e26043ac3cef6e94581ff195c00d343f6a84bae4 Mon Sep 17 00:00:00 2001 From: lguohan Date: Wed, 5 Sep 2018 15:28:32 -0700 Subject: [PATCH 202/219] [build]: use vfs storage driver to build dockers (#2016) seen issues to build dockers using aufs in ubuntu 18.04 Immedidate dockers are exported to docker file and then imported into sonic image. Thus, whether using vfs or aufs as the storage driver does not matter for the immediate build. Signed-off-by: Guohan Lu --- slave.mk | 2 ++ sonic-slave/Dockerfile | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/slave.mk b/slave.mk index 803b87aaffdb..efbf3d2e0b6f 100644 --- a/slave.mk +++ b/slave.mk @@ -358,6 +358,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_SIMPLE_DOCKER_IMAGES)) : $(TARGET_PATH)/%.g $(HEADER) # Apply series of patches if exist if [ -f $($*.gz_PATH).patch/series ]; then pushd $($*.gz_PATH) && QUILT_PATCHES=../$(notdir $($*.gz_PATH)).patch quilt push -a; popd; fi + docker info $(LOG) docker build --squash --no-cache \ --build-arg http_proxy=$(HTTP_PROXY) \ --build-arg https_proxy=$(HTTPS_PROXY) \ @@ -388,6 +389,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_DOCKER_IMAGES)) : $(TARGET_PATH)/%.gz : .pl $(eval export $(subst -,_,$(notdir $($*.gz_PATH)))_whls=$(shell printf "$(subst $(SPACE),\n,$(call expand,$($*.gz_PYTHON_WHEELS)))\n" | awk '!a[$$0]++')) $(eval export $(subst -,_,$(notdir $($*.gz_PATH)))_dbgs=$(shell printf "$(subst $(SPACE),\n,$(call expand,$($*.gz_DBG_PACKAGES)))\n" | awk '!a[$$0]++')) j2 $($*.gz_PATH)/Dockerfile.j2 > $($*.gz_PATH)/Dockerfile + docker info $(LOG) docker build --squash --no-cache \ --build-arg http_proxy=$(HTTP_PROXY) \ --build-arg https_proxy=$(HTTPS_PROXY) \ diff --git a/sonic-slave/Dockerfile b/sonic-slave/Dockerfile index 803fabcfb105..35e73e3e308a 100644 --- a/sonic-slave/Dockerfile +++ b/sonic-slave/Dockerfile @@ -288,4 +288,4 @@ RUN add-apt-repository \ stable" RUN apt-get update RUN apt-get install -y docker-ce=17.03.2~ce-0~debian-jessie -RUN echo "DOCKER_OPTS=\"--experimental\"" >> /etc/default/docker +RUN echo "DOCKER_OPTS=\"--experimental --storage-driver=vfs\"" >> /etc/default/docker From e77a7b12fb377b3a0ae27f519dbb30ba2b5438b4 Mon Sep 17 00:00:00 2001 From: paavaanan Date: Sat, 9 Feb 2019 11:36:15 +0530 Subject: [PATCH 203/219] [devices]: Dell SMF driver hwmon number reorder fix for Dell S6100/Z9100 (#2542) --- device/dell/x86_64-dell_s6100_c2538-r0/plugins/psuutil.py | 4 +++- device/dell/x86_64-dell_z9100_c2538-r0/plugins/psuutil.py | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/plugins/psuutil.py b/device/dell/x86_64-dell_s6100_c2538-r0/plugins/psuutil.py index 5f9661a51e3c..eef8d6c8f131 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/plugins/psuutil.py +++ b/device/dell/x86_64-dell_s6100_c2538-r0/plugins/psuutil.py @@ -11,6 +11,8 @@ except ImportError as e: raise ImportError(str(e) + "- required module not found") +HWMON_DIR = "/sys/devices/platform/SMF.512/hwmon/" +HWMON_NODE = ', '.join(os.listdir(HWMON_DIR)) class PsuUtil(PsuBase): """Platform-specific PSUutil class""" @@ -20,7 +22,7 @@ def __init__(self): # Get a mailbox register def get_pmc_register(self, reg_name): - mailbox_dir = "/sys/devices/platform/SMF.512/hwmon/hwmon1" + mailbox_dir = HWMON_DIR + HWMON_NODE retval = 'ERR' mb_reg_file = mailbox_dir+'/' + reg_name if (not os.path.isfile(mb_reg_file)): diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/plugins/psuutil.py b/device/dell/x86_64-dell_z9100_c2538-r0/plugins/psuutil.py index 66253850e6ff..28390561c628 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/plugins/psuutil.py +++ b/device/dell/x86_64-dell_z9100_c2538-r0/plugins/psuutil.py @@ -11,6 +11,8 @@ except ImportError as e: raise ImportError(str(e) + "- required module not found") +HWMON_DIR = "/sys/devices/platform/SMF.512/hwmon/" +HWMON_NODE = ', '.join(os.listdir(HWMON_DIR)) class PsuUtil(PsuBase): """Platform-specific PSUutil class""" @@ -20,7 +22,7 @@ def __init__(self): # Get a mailbox register def get_pmc_register(self, reg_name): - mailbox_dir = "/sys/devices/platform/SMF.512/hwmon/hwmon1" + mailbox_dir = HWMON_DIR + HWMON_NODE retval = 'ERR' mb_reg_file = mailbox_dir+'/' + reg_name if (not os.path.isfile(mb_reg_file)): From b233d6f1c4daaad90dd74d220bb9fe0cdd855dd6 Mon Sep 17 00:00:00 2001 From: Shuotian Cheng Date: Mon, 11 Feb 2019 21:53:40 -0800 Subject: [PATCH 204/219] [Broadcom]: Update SAI to 3.1.3.4-19 (#2554) Signed-off-by: Shu0T1an ChenG --- platform/broadcom/sai.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 69e389238720..03819ead0741 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,9 +1,9 @@ -BRCM_SAI = libsaibcm_3.1.3.4-18_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/libsaibcm_3.1.3.4-18_amd64.deb?sv=2015-04-05&sr=b&sig=FqiCA8J4cvVyaKG9VrA9HAh2TedtJHHQUmjXQOoxiJY%3D&se=2155-08-28T19%3A38%3A44Z&sp=r" +BRCM_SAI = libsaibcm_3.1.3.4-19_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/libsaibcm_3.1.3.4-19_amd64.deb?sv=2015-04-05&sr=b&sig=tbjRGxCW644D0kAuVsl2WQLj99vlb0dKgizE6TpoYjw%3D&se=2032-10-21T03%3A08%3A33Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.1.3.4-18_amd64.deb +BRCM_SAI_DEV = libsaibcm-dev_3.1.3.4-19_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/libsaibcm-dev_3.1.3.4-18_amd64.deb?sv=2015-04-05&sr=b&sig=kI7rK1xQ%2BkNePGDlagQgDCYmoBN%2By9Dn2UFnDAT34oA%3D&se=2155-08-28T19%3A42%3A49Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/libsaibcm-dev_3.1.3.4-19_amd64.deb?sv=2015-04-05&sr=b&sig=AIteLXKhrlbhY661nG1LihraEu31j5G9J%2FLsFETfXvc%3D&se=2032-10-21T03%3A09%3A32Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) From fe01470fe144bcec7044da1e794a9a4cb9a15f91 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 12 Feb 2019 14:53:21 -0800 Subject: [PATCH 205/219] [201803] [radvd] Build radvd from source; Patch so as not to treat out-of-range MTU as an error (#2552) * Build radvd from source and patch to ignore out-of-range MTU size * Add comments to radvd patch, remove line instead of commenting it out --- .gitignore | 3 ++ .../docker-router-advertiser/Dockerfile.j2 | 3 -- rules/docker-router-advertiser.mk | 1 + rules/radvd.mk | 9 +++++ src/radvd/Makefile | 30 +++++++++++++++++ ...t-treat-out-of-range-MTU-as-an-error.patch | 33 +++++++++++++++++++ src/radvd/patch/series | 2 ++ 7 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 rules/radvd.mk create mode 100644 src/radvd/Makefile create mode 100644 src/radvd/patch/0001-Don-t-treat-out-of-range-MTU-as-an-error.patch create mode 100644 src/radvd/patch/series diff --git a/.gitignore b/.gitignore index 74998573e491..922790873dbb 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,9 @@ src/mpdecimal/* !src/mpdecimal/Makefile src/python3/* !src/python3/Makefile +src/radvd/* +!src/radvd/Makefile +!src/radvd/patch/ src/redis/* !src/redis/Makefile src/snmpd/* diff --git a/dockers/docker-router-advertiser/Dockerfile.j2 b/dockers/docker-router-advertiser/Dockerfile.j2 index 5007daf122cf..f9cf5f90b85e 100644 --- a/dockers/docker-router-advertiser/Dockerfile.j2 +++ b/dockers/docker-router-advertiser/Dockerfile.j2 @@ -6,9 +6,6 @@ ENV DEBIAN_FRONTEND=noninteractive # Update apt's cache of available packages RUN apt-get update -# Install radvd Debian package -RUN apt-get -y install radvd - {% if docker_router_advertiser_debs.strip() -%} # Copy built Debian packages {%- for deb in docker_router_advertiser_debs.split(' ') %} diff --git a/rules/docker-router-advertiser.mk b/rules/docker-router-advertiser.mk index 129246d8fa2d..33e805cf4c2d 100644 --- a/rules/docker-router-advertiser.mk +++ b/rules/docker-router-advertiser.mk @@ -2,6 +2,7 @@ DOCKER_ROUTER_ADVERTISER = docker-router-advertiser.gz $(DOCKER_ROUTER_ADVERTISER)_PATH = $(DOCKERS_PATH)/docker-router-advertiser +$(DOCKER_ROUTER_ADVERTISER)_DEPENDS += $(RADVD) $(DOCKER_ROUTER_ADVERTISER)_LOAD_DOCKERS = $(DOCKER_CONFIG_ENGINE) SONIC_DOCKER_IMAGES += $(DOCKER_ROUTER_ADVERTISER) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_ROUTER_ADVERTISER) diff --git a/rules/radvd.mk b/rules/radvd.mk new file mode 100644 index 000000000000..682f1d5e7595 --- /dev/null +++ b/rules/radvd.mk @@ -0,0 +1,9 @@ +# radvd package + +RADVD_VERSION = 1.9.1-1.3 + +export RADVD_VERSION + +RADVD = radvd_$(RADVD_VERSION)_amd64.deb +$(RADVD)_SRC_PATH = $(SRC_PATH)/radvd +SONIC_MAKE_DEBS += $(RADVD) diff --git a/src/radvd/Makefile b/src/radvd/Makefile new file mode 100644 index 000000000000..9064a43c25c1 --- /dev/null +++ b/src/radvd/Makefile @@ -0,0 +1,30 @@ +.ONESHELL: +SHELL = /bin/bash +.SHELLFLAGS += -e + +MAIN_TARGET = radvd_$(RADVD_VERSION)_amd64.deb + +$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + # Remove any stale files + rm -rf ./radvd + + # Clone radvd repo + git clone https://salsa.debian.org/debian/radvd.git + pushd ./radvd + + # Reset HEAD to the commit of the proper tag + # NOTE: Using "git checkout " here detaches our HEAD, + # which stg doesn't like, so we use this method instead + # NOTE: For some reason, tags in the Debian radvd repo are prefixed with "1%" + git reset --hard debian/1\%$(RADVD_VERSION) + + # Apply patches + stg init + stg import -s ../patch/series + + # Build source and Debian packages + dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) + popd + + # Move the newly-built .deb packages to the destination directory + mv $* $(DERIVED_TARGETS) $(DEST)/ diff --git a/src/radvd/patch/0001-Don-t-treat-out-of-range-MTU-as-an-error.patch b/src/radvd/patch/0001-Don-t-treat-out-of-range-MTU-as-an-error.patch new file mode 100644 index 000000000000..bb77d57814b2 --- /dev/null +++ b/src/radvd/patch/0001-Don-t-treat-out-of-range-MTU-as-an-error.patch @@ -0,0 +1,33 @@ +From e5af09b187bcce4e48ea3f1f71b81329e2d91ea4 Mon Sep 17 00:00:00 2001 +From: Joe LeVeque +Date: Tue, 12 Feb 2019 19:13:45 +0000 +Subject: [PATCH] Don't treat out-of-range MTU as an error + +--- + interface.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/interface.c b/interface.c +index d17267e..b59c6e8 100644 +--- a/interface.c ++++ b/interface.c +@@ -158,9 +158,14 @@ check_iface(struct Interface *iface) + ((iface->AdvLinkMTU < MIN_AdvLinkMTU) || + (iface->if_maxmtu != -1 && (iface->AdvLinkMTU > iface->if_maxmtu)))) + { +- flog(LOG_ERR, "AdvLinkMTU for %s (%u) must be zero or between %u and %u", ++ // FIXME: Temporary workaround for SONiC. Currently, when interfaces are added ++ // or removed from VLANs, the kernel sets the MTU size for the VLAN to the ++ // default value of 1500. Here, we prevent radvd from treating a larger value ++ // in its configuration as an error. Instead of logging an error and setting ++ // res to -1, we simply log a warning and continue on. Once the aforementioned ++ // behavior is addressed, this patch should be removed. ++ flog(LOG_WARNING, "AdvLinkMTU for %s (%u) must be zero or between %u and %u", + iface->Name, iface->AdvLinkMTU, MIN_AdvLinkMTU, iface->if_maxmtu); +- res = -1; + } + + if (iface->AdvReachableTime > MAX_AdvReachableTime) +-- +2.17.1 + diff --git a/src/radvd/patch/series b/src/radvd/patch/series new file mode 100644 index 000000000000..2892590bfcdb --- /dev/null +++ b/src/radvd/patch/series @@ -0,0 +1,2 @@ +# This series applies on GIT commit 3ab9ce1f298cec3600fdad0a4000c1b1351562fd +0001-Don-t-treat-out-of-range-MTU-as-an-error.patch From 3eea909d5e24e46989acdfe9257ad109bc6f0f89 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Sat, 16 Feb 2019 00:01:01 +0000 Subject: [PATCH 206/219] [quagga]: collect quagga-dbg debian package Signed-off-by: Guohan Lu --- rules/quagga.mk | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/rules/quagga.mk b/rules/quagga.mk index f4ba4f2d0be8..353cd5e3fac2 100644 --- a/rules/quagga.mk +++ b/rules/quagga.mk @@ -1,6 +1,11 @@ # quagga package -QUAGGA = quagga_0.99.24.1-2.1_amd64.deb +QUAGGA_VERSION_FULL = 0.99.24.1-2.1 + +QUAGGA = quagga_$(QUAGGA_VERSION_FULL)_amd64.deb $(QUAGGA)_DEPENDS += $(LIBSNMP_DEV) $(QUAGGA)_SRC_PATH = $(SRC_PATH)/sonic-quagga SONIC_DPKG_DEBS += $(QUAGGA) + +QUAGGA_DBG = quagga-dbg_$(QUAGGA_VERSION_FULL)_amd64.deb +$(eval $(call add_derived_package,$(QUAGGA),$(QUAGGA_DBG))) From 8e887e2b07ae6b8f4e25d481a82d658e47f60c70 Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Tue, 29 Jan 2019 09:03:23 -0800 Subject: [PATCH 207/219] Disable IPv6 ra for eth0 interface (#2493) * Disable IPv6 ra for eth0 interface --- build_debian.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/build_debian.sh b/build_debian.sh index ab8bb81824a0..10d1539381b1 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -306,6 +306,7 @@ set /files/etc/sysctl.conf/net.ipv6.conf.all.accept_dad 0 set /files/etc/sysctl.conf/net.ipv6.conf.eth0.accept_dad 0 set /files/etc/sysctl.conf/net.ipv6.conf.eth0.accept_ra_defrtr 0 +set /files/etc/sysctl.conf/net.ipv6.conf.eth0.accept_ra 0 set /files/etc/sysctl.conf/net.core.rmem_max 2097152 set /files/etc/sysctl.conf/net.core.wmem_max 2097152 From 08801d35861aca898fa5a336da333054405d5105 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Fri, 22 Feb 2019 17:56:22 -0800 Subject: [PATCH 208/219] [201803 sub-module] advance sonic-swss submodule (#2598) Submodule src/sonic-swss e7bb548..2e8723b: > Fix incorrect ACL CRM increment, resulting orchagent crash (#800) Signed-off-by: Ying Xie --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index e7bb5483b1f6..2e8723b705f1 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit e7bb5483b1f6109760b5738551368184aa0ab711 +Subproject commit 2e8723b705f12dedda3e0af2f960dd15bf917246 From ec694a537b97c6ef761689e571a6f3ac04db0ab3 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 26 Feb 2019 11:25:50 -0800 Subject: [PATCH 209/219] [201803] Set a rate limit on syslog messages from all Docker containers (#2574) --- dockers/docker-base/etc/rsyslog.conf | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dockers/docker-base/etc/rsyslog.conf b/dockers/docker-base/etc/rsyslog.conf index 8cd8928e2b14..6886dbd2e975 100644 --- a/dockers/docker-base/etc/rsyslog.conf +++ b/dockers/docker-base/etc/rsyslog.conf @@ -14,6 +14,13 @@ ################# $ModLoad imuxsock # provides support for local system logging + +# +# Set a rate limit on messages from the container +# +$SystemLogRateLimitInterval 300 +$SystemLogRateLimitBurst 10000 + #$ModLoad imklog # provides kernel logging support #$ModLoad immark # provides --MARK-- message capability From 2a8af2705e216c1b26f0218eff60ef8c1a84449f Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 26 Feb 2019 11:26:14 -0800 Subject: [PATCH 210/219] [201803] [services] Restart SwSS service upon unexpected critical process exit (#2546) * [service] Restart SwSS Docker container if orchagent exits unexpectedly * [dhcp_relay] Use STATE_DB to determine whether interfaces are ready * Supervisor now autorestarts rsyslogd upon unexpected exit * Add other critical processes to event listener * Make supervisor-proc-exit-listener script global, have it read from 'critical_processes' file inside container * Add SwSS to 'WantedBy=' option of services which should be started along with SwSS --- dockers/docker-dhcp-relay/wait_for_intf.sh.j2 | 38 +++++++------- dockers/docker-orchagent/Dockerfile.j2 | 2 + dockers/docker-orchagent/critical_processes | 7 +++ dockers/docker-orchagent/supervisord.conf | 8 ++- files/build_templates/dhcp_relay.service.j2 | 2 +- files/build_templates/radv.service.j2 | 2 +- files/build_templates/snmp.service.j2 | 3 ++ files/build_templates/swss.service.j2 | 4 ++ files/build_templates/teamd.service.j2 | 6 +-- files/scripts/supervisor-proc-exit-listener | 45 +++++++++++++++++ platform/broadcom/docker-orchagent-brcm.mk | 2 +- platform/cavium/docker-orchagent-cavm.mk | 2 +- platform/centec/docker-orchagent-centec.mk | 2 +- platform/marvell/docker-orchagent-mrvl.mk | 2 +- platform/mellanox/docker-orchagent-mlnx.mk | 2 +- platform/nephos/docker-orchagent-nephos.mk | 2 +- rules/docker-dhcp-relay.mk | 2 +- rules/scripts.mk | 6 ++- .../tests/sample_output/wait_for_intf.sh | 50 +++++++++---------- 19 files changed, 127 insertions(+), 60 deletions(-) create mode 100644 dockers/docker-orchagent/critical_processes create mode 100755 files/scripts/supervisor-proc-exit-listener diff --git a/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 b/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 index 037dc66ead63..23133706cb6c 100644 --- a/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 +++ b/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 @@ -1,42 +1,40 @@ #!/usr/bin/env bash -function wait_until_iface_ready -{ - IFACE=$1 +STATE_DB_IDX="6" - echo "Waiting until interface $IFACE is up..." - - # Wait for the interface to come up (i.e., 'ip link show' returns 0) - until ip link show dev $IFACE up > /dev/null 2>&1; do - sleep 1 - done +PORT_TABLE_PREFIX="PORT_TABLE" +VLAN_TABLE_PREFIX="VLAN_TABLE" +LAG_TABLE_PREFIX="LAG_TABLE" - echo "Interface $IFACE is up" +function wait_until_iface_ready +{ + TABLE_PREFIX=$1 + IFACE=$2 - echo "Waiting until interface $IFACE has an IPv4 address..." + echo "Waiting until interface $IFACE is ready..." - # Wait until the interface gets assigned an IPv4 address + # Wait for the interface to come up + # (i.e., interface is present in STATE_DB and state is "ok") while true; do - IP=$(ip -4 addr show dev $IFACE | grep "inet " | awk '{ print $2 }' | cut -d '/' -f1) - - if [ -n "$IP" ]; then + RESULT=$(redis-cli -n ${STATE_DB_IDX} HGET "${TABLE_PREFIX}|${IFACE}" "state" 2> /dev/null) + if [ x"$RESULT" == x"ok" ]; then break fi sleep 1 done - echo "Interface $IFACE is configured with IP $IP" + echo "Interface ${IFACE} is ready!" } -# Wait for all interfaces to come up and have IPv4 addresses assigned +# Wait for all interfaces to be up and ready {% for (name, prefix) in INTERFACE %} -wait_until_iface_ready {{ name }} +wait_until_iface_ready ${PORT_TABLE_PREFIX} {{ name }} {% endfor %} {% for (name, prefix) in VLAN_INTERFACE %} -wait_until_iface_ready {{ name }} +wait_until_iface_ready ${VLAN_TABLE_PREFIX} {{ name }} {% endfor %} {% for (name, prefix) in PORTCHANNEL_INTERFACE %} -wait_until_iface_ready {{ name }} +wait_until_iface_ready ${LAG_TABLE_PREFIX} {{ name }} {% endfor %} diff --git a/dockers/docker-orchagent/Dockerfile.j2 b/dockers/docker-orchagent/Dockerfile.j2 index 1597b436c3fe..6958390ed2da 100755 --- a/dockers/docker-orchagent/Dockerfile.j2 +++ b/dockers/docker-orchagent/Dockerfile.j2 @@ -30,6 +30,8 @@ COPY ["files/arp_update", "/usr/bin"] COPY ["enable_counters.py", "/usr/bin"] COPY ["start.sh", "orchagent.sh", "swssconfig.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] ## Copy all Jinja2 template files into the templates folder COPY ["*.j2", "/usr/share/sonic/templates/"] diff --git a/dockers/docker-orchagent/critical_processes b/dockers/docker-orchagent/critical_processes new file mode 100644 index 000000000000..d48eb66cda1b --- /dev/null +++ b/dockers/docker-orchagent/critical_processes @@ -0,0 +1,7 @@ +orchagent +portsyncd +intfsyncd +neighsyncd +vlanmgrd +intfmgrd +buffermgrd diff --git a/dockers/docker-orchagent/supervisord.conf b/dockers/docker-orchagent/supervisord.conf index 2369a4c31b05..076c02abd289 100644 --- a/dockers/docker-orchagent/supervisord.conf +++ b/dockers/docker-orchagent/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog diff --git a/files/build_templates/dhcp_relay.service.j2 b/files/build_templates/dhcp_relay.service.j2 index b4d9ceb38f0c..c3edc27bea94 100644 --- a/files/build_templates/dhcp_relay.service.j2 +++ b/files/build_templates/dhcp_relay.service.j2 @@ -11,4 +11,4 @@ ExecStart=/usr/bin/{{ docker_container_name }}.sh attach ExecStop=/usr/bin/{{ docker_container_name }}.sh stop [Install] -WantedBy=multi-user.target teamd.service +WantedBy=multi-user.target swss.service teamd.service diff --git a/files/build_templates/radv.service.j2 b/files/build_templates/radv.service.j2 index 065f01906076..469cf92108ad 100644 --- a/files/build_templates/radv.service.j2 +++ b/files/build_templates/radv.service.j2 @@ -11,4 +11,4 @@ ExecStart=/usr/bin/{{ docker_container_name }}.sh attach ExecStop=/usr/bin/{{ docker_container_name }}.sh stop [Install] -WantedBy=multi-user.target +WantedBy=multi-user.target swss.service diff --git a/files/build_templates/snmp.service.j2 b/files/build_templates/snmp.service.j2 index f344f2e805ea..ca2648cd80e8 100644 --- a/files/build_templates/snmp.service.j2 +++ b/files/build_templates/snmp.service.j2 @@ -8,3 +8,6 @@ Before=ntp-config.service ExecStartPre=/usr/bin/{{docker_container_name}}.sh start ExecStart=/usr/bin/{{docker_container_name}}.sh attach ExecStop=/usr/bin/{{docker_container_name}}.sh stop + +[Install] +WantedBy=multi-user.target swss.service diff --git a/files/build_templates/swss.service.j2 b/files/build_templates/swss.service.j2 index afd442e8c44a..c122e678c4fe 100644 --- a/files/build_templates/swss.service.j2 +++ b/files/build_templates/swss.service.j2 @@ -14,6 +14,8 @@ After=opennsl-modules-3.16.0-6-amd64.service After=nps-modules-3.16.0-6-amd64.service {% endif %} Before=ntp-config.service +StartLimitInterval=1200 +StartLimitBurst=3 [Service] User=root @@ -52,6 +54,8 @@ ExecStopPost=/usr/bin/mst stop ExecStopPost=/etc/init.d/xpnet.sh stop ExecStopPost=/etc/init.d/xpnet.sh start {% endif %} +Restart=always +RestartSec=30 [Install] WantedBy=multi-user.target diff --git a/files/build_templates/teamd.service.j2 b/files/build_templates/teamd.service.j2 index 5cd36c6748b9..0255e14a34f8 100644 --- a/files/build_templates/teamd.service.j2 +++ b/files/build_templates/teamd.service.j2 @@ -1,7 +1,7 @@ [Unit] Description=TEAMD container -Requires=updategraph.service -After=updategraph.service +Requires=updategraph.service swss.service +After=updategraph.service swss.service Before=ntp-config.service [Service] @@ -11,4 +11,4 @@ ExecStart=/usr/bin/{{docker_container_name}}.sh attach ExecStop=/usr/bin/{{docker_container_name}}.sh stop [Install] -WantedBy=multi-user.target +WantedBy=multi-user.target swss.service diff --git a/files/scripts/supervisor-proc-exit-listener b/files/scripts/supervisor-proc-exit-listener new file mode 100755 index 000000000000..6bc62fc400c8 --- /dev/null +++ b/files/scripts/supervisor-proc-exit-listener @@ -0,0 +1,45 @@ +#!/usr/bin/env python + +import os +import signal +import sys +import syslog + +from supervisor import childutils + +# Contents of file should be the names of critical processes (as defined in +# supervisor.conf file), one per line +CRITICAL_PROCESSES_FILE = '/etc/supervisor/critical_processes' + +def main(): + # Read the list of critical processes from a file + with open(CRITICAL_PROCESSES_FILE, 'r') as f: + critical_processes = [line.rstrip('\n') for line in f] + + while True: + # Transition from ACKNOWLEDGED to READY + childutils.listener.ready() + + line = sys.stdin.readline() + headers = childutils.get_headers(line) + payload = sys.stdin.read(int(headers['len'])) + + # Transition from READY to ACKNOWLEDGED + childutils.listener.ok() + + # We only care about PROCESS_STATE_EXITED events + if headers['eventname'] == 'PROCESS_STATE_EXITED': + payload_headers, payload_data = childutils.eventdata(payload + '\n') + + expected = int(payload_headers['expected']) + processname = payload_headers['processname'] + + # If a critical process exited unexpectedly, terminate supervisor + if expected == 0 and processname in critical_processes: + MSG_FORMAT_STR = "Process {} exited unxepectedly. Terminating supervisor..." + msg = MSG_FORMAT_STR.format(payload_headers['processname']) + syslog.syslog(syslog.LOG_INFO, msg) + os.kill(os.getppid(), signal.SIGTERM) + +if __name__ == "__main__": + main() diff --git a/platform/broadcom/docker-orchagent-brcm.mk b/platform/broadcom/docker-orchagent-brcm.mk index 066973967450..a3bbb3fe4193 100644 --- a/platform/broadcom/docker-orchagent-brcm.mk +++ b/platform/broadcom/docker-orchagent-brcm.mk @@ -16,4 +16,4 @@ $(DOCKER_ORCHAGENT_BRCM)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_ORCHAGENT_BRCM)_RUN_OPT += -v /var/log/swss:/var/log/swss:rw $(DOCKER_ORCHAGENT_BRCM)_BASE_IMAGE_FILES += swssloglevel:/usr/bin/swssloglevel -$(DOCKER_ORCHAGENT_BRCM)_FILES += $(ARP_UPDATE_SCRIPT) +$(DOCKER_ORCHAGENT_BRCM)_FILES += $(ARP_UPDATE_SCRIPT) $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/platform/cavium/docker-orchagent-cavm.mk b/platform/cavium/docker-orchagent-cavm.mk index a171a6c801d7..684376647fa9 100644 --- a/platform/cavium/docker-orchagent-cavm.mk +++ b/platform/cavium/docker-orchagent-cavm.mk @@ -16,4 +16,4 @@ $(DOCKER_ORCHAGENT_CAVM)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_ORCHAGENT_CAVM)_RUN_OPT += -v /var/log/swss:/var/log/swss:rw $(DOCKER_ORCHAGENT_CAVM)_BASE_IMAGE_FILES += swssloglevel:/usr/bin/swssloglevel -$(DOCKER_ORCHAGENT_CAVM)_FILES += $(ARP_UPDATE_SCRIPT) +$(DOCKER_ORCHAGENT_CAVM)_FILES += $(ARP_UPDATE_SCRIPT) $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/platform/centec/docker-orchagent-centec.mk b/platform/centec/docker-orchagent-centec.mk index e1d7fd6cf0d6..253e6be06e9e 100644 --- a/platform/centec/docker-orchagent-centec.mk +++ b/platform/centec/docker-orchagent-centec.mk @@ -16,4 +16,4 @@ $(DOCKER_ORCHAGENT_CENTEC)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_ORCHAGENT_CENTEC)_RUN_OPT += -v /var/log/swss:/var/log/swss:rw $(DOCKER_ORCHAGENT_CENTEC)_BASE_IMAGE_FILES += swssloglevel:/usr/bin/swssloglevel -$(DOCKER_ORCHAGENT_CENTEC)_FILES += $(ARP_UPDATE_SCRIPT) +$(DOCKER_ORCHAGENT_CENTEC)_FILES += $(ARP_UPDATE_SCRIPT) $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/platform/marvell/docker-orchagent-mrvl.mk b/platform/marvell/docker-orchagent-mrvl.mk index f2cb0c997d75..6b24c5905c0b 100644 --- a/platform/marvell/docker-orchagent-mrvl.mk +++ b/platform/marvell/docker-orchagent-mrvl.mk @@ -15,4 +15,4 @@ $(DOCKER_ORCHAGENT_MRVL)_RUN_OPT += -v /host/machine.conf:/host/machine.conf $(DOCKER_ORCHAGENT_MRVL)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_ORCHAGENT_MRVL)_BASE_IMAGE_FILES += swssloglevel:/usr/bin/swssloglevel -$(DOCKER_ORCHAGENT_MRVL)_FILES += $(ARP_UPDATE_SCRIPT) +$(DOCKER_ORCHAGENT_MRVL)_FILES += $(ARP_UPDATE_SCRIPT) $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/platform/mellanox/docker-orchagent-mlnx.mk b/platform/mellanox/docker-orchagent-mlnx.mk index 6dda3c446b06..78bf8d44cf4b 100644 --- a/platform/mellanox/docker-orchagent-mlnx.mk +++ b/platform/mellanox/docker-orchagent-mlnx.mk @@ -16,4 +16,4 @@ $(DOCKER_ORCHAGENT_MLNX)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_ORCHAGENT_MLNX)_RUN_OPT += -v /var/log/swss:/var/log/swss:rw $(DOCKER_ORCHAGENT_MLNX)_BASE_IMAGE_FILES += swssloglevel:/usr/bin/swssloglevel -$(DOCKER_ORCHAGENT_MLNX)_FILES += $(ARP_UPDATE_SCRIPT) +$(DOCKER_ORCHAGENT_MLNX)_FILES += $(ARP_UPDATE_SCRIPT) $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/platform/nephos/docker-orchagent-nephos.mk b/platform/nephos/docker-orchagent-nephos.mk index b21e69d6cf87..4b6ef241f536 100644 --- a/platform/nephos/docker-orchagent-nephos.mk +++ b/platform/nephos/docker-orchagent-nephos.mk @@ -16,4 +16,4 @@ $(DOCKER_ORCHAGENT_NEPHOS)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_ORCHAGENT_NEPHOS)_RUN_OPT += -v /var/log/swss:/var/log/swss:rw $(DOCKER_ORCHAGENT_NEPHOS)_BASE_IMAGE_FILES += swssloglevel:/usr/bin/swssloglevel -$(DOCKER_ORCHAGENT_NEPHOS)_FILES += $(ARP_UPDATE_SCRIPT) +$(DOCKER_ORCHAGENT_NEPHOS)_FILES += $(ARP_UPDATE_SCRIPT) $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-dhcp-relay.mk b/rules/docker-dhcp-relay.mk index 53406ad1e15f..7f960920ec0c 100644 --- a/rules/docker-dhcp-relay.mk +++ b/rules/docker-dhcp-relay.mk @@ -2,7 +2,7 @@ DOCKER_DHCP_RELAY = docker-dhcp-relay.gz $(DOCKER_DHCP_RELAY)_PATH = $(DOCKERS_PATH)/docker-dhcp-relay -$(DOCKER_DHCP_RELAY)_DEPENDS += $(ISC_DHCP_COMMON) $(ISC_DHCP_RELAY) $(ISC_DHCP_CLIENT) +$(DOCKER_DHCP_RELAY)_DEPENDS += $(ISC_DHCP_COMMON) $(ISC_DHCP_RELAY) $(ISC_DHCP_CLIENT) $(REDIS_TOOLS) $(DOCKER_DHCP_RELAY)_LOAD_DOCKERS = $(DOCKER_CONFIG_ENGINE) SONIC_DOCKER_IMAGES += $(DOCKER_DHCP_RELAY) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_DHCP_RELAY) diff --git a/rules/scripts.mk b/rules/scripts.mk index fbefdd68d2cd..d5bcc51fd3a9 100644 --- a/rules/scripts.mk +++ b/rules/scripts.mk @@ -5,7 +5,11 @@ $(ARP_UPDATE_SCRIPT)_PATH = files/scripts CONFIGDB_LOAD_SCRIPT = configdb-load.sh $(CONFIGDB_LOAD_SCRIPT)_PATH = files/scripts +SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT = supervisor-proc-exit-listener +$(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT)_PATH = files/scripts + SONIC_COPY_FILES += $(CONFIGDB_LOAD_SCRIPT) \ - $(ARP_UPDATE_SCRIPT) + $(ARP_UPDATE_SCRIPT) \ + $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh b/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh index 3cbde972fe18..3562082647a0 100644 --- a/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh +++ b/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh @@ -1,43 +1,41 @@ #!/usr/bin/env bash -function wait_until_iface_ready -{ - IFACE=$1 +STATE_DB_IDX="6" - echo "Waiting until interface $IFACE is up..." - - # Wait for the interface to come up (i.e., 'ip link show' returns 0) - until ip link show dev $IFACE up > /dev/null 2>&1; do - sleep 1 - done +PORT_TABLE_PREFIX="PORT_TABLE" +VLAN_TABLE_PREFIX="VLAN_TABLE" +LAG_TABLE_PREFIX="LAG_TABLE" - echo "Interface $IFACE is up" +function wait_until_iface_ready +{ + TABLE_PREFIX=$1 + IFACE=$2 - echo "Waiting until interface $IFACE has an IPv4 address..." + echo "Waiting until interface $IFACE is ready..." - # Wait until the interface gets assigned an IPv4 address + # Wait for the interface to come up + # (i.e., interface is present in STATE_DB and state is "ok") while true; do - IP=$(ip -4 addr show dev $IFACE | grep "inet " | awk '{ print $2 }' | cut -d '/' -f1) - - if [ -n "$IP" ]; then + RESULT=$(redis-cli -n ${STATE_DB_IDX} HGET "${TABLE_PREFIX}|${IFACE}" "state" 2> /dev/null) + if [ x"$RESULT" == x"ok" ]; then break fi sleep 1 done - echo "Interface $IFACE is configured with IP $IP" + echo "Interface ${IFACE} is ready!" } -# Wait for all interfaces to come up and have IPv4 addresses assigned -wait_until_iface_ready Vlan1000 -wait_until_iface_ready PortChannel04 -wait_until_iface_ready PortChannel02 -wait_until_iface_ready PortChannel03 -wait_until_iface_ready PortChannel03 -wait_until_iface_ready PortChannel01 -wait_until_iface_ready PortChannel02 -wait_until_iface_ready PortChannel04 -wait_until_iface_ready PortChannel01 +# Wait for all interfaces to be up and ready +wait_until_iface_ready ${VLAN_TABLE_PREFIX} Vlan1000 +wait_until_iface_ready ${LAG_TABLE_PREFIX} PortChannel04 +wait_until_iface_ready ${LAG_TABLE_PREFIX} PortChannel02 +wait_until_iface_ready ${LAG_TABLE_PREFIX} PortChannel03 +wait_until_iface_ready ${LAG_TABLE_PREFIX} PortChannel03 +wait_until_iface_ready ${LAG_TABLE_PREFIX} PortChannel01 +wait_until_iface_ready ${LAG_TABLE_PREFIX} PortChannel02 +wait_until_iface_ready ${LAG_TABLE_PREFIX} PortChannel04 +wait_until_iface_ready ${LAG_TABLE_PREFIX} PortChannel01 From 2c5bd96e1be7bf79ac81de3a16baf0966b5619a4 Mon Sep 17 00:00:00 2001 From: Andriy Moroz Date: Wed, 27 Feb 2019 20:26:35 +0200 Subject: [PATCH 211/219] Update SAI and SDK (v4.2.7304) (#2612) This fixes FDB events for SONiC Signed-off-by: Andriy Moroz --- platform/mellanox/mlnx-sai.mk | 2 +- platform/mellanox/sdk.mk | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index 648ee3eca5b7..ce1338280234 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,7 +1,7 @@ # Mellanox SAI MLNX_SAI_VERSION = SAIRel1.11.5-master -MLNX_SAI_REVISION = 5675ef1037813992cd234d3afcee43959e1ca4f6 +MLNX_SAI_REVISION = a8ae004f7c24638424ad70196d7ea4e6aea7f05b export MLNX_SAI_VERSION MLNX_SAI_REVISION diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index b85fc0bcb033..6391a9066543 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,5 +1,5 @@ -MLNX_SDK_BASE_URL = https://github.com/Mellanox/SAI-Implementation/raw/dc2bafed31d0a84d9282d65bd94b5e20574d1a4d/sdk -MLNX_SDK_VERSION = 4.2.7303 +MLNX_SDK_BASE_URL = https://github.com/Mellanox/SAI-Implementation/raw/a8ae004f7c24638424ad70196d7ea4e6aea7f05b/sdk +MLNX_SDK_VERSION = 4.2.7304 MLNX_SDK_RDEBS += $(APPLIBS) $(IPROUTE2_MLNX) $(SX_ACL_RM) $(SX_COMPLIB) \ $(SX_EXAMPLES) $(SX_GEN_UTILS) $(SX_SCEW) $(SX_SDN_HAL) \ $(SXD_LIBS) $(TESTX) From 41800b063abc9e20e06b357f258e3c33ac496795 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Mon, 4 Mar 2019 09:15:11 -0800 Subject: [PATCH 212/219] [supervisor] Fix crash if system clock rolls back within startsecs; Refactor patch (#2624) --- ...-hanging-and-crashes-if-system-cloc.patch} | 140 ++++++++++++++++-- ...e-hanging-delays-in-process-state-tr.patch | 83 ----------- src/supervisor/patch/series | 4 +- 3 files changed, 132 insertions(+), 95 deletions(-) rename src/supervisor/patch/{0002-Add-unit-test-cases-to-ensure-state-transitions-work.patch => 0001-Prevent-excessive-hanging-and-crashes-if-system-cloc.patch} (54%) delete mode 100644 src/supervisor/patch/0001-Prevent-excessive-hanging-delays-in-process-state-tr.patch diff --git a/src/supervisor/patch/0002-Add-unit-test-cases-to-ensure-state-transitions-work.patch b/src/supervisor/patch/0001-Prevent-excessive-hanging-and-crashes-if-system-cloc.patch similarity index 54% rename from src/supervisor/patch/0002-Add-unit-test-cases-to-ensure-state-transitions-work.patch rename to src/supervisor/patch/0001-Prevent-excessive-hanging-and-crashes-if-system-cloc.patch index cb01665ba80b..6c4a6b7c2a4c 100644 --- a/src/supervisor/patch/0002-Add-unit-test-cases-to-ensure-state-transitions-work.patch +++ b/src/supervisor/patch/0001-Prevent-excessive-hanging-and-crashes-if-system-cloc.patch @@ -1,15 +1,91 @@ -From 43b6f3ee93593f666af2c6a7af897bf3b5ee762d Mon Sep 17 00:00:00 2001 +From 5b56519e68e866662d9fd9a6681b6b47d6b5fcdb Mon Sep 17 00:00:00 2001 From: Joe LeVeque -Date: Wed, 17 Jan 2018 22:27:56 +0000 -Subject: [PATCH 2/2] Add unit test cases to ensure state transitions work if - system time has rolled backward +Date: Thu, 28 Feb 2019 01:43:54 +0000 +Subject: [PATCH] Prevent excessive hanging and crashes if system clock rolls + backward --- - supervisor/tests/test_process.py | 146 +++++++++++++++++++++++++++++++++++++++ - 1 file changed, 146 insertions(+) + supervisor/process.py | 36 ++++++ + supervisor/tests/test_process.py | 183 +++++++++++++++++++++++++++++++ + 2 files changed, 219 insertions(+) +diff --git a/supervisor/process.py b/supervisor/process.py +index f9ddcd9..5f73e6b 100644 +--- a/supervisor/process.py ++++ b/supervisor/process.py +@@ -347,6 +347,28 @@ class Subprocess: + options.write(2, "supervisor: child process was not spawned\n") + options._exit(127) # exit process with code for spawn failure + ++ def _check_and_adjust_for_system_clock_rollback(self, test_time): ++ """ ++ Check if system clock has rolled backward beyond test_time. If so, set ++ affected timestamps to test_time. ++ """ ++ if self.state == ProcessStates.STARTING: ++ if test_time < self.laststart: ++ self.laststart = test_time; ++ if self.delay > 0 and test_time < (self.delay - self.config.startsecs): ++ self.delay = test_time + self.config.startsecs ++ elif self.state == ProcessStates.RUNNING: ++ if test_time > self.laststart and test_time < (self.laststart + self.config.startsecs): ++ self.laststart = test_time - self.config.startsecs ++ elif self.state == ProcessStates.STOPPING: ++ if test_time < self.laststopreport: ++ self.laststopreport = test_time; ++ if self.delay > 0 and test_time < (self.delay - self.config.stopwaitsecs): ++ self.delay = test_time + self.config.stopwaitsecs ++ elif self.state == ProcessStates.BACKOFF: ++ if self.delay > 0 and test_time < (self.delay - self.backoff): ++ self.delay = test_time + self.backoff ++ + def stop(self): + """ Administrative stop """ + self.administrative_stop = True +@@ -357,6 +379,9 @@ class Subprocess: + """ Log a 'waiting for x to stop' message with throttling. """ + if self.state == ProcessStates.STOPPING: + now = time.time() ++ ++ self._check_and_adjust_for_system_clock_rollback(now) ++ + if now > (self.laststopreport + 2): # every 2 seconds + self.config.options.logger.info( + 'waiting for %s to stop' % self.config.name) +@@ -487,6 +512,9 @@ class Subprocess: + es, msg = decode_wait_status(sts) + + now = time.time() ++ ++ self._check_and_adjust_for_system_clock_rollback(now) ++ + self.laststop = now + processname = self.config.name + +@@ -586,6 +614,8 @@ class Subprocess: + now = time.time() + state = self.state + ++ self._check_and_adjust_for_system_clock_rollback(now) ++ + logger = self.config.options.logger + + if self.config.options.mood > SupervisorStates.RESTARTING: +@@ -805,6 +835,12 @@ class EventListenerPool(ProcessGroupBase): + if dispatch_capable: + if self.dispatch_throttle: + now = time.time() ++ ++ if now < self.last_dispatch: ++ # The system clock appears to have moved backward ++ # Reset self.last_dispatch accordingly ++ self.last_dispatch = now; ++ + if now - self.last_dispatch < self.dispatch_throttle: + return + self.dispatch() diff --git a/supervisor/tests/test_process.py b/supervisor/tests/test_process.py -index 7f9bab2..ea16315 100644 +index 7f9bab2..6808f60 100644 --- a/supervisor/tests/test_process.py +++ b/supervisor/tests/test_process.py @@ -736,6 +736,40 @@ class SubprocessTests(unittest.TestCase): @@ -53,7 +129,51 @@ index 7f9bab2..ea16315 100644 def test_give_up(self): options = DummyOptions() config = DummyPConfig(options, 'test', '/test') -@@ -1402,6 +1436,92 @@ class SubprocessTests(unittest.TestCase): +@@ -1105,6 +1139,43 @@ class SubprocessTests(unittest.TestCase): + self.assertEqual(event.__class__, events.ProcessStateBackoffEvent) + self.assertEqual(event.from_state, ProcessStates.STARTING) + ++ # This tests the case where the process has stayed alive longer than ++ # startsecs (i.e., long enough to enter the RUNNING state), however the ++ # system clock has since rolled backward such that the current time is ++ # greater than laststart but less than startsecs. ++ def test_finish_running_state_exited_too_quickly_due_to_clock_rollback(self): ++ options = DummyOptions() ++ config = DummyPConfig(options, 'notthere', '/notthere', ++ stdout_logfile='/tmp/foo', startsecs=10) ++ instance = self._makeOne(config) ++ instance.config.options.pidhistory[123] = instance ++ pipes = {'stdout':'','stderr':''} ++ instance.pipes = pipes ++ instance.config.exitcodes =[-1] ++ instance.laststart = time.time() ++ from supervisor.states import ProcessStates ++ from supervisor import events ++ instance.state = ProcessStates.RUNNING ++ L = [] ++ events.subscribe(events.ProcessStateEvent, lambda x: L.append(x)) ++ instance.pid = 123 ++ instance.finish(123, 1) ++ self.assertFalse(instance.killing) ++ self.assertEqual(instance.pid, 0) ++ self.assertEqual(options.parent_pipes_closed, pipes) ++ self.assertEqual(instance.pipes, {}) ++ self.assertEqual(instance.dispatchers, {}) ++ self.assertEqual(options.logger.data[0], ++ 'exited: notthere (terminated by SIGHUP; expected)') ++ self.assertEqual(instance.exitstatus, -1) ++ self.assertEqual(len(L), 1) ++ event = L[0] ++ self.assertEqual(event.__class__, ++ events.ProcessStateExitedEvent) ++ self.assertEqual(event.expected, True) ++ self.assertEqual(event.extra_values, [('expected', True), ('pid', 123)]) ++ self.assertEqual(event.from_state, ProcessStates.RUNNING) ++ + def test_finish_running_state_laststart_in_future(self): + options = DummyOptions() + config = DummyPConfig(options, 'notthere', '/notthere', +@@ -1402,6 +1473,92 @@ class SubprocessTests(unittest.TestCase): event = L[0] self.assertEqual(event.__class__, events.ProcessStateRunningEvent) @@ -146,7 +266,7 @@ index 7f9bab2..ea16315 100644 def test_transition_backoff_to_fatal(self): from supervisor import events L = [] -@@ -2033,6 +2153,32 @@ class EventListenerPoolTests(ProcessGroupBaseTests): +@@ -2033,6 +2190,32 @@ class EventListenerPoolTests(ProcessGroupBaseTests): self.assertEqual(process1.listener_state, EventListenerStates.BUSY) self.assertEqual(process1.event, event) @@ -180,5 +300,5 @@ index 7f9bab2..ea16315 100644 options = DummyOptions() from supervisor.states import ProcessStates -- -2.1.4 +2.17.1 diff --git a/src/supervisor/patch/0001-Prevent-excessive-hanging-delays-in-process-state-tr.patch b/src/supervisor/patch/0001-Prevent-excessive-hanging-delays-in-process-state-tr.patch deleted file mode 100644 index c0263e9baf10..000000000000 --- a/src/supervisor/patch/0001-Prevent-excessive-hanging-delays-in-process-state-tr.patch +++ /dev/null @@ -1,83 +0,0 @@ -From bac496af4c2051b3c15038e06533f9094b1c3604 Mon Sep 17 00:00:00 2001 -From: Joe LeVeque -Date: Tue, 16 Jan 2018 20:42:13 +0000 -Subject: [PATCH 1/2] Prevent excessive hanging/delays in process state - transitions if the system time rolls backward - ---- - supervisor/process.py | 32 ++++++++++++++++++++++++++++++++ - 1 file changed, 32 insertions(+) - -diff --git a/supervisor/process.py b/supervisor/process.py -index f9ddcd9..216372f 100644 ---- a/supervisor/process.py -+++ b/supervisor/process.py -@@ -357,6 +357,12 @@ class Subprocess: - """ Log a 'waiting for x to stop' message with throttling. """ - if self.state == ProcessStates.STOPPING: - now = time.time() -+ -+ # If the system clock has moved backward, reset -+ # self.laststopreport to current system time -+ if now < self.laststopreport: -+ self.laststopreport = now; -+ - if now > (self.laststopreport + 2): # every 2 seconds - self.config.options.logger.info( - 'waiting for %s to stop' % self.config.name) -@@ -604,12 +610,27 @@ class Subprocess: - # STOPPED -> STARTING - self.spawn() - elif state == ProcessStates.BACKOFF: -+ if self.delay > 0 and now < self.delay - self.backoff: -+ # The system clock appears to have moved backward -+ # Reset self.delay accordingly -+ self.delay = now + self.backoff -+ - if self.backoff <= self.config.startretries: - if now > self.delay: - # BACKOFF -> STARTING - self.spawn() - - if state == ProcessStates.STARTING: -+ if now < self.laststart: -+ # The system clock appears to have moved backward -+ # Reset self.laststart to current system time -+ self.laststart = now; -+ -+ if self.delay > 0 and now < self.delay - self.config.startsecs: -+ # The system clock appears to have moved backward -+ # Reset self.delay accordingly -+ self.delay = now + self.config.startsecs -+ - if now - self.laststart > self.config.startsecs: - # STARTING -> RUNNING if the proc has started - # successfully and it has stayed up for at least -@@ -633,6 +654,11 @@ class Subprocess: - logger.info('gave up: %s %s' % (self.config.name, msg)) - - elif state == ProcessStates.STOPPING: -+ if self.delay > 0 and now < self.delay - self.config.stopwaitsecs: -+ # The system clock appears to have moved backward -+ # Reset self.delay accordingly -+ self.delay = now + self.config.stopwaitsecs -+ - time_left = self.delay - now - if time_left <= 0: - # kill processes which are taking too long to stop with a final -@@ -805,6 +831,12 @@ class EventListenerPool(ProcessGroupBase): - if dispatch_capable: - if self.dispatch_throttle: - now = time.time() -+ -+ # If the system clock has moved backward, reset -+ # self.last_dispatch to current system time -+ if now < self.last_dispatch: -+ self.last_dispatch = now; -+ - if now - self.last_dispatch < self.dispatch_throttle: - return - self.dispatch() --- -2.1.4 - diff --git a/src/supervisor/patch/series b/src/supervisor/patch/series index d141fddf3301..9d87dccfa780 100644 --- a/src/supervisor/patch/series +++ b/src/supervisor/patch/series @@ -1,2 +1,2 @@ -0001-Prevent-excessive-hanging-delays-in-process-state-tr.patch -0002-Add-unit-test-cases-to-ensure-state-transitions-work.patch +# This series applies on GIT commit 34b690aea8cf7572d73765c95c54a83261d69aad +0001-Prevent-excessive-hanging-and-crashes-if-system-cloc.patch From 9e8518c855106fdce9fa7938e43194f7a719f162 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 6 Mar 2019 23:49:58 -0800 Subject: [PATCH 213/219] [201803] Restart SwSS, syncd and dependent services if a critical process in syncd container exits (#2615) * Add process exit listeners to syncd containers so that containers stop upon unexpected critical process exit * swss.service unit file now starts both swss and syncd containers as ExecStartPre steps, and for ExecStart, it indefinitely checks that the containers are running * Add 'docker-wait-any' script, use it to wait for containers to exit --- .../build_templates/sonic_debian_extension.j2 | 3 + files/build_templates/swss.service.j2 | 2 +- files/image_config/misc/docker-wait-any | 65 +++++++++++++++++++ platform/broadcom/docker-syncd-brcm-rpc.mk | 2 +- platform/broadcom/docker-syncd-brcm.mk | 2 +- .../broadcom/docker-syncd-brcm/Dockerfile.j2 | 2 + .../docker-syncd-brcm/critical_processes | 2 + .../docker-syncd-brcm/supervisord.conf | 8 ++- platform/cavium/docker-syncd-cavm-rpc.mk | 1 + platform/cavium/docker-syncd-cavm.mk | 1 + .../cavium/docker-syncd-cavm/Dockerfile.j2 | 2 + .../docker-syncd-cavm/critical_processes | 1 + .../cavium/docker-syncd-cavm/supervisord.conf | 8 ++- platform/centec/docker-syncd-centec-rpc.mk | 1 + platform/centec/docker-syncd-centec.mk | 1 + .../centec/docker-syncd-centec/Dockerfile.j2 | 2 + .../docker-syncd-centec/critical_processes | 1 + .../docker-syncd-centec/supervisord.conf | 8 ++- platform/marvell/docker-syncd-mrvl-rpc.mk | 1 + platform/marvell/docker-syncd-mrvl.mk | 1 + .../marvell/docker-syncd-mrvl/Dockerfile.j2 | 2 + .../docker-syncd-mrvl/critical_processes | 1 + .../docker-syncd-mrvl/supervisord.conf | 8 ++- platform/mellanox/docker-syncd-mlnx-rpc.mk | 1 + platform/mellanox/docker-syncd-mlnx.mk | 1 + .../mellanox/docker-syncd-mlnx/Dockerfile.j2 | 2 + .../docker-syncd-mlnx/critical_processes | 1 + .../docker-syncd-mlnx/supervisord.conf | 8 ++- platform/nephos/docker-syncd-nephos-rpc.mk | 2 +- platform/nephos/docker-syncd-nephos.mk | 2 +- .../nephos/docker-syncd-nephos/Dockerfile.j2 | 2 + .../docker-syncd-nephos/critical_processes | 2 + .../docker-syncd-nephos/supervisord.conf | 8 ++- 33 files changed, 143 insertions(+), 11 deletions(-) create mode 100755 files/image_config/misc/docker-wait-any create mode 100644 platform/broadcom/docker-syncd-brcm/critical_processes create mode 100644 platform/cavium/docker-syncd-cavm/critical_processes create mode 100644 platform/centec/docker-syncd-centec/critical_processes create mode 100644 platform/marvell/docker-syncd-mrvl/critical_processes create mode 100644 platform/mellanox/docker-syncd-mlnx/critical_processes create mode 100644 platform/nephos/docker-syncd-nephos/critical_processes diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 84dbaca39854..1575dd56abda 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -163,6 +163,9 @@ sudo cp $IMAGE_CONFIGS/hostname/hostname-config.service $FILESYSTEM_ROOT/etc/sy sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable hostname-config.service sudo cp $IMAGE_CONFIGS/hostname/hostname-config.sh $FILESYSTEM_ROOT/usr/bin/ +# Copy miscellaneous scripts +sudo cp $IMAGE_CONFIGS/misc/docker-wait-any $FILESYSTEM_ROOT/usr/bin/ + # Copy updategraph script and service file j2 files/build_templates/updategraph.service.j2 | sudo tee $FILESYSTEM_ROOT/etc/systemd/system/updategraph.service sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable updategraph.service diff --git a/files/build_templates/swss.service.j2 b/files/build_templates/swss.service.j2 index c122e678c4fe..56c0c1ca98b6 100644 --- a/files/build_templates/swss.service.j2 +++ b/files/build_templates/swss.service.j2 @@ -41,7 +41,7 @@ ExecStartPre=/etc/init.d/xpnet.sh start ExecStartPre=/usr/bin/{{docker_container_name}}.sh start ExecStartPre=/usr/bin/syncd.sh start -ExecStart=/usr/bin/{{docker_container_name}}.sh attach +ExecStart=/bin/bash -c "sleep 5; /usr/bin/docker-wait-any {{docker_container_name}} syncd" ExecStop=/usr/bin/{{docker_container_name}}.sh stop ExecStopPost=/usr/bin/syncd.sh stop diff --git a/files/image_config/misc/docker-wait-any b/files/image_config/misc/docker-wait-any new file mode 100755 index 000000000000..ed8d2d9c083d --- /dev/null +++ b/files/image_config/misc/docker-wait-any @@ -0,0 +1,65 @@ +#!/usr/bin/env python + +""" + docker-wait-any + + This script takes one or more Docker container names as arguments, + and it will block indefinitely while all of the specified containers + are running. If any of the specified containers stop, the script will + exit. + + This script was created because the 'docker wait' command is lacking + this functionality. It will block until ALL specified containers have + stopped running. Here, we spawn multiple threads and wait on one + container per thread. If any of the threads exit, the entire + application will exit. + + NOTE: This script is written against docker-py version 1.6.0. Newer + versions of docker-py have a different API. +""" + +import sys +import threading +from docker import Client + +# Instantiate a global event to share among our threads +g_thread_exit_event = threading.Event() + + +def usage(): + print("Usage: {} [ ...]".format(sys.argv[0])) + sys.exit(1) + + +def wait_for_container(docker_client, container_name): + docker_client.wait(container_name) + + print("No longer waiting on container '{}'".format(container_name)) + + # Signal the main thread to exit + g_thread_exit_event.set() + + +def main(): + thread_list = [] + + docker_client = Client(base_url='unix://var/run/docker.sock') + + # Ensure we were passed at least one argument + if len(sys.argv) < 2: + usage() + + container_names = sys.argv[1:] + + for container_name in container_names: + t = threading.Thread(target=wait_for_container, args=[docker_client, container_name]) + t.daemon = True + t.start() + thread_list.append(t) + + # Wait until we receive an event signifying one of the containers has stopped + g_thread_exit_event.wait() + sys.exit(0) + +if __name__ == '__main__': + main() diff --git a/platform/broadcom/docker-syncd-brcm-rpc.mk b/platform/broadcom/docker-syncd-brcm-rpc.mk index fa7c0fb797c7..4e8048bcdd99 100644 --- a/platform/broadcom/docker-syncd-brcm-rpc.mk +++ b/platform/broadcom/docker-syncd-brcm-rpc.mk @@ -3,7 +3,7 @@ DOCKER_SYNCD_BRCM_RPC = docker-syncd-brcm-rpc.gz $(DOCKER_SYNCD_BRCM_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-brcm-rpc $(DOCKER_SYNCD_BRCM_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) -$(DOCKER_SYNCD_BRCM_RPC)_FILES += $(DSSERVE) $(BCMCMD) +$(DOCKER_SYNCD_BRCM_RPC)_FILES += $(DSSERVE) $(BCMCMD) $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) $(DOCKER_SYNCD_BRCM_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_BRCM) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_BRCM_RPC) ifeq ($(ENABLE_SYNCD_RPC),y) diff --git a/platform/broadcom/docker-syncd-brcm.mk b/platform/broadcom/docker-syncd-brcm.mk index 6ef1587adecd..9155158e7b6d 100644 --- a/platform/broadcom/docker-syncd-brcm.mk +++ b/platform/broadcom/docker-syncd-brcm.mk @@ -3,7 +3,7 @@ DOCKER_SYNCD_BRCM = docker-syncd-brcm.gz $(DOCKER_SYNCD_BRCM)_PATH = $(PLATFORM_PATH)/docker-syncd-brcm $(DOCKER_SYNCD_BRCM)_DEPENDS += $(SYNCD) -$(DOCKER_SYNCD_BRCM)_FILES += $(DSSERVE) $(BCMCMD) +$(DOCKER_SYNCD_BRCM)_FILES += $(DSSERVE) $(BCMCMD) $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) $(DOCKER_SYNCD_BRCM)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_BRCM) ifneq ($(ENABLE_SYNCD_RPC),y) diff --git a/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 b/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 index 96ae65ee8897..e06f57cc3dde 100755 --- a/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 +++ b/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 @@ -23,6 +23,8 @@ COPY ["files/dsserve", "files/bcmcmd", "start.sh", "/usr/bin/"] RUN chmod +x /usr/bin/dsserve /usr/bin/bcmcmd COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] ## Clean up RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y diff --git a/platform/broadcom/docker-syncd-brcm/critical_processes b/platform/broadcom/docker-syncd-brcm/critical_processes new file mode 100644 index 000000000000..489668a89e08 --- /dev/null +++ b/platform/broadcom/docker-syncd-brcm/critical_processes @@ -0,0 +1,2 @@ +dsserve +syncd diff --git a/platform/broadcom/docker-syncd-brcm/supervisord.conf b/platform/broadcom/docker-syncd-brcm/supervisord.conf index a2e0743b1cf5..cd6712acbf22 100644 --- a/platform/broadcom/docker-syncd-brcm/supervisord.conf +++ b/platform/broadcom/docker-syncd-brcm/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog diff --git a/platform/cavium/docker-syncd-cavm-rpc.mk b/platform/cavium/docker-syncd-cavm-rpc.mk index e0136f5324b6..b7204a49aafa 100644 --- a/platform/cavium/docker-syncd-cavm-rpc.mk +++ b/platform/cavium/docker-syncd-cavm-rpc.mk @@ -3,6 +3,7 @@ DOCKER_SYNCD_CAVM_RPC = docker-syncd-cavm-rpc.gz $(DOCKER_SYNCD_CAVM_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-cavm-rpc $(DOCKER_SYNCD_CAVM_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(CAVM_LIBSAI) $(XP_TOOLS) $(REDIS_TOOLS) +$(DOCKER_SYNCD_CAVM_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) $(DOCKER_SYNCD_CAVM_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_CAVM) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_CAVM_RPC) ifeq ($(ENABLE_SYNCD_RPC),y) diff --git a/platform/cavium/docker-syncd-cavm.mk b/platform/cavium/docker-syncd-cavm.mk index 8a3b0857dadf..780bb6fb12c2 100644 --- a/platform/cavium/docker-syncd-cavm.mk +++ b/platform/cavium/docker-syncd-cavm.mk @@ -3,6 +3,7 @@ DOCKER_SYNCD_CAVM = docker-syncd-cavm.gz $(DOCKER_SYNCD_CAVM)_PATH = $(PLATFORM_PATH)/docker-syncd-cavm $(DOCKER_SYNCD_CAVM)_DEPENDS += $(SYNCD) $(CAVM_LIBSAI) $(XP_TOOLS) $(REDIS_TOOLS) +$(DOCKER_SYNCD_CAVM)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) $(DOCKER_SYNCD_CAVM)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_CAVM) ifneq ($(ENABLE_SYNCD_RPC),y) diff --git a/platform/cavium/docker-syncd-cavm/Dockerfile.j2 b/platform/cavium/docker-syncd-cavm/Dockerfile.j2 index a35abf576f6d..db08a30a506f 100755 --- a/platform/cavium/docker-syncd-cavm/Dockerfile.j2 +++ b/platform/cavium/docker-syncd-cavm/Dockerfile.j2 @@ -20,6 +20,8 @@ debs/{{ deb }}{{' '}} COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] COPY ["profile.ini", "/etc/ssw/AS7512/"] diff --git a/platform/cavium/docker-syncd-cavm/critical_processes b/platform/cavium/docker-syncd-cavm/critical_processes new file mode 100644 index 000000000000..6082f242b872 --- /dev/null +++ b/platform/cavium/docker-syncd-cavm/critical_processes @@ -0,0 +1 @@ +syncd diff --git a/platform/cavium/docker-syncd-cavm/supervisord.conf b/platform/cavium/docker-syncd-cavm/supervisord.conf index 1af5d70a1d0c..c823ab5680ef 100644 --- a/platform/cavium/docker-syncd-cavm/supervisord.conf +++ b/platform/cavium/docker-syncd-cavm/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog diff --git a/platform/centec/docker-syncd-centec-rpc.mk b/platform/centec/docker-syncd-centec-rpc.mk index 1798a034980d..4a94eaf0dbbe 100644 --- a/platform/centec/docker-syncd-centec-rpc.mk +++ b/platform/centec/docker-syncd-centec-rpc.mk @@ -3,6 +3,7 @@ DOCKER_SYNCD_CENTEC_RPC = docker-syncd-centec-rpc.gz $(DOCKER_SYNCD_CENTEC_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-centec-rpc $(DOCKER_SYNCD_CENTEC_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_CENTEC_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) $(DOCKER_SYNCD_CENTEC_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_CENTEC) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_CENTEC_RPC) ifeq ($(ENABLE_SYNCD_RPC),y) diff --git a/platform/centec/docker-syncd-centec.mk b/platform/centec/docker-syncd-centec.mk index c4335ab356ac..46f5d86c7150 100644 --- a/platform/centec/docker-syncd-centec.mk +++ b/platform/centec/docker-syncd-centec.mk @@ -3,6 +3,7 @@ DOCKER_SYNCD_CENTEC = docker-syncd-centec.gz $(DOCKER_SYNCD_CENTEC)_PATH = $(PLATFORM_PATH)/docker-syncd-centec $(DOCKER_SYNCD_CENTEC)_DEPENDS += $(SYNCD) +$(DOCKER_SYNCD_CENTEC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) $(DOCKER_SYNCD_CENTEC)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_CENTEC) ifneq ($(ENABLE_SYNCD_RPC),y) diff --git a/platform/centec/docker-syncd-centec/Dockerfile.j2 b/platform/centec/docker-syncd-centec/Dockerfile.j2 index d9b12bb426e4..e511d75678f4 100755 --- a/platform/centec/docker-syncd-centec/Dockerfile.j2 +++ b/platform/centec/docker-syncd-centec/Dockerfile.j2 @@ -21,6 +21,8 @@ RUN apt-get install -f kmod COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] ## Clean up RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y diff --git a/platform/centec/docker-syncd-centec/critical_processes b/platform/centec/docker-syncd-centec/critical_processes new file mode 100644 index 000000000000..6082f242b872 --- /dev/null +++ b/platform/centec/docker-syncd-centec/critical_processes @@ -0,0 +1 @@ +syncd diff --git a/platform/centec/docker-syncd-centec/supervisord.conf b/platform/centec/docker-syncd-centec/supervisord.conf index 1af5d70a1d0c..c823ab5680ef 100644 --- a/platform/centec/docker-syncd-centec/supervisord.conf +++ b/platform/centec/docker-syncd-centec/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog diff --git a/platform/marvell/docker-syncd-mrvl-rpc.mk b/platform/marvell/docker-syncd-mrvl-rpc.mk index d4002a3d645f..9110607c04d2 100644 --- a/platform/marvell/docker-syncd-mrvl-rpc.mk +++ b/platform/marvell/docker-syncd-mrvl-rpc.mk @@ -3,6 +3,7 @@ DOCKER_SYNCD_MRVL_RPC = docker-syncd-mrvl-rpc.gz $(DOCKER_SYNCD_MRVL_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-mrvl-rpc $(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_MRVL_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) $(DOCKER_SYNCD_MRVL_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_MRVL) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_MRVL_RPC) ifeq ($(ENABLE_SYNCD_RPC),y) diff --git a/platform/marvell/docker-syncd-mrvl.mk b/platform/marvell/docker-syncd-mrvl.mk index 4ee42e9cb904..983129f11107 100644 --- a/platform/marvell/docker-syncd-mrvl.mk +++ b/platform/marvell/docker-syncd-mrvl.mk @@ -3,6 +3,7 @@ DOCKER_SYNCD_MRVL = docker-syncd-mrvl.gz $(DOCKER_SYNCD_MRVL)_PATH = $(PLATFORM_PATH)/docker-syncd-mrvl $(DOCKER_SYNCD_MRVL)_DEPENDS += $(SYNCD) $(MRVL_FPA) $(REDIS_TOOLS) +$(DOCKER_SYNCD_MRVL)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) $(DOCKER_SYNCD_MRVL)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_MRVL) ifneq ($(ENABLE_SYNCD_RPC),y) diff --git a/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 b/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 index 7676b3f2ffa1..5eefa7002665 100755 --- a/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 +++ b/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 @@ -20,6 +20,8 @@ debs/{{ deb }}{{' '}} COPY ["start.sh", "syncd.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] ## Clean up RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y diff --git a/platform/marvell/docker-syncd-mrvl/critical_processes b/platform/marvell/docker-syncd-mrvl/critical_processes new file mode 100644 index 000000000000..6082f242b872 --- /dev/null +++ b/platform/marvell/docker-syncd-mrvl/critical_processes @@ -0,0 +1 @@ +syncd diff --git a/platform/marvell/docker-syncd-mrvl/supervisord.conf b/platform/marvell/docker-syncd-mrvl/supervisord.conf index 1e015fef931f..aea4d45b9afd 100644 --- a/platform/marvell/docker-syncd-mrvl/supervisord.conf +++ b/platform/marvell/docker-syncd-mrvl/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog diff --git a/platform/mellanox/docker-syncd-mlnx-rpc.mk b/platform/mellanox/docker-syncd-mlnx-rpc.mk index f27242ce17dc..6dd9936c336c 100644 --- a/platform/mellanox/docker-syncd-mlnx-rpc.mk +++ b/platform/mellanox/docker-syncd-mlnx-rpc.mk @@ -3,6 +3,7 @@ DOCKER_SYNCD_MLNX_RPC = docker-syncd-mlnx-rpc.gz $(DOCKER_SYNCD_MLNX_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-mlnx-rpc $(DOCKER_SYNCD_MLNX_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_MLNX_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) $(DOCKER_SYNCD_MLNX_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_MLNX) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_MLNX_RPC) ifeq ($(ENABLE_SYNCD_RPC),y) diff --git a/platform/mellanox/docker-syncd-mlnx.mk b/platform/mellanox/docker-syncd-mlnx.mk index 2da5961fc046..1e96acc1cf1b 100644 --- a/platform/mellanox/docker-syncd-mlnx.mk +++ b/platform/mellanox/docker-syncd-mlnx.mk @@ -3,6 +3,7 @@ DOCKER_SYNCD_MLNX = docker-syncd-mlnx.gz $(DOCKER_SYNCD_MLNX)_PATH = $(PLATFORM_PATH)/docker-syncd-mlnx $(DOCKER_SYNCD_MLNX)_DEPENDS += $(SYNCD) $(PYTHON_SDK_API) +$(DOCKER_SYNCD_MLNX)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) $(DOCKER_SYNCD_MLNX)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_MLNX) ifneq ($(ENABLE_SYNCD_RPC),y) diff --git a/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 b/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 index 966ef35ac9c8..9b62c9ec97ea 100755 --- a/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 +++ b/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 @@ -20,6 +20,8 @@ debs/{{ deb }}{{' '}} COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] ## Clean up RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y diff --git a/platform/mellanox/docker-syncd-mlnx/critical_processes b/platform/mellanox/docker-syncd-mlnx/critical_processes new file mode 100644 index 000000000000..6082f242b872 --- /dev/null +++ b/platform/mellanox/docker-syncd-mlnx/critical_processes @@ -0,0 +1 @@ +syncd diff --git a/platform/mellanox/docker-syncd-mlnx/supervisord.conf b/platform/mellanox/docker-syncd-mlnx/supervisord.conf index 1af5d70a1d0c..c823ab5680ef 100644 --- a/platform/mellanox/docker-syncd-mlnx/supervisord.conf +++ b/platform/mellanox/docker-syncd-mlnx/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog diff --git a/platform/nephos/docker-syncd-nephos-rpc.mk b/platform/nephos/docker-syncd-nephos-rpc.mk index e891d0b1a68d..4546a79fdab7 100644 --- a/platform/nephos/docker-syncd-nephos-rpc.mk +++ b/platform/nephos/docker-syncd-nephos-rpc.mk @@ -3,7 +3,7 @@ DOCKER_SYNCD_NEPHOS_RPC = docker-syncd-nephos-rpc.gz $(DOCKER_SYNCD_NEPHOS_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-nephos-rpc $(DOCKER_SYNCD_NEPHOS_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) -$(DOCKER_SYNCD_NEPHOS_RPC)_FILES += $(DSSERVE) $(NPX_DIAG) +$(DOCKER_SYNCD_NEPHOS_RPC)_FILES += $(DSSERVE) $(NPX_DIAG) $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) $(DOCKER_SYNCD_NEPHOS_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_NEPHOS) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_NEPHOS_RPC) ifeq ($(ENABLE_SYNCD_RPC),y) diff --git a/platform/nephos/docker-syncd-nephos.mk b/platform/nephos/docker-syncd-nephos.mk index a79c8524b890..ac5aeab5c3bc 100644 --- a/platform/nephos/docker-syncd-nephos.mk +++ b/platform/nephos/docker-syncd-nephos.mk @@ -3,7 +3,7 @@ DOCKER_SYNCD_NEPHOS = docker-syncd-nephos.gz $(DOCKER_SYNCD_NEPHOS)_PATH = $(PLATFORM_PATH)/docker-syncd-nephos $(DOCKER_SYNCD_NEPHOS)_DEPENDS += $(SYNCD) -$(DOCKER_SYNCD_NEPHOS)_FILES += $(DSSERVE) $(NPX_DIAG) +$(DOCKER_SYNCD_NEPHOS)_FILES += $(DSSERVE) $(NPX_DIAG) $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) $(DOCKER_SYNCD_NEPHOS)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_NEPHOS) ifneq ($(ENABLE_SYNCD_RPC),y) diff --git a/platform/nephos/docker-syncd-nephos/Dockerfile.j2 b/platform/nephos/docker-syncd-nephos/Dockerfile.j2 index e0248d460a12..0d02cc5557b1 100755 --- a/platform/nephos/docker-syncd-nephos/Dockerfile.j2 +++ b/platform/nephos/docker-syncd-nephos/Dockerfile.j2 @@ -23,6 +23,8 @@ COPY ["files/dsserve", "files/npx_diag", "start.sh", "/usr/bin/"] RUN chmod +x /usr/bin/dsserve /usr/bin/npx_diag COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] ## Clean up RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y diff --git a/platform/nephos/docker-syncd-nephos/critical_processes b/platform/nephos/docker-syncd-nephos/critical_processes new file mode 100644 index 000000000000..489668a89e08 --- /dev/null +++ b/platform/nephos/docker-syncd-nephos/critical_processes @@ -0,0 +1,2 @@ +dsserve +syncd diff --git a/platform/nephos/docker-syncd-nephos/supervisord.conf b/platform/nephos/docker-syncd-nephos/supervisord.conf index 1af5d70a1d0c..c823ab5680ef 100644 --- a/platform/nephos/docker-syncd-nephos/supervisord.conf +++ b/platform/nephos/docker-syncd-nephos/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog From d904b3e596bcc2a9efa745032694d9b8bac68e7e Mon Sep 17 00:00:00 2001 From: Wenda Ni Date: Tue, 5 Mar 2019 22:06:00 +0000 Subject: [PATCH 214/219] Add hook to allow customizing link cable lengths Signed-off-by: Wenda Ni --- files/build_templates/buffers_config.j2 | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/files/build_templates/buffers_config.j2 b/files/build_templates/buffers_config.j2 index 686d2824d4b4..284cf58a7791 100644 --- a/files/build_templates/buffers_config.j2 +++ b/files/build_templates/buffers_config.j2 @@ -29,12 +29,16 @@ def {# 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' - } --%} +{%- if defs.ports2cable is defined %} + {%- set ports2cable = defs.ports2cable %} +{%- else %} + {%- set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } + -%} +{%- endif %} {%- macro cable_length(port_name) %} {%- set cable_len = [] %} From b38bab0e4b5c40343ad1f04e9dce597dcd0377a7 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Wed, 21 Nov 2018 08:08:37 -0800 Subject: [PATCH 215/219] [bde driver] black list linux_kernel_bde driver (#2284) This driver should be loaded by sonic service. If kernel tries to load it, the driver would be loaded with default parameters, which is not right for sonic. Signed-off-by: Ying Xie --- files/build_templates/sonic_debian_extension.j2 | 4 ++++ files/image_config/platform/linux_kernel_bde.conf | 1 + 2 files changed, 5 insertions(+) create mode 100644 files/image_config/platform/linux_kernel_bde.conf diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 1575dd56abda..2f8a7485fbdf 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -58,6 +58,7 @@ sudo cp $IMAGE_CONFIGS/environment/motd $FILESYSTEM_ROOT/etc/ # Create all needed directories sudo mkdir -p $FILESYSTEM_ROOT/etc/sonic/ +sudo mkdir -p $FILESYSTEM_ROOT/etc/modprobe.d/ sudo mkdir -p $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ # Install dependencies for SONiC config engine @@ -264,6 +265,9 @@ sudo cp src/libwrap/tcp-wrappers-7.6.q/tcpdmatch $FILESYSTEM_ROOT/usr/bin ## copy platform rc.local sudo cp $IMAGE_CONFIGS/platform/rc.local $FILESYSTEM_ROOT/etc/ +## copy blacklist file +sudo cp $IMAGE_CONFIGS/platform/linux_kernel_bde.conf $FILESYSTEM_ROOT/etc/modprobe.d/ + {% if installer_images.strip() -%} {% for image in installer_images.strip().split(' ') -%} {% set imagefilename = image.split('/')|last -%} diff --git a/files/image_config/platform/linux_kernel_bde.conf b/files/image_config/platform/linux_kernel_bde.conf new file mode 100644 index 000000000000..5f2b1c4e644d --- /dev/null +++ b/files/image_config/platform/linux_kernel_bde.conf @@ -0,0 +1 @@ +blacklist linux_kernel_bde From 09f413246ea8d7fcab36f00a0dda198060ead702 Mon Sep 17 00:00:00 2001 From: Shuotian Cheng Date: Tue, 26 Mar 2019 23:48:22 -0700 Subject: [PATCH 216/219] [Broadcom]: Update SAI to 3.1.3.4-20 (#2708) Address parity error in XOR bank for TH device Signed-off-by: Shu0T1an ChenG --- platform/broadcom/sai.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 03819ead0741..f2ed825d5dbe 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,9 +1,9 @@ -BRCM_SAI = libsaibcm_3.1.3.4-19_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/libsaibcm_3.1.3.4-19_amd64.deb?sv=2015-04-05&sr=b&sig=tbjRGxCW644D0kAuVsl2WQLj99vlb0dKgizE6TpoYjw%3D&se=2032-10-21T03%3A08%3A33Z&sp=r" +BRCM_SAI = libsaibcm_3.1.3.4-20_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/libsaibcm_3.1.3.4-20_amd64.deb?sv=2015-04-05&sr=b&sig=r5ezPQ1tNe53icqTFio2dpE2it2XKPTk5kv4LcEA4gs%3D&se=2032-12-02T18%3A10%3A05Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.1.3.4-19_amd64.deb +BRCM_SAI_DEV = libsaibcm-dev_3.1.3.4-20_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/libsaibcm-dev_3.1.3.4-19_amd64.deb?sv=2015-04-05&sr=b&sig=AIteLXKhrlbhY661nG1LihraEu31j5G9J%2FLsFETfXvc%3D&se=2032-10-21T03%3A09%3A32Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/libsaibcm-dev_3.1.3.4-20_amd64.deb?sv=2015-04-05&sr=b&sig=VFbXjNqtnZTNk7ffwcmjPjeXakXmJL4hozjlyNhT%2F3A%3D&se=2032-12-02T18%3A10%3A28Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) From 99ed95420353d2e08fe9c89c4f2ed7cdb7884036 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 27 Mar 2019 11:23:38 -0700 Subject: [PATCH 217/219] [201803] Modify Debian apt repos to reflect changes made by maintainers (#2709) * [201803][apt] Point to archive.debian.org for jessie-backports; remove jessie-updates * Add no-check-valid-until for apt in base image * Add no-check-valid-until for apt in docker-base * [sonic-slave] Remove jessie-backports, as it is unused in the slave container --- build_debian.sh | 2 +- dockers/docker-base/Dockerfile.j2 | 4 ++++ dockers/docker-base/no-check-valid-until | 1 + dockers/docker-base/sources.list | 2 +- dockers/docker-ptf/Dockerfile.j2 | 3 +++ files/apt/apt.conf.d/no-check-valid-until | 1 + files/apt/sources.list | 2 +- .../debian_archive_trafficmanager_net_debian.list | 2 +- sonic-slave/Dockerfile | 6 ++++-- 9 files changed, 17 insertions(+), 6 deletions(-) create mode 100644 dockers/docker-base/no-check-valid-until create mode 100644 files/apt/apt.conf.d/no-check-valid-until diff --git a/build_debian.sh b/build_debian.sh index 10d1539381b1..ea060249a1b3 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -91,7 +91,7 @@ sudo LANG=C chroot $FILESYSTEM_ROOT mount proc /proc -t proc ## Pointing apt to public apt mirrors and getting latest packages, needed for latest security updates sudo cp files/apt/sources.list $FILESYSTEM_ROOT/etc/apt/ -sudo cp files/apt/apt.conf.d/{81norecommends,apt-{clean,gzip-indexes,no-languages}} $FILESYSTEM_ROOT/etc/apt/apt.conf.d/ +sudo cp files/apt/apt.conf.d/* $FILESYSTEM_ROOT/etc/apt/apt.conf.d/ sudo LANG=C chroot $FILESYSTEM_ROOT bash -c 'apt-mark auto `apt-mark showmanual`' ## Note: set lang to prevent locale warnings in your chroot diff --git a/dockers/docker-base/Dockerfile.j2 b/dockers/docker-base/Dockerfile.j2 index 43ae42a11e69..15d3faf57c81 100644 --- a/dockers/docker-base/Dockerfile.j2 +++ b/dockers/docker-base/Dockerfile.j2 @@ -17,9 +17,13 @@ RUN rm -rf \ # Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive +# Remove retired jessie-updates repo +RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list + # Configure data sources for apt/dpkg COPY ["sources.list", "/etc/apt/sources.list"] COPY ["dpkg_01_drop", "/etc/dpkg/dpkg.cfg.d/01_drop"] +COPY ["no-check-valid-until", "/etc/apt/apt.conf.d"] RUN apt-get update # Pre-install fundamental packages diff --git a/dockers/docker-base/no-check-valid-until b/dockers/docker-base/no-check-valid-until new file mode 100644 index 000000000000..97b9c9005181 --- /dev/null +++ b/dockers/docker-base/no-check-valid-until @@ -0,0 +1 @@ +Acquire::Check-Valid-Until "false"; diff --git a/dockers/docker-base/sources.list b/dockers/docker-base/sources.list index 7121d6fd8c2d..45a508420a89 100644 --- a/dockers/docker-base/sources.list +++ b/dockers/docker-base/sources.list @@ -5,4 +5,4 @@ deb http://debian-archive.trafficmanager.net/debian/ jessie main contrib non-fre deb-src http://debian-archive.trafficmanager.net/debian/ jessie main contrib non-free deb http://debian-archive.trafficmanager.net/debian-security/ jessie/updates main contrib non-free deb-src http://debian-archive.trafficmanager.net/debian-security/ jessie/updates main contrib non-free -deb http://debian-archive.trafficmanager.net/debian/ jessie-backports main contrib non-free +deb http://archive.debian.org/debian/ jessie-backports main contrib non-free diff --git a/dockers/docker-ptf/Dockerfile.j2 b/dockers/docker-ptf/Dockerfile.j2 index 2d9b1544d95a..6b7537b6fdf7 100644 --- a/dockers/docker-ptf/Dockerfile.j2 +++ b/dockers/docker-ptf/Dockerfile.j2 @@ -12,6 +12,9 @@ debs/ ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive +# Remove retired jessie-updates repo +RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list + ## Set the apt source, update package cache and install necessary packages RUN sed --in-place 's/httpredir.debian.org/debian-archive.trafficmanager.net/' /etc/apt/sources.list \ && apt-get update \ diff --git a/files/apt/apt.conf.d/no-check-valid-until b/files/apt/apt.conf.d/no-check-valid-until new file mode 100644 index 000000000000..97b9c9005181 --- /dev/null +++ b/files/apt/apt.conf.d/no-check-valid-until @@ -0,0 +1 @@ +Acquire::Check-Valid-Until "false"; diff --git a/files/apt/sources.list b/files/apt/sources.list index 7121d6fd8c2d..45a508420a89 100644 --- a/files/apt/sources.list +++ b/files/apt/sources.list @@ -5,4 +5,4 @@ deb http://debian-archive.trafficmanager.net/debian/ jessie main contrib non-fre deb-src http://debian-archive.trafficmanager.net/debian/ jessie main contrib non-free deb http://debian-archive.trafficmanager.net/debian-security/ jessie/updates main contrib non-free deb-src http://debian-archive.trafficmanager.net/debian-security/ jessie/updates main contrib non-free -deb http://debian-archive.trafficmanager.net/debian/ jessie-backports main contrib non-free +deb http://archive.debian.org/debian/ jessie-backports main contrib non-free diff --git a/files/image_config/apt/sources.list.d/debian_archive_trafficmanager_net_debian.list b/files/image_config/apt/sources.list.d/debian_archive_trafficmanager_net_debian.list index 4daa3ccba677..e32bc63d14c8 100644 --- a/files/image_config/apt/sources.list.d/debian_archive_trafficmanager_net_debian.list +++ b/files/image_config/apt/sources.list.d/debian_archive_trafficmanager_net_debian.list @@ -1,3 +1,3 @@ deb http://debian-archive.trafficmanager.net/debian/ jessie main contrib non-free deb http://debian-archive.trafficmanager.net/debian-security/ jessie/updates main contrib non-free -deb http://debian-archive.trafficmanager.net/debian/ jessie-backports main contrib non-free +deb http://archive.debian.org/debian/ jessie-backports main contrib non-free diff --git a/sonic-slave/Dockerfile b/sonic-slave/Dockerfile index 35e73e3e308a..0b51df14ea19 100644 --- a/sonic-slave/Dockerfile +++ b/sonic-slave/Dockerfile @@ -2,11 +2,13 @@ FROM debian:jessie MAINTAINER johnar@microsoft.com +# Remove retired jessie-updates repo +RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list + RUN echo "deb http://debian-archive.trafficmanager.net/debian/ jessie main contrib non-free" >> /etc/apt/sources.list && \ echo "deb-src http://debian-archive.trafficmanager.net/debian/ jessie main contrib non-free" >> /etc/apt/sources.list && \ echo "deb http://debian-archive.trafficmanager.net/debian-security/ jessie/updates main contrib non-free" >> /etc/apt/sources.list && \ - echo "deb-src http://debian-archive.trafficmanager.net/debian-security/ jessie/updates main contrib non-free" >> /etc/apt/sources.list && \ - echo "deb http://debian-archive.trafficmanager.net/debian/ jessie-backports main contrib non-free" >> /etc/apt/sources.list + echo "deb-src http://debian-archive.trafficmanager.net/debian-security/ jessie/updates main contrib non-free" >> /etc/apt/sources.list ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive From cbca6847d1bf190ce1ca90b91a57fb60ca59796e Mon Sep 17 00:00:00 2001 From: Andriy Moroz Date: Thu, 28 Mar 2019 03:34:12 +0200 Subject: [PATCH 218/219] [devices]: Add support of HwSKU Mellanox-SN2700-C28D8 (#2690) * Add support of HwSKU Mellanox-SN2700-C28D8 Signed-off-by: Andriy Moroz --- .../Mellanox-SN2700-C28D8/buffers.json.j2 | 1 + .../buffers_defaults_t0.j2 | 1 + .../buffers_defaults_t1.j2 | 1 + .../pg_profile_lookup.ini | 1 + .../Mellanox-SN2700-C28D8/port_config.ini | 37 +++ .../Mellanox-SN2700-C28D8/qos.json | 164 ++++++++++++ .../Mellanox-SN2700-C28D8/sai.profile | 1 + .../sai_2700_8x50g_28x100g.xml | 247 ++++++++++++++++++ 8 files changed, 453 insertions(+) create mode 120000 device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/buffers.json.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/buffers_defaults_t0.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/buffers_defaults_t1.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/pg_profile_lookup.ini create mode 100644 device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/port_config.ini create mode 100644 device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/qos.json create mode 100644 device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/sai.profile create mode 100644 device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/sai_2700_8x50g_28x100g.xml diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/buffers.json.j2 new file mode 120000 index 000000000000..30c4e1d5bfdd --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/buffers.json.j2 @@ -0,0 +1 @@ +../ACS-MSN2700/buffers.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/buffers_defaults_t0.j2 new file mode 120000 index 000000000000..a722094938f8 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/buffers_defaults_t0.j2 @@ -0,0 +1 @@ +../ACS-MSN2700/buffers_defaults_t0.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/buffers_defaults_t1.j2 new file mode 120000 index 000000000000..b02d5e0194ac --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/buffers_defaults_t1.j2 @@ -0,0 +1 @@ +../ACS-MSN2700/buffers_defaults_t1.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/pg_profile_lookup.ini new file mode 120000 index 000000000000..229a556f88a8 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/pg_profile_lookup.ini @@ -0,0 +1 @@ +../ACS-MSN2700/pg_profile_lookup.ini \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/port_config.ini b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/port_config.ini new file mode 100644 index 000000000000..345e6a206731 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/port_config.ini @@ -0,0 +1,37 @@ +# name lanes speed alias index +Ethernet0 0,1,2,3 100000 etp1 1 +Ethernet4 4,5,6,7 100000 etp2 2 +Ethernet8 8,9,10,11 100000 etp3 3 +Ethernet12 12,13,14,15 100000 etp4 4 +Ethernet16 16,17,18,19 100000 etp5 5 +Ethernet20 20,21,22,23 100000 etp6 6 +Ethernet24 24,25,26,27 100000 etp7 7 +Ethernet28 28,29,30,31 100000 etp8 8 +Ethernet32 32,33,34,35 100000 etp9 9 +Ethernet36 36,37,38,39 100000 etp10 10 +Ethernet40 40,41,42,43 100000 etp11 11 +Ethernet44 44,45,46,47 100000 etp12 12 +Ethernet48 48,49,50,51 100000 etp13 13 +Ethernet52 52,53,54,55 100000 etp14 14 +Ethernet56 56,57,58,59 100000 etp15 15 +Ethernet60 60,61,62,63 100000 etp16 16 +Ethernet64 64,65,66,67 100000 etp17 17 +Ethernet68 68,69,70,71 100000 etp18 18 +Ethernet72 72,73,74,75 100000 etp19 19 +Ethernet76 76,77,78,79 100000 etp20 20 +Ethernet80 80,81,82,83 100000 etp21 21 +Ethernet84 84,85,86,87 100000 etp22 22 +Ethernet88 88,89,90,91 100000 etp23 23 +Ethernet92 92,93,94,95 100000 etp24 24 +Ethernet96 96,97,98,99 100000 etp25 25 +Ethernet100 100,101,102,103 100000 etp26 26 +Ethernet104 104,105,106,107 100000 etp27 27 +Ethernet108 108,109,110,111 100000 etp28 28 +Ethernet112 112,113 50000 etp29a 29 +Ethernet114 114,115 50000 etp29b 29 +Ethernet116 116,117 50000 etp30a 30 +Ethernet118 118,119 50000 etp30b 30 +Ethernet120 120,121 50000 etp31a 31 +Ethernet122 122,123 50000 etp31b 31 +Ethernet124 124,125 50000 etp32a 32 +Ethernet126 126,127 50000 etp32b 32 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/qos.json b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/qos.json new file mode 100644 index 000000000000..42e8943676c6 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/qos.json @@ -0,0 +1,164 @@ +{ + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4" + } + }, + "MAP_PFC_PRIORITY_TO_QUEUE": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4" + } + }, + "TC_TO_QUEUE_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"3", + "4":"4", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type":"DWRR", + "weight": "25" + }, + "scheduler.1": { + "type":"DWRR", + "weight": "30" + }, + "scheduler.2": { + "type":"DWRR", + "weight": "20" + } + }, + "PFC_PRIORITY_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4" + } + }, + "PORT_QOS_MAP": { + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_to_pg_map" : "[PFC_PRIORITY_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_enable": "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSY": { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "wred_red_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"516096", + "red_min_threshold":"516096", + "yellow_max_threshold":"516096", + "yellow_min_threshold":"516096", + "green_max_threshold": "184320", + "green_min_threshold": "184320" + }, + "AZURE_LOSSLESS": { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "wred_red_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"516096", + "red_min_threshold":"516096", + "yellow_max_threshold":"516096", + "yellow_min_threshold":"516096", + "green_max_threshold": "184320", + "green_min_threshold": "184320" + } + }, + "QUEUE": { + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126|0": { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126|1": { + "scheduler" : "[SCHEDULER|scheduler.2]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet114,Ethernet116,Ethernet118,Ethernet120,Ethernet122,Ethernet124,Ethernet126|3-4": { + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/sai.profile b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/sai.profile new file mode 100644 index 000000000000..cfeb4a5fa4ba --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_2700_8x50g_28x100g.xml diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/sai_2700_8x50g_28x100g.xml b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/sai_2700_8x50g_28x100g.xml new file mode 100644 index 000000000000..3baf0fdf04a9 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/sai_2700_8x50g_28x100g.xml @@ -0,0 +1,247 @@ + + + + + + 00:02:03:04:05:00 + + + 32 + + + + + 1 + 4 + 16 + + + 3 + + + 11534336 + + + 3 + 4 + 17 + 1 + 11534336 + + + 5 + 4 + 18 + 3 + 11534336 + + + 7 + 4 + 19 + 1 + 11534336 + + + 9 + 4 + 20 + 3 + 11534336 + + + 11 + 4 + 21 + 1 + 11534336 + + + 13 + 4 + 22 + 3 + 11534336 + + + 15 + 4 + 23 + 1 + 11534336 + + + 17 + 4 + 24 + 3 + 11534336 + + + 19 + 4 + 25 + 1 + 11534336 + + + 21 + 4 + 26 + 3 + 11534336 + + + 23 + 4 + 27 + 1 + 11534336 + + + 25 + 4 + 28 + 3 + 3221225472 + 2 + + + 27 + 4 + 29 + 1 + 3221225472 + 2 + + + 29 + 4 + 30 + 3 + 3221225472 + 2 + + + 31 + 4 + 31 + 1 + 3221225472 + 2 + + + 33 + 4 + 14 + 3 + 11534336 + + + 35 + 4 + 15 + 1 + 11534336 + + + 37 + 4 + 12 + 3 + 11534336 + + + 39 + 4 + 13 + 1 + 11534336 + + + 41 + 4 + 10 + 3 + 11534336 + + + 43 + 4 + 11 + 1 + 11534336 + + + 45 + 4 + 8 + 3 + 11534336 + + + 47 + 4 + 9 + 1 + 11534336 + + + 49 + 4 + 6 + 3 + 11534336 + + + 51 + 4 + 7 + 1 + 11534336 + + + 53 + 4 + 4 + 3 + 11534336 + + + 55 + 4 + 5 + 1 + 11534336 + + + 57 + 4 + 2 + 3 + 11534336 + + + 59 + 4 + 3 + 1 + 11534336 + + + 61 + 4 + 0 + 3 + 11534336 + + + 63 + 4 + 1 + 1 + 11534336 + + + + From 9e76a47aa9237fa004de6f8637383b108199404e Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Tue, 2 Apr 2019 01:47:00 +0300 Subject: [PATCH 219/219] [devices]: Upgrade Mellanox HW-MGMT: fix high CPU utilization issue. (#2726) Signed-off-by: Nazarii Hnydyn --- platform/mellanox/hw-management.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/mellanox/hw-management.mk b/platform/mellanox/hw-management.mk index dcbce4564ee8..b252504f10b8 100644 --- a/platform/mellanox/hw-management.mk +++ b/platform/mellanox/hw-management.mk @@ -1,6 +1,6 @@ # Mellanox HW Management -MLNX_HW_MANAGEMENT_VERSION = V1.0.0160 +MLNX_HW_MANAGEMENT_VERSION = V1.0.0165 export MLNX_HW_MANAGEMENT_VERSION